opentrons 8.6.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of opentrons might be problematic. Click here for more details.
- opentrons/__init__.py +150 -0
- opentrons/_version.py +34 -0
- opentrons/calibration_storage/__init__.py +54 -0
- opentrons/calibration_storage/deck_configuration.py +62 -0
- opentrons/calibration_storage/encoder_decoder.py +31 -0
- opentrons/calibration_storage/file_operators.py +142 -0
- opentrons/calibration_storage/helpers.py +103 -0
- opentrons/calibration_storage/ot2/__init__.py +34 -0
- opentrons/calibration_storage/ot2/deck_attitude.py +85 -0
- opentrons/calibration_storage/ot2/mark_bad_calibration.py +27 -0
- opentrons/calibration_storage/ot2/models/__init__.py +0 -0
- opentrons/calibration_storage/ot2/models/v1.py +149 -0
- opentrons/calibration_storage/ot2/pipette_offset.py +129 -0
- opentrons/calibration_storage/ot2/tip_length.py +281 -0
- opentrons/calibration_storage/ot3/__init__.py +31 -0
- opentrons/calibration_storage/ot3/deck_attitude.py +83 -0
- opentrons/calibration_storage/ot3/gripper_offset.py +156 -0
- opentrons/calibration_storage/ot3/models/__init__.py +0 -0
- opentrons/calibration_storage/ot3/models/v1.py +122 -0
- opentrons/calibration_storage/ot3/module_offset.py +138 -0
- opentrons/calibration_storage/ot3/pipette_offset.py +95 -0
- opentrons/calibration_storage/types.py +45 -0
- opentrons/cli/__init__.py +21 -0
- opentrons/cli/__main__.py +5 -0
- opentrons/cli/analyze.py +501 -0
- opentrons/config/__init__.py +631 -0
- opentrons/config/advanced_settings.py +871 -0
- opentrons/config/defaults_ot2.py +214 -0
- opentrons/config/defaults_ot3.py +499 -0
- opentrons/config/feature_flags.py +86 -0
- opentrons/config/gripper_config.py +55 -0
- opentrons/config/reset.py +203 -0
- opentrons/config/robot_configs.py +187 -0
- opentrons/config/types.py +183 -0
- opentrons/drivers/__init__.py +0 -0
- opentrons/drivers/absorbance_reader/__init__.py +11 -0
- opentrons/drivers/absorbance_reader/abstract.py +72 -0
- opentrons/drivers/absorbance_reader/async_byonoy.py +352 -0
- opentrons/drivers/absorbance_reader/driver.py +81 -0
- opentrons/drivers/absorbance_reader/hid_protocol.py +161 -0
- opentrons/drivers/absorbance_reader/simulator.py +84 -0
- opentrons/drivers/asyncio/__init__.py +0 -0
- opentrons/drivers/asyncio/communication/__init__.py +22 -0
- opentrons/drivers/asyncio/communication/async_serial.py +183 -0
- opentrons/drivers/asyncio/communication/errors.py +88 -0
- opentrons/drivers/asyncio/communication/serial_connection.py +552 -0
- opentrons/drivers/command_builder.py +102 -0
- opentrons/drivers/flex_stacker/__init__.py +13 -0
- opentrons/drivers/flex_stacker/abstract.py +214 -0
- opentrons/drivers/flex_stacker/driver.py +768 -0
- opentrons/drivers/flex_stacker/errors.py +68 -0
- opentrons/drivers/flex_stacker/simulator.py +309 -0
- opentrons/drivers/flex_stacker/types.py +367 -0
- opentrons/drivers/flex_stacker/utils.py +19 -0
- opentrons/drivers/heater_shaker/__init__.py +5 -0
- opentrons/drivers/heater_shaker/abstract.py +76 -0
- opentrons/drivers/heater_shaker/driver.py +204 -0
- opentrons/drivers/heater_shaker/simulator.py +94 -0
- opentrons/drivers/mag_deck/__init__.py +6 -0
- opentrons/drivers/mag_deck/abstract.py +44 -0
- opentrons/drivers/mag_deck/driver.py +208 -0
- opentrons/drivers/mag_deck/simulator.py +63 -0
- opentrons/drivers/rpi_drivers/__init__.py +33 -0
- opentrons/drivers/rpi_drivers/dev_types.py +94 -0
- opentrons/drivers/rpi_drivers/gpio.py +282 -0
- opentrons/drivers/rpi_drivers/gpio_simulator.py +127 -0
- opentrons/drivers/rpi_drivers/interfaces.py +15 -0
- opentrons/drivers/rpi_drivers/types.py +364 -0
- opentrons/drivers/rpi_drivers/usb.py +102 -0
- opentrons/drivers/rpi_drivers/usb_simulator.py +22 -0
- opentrons/drivers/serial_communication.py +151 -0
- opentrons/drivers/smoothie_drivers/__init__.py +4 -0
- opentrons/drivers/smoothie_drivers/connection.py +51 -0
- opentrons/drivers/smoothie_drivers/constants.py +121 -0
- opentrons/drivers/smoothie_drivers/driver_3_0.py +1933 -0
- opentrons/drivers/smoothie_drivers/errors.py +49 -0
- opentrons/drivers/smoothie_drivers/parse_utils.py +143 -0
- opentrons/drivers/smoothie_drivers/simulator.py +99 -0
- opentrons/drivers/smoothie_drivers/types.py +16 -0
- opentrons/drivers/temp_deck/__init__.py +10 -0
- opentrons/drivers/temp_deck/abstract.py +54 -0
- opentrons/drivers/temp_deck/driver.py +197 -0
- opentrons/drivers/temp_deck/simulator.py +57 -0
- opentrons/drivers/thermocycler/__init__.py +12 -0
- opentrons/drivers/thermocycler/abstract.py +99 -0
- opentrons/drivers/thermocycler/driver.py +395 -0
- opentrons/drivers/thermocycler/simulator.py +126 -0
- opentrons/drivers/types.py +107 -0
- opentrons/drivers/utils.py +222 -0
- opentrons/execute.py +742 -0
- opentrons/hardware_control/__init__.py +65 -0
- opentrons/hardware_control/__main__.py +77 -0
- opentrons/hardware_control/adapters.py +98 -0
- opentrons/hardware_control/api.py +1347 -0
- opentrons/hardware_control/backends/__init__.py +7 -0
- opentrons/hardware_control/backends/controller.py +400 -0
- opentrons/hardware_control/backends/errors.py +9 -0
- opentrons/hardware_control/backends/estop_state.py +164 -0
- opentrons/hardware_control/backends/flex_protocol.py +497 -0
- opentrons/hardware_control/backends/ot3controller.py +1930 -0
- opentrons/hardware_control/backends/ot3simulator.py +900 -0
- opentrons/hardware_control/backends/ot3utils.py +664 -0
- opentrons/hardware_control/backends/simulator.py +442 -0
- opentrons/hardware_control/backends/status_bar_state.py +240 -0
- opentrons/hardware_control/backends/subsystem_manager.py +431 -0
- opentrons/hardware_control/backends/tip_presence_manager.py +173 -0
- opentrons/hardware_control/backends/types.py +14 -0
- opentrons/hardware_control/constants.py +6 -0
- opentrons/hardware_control/dev_types.py +125 -0
- opentrons/hardware_control/emulation/__init__.py +0 -0
- opentrons/hardware_control/emulation/abstract_emulator.py +21 -0
- opentrons/hardware_control/emulation/app.py +56 -0
- opentrons/hardware_control/emulation/connection_handler.py +38 -0
- opentrons/hardware_control/emulation/heater_shaker.py +150 -0
- opentrons/hardware_control/emulation/magdeck.py +60 -0
- opentrons/hardware_control/emulation/module_server/__init__.py +8 -0
- opentrons/hardware_control/emulation/module_server/client.py +78 -0
- opentrons/hardware_control/emulation/module_server/helpers.py +130 -0
- opentrons/hardware_control/emulation/module_server/models.py +31 -0
- opentrons/hardware_control/emulation/module_server/server.py +110 -0
- opentrons/hardware_control/emulation/parser.py +74 -0
- opentrons/hardware_control/emulation/proxy.py +241 -0
- opentrons/hardware_control/emulation/run_emulator.py +68 -0
- opentrons/hardware_control/emulation/scripts/__init__.py +0 -0
- opentrons/hardware_control/emulation/scripts/run_app.py +54 -0
- opentrons/hardware_control/emulation/scripts/run_module_emulator.py +72 -0
- opentrons/hardware_control/emulation/scripts/run_smoothie.py +37 -0
- opentrons/hardware_control/emulation/settings.py +119 -0
- opentrons/hardware_control/emulation/simulations.py +133 -0
- opentrons/hardware_control/emulation/smoothie.py +192 -0
- opentrons/hardware_control/emulation/tempdeck.py +69 -0
- opentrons/hardware_control/emulation/thermocycler.py +128 -0
- opentrons/hardware_control/emulation/types.py +10 -0
- opentrons/hardware_control/emulation/util.py +38 -0
- opentrons/hardware_control/errors.py +43 -0
- opentrons/hardware_control/execution_manager.py +164 -0
- opentrons/hardware_control/instruments/__init__.py +5 -0
- opentrons/hardware_control/instruments/instrument_abc.py +39 -0
- opentrons/hardware_control/instruments/ot2/__init__.py +0 -0
- opentrons/hardware_control/instruments/ot2/instrument_calibration.py +152 -0
- opentrons/hardware_control/instruments/ot2/pipette.py +777 -0
- opentrons/hardware_control/instruments/ot2/pipette_handler.py +995 -0
- opentrons/hardware_control/instruments/ot3/__init__.py +0 -0
- opentrons/hardware_control/instruments/ot3/gripper.py +420 -0
- opentrons/hardware_control/instruments/ot3/gripper_handler.py +173 -0
- opentrons/hardware_control/instruments/ot3/instrument_calibration.py +214 -0
- opentrons/hardware_control/instruments/ot3/pipette.py +858 -0
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +1030 -0
- opentrons/hardware_control/module_control.py +332 -0
- opentrons/hardware_control/modules/__init__.py +69 -0
- opentrons/hardware_control/modules/absorbance_reader.py +373 -0
- opentrons/hardware_control/modules/errors.py +7 -0
- opentrons/hardware_control/modules/flex_stacker.py +948 -0
- opentrons/hardware_control/modules/heater_shaker.py +426 -0
- opentrons/hardware_control/modules/lid_temp_status.py +35 -0
- opentrons/hardware_control/modules/magdeck.py +233 -0
- opentrons/hardware_control/modules/mod_abc.py +245 -0
- opentrons/hardware_control/modules/module_calibration.py +93 -0
- opentrons/hardware_control/modules/plate_temp_status.py +61 -0
- opentrons/hardware_control/modules/tempdeck.py +299 -0
- opentrons/hardware_control/modules/thermocycler.py +731 -0
- opentrons/hardware_control/modules/types.py +417 -0
- opentrons/hardware_control/modules/update.py +255 -0
- opentrons/hardware_control/modules/utils.py +73 -0
- opentrons/hardware_control/motion_utilities.py +318 -0
- opentrons/hardware_control/nozzle_manager.py +422 -0
- opentrons/hardware_control/ot3_calibration.py +1171 -0
- opentrons/hardware_control/ot3api.py +3227 -0
- opentrons/hardware_control/pause_manager.py +31 -0
- opentrons/hardware_control/poller.py +112 -0
- opentrons/hardware_control/protocols/__init__.py +106 -0
- opentrons/hardware_control/protocols/asyncio_configurable.py +11 -0
- opentrons/hardware_control/protocols/calibratable.py +45 -0
- opentrons/hardware_control/protocols/chassis_accessory_manager.py +90 -0
- opentrons/hardware_control/protocols/configurable.py +48 -0
- opentrons/hardware_control/protocols/event_sourcer.py +18 -0
- opentrons/hardware_control/protocols/execution_controllable.py +33 -0
- opentrons/hardware_control/protocols/flex_calibratable.py +96 -0
- opentrons/hardware_control/protocols/flex_instrument_configurer.py +52 -0
- opentrons/hardware_control/protocols/gripper_controller.py +55 -0
- opentrons/hardware_control/protocols/hardware_manager.py +51 -0
- opentrons/hardware_control/protocols/identifiable.py +16 -0
- opentrons/hardware_control/protocols/instrument_configurer.py +206 -0
- opentrons/hardware_control/protocols/liquid_handler.py +266 -0
- opentrons/hardware_control/protocols/module_provider.py +16 -0
- opentrons/hardware_control/protocols/motion_controller.py +243 -0
- opentrons/hardware_control/protocols/position_estimator.py +45 -0
- opentrons/hardware_control/protocols/simulatable.py +10 -0
- opentrons/hardware_control/protocols/stoppable.py +9 -0
- opentrons/hardware_control/protocols/types.py +27 -0
- opentrons/hardware_control/robot_calibration.py +224 -0
- opentrons/hardware_control/scripts/README.md +28 -0
- opentrons/hardware_control/scripts/__init__.py +1 -0
- opentrons/hardware_control/scripts/gripper_control.py +208 -0
- opentrons/hardware_control/scripts/ot3gripper +7 -0
- opentrons/hardware_control/scripts/ot3repl +7 -0
- opentrons/hardware_control/scripts/repl.py +187 -0
- opentrons/hardware_control/scripts/tc_control.py +97 -0
- opentrons/hardware_control/simulator_setup.py +260 -0
- opentrons/hardware_control/thread_manager.py +431 -0
- opentrons/hardware_control/threaded_async_lock.py +97 -0
- opentrons/hardware_control/types.py +792 -0
- opentrons/hardware_control/util.py +234 -0
- opentrons/legacy_broker.py +53 -0
- opentrons/legacy_commands/__init__.py +1 -0
- opentrons/legacy_commands/commands.py +483 -0
- opentrons/legacy_commands/helpers.py +153 -0
- opentrons/legacy_commands/module_commands.py +215 -0
- opentrons/legacy_commands/protocol_commands.py +54 -0
- opentrons/legacy_commands/publisher.py +155 -0
- opentrons/legacy_commands/robot_commands.py +51 -0
- opentrons/legacy_commands/types.py +1115 -0
- opentrons/motion_planning/__init__.py +32 -0
- opentrons/motion_planning/adjacent_slots_getters.py +168 -0
- opentrons/motion_planning/deck_conflict.py +396 -0
- opentrons/motion_planning/errors.py +35 -0
- opentrons/motion_planning/types.py +42 -0
- opentrons/motion_planning/waypoints.py +218 -0
- opentrons/ordered_set.py +138 -0
- opentrons/protocol_api/__init__.py +105 -0
- opentrons/protocol_api/_liquid.py +157 -0
- opentrons/protocol_api/_liquid_properties.py +814 -0
- opentrons/protocol_api/_nozzle_layout.py +31 -0
- opentrons/protocol_api/_parameter_context.py +300 -0
- opentrons/protocol_api/_parameters.py +31 -0
- opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
- opentrons/protocol_api/_types.py +43 -0
- opentrons/protocol_api/config.py +23 -0
- opentrons/protocol_api/core/__init__.py +23 -0
- opentrons/protocol_api/core/common.py +33 -0
- opentrons/protocol_api/core/core_map.py +74 -0
- opentrons/protocol_api/core/engine/__init__.py +22 -0
- opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
- opentrons/protocol_api/core/engine/deck_conflict.py +348 -0
- opentrons/protocol_api/core/engine/exceptions.py +19 -0
- opentrons/protocol_api/core/engine/instrument.py +2391 -0
- opentrons/protocol_api/core/engine/labware.py +238 -0
- opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
- opentrons/protocol_api/core/engine/module_core.py +1025 -0
- opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
- opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
- opentrons/protocol_api/core/engine/point_calculations.py +64 -0
- opentrons/protocol_api/core/engine/protocol.py +1153 -0
- opentrons/protocol_api/core/engine/robot.py +139 -0
- opentrons/protocol_api/core/engine/stringify.py +74 -0
- opentrons/protocol_api/core/engine/transfer_components_executor.py +990 -0
- opentrons/protocol_api/core/engine/well.py +241 -0
- opentrons/protocol_api/core/instrument.py +459 -0
- opentrons/protocol_api/core/labware.py +151 -0
- opentrons/protocol_api/core/legacy/__init__.py +11 -0
- opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
- opentrons/protocol_api/core/legacy/deck.py +369 -0
- opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
- opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
- opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
- opentrons/protocol_api/core/legacy/load_info.py +67 -0
- opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
- opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
- opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
- opentrons/protocol_api/core/module.py +484 -0
- opentrons/protocol_api/core/protocol.py +311 -0
- opentrons/protocol_api/core/robot.py +51 -0
- opentrons/protocol_api/core/well.py +116 -0
- opentrons/protocol_api/core/well_grid.py +45 -0
- opentrons/protocol_api/create_protocol_context.py +177 -0
- opentrons/protocol_api/deck.py +223 -0
- opentrons/protocol_api/disposal_locations.py +244 -0
- opentrons/protocol_api/instrument_context.py +3212 -0
- opentrons/protocol_api/labware.py +1579 -0
- opentrons/protocol_api/module_contexts.py +1425 -0
- opentrons/protocol_api/module_validation_and_errors.py +61 -0
- opentrons/protocol_api/protocol_context.py +1688 -0
- opentrons/protocol_api/robot_context.py +303 -0
- opentrons/protocol_api/validation.py +761 -0
- opentrons/protocol_engine/__init__.py +155 -0
- opentrons/protocol_engine/actions/__init__.py +65 -0
- opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
- opentrons/protocol_engine/actions/action_handler.py +13 -0
- opentrons/protocol_engine/actions/actions.py +302 -0
- opentrons/protocol_engine/actions/get_state_update.py +38 -0
- opentrons/protocol_engine/clients/__init__.py +5 -0
- opentrons/protocol_engine/clients/sync_client.py +174 -0
- opentrons/protocol_engine/clients/transports.py +197 -0
- opentrons/protocol_engine/commands/__init__.py +757 -0
- opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
- opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
- opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
- opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
- opentrons/protocol_engine/commands/aspirate.py +244 -0
- opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
- opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
- opentrons/protocol_engine/commands/blow_out.py +146 -0
- opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
- opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
- opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
- opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
- opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
- opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
- opentrons/protocol_engine/commands/command.py +308 -0
- opentrons/protocol_engine/commands/command_unions.py +974 -0
- opentrons/protocol_engine/commands/comment.py +57 -0
- opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
- opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
- opentrons/protocol_engine/commands/custom.py +67 -0
- opentrons/protocol_engine/commands/dispense.py +194 -0
- opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
- opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
- opentrons/protocol_engine/commands/drop_tip.py +232 -0
- opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
- opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
- opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
- opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
- opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
- opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
- opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
- opentrons/protocol_engine/commands/flex_stacker/store.py +326 -0
- opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
- opentrons/protocol_engine/commands/get_next_tip.py +134 -0
- opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
- opentrons/protocol_engine/commands/hash_command_params.py +38 -0
- opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
- opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
- opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
- opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
- opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
- opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
- opentrons/protocol_engine/commands/home.py +100 -0
- opentrons/protocol_engine/commands/identify_module.py +86 -0
- opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
- opentrons/protocol_engine/commands/liquid_probe.py +464 -0
- opentrons/protocol_engine/commands/load_labware.py +210 -0
- opentrons/protocol_engine/commands/load_lid.py +154 -0
- opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
- opentrons/protocol_engine/commands/load_liquid.py +95 -0
- opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
- opentrons/protocol_engine/commands/load_module.py +223 -0
- opentrons/protocol_engine/commands/load_pipette.py +167 -0
- opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
- opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
- opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
- opentrons/protocol_engine/commands/move_labware.py +546 -0
- opentrons/protocol_engine/commands/move_relative.py +102 -0
- opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
- opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
- opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
- opentrons/protocol_engine/commands/move_to_well.py +119 -0
- opentrons/protocol_engine/commands/movement_common.py +338 -0
- opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
- opentrons/protocol_engine/commands/pipetting_common.py +443 -0
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
- opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
- opentrons/protocol_engine/commands/reload_labware.py +90 -0
- opentrons/protocol_engine/commands/retract_axis.py +75 -0
- opentrons/protocol_engine/commands/robot/__init__.py +70 -0
- opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
- opentrons/protocol_engine/commands/robot/common.py +18 -0
- opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
- opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
- opentrons/protocol_engine/commands/robot/move_to.py +94 -0
- opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
- opentrons/protocol_engine/commands/save_position.py +109 -0
- opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
- opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
- opentrons/protocol_engine/commands/set_status_bar.py +89 -0
- opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
- opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
- opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
- opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
- opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
- opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
- opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
- opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
- opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
- opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
- opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
- opentrons/protocol_engine/commands/touch_tip.py +189 -0
- opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
- opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
- opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
- opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
- opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
- opentrons/protocol_engine/create_protocol_engine.py +193 -0
- opentrons/protocol_engine/engine_support.py +28 -0
- opentrons/protocol_engine/error_recovery_policy.py +81 -0
- opentrons/protocol_engine/errors/__init__.py +191 -0
- opentrons/protocol_engine/errors/error_occurrence.py +182 -0
- opentrons/protocol_engine/errors/exceptions.py +1308 -0
- opentrons/protocol_engine/execution/__init__.py +50 -0
- opentrons/protocol_engine/execution/command_executor.py +216 -0
- opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
- opentrons/protocol_engine/execution/door_watcher.py +119 -0
- opentrons/protocol_engine/execution/equipment.py +819 -0
- opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
- opentrons/protocol_engine/execution/gantry_mover.py +686 -0
- opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
- opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
- opentrons/protocol_engine/execution/labware_movement.py +297 -0
- opentrons/protocol_engine/execution/movement.py +349 -0
- opentrons/protocol_engine/execution/pipetting.py +607 -0
- opentrons/protocol_engine/execution/queue_worker.py +86 -0
- opentrons/protocol_engine/execution/rail_lights.py +25 -0
- opentrons/protocol_engine/execution/run_control.py +33 -0
- opentrons/protocol_engine/execution/status_bar.py +34 -0
- opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
- opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
- opentrons/protocol_engine/execution/tip_handler.py +550 -0
- opentrons/protocol_engine/labware_offset_standardization.py +194 -0
- opentrons/protocol_engine/notes/__init__.py +17 -0
- opentrons/protocol_engine/notes/notes.py +59 -0
- opentrons/protocol_engine/plugins.py +104 -0
- opentrons/protocol_engine/protocol_engine.py +683 -0
- opentrons/protocol_engine/resources/__init__.py +26 -0
- opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
- opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
- opentrons/protocol_engine/resources/file_provider.py +161 -0
- opentrons/protocol_engine/resources/fixture_validation.py +58 -0
- opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
- opentrons/protocol_engine/resources/labware_validation.py +73 -0
- opentrons/protocol_engine/resources/model_utils.py +32 -0
- opentrons/protocol_engine/resources/module_data_provider.py +44 -0
- opentrons/protocol_engine/resources/ot3_validation.py +21 -0
- opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
- opentrons/protocol_engine/slot_standardization.py +128 -0
- opentrons/protocol_engine/state/__init__.py +1 -0
- opentrons/protocol_engine/state/_abstract_store.py +27 -0
- opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
- opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
- opentrons/protocol_engine/state/_move_types.py +83 -0
- opentrons/protocol_engine/state/_well_math.py +193 -0
- opentrons/protocol_engine/state/addressable_areas.py +699 -0
- opentrons/protocol_engine/state/command_history.py +309 -0
- opentrons/protocol_engine/state/commands.py +1158 -0
- opentrons/protocol_engine/state/config.py +39 -0
- opentrons/protocol_engine/state/files.py +57 -0
- opentrons/protocol_engine/state/fluid_stack.py +138 -0
- opentrons/protocol_engine/state/geometry.py +2359 -0
- opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
- opentrons/protocol_engine/state/labware.py +1459 -0
- opentrons/protocol_engine/state/liquid_classes.py +82 -0
- opentrons/protocol_engine/state/liquids.py +73 -0
- opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
- opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
- opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
- opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
- opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
- opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
- opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
- opentrons/protocol_engine/state/modules.py +1500 -0
- opentrons/protocol_engine/state/motion.py +373 -0
- opentrons/protocol_engine/state/pipettes.py +905 -0
- opentrons/protocol_engine/state/state.py +421 -0
- opentrons/protocol_engine/state/state_summary.py +36 -0
- opentrons/protocol_engine/state/tips.py +420 -0
- opentrons/protocol_engine/state/update_types.py +904 -0
- opentrons/protocol_engine/state/wells.py +290 -0
- opentrons/protocol_engine/types/__init__.py +308 -0
- opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
- opentrons/protocol_engine/types/command_annotations.py +53 -0
- opentrons/protocol_engine/types/deck_configuration.py +81 -0
- opentrons/protocol_engine/types/execution.py +96 -0
- opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
- opentrons/protocol_engine/types/instrument.py +47 -0
- opentrons/protocol_engine/types/instrument_sensors.py +47 -0
- opentrons/protocol_engine/types/labware.py +131 -0
- opentrons/protocol_engine/types/labware_movement.py +22 -0
- opentrons/protocol_engine/types/labware_offset_location.py +111 -0
- opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
- opentrons/protocol_engine/types/liquid.py +40 -0
- opentrons/protocol_engine/types/liquid_class.py +59 -0
- opentrons/protocol_engine/types/liquid_handling.py +13 -0
- opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
- opentrons/protocol_engine/types/location.py +194 -0
- opentrons/protocol_engine/types/module.py +303 -0
- opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
- opentrons/protocol_engine/types/run_time_parameters.py +133 -0
- opentrons/protocol_engine/types/tip.py +18 -0
- opentrons/protocol_engine/types/util.py +21 -0
- opentrons/protocol_engine/types/well_position.py +124 -0
- opentrons/protocol_reader/__init__.py +37 -0
- opentrons/protocol_reader/extract_labware_definitions.py +66 -0
- opentrons/protocol_reader/file_format_validator.py +152 -0
- opentrons/protocol_reader/file_hasher.py +27 -0
- opentrons/protocol_reader/file_identifier.py +284 -0
- opentrons/protocol_reader/file_reader_writer.py +90 -0
- opentrons/protocol_reader/input_file.py +16 -0
- opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
- opentrons/protocol_reader/protocol_reader.py +188 -0
- opentrons/protocol_reader/protocol_source.py +124 -0
- opentrons/protocol_reader/role_analyzer.py +86 -0
- opentrons/protocol_runner/__init__.py +26 -0
- opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
- opentrons/protocol_runner/json_file_reader.py +55 -0
- opentrons/protocol_runner/json_translator.py +314 -0
- opentrons/protocol_runner/legacy_command_mapper.py +848 -0
- opentrons/protocol_runner/legacy_context_plugin.py +116 -0
- opentrons/protocol_runner/protocol_runner.py +530 -0
- opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
- opentrons/protocol_runner/run_orchestrator.py +496 -0
- opentrons/protocol_runner/task_queue.py +95 -0
- opentrons/protocols/__init__.py +6 -0
- opentrons/protocols/advanced_control/__init__.py +0 -0
- opentrons/protocols/advanced_control/common.py +38 -0
- opentrons/protocols/advanced_control/mix.py +60 -0
- opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
- opentrons/protocols/advanced_control/transfers/common.py +180 -0
- opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
- opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
- opentrons/protocols/api_support/__init__.py +0 -0
- opentrons/protocols/api_support/constants.py +8 -0
- opentrons/protocols/api_support/deck_type.py +110 -0
- opentrons/protocols/api_support/definitions.py +18 -0
- opentrons/protocols/api_support/instrument.py +151 -0
- opentrons/protocols/api_support/labware_like.py +233 -0
- opentrons/protocols/api_support/tip_tracker.py +175 -0
- opentrons/protocols/api_support/types.py +32 -0
- opentrons/protocols/api_support/util.py +403 -0
- opentrons/protocols/bundle.py +89 -0
- opentrons/protocols/duration/__init__.py +4 -0
- opentrons/protocols/duration/errors.py +5 -0
- opentrons/protocols/duration/estimator.py +628 -0
- opentrons/protocols/execution/__init__.py +0 -0
- opentrons/protocols/execution/dev_types.py +181 -0
- opentrons/protocols/execution/errors.py +40 -0
- opentrons/protocols/execution/execute.py +84 -0
- opentrons/protocols/execution/execute_json_v3.py +275 -0
- opentrons/protocols/execution/execute_json_v4.py +359 -0
- opentrons/protocols/execution/execute_json_v5.py +28 -0
- opentrons/protocols/execution/execute_python.py +169 -0
- opentrons/protocols/execution/json_dispatchers.py +87 -0
- opentrons/protocols/execution/types.py +7 -0
- opentrons/protocols/geometry/__init__.py +0 -0
- opentrons/protocols/geometry/planning.py +297 -0
- opentrons/protocols/labware.py +312 -0
- opentrons/protocols/models/__init__.py +0 -0
- opentrons/protocols/models/json_protocol.py +679 -0
- opentrons/protocols/parameters/__init__.py +0 -0
- opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
- opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
- opentrons/protocols/parameters/exceptions.py +34 -0
- opentrons/protocols/parameters/parameter_definition.py +272 -0
- opentrons/protocols/parameters/types.py +17 -0
- opentrons/protocols/parameters/validation.py +267 -0
- opentrons/protocols/parse.py +671 -0
- opentrons/protocols/types.py +159 -0
- opentrons/py.typed +0 -0
- opentrons/resources/scripts/lpc21isp +0 -0
- opentrons/resources/smoothie-edge-8414642.hex +23010 -0
- opentrons/simulate.py +1065 -0
- opentrons/system/__init__.py +6 -0
- opentrons/system/camera.py +51 -0
- opentrons/system/log_control.py +59 -0
- opentrons/system/nmcli.py +856 -0
- opentrons/system/resin.py +24 -0
- opentrons/system/smoothie_update.py +15 -0
- opentrons/system/wifi.py +204 -0
- opentrons/tools/__init__.py +0 -0
- opentrons/tools/args_handler.py +22 -0
- opentrons/tools/write_pipette_memory.py +157 -0
- opentrons/types.py +618 -0
- opentrons/util/__init__.py +1 -0
- opentrons/util/async_helpers.py +166 -0
- opentrons/util/broker.py +84 -0
- opentrons/util/change_notifier.py +47 -0
- opentrons/util/entrypoint_util.py +278 -0
- opentrons/util/get_union_elements.py +26 -0
- opentrons/util/helpers.py +6 -0
- opentrons/util/linal.py +178 -0
- opentrons/util/logging_config.py +265 -0
- opentrons/util/logging_queue_handler.py +61 -0
- opentrons/util/performance_helpers.py +157 -0
- opentrons-8.6.0a1.dist-info/METADATA +37 -0
- opentrons-8.6.0a1.dist-info/RECORD +600 -0
- opentrons-8.6.0a1.dist-info/WHEEL +4 -0
- opentrons-8.6.0a1.dist-info/entry_points.txt +3 -0
- opentrons-8.6.0a1.dist-info/licenses/LICENSE +202 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Motion planning module."""
|
|
2
|
+
|
|
3
|
+
from .waypoints import (
|
|
4
|
+
DEFAULT_GENERAL_ARC_Z_MARGIN,
|
|
5
|
+
DEFAULT_IN_LABWARE_ARC_Z_MARGIN,
|
|
6
|
+
MINIMUM_Z_MARGIN,
|
|
7
|
+
get_waypoints,
|
|
8
|
+
get_gripper_labware_movement_waypoints,
|
|
9
|
+
get_gripper_labware_placement_waypoints,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from .types import Waypoint, MoveType
|
|
13
|
+
|
|
14
|
+
from .errors import (
|
|
15
|
+
MotionPlanningError,
|
|
16
|
+
DestinationOutOfBoundsError,
|
|
17
|
+
ArcOutOfBoundsError,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"DEFAULT_GENERAL_ARC_Z_MARGIN",
|
|
22
|
+
"DEFAULT_IN_LABWARE_ARC_Z_MARGIN",
|
|
23
|
+
"MINIMUM_Z_MARGIN",
|
|
24
|
+
"Waypoint",
|
|
25
|
+
"MoveType",
|
|
26
|
+
"MotionPlanningError",
|
|
27
|
+
"DestinationOutOfBoundsError",
|
|
28
|
+
"ArcOutOfBoundsError",
|
|
29
|
+
"get_waypoints",
|
|
30
|
+
"get_gripper_labware_movement_waypoints",
|
|
31
|
+
"get_gripper_labware_placement_waypoints",
|
|
32
|
+
]
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""Getters for specific adjacent slots."""
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Optional, List, Dict, Union
|
|
4
|
+
|
|
5
|
+
from opentrons_shared_data.robot.types import RobotType
|
|
6
|
+
|
|
7
|
+
from opentrons.types import DeckSlotName, StagingSlotName
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_north_slot(slot: int) -> Optional[int]:
|
|
11
|
+
"""Get slot north of the given slot."""
|
|
12
|
+
if slot in [10, 11, 12]:
|
|
13
|
+
return None
|
|
14
|
+
else:
|
|
15
|
+
return slot + 3
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_south_slot(slot: int) -> Optional[int]:
|
|
19
|
+
"""Get slot south of the given slot."""
|
|
20
|
+
if slot in [1, 2, 3]:
|
|
21
|
+
return None
|
|
22
|
+
else:
|
|
23
|
+
return slot - 3
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_east_slot(slot: int) -> Optional[int]:
|
|
27
|
+
"""Get slot east of the given slot."""
|
|
28
|
+
if slot in [3, 6, 9, 12]:
|
|
29
|
+
return None
|
|
30
|
+
else:
|
|
31
|
+
return slot + 1
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_west_slot(slot: int) -> Optional[int]:
|
|
35
|
+
"""Get slot west of the given slot."""
|
|
36
|
+
if slot in [1, 4, 7, 10]:
|
|
37
|
+
return None
|
|
38
|
+
else:
|
|
39
|
+
return slot - 1
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_north_west_slot(slot: int) -> Optional[int]:
|
|
43
|
+
"""Get the slot that's north-west of the given slot."""
|
|
44
|
+
if slot in [1, 4, 7, 10, 11, 12]:
|
|
45
|
+
return None
|
|
46
|
+
else:
|
|
47
|
+
north_slot = get_north_slot(slot)
|
|
48
|
+
return north_slot - 1 if north_slot else None
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_north_east_slot(slot: int) -> Optional[int]:
|
|
52
|
+
"""Get the slot that's north-east of the given slot."""
|
|
53
|
+
if slot in [3, 6, 9, 10, 11, 12]:
|
|
54
|
+
return None
|
|
55
|
+
else:
|
|
56
|
+
north_slot = get_north_slot(slot)
|
|
57
|
+
return north_slot + 1 if north_slot else None
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_south_west_slot(slot: int) -> Optional[int]:
|
|
61
|
+
"""Get the slot that's south-west of the given slot."""
|
|
62
|
+
if slot in [1, 2, 3, 4, 7, 10]:
|
|
63
|
+
return None
|
|
64
|
+
else:
|
|
65
|
+
south_slot = get_south_slot(slot)
|
|
66
|
+
return south_slot - 1 if south_slot else None
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def get_south_east_slot(slot: int) -> Optional[int]:
|
|
70
|
+
"""Get the slot that's south-east of the given slot."""
|
|
71
|
+
if slot in [1, 2, 3, 6, 9, 12]:
|
|
72
|
+
return None
|
|
73
|
+
else:
|
|
74
|
+
south_slot = get_south_slot(slot)
|
|
75
|
+
return south_slot + 1 if south_slot else None
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass
|
|
79
|
+
class _MixedTypeSlots:
|
|
80
|
+
regular_slots: List[DeckSlotName]
|
|
81
|
+
staging_slots: List[StagingSlotName]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def get_surrounding_slots(slot: int, robot_type: RobotType) -> _MixedTypeSlots:
|
|
85
|
+
"""Get all the surrounding slots, i.e., adjacent slots as well as corner slots."""
|
|
86
|
+
corner_slots: List[Union[int, None]] = [
|
|
87
|
+
get_north_east_slot(slot),
|
|
88
|
+
get_north_west_slot(slot),
|
|
89
|
+
get_south_east_slot(slot),
|
|
90
|
+
get_south_west_slot(slot),
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
surrounding_regular_slots_int = get_adjacent_slots(slot) + [
|
|
94
|
+
maybe_slot for maybe_slot in corner_slots if maybe_slot is not None
|
|
95
|
+
]
|
|
96
|
+
surrounding_regular_slots = [
|
|
97
|
+
DeckSlotName.from_primitive(slot_int).to_equivalent_for_robot_type(robot_type)
|
|
98
|
+
for slot_int in surrounding_regular_slots_int
|
|
99
|
+
]
|
|
100
|
+
surrounding_staging_slots = _SURROUNDING_STAGING_SLOTS_MAP.get(
|
|
101
|
+
DeckSlotName.from_primitive(slot).to_equivalent_for_robot_type(robot_type), []
|
|
102
|
+
)
|
|
103
|
+
return _MixedTypeSlots(
|
|
104
|
+
regular_slots=surrounding_regular_slots, staging_slots=surrounding_staging_slots
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
_WEST_OF_STAGING_SLOT_MAP: Dict[StagingSlotName, DeckSlotName] = {
|
|
109
|
+
StagingSlotName.SLOT_A4: DeckSlotName.SLOT_A3,
|
|
110
|
+
StagingSlotName.SLOT_B4: DeckSlotName.SLOT_B3,
|
|
111
|
+
StagingSlotName.SLOT_C4: DeckSlotName.SLOT_C3,
|
|
112
|
+
StagingSlotName.SLOT_D4: DeckSlotName.SLOT_D3,
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
_EAST_OF_FLEX_COLUMN_3_MAP: Dict[DeckSlotName, StagingSlotName] = {
|
|
116
|
+
deck_slot: staging_slot
|
|
117
|
+
for staging_slot, deck_slot in _WEST_OF_STAGING_SLOT_MAP.items()
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
_SURROUNDING_STAGING_SLOTS_MAP: Dict[DeckSlotName, List[StagingSlotName]] = {
|
|
122
|
+
DeckSlotName.SLOT_D3: [StagingSlotName.SLOT_C4, StagingSlotName.SLOT_D4],
|
|
123
|
+
DeckSlotName.SLOT_C3: [
|
|
124
|
+
StagingSlotName.SLOT_B4,
|
|
125
|
+
StagingSlotName.SLOT_C4,
|
|
126
|
+
StagingSlotName.SLOT_D4,
|
|
127
|
+
],
|
|
128
|
+
DeckSlotName.SLOT_B3: [
|
|
129
|
+
StagingSlotName.SLOT_A4,
|
|
130
|
+
StagingSlotName.SLOT_B4,
|
|
131
|
+
StagingSlotName.SLOT_C4,
|
|
132
|
+
],
|
|
133
|
+
DeckSlotName.SLOT_A3: [StagingSlotName.SLOT_A4, StagingSlotName.SLOT_B4],
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def get_west_of_staging_slot(staging_slot: StagingSlotName) -> DeckSlotName:
|
|
138
|
+
"""Get slot west of a staging slot."""
|
|
139
|
+
return _WEST_OF_STAGING_SLOT_MAP[staging_slot]
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def get_adjacent_staging_slot(deck_slot: DeckSlotName) -> Optional[StagingSlotName]:
|
|
143
|
+
"""Get the adjacent staging slot if the deck slot is in the third column."""
|
|
144
|
+
return _EAST_OF_FLEX_COLUMN_3_MAP.get(deck_slot)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def get_surrounding_staging_slots(deck_slot: DeckSlotName) -> List[StagingSlotName]:
|
|
148
|
+
"""Get the staging slots surrounding the given deck slot."""
|
|
149
|
+
return _SURROUNDING_STAGING_SLOTS_MAP.get(deck_slot, [])
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def get_east_west_slots(slot: int) -> List[int]:
|
|
153
|
+
"""Get slots east & west of the given slot."""
|
|
154
|
+
east = get_east_slot(slot)
|
|
155
|
+
west = get_west_slot(slot)
|
|
156
|
+
return [maybe_slot for maybe_slot in [east, west] if maybe_slot is not None]
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def get_north_south_slots(slot: int) -> List[int]:
|
|
160
|
+
"""Get slots north & south of the given slot."""
|
|
161
|
+
north = get_north_slot(slot)
|
|
162
|
+
south = get_south_slot(slot)
|
|
163
|
+
return [maybe_slot for maybe_slot in [north, south] if maybe_slot is not None]
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def get_adjacent_slots(slot: int) -> List[int]:
|
|
167
|
+
"""Get slots on the east, west, north and south of the given slot."""
|
|
168
|
+
return get_east_west_slots(slot) + get_north_south_slots(slot)
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
"""Check a deck layout for conflicts."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import List, Mapping, NamedTuple, Optional, Set, Union
|
|
6
|
+
from typing_extensions import Final
|
|
7
|
+
|
|
8
|
+
from opentrons_shared_data.labware.types import LabwareUri
|
|
9
|
+
from opentrons_shared_data.robot.types import RobotType
|
|
10
|
+
from opentrons.motion_planning.adjacent_slots_getters import (
|
|
11
|
+
get_east_west_slots,
|
|
12
|
+
get_south_slot,
|
|
13
|
+
get_adjacent_slots,
|
|
14
|
+
get_adjacent_staging_slot,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from opentrons.types import DeckSlotName, StagingSlotName
|
|
18
|
+
|
|
19
|
+
_FIXED_TRASH_SLOT: Final[Set[DeckSlotName]] = {
|
|
20
|
+
DeckSlotName.FIXED_TRASH,
|
|
21
|
+
DeckSlotName.SLOT_A3,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# The maximum height allowed for items adjacent to a Heater-Shaker in the x-direction.
|
|
26
|
+
# This value selected to avoid interference with the Heater-Shaker's labware latch.
|
|
27
|
+
# For background, see: https://github.com/Opentrons/opentrons/issues/10316
|
|
28
|
+
#
|
|
29
|
+
# TODO(mc, 2022-06-16): move this constant to the module definition
|
|
30
|
+
HS_MAX_X_ADJACENT_ITEM_HEIGHT = 53.0
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# URIs of labware that are allowed to exceed HS_MAX_X_ADJACENT_ITEM_HEIGHT.
|
|
34
|
+
# These labware do not take up the full width of the slot
|
|
35
|
+
# in the area that would interfere with the labware latch.
|
|
36
|
+
# For background, see: https://github.com/Opentrons/opentrons/issues/10316
|
|
37
|
+
#
|
|
38
|
+
# TODO(mc, 2022-06-16): move this constant to the module definition
|
|
39
|
+
HS_ALLOWED_ADJACENT_TALL_LABWARE = [
|
|
40
|
+
LabwareUri("opentrons/opentrons_96_filtertiprack_10ul/1"),
|
|
41
|
+
LabwareUri("opentrons/opentrons_96_filtertiprack_200ul/1"),
|
|
42
|
+
LabwareUri("opentrons/opentrons_96_filtertiprack_20ul/1"),
|
|
43
|
+
LabwareUri("opentrons/opentrons_96_tiprack_10ul/1"),
|
|
44
|
+
LabwareUri("opentrons/opentrons_96_tiprack_20ul/1"),
|
|
45
|
+
LabwareUri("opentrons/opentrons_96_tiprack_300ul/1"),
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@dataclass
|
|
50
|
+
class Labware:
|
|
51
|
+
"""A normal labware that directly occupies a slot.
|
|
52
|
+
|
|
53
|
+
Do not use this to represent a labware that's loaded atop a module.
|
|
54
|
+
Use one of the module types, instead.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
name_for_errors: str
|
|
58
|
+
highest_z: float
|
|
59
|
+
uri: LabwareUri
|
|
60
|
+
is_fixed_trash: bool
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass
|
|
64
|
+
class TrashBin:
|
|
65
|
+
"""A non-labware trash bin (loaded via api level 2.16 and above)."""
|
|
66
|
+
|
|
67
|
+
name_for_errors: str
|
|
68
|
+
highest_z: float
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass
|
|
72
|
+
class _Module:
|
|
73
|
+
name_for_errors: str
|
|
74
|
+
highest_z_including_labware: float
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@dataclass
|
|
78
|
+
class HeaterShakerModule(_Module):
|
|
79
|
+
"""A Heater-Shaker module."""
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@dataclass
|
|
83
|
+
class MagneticBlockModule(_Module):
|
|
84
|
+
"""A Magnetic Block module."""
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@dataclass
|
|
88
|
+
class ThermocyclerModule(_Module):
|
|
89
|
+
"""A Thermocycler module."""
|
|
90
|
+
|
|
91
|
+
is_semi_configuration: bool
|
|
92
|
+
"""Whether this Thermocycler is loaded in its "semi" configuration.
|
|
93
|
+
|
|
94
|
+
In this configuration, it's offset to the left, so it takes up fewer deck slots.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@dataclass
|
|
99
|
+
class OtherModule(_Module):
|
|
100
|
+
"""A module that's not a Heater-Shaker or Thermocycler."""
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
DeckItem = Union[
|
|
104
|
+
Labware,
|
|
105
|
+
HeaterShakerModule,
|
|
106
|
+
MagneticBlockModule,
|
|
107
|
+
ThermocyclerModule,
|
|
108
|
+
OtherModule,
|
|
109
|
+
TrashBin,
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class _NothingAllowed(NamedTuple):
|
|
114
|
+
"""Nothing is allowed in this slot."""
|
|
115
|
+
|
|
116
|
+
location: Union[DeckSlotName, StagingSlotName]
|
|
117
|
+
source_item: DeckItem
|
|
118
|
+
source_location: Union[DeckSlotName, StagingSlotName]
|
|
119
|
+
|
|
120
|
+
def is_allowed(self, item: DeckItem) -> bool:
|
|
121
|
+
return False
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class _MaxHeight(NamedTuple):
|
|
125
|
+
"""Nothing over a certain height is allowed in this slot."""
|
|
126
|
+
|
|
127
|
+
location: DeckSlotName
|
|
128
|
+
source_item: DeckItem
|
|
129
|
+
source_location: DeckSlotName
|
|
130
|
+
max_height: float
|
|
131
|
+
allowed_labware: List[LabwareUri]
|
|
132
|
+
|
|
133
|
+
def is_allowed(self, item: DeckItem) -> bool:
|
|
134
|
+
if isinstance(item, Labware):
|
|
135
|
+
if item.uri in self.allowed_labware:
|
|
136
|
+
return True
|
|
137
|
+
else:
|
|
138
|
+
return item.highest_z < self.max_height
|
|
139
|
+
elif isinstance(item, _Module):
|
|
140
|
+
return item.highest_z_including_labware < self.max_height
|
|
141
|
+
elif isinstance(item, TrashBin):
|
|
142
|
+
return item.highest_z < self.max_height
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class _NoModule(NamedTuple):
|
|
146
|
+
"""No module of any kind is allowed in this slot."""
|
|
147
|
+
|
|
148
|
+
location: DeckSlotName
|
|
149
|
+
source_item: DeckItem
|
|
150
|
+
source_location: DeckSlotName
|
|
151
|
+
|
|
152
|
+
def is_allowed(self, item: DeckItem) -> bool:
|
|
153
|
+
return not isinstance(item, _Module)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class _NoHeaterShakerModule(NamedTuple):
|
|
157
|
+
"""No Heater-Shaker module is allowed in this slot."""
|
|
158
|
+
|
|
159
|
+
location: DeckSlotName
|
|
160
|
+
source_item: DeckItem
|
|
161
|
+
source_location: DeckSlotName
|
|
162
|
+
|
|
163
|
+
def is_allowed(self, item: DeckItem) -> bool:
|
|
164
|
+
return not isinstance(item, HeaterShakerModule)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
_DeckRestriction = Union[
|
|
168
|
+
_NothingAllowed,
|
|
169
|
+
_MaxHeight,
|
|
170
|
+
_NoModule,
|
|
171
|
+
_NoHeaterShakerModule,
|
|
172
|
+
]
|
|
173
|
+
"""A restriction on what is allowed in a given slot."""
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class DeckConflictError(ValueError):
|
|
177
|
+
"""Adding an item to the deck would cause a conflict."""
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
# TODO(mm, 2023-02-16): Taking a single int as the deck location doesn't make sense for
|
|
181
|
+
# things that don't fit into a single deck slot, like the Thermocycler.
|
|
182
|
+
# Refactor this interface to take a more symbolic location.
|
|
183
|
+
def check(
|
|
184
|
+
existing_items: Mapping[Union[DeckSlotName, StagingSlotName], DeckItem],
|
|
185
|
+
new_item: DeckItem,
|
|
186
|
+
new_location: Union[DeckSlotName, StagingSlotName],
|
|
187
|
+
robot_type: RobotType,
|
|
188
|
+
) -> None:
|
|
189
|
+
"""Check a deck layout for conflicts.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
existing_items: Existing items on the deck, assumed to be valid.
|
|
193
|
+
new_item: New item to add to the deck.
|
|
194
|
+
new_location: Location where the new item will be added.
|
|
195
|
+
robot_type: The type of the robot to choose the restriction rules.
|
|
196
|
+
|
|
197
|
+
Raises:
|
|
198
|
+
DeckConflictError: Adding this item should not be allowed.
|
|
199
|
+
"""
|
|
200
|
+
restrictions: List[_DeckRestriction] = []
|
|
201
|
+
# build restrictions driven by existing items
|
|
202
|
+
for location, item in existing_items.items():
|
|
203
|
+
restrictions += _create_restrictions(
|
|
204
|
+
item=item, location=location, robot_type=robot_type
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
# check new item against existing restrictions
|
|
208
|
+
for r in restrictions:
|
|
209
|
+
if r.location == new_location and not r.is_allowed(new_item):
|
|
210
|
+
raise DeckConflictError(
|
|
211
|
+
_create_deck_conflict_error_message(restriction=r, new_item=new_item)
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
# check new restrictions required by new item
|
|
215
|
+
# do not interfere with existing items
|
|
216
|
+
new_restrictions = _create_restrictions(
|
|
217
|
+
item=new_item, location=new_location, robot_type=robot_type
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
for r in new_restrictions:
|
|
221
|
+
existing_item = existing_items.get(r.location)
|
|
222
|
+
if existing_item is not None and not r.is_allowed(existing_item):
|
|
223
|
+
raise DeckConflictError(
|
|
224
|
+
_create_deck_conflict_error_message(
|
|
225
|
+
restriction=r,
|
|
226
|
+
existing_item=existing_item,
|
|
227
|
+
)
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def _create_ot2_restrictions( # noqa: C901
|
|
232
|
+
item: DeckItem, location: Union[DeckSlotName, StagingSlotName]
|
|
233
|
+
) -> List[_DeckRestriction]:
|
|
234
|
+
restrictions: List[_DeckRestriction] = []
|
|
235
|
+
if isinstance(location, StagingSlotName):
|
|
236
|
+
raise DeckConflictError(f"OT-2 does not support staging slots ({location.id}).")
|
|
237
|
+
|
|
238
|
+
if location not in _FIXED_TRASH_SLOT:
|
|
239
|
+
# Disallow a different item from overlapping this item in this deck slot.
|
|
240
|
+
restrictions.append(
|
|
241
|
+
_NothingAllowed(
|
|
242
|
+
location=location,
|
|
243
|
+
source_item=item,
|
|
244
|
+
source_location=location,
|
|
245
|
+
)
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
if _is_ot2_fixed_trash(item):
|
|
249
|
+
# A Heater-Shaker can't safely be placed just south of the fixed trash,
|
|
250
|
+
# because the fixed trash blocks access to the screw that locks the
|
|
251
|
+
# Heater-Shaker onto the deck.
|
|
252
|
+
location_south_of_fixed_trash = get_south_slot(location.as_int())
|
|
253
|
+
if location_south_of_fixed_trash is not None:
|
|
254
|
+
restrictions.append(
|
|
255
|
+
_NoHeaterShakerModule(
|
|
256
|
+
location=DeckSlotName.from_primitive(location_south_of_fixed_trash),
|
|
257
|
+
source_item=item,
|
|
258
|
+
source_location=location,
|
|
259
|
+
)
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
if isinstance(item, ThermocyclerModule):
|
|
263
|
+
for covered_location in _ot2_slots_covered_by_thermocycler(item):
|
|
264
|
+
restrictions.append(
|
|
265
|
+
_NothingAllowed(
|
|
266
|
+
location=covered_location,
|
|
267
|
+
source_item=item,
|
|
268
|
+
source_location=location,
|
|
269
|
+
)
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
if isinstance(item, HeaterShakerModule):
|
|
273
|
+
for hs_covered_location in get_adjacent_slots(location.as_int()):
|
|
274
|
+
restrictions.append(
|
|
275
|
+
_NoModule(
|
|
276
|
+
location=DeckSlotName.from_primitive(hs_covered_location),
|
|
277
|
+
source_item=item,
|
|
278
|
+
source_location=location,
|
|
279
|
+
)
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
for hs_covered_location in get_east_west_slots(location.as_int()):
|
|
283
|
+
restrictions.append(
|
|
284
|
+
_MaxHeight(
|
|
285
|
+
location=DeckSlotName.from_primitive(hs_covered_location),
|
|
286
|
+
source_item=item,
|
|
287
|
+
source_location=location,
|
|
288
|
+
max_height=HS_MAX_X_ADJACENT_ITEM_HEIGHT,
|
|
289
|
+
allowed_labware=HS_ALLOWED_ADJACENT_TALL_LABWARE,
|
|
290
|
+
)
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
return restrictions
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def _create_flex_restrictions(
|
|
297
|
+
item: DeckItem, location: Union[DeckSlotName, StagingSlotName]
|
|
298
|
+
) -> List[_DeckRestriction]:
|
|
299
|
+
restrictions: List[_DeckRestriction] = [
|
|
300
|
+
_NothingAllowed(
|
|
301
|
+
location=location,
|
|
302
|
+
source_item=item,
|
|
303
|
+
source_location=location,
|
|
304
|
+
)
|
|
305
|
+
]
|
|
306
|
+
|
|
307
|
+
if isinstance(item, (HeaterShakerModule, OtherModule)):
|
|
308
|
+
if isinstance(location, StagingSlotName):
|
|
309
|
+
raise DeckConflictError(
|
|
310
|
+
"Cannot have a module loaded on a staging area slot."
|
|
311
|
+
)
|
|
312
|
+
adjacent_staging_slot = get_adjacent_staging_slot(location)
|
|
313
|
+
if adjacent_staging_slot is not None:
|
|
314
|
+
# You can't have anything on a staging area slot next to a heater-shaker or
|
|
315
|
+
# temperature module because the module caddy physically blocks you from having
|
|
316
|
+
# that staging area slot installed in the first place.
|
|
317
|
+
restrictions.append(
|
|
318
|
+
_NothingAllowed(
|
|
319
|
+
location=adjacent_staging_slot,
|
|
320
|
+
source_item=item,
|
|
321
|
+
source_location=location,
|
|
322
|
+
)
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
elif isinstance(item, ThermocyclerModule):
|
|
326
|
+
for covered_location in _flex_slots_covered_by_thermocycler():
|
|
327
|
+
restrictions.append(
|
|
328
|
+
_NothingAllowed(
|
|
329
|
+
location=covered_location,
|
|
330
|
+
source_item=item,
|
|
331
|
+
source_location=location,
|
|
332
|
+
)
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
return restrictions
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def _create_restrictions(
|
|
339
|
+
item: DeckItem, location: Union[DeckSlotName, StagingSlotName], robot_type: str
|
|
340
|
+
) -> List[_DeckRestriction]:
|
|
341
|
+
|
|
342
|
+
if robot_type == "OT-2 Standard":
|
|
343
|
+
return _create_ot2_restrictions(item, location)
|
|
344
|
+
else:
|
|
345
|
+
return _create_flex_restrictions(item, location)
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
def _create_deck_conflict_error_message(
|
|
349
|
+
restriction: _DeckRestriction,
|
|
350
|
+
new_item: Optional[DeckItem] = None,
|
|
351
|
+
existing_item: Optional[DeckItem] = None,
|
|
352
|
+
) -> str:
|
|
353
|
+
assert (
|
|
354
|
+
new_item is not None or existing_item is not None
|
|
355
|
+
), "Conflict error expects either new_item or existing_item"
|
|
356
|
+
|
|
357
|
+
if new_item is not None:
|
|
358
|
+
message = (
|
|
359
|
+
f"{restriction.source_item.name_for_errors}"
|
|
360
|
+
f" in slot {restriction.source_location}"
|
|
361
|
+
f" prevents {new_item.name_for_errors}"
|
|
362
|
+
f" from using slot {restriction.location}."
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
elif existing_item is not None:
|
|
366
|
+
message = (
|
|
367
|
+
f"{existing_item.name_for_errors} in slot {restriction.location}"
|
|
368
|
+
f" prevents {restriction.source_item.name_for_errors}"
|
|
369
|
+
f" from using slot {restriction.source_location}."
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
return message
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def _ot2_slots_covered_by_thermocycler(
|
|
376
|
+
thermocycler: ThermocyclerModule,
|
|
377
|
+
) -> Set[DeckSlotName]:
|
|
378
|
+
if thermocycler.is_semi_configuration:
|
|
379
|
+
return {DeckSlotName.SLOT_7, DeckSlotName.SLOT_10}
|
|
380
|
+
else:
|
|
381
|
+
return {
|
|
382
|
+
DeckSlotName.SLOT_7,
|
|
383
|
+
DeckSlotName.SLOT_10,
|
|
384
|
+
DeckSlotName.SLOT_8,
|
|
385
|
+
DeckSlotName.SLOT_11,
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def _flex_slots_covered_by_thermocycler() -> Set[DeckSlotName]:
|
|
390
|
+
return {DeckSlotName.SLOT_B1, DeckSlotName.SLOT_A1}
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def _is_ot2_fixed_trash(item: DeckItem) -> bool:
|
|
394
|
+
return (isinstance(item, Labware) and item.is_fixed_trash) or isinstance(
|
|
395
|
+
item, TrashBin
|
|
396
|
+
)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Movement planning errors."""
|
|
2
|
+
from opentrons.types import Point
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class MotionPlanningError(Exception):
|
|
6
|
+
"""Sub-class for errors from the movement_planning module."""
|
|
7
|
+
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
origin: Point,
|
|
11
|
+
dest: Point,
|
|
12
|
+
clearance: float,
|
|
13
|
+
min_travel_z: float,
|
|
14
|
+
max_travel_z: float,
|
|
15
|
+
message: str,
|
|
16
|
+
) -> None:
|
|
17
|
+
"""Initialize an error with properties of the planned motion."""
|
|
18
|
+
super().__init__(message)
|
|
19
|
+
self.origin = origin
|
|
20
|
+
self.dest = dest
|
|
21
|
+
self.clearance = clearance
|
|
22
|
+
self.min_travel_z = min_travel_z
|
|
23
|
+
self.max_travel_z = max_travel_z
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class DestinationOutOfBoundsError(MotionPlanningError, ValueError):
|
|
27
|
+
"""An error raised when a requested destination is out of bounds."""
|
|
28
|
+
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ArcOutOfBoundsError(MotionPlanningError, ValueError):
|
|
33
|
+
"""An error raised when a calculated movement arc is out of bounds."""
|
|
34
|
+
|
|
35
|
+
pass
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Motion planning base interfaces."""
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from enum import Enum, auto as auto_enum_value
|
|
4
|
+
from typing import Optional
|
|
5
|
+
from typing_extensions import final
|
|
6
|
+
|
|
7
|
+
from opentrons.types import Point
|
|
8
|
+
from opentrons.hardware_control.types import CriticalPoint
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
@final
|
|
13
|
+
class Waypoint:
|
|
14
|
+
"""Motion waypoint with position and optional pipette critical point."""
|
|
15
|
+
|
|
16
|
+
position: Point
|
|
17
|
+
critical_point: Optional[CriticalPoint] = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@final
|
|
21
|
+
class MoveType(Enum):
|
|
22
|
+
"""Arc or direct movement type.
|
|
23
|
+
|
|
24
|
+
- GENERAL_ARC: an arc movement between two unrelated locations
|
|
25
|
+
- IN_LABWARE_ARC: an arc movement between two locations in the same labware
|
|
26
|
+
- DIRECT: a direct movement between two locations
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
GENERAL_ARC = auto_enum_value()
|
|
30
|
+
IN_LABWARE_ARC = auto_enum_value()
|
|
31
|
+
DIRECT = auto_enum_value()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass(frozen=True)
|
|
35
|
+
@final
|
|
36
|
+
class GripperMovementWaypointsWithJawStatus:
|
|
37
|
+
"""Gripper motion waypoint with expected jaw status while moving to the waypoint."""
|
|
38
|
+
|
|
39
|
+
position: Point
|
|
40
|
+
jaw_open: bool
|
|
41
|
+
dropping: bool
|
|
42
|
+
"""This flag should only be set to True if this waypoint involves dropping a piece of labware."""
|