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.

Files changed (600) hide show
  1. opentrons/__init__.py +150 -0
  2. opentrons/_version.py +34 -0
  3. opentrons/calibration_storage/__init__.py +54 -0
  4. opentrons/calibration_storage/deck_configuration.py +62 -0
  5. opentrons/calibration_storage/encoder_decoder.py +31 -0
  6. opentrons/calibration_storage/file_operators.py +142 -0
  7. opentrons/calibration_storage/helpers.py +103 -0
  8. opentrons/calibration_storage/ot2/__init__.py +34 -0
  9. opentrons/calibration_storage/ot2/deck_attitude.py +85 -0
  10. opentrons/calibration_storage/ot2/mark_bad_calibration.py +27 -0
  11. opentrons/calibration_storage/ot2/models/__init__.py +0 -0
  12. opentrons/calibration_storage/ot2/models/v1.py +149 -0
  13. opentrons/calibration_storage/ot2/pipette_offset.py +129 -0
  14. opentrons/calibration_storage/ot2/tip_length.py +281 -0
  15. opentrons/calibration_storage/ot3/__init__.py +31 -0
  16. opentrons/calibration_storage/ot3/deck_attitude.py +83 -0
  17. opentrons/calibration_storage/ot3/gripper_offset.py +156 -0
  18. opentrons/calibration_storage/ot3/models/__init__.py +0 -0
  19. opentrons/calibration_storage/ot3/models/v1.py +122 -0
  20. opentrons/calibration_storage/ot3/module_offset.py +138 -0
  21. opentrons/calibration_storage/ot3/pipette_offset.py +95 -0
  22. opentrons/calibration_storage/types.py +45 -0
  23. opentrons/cli/__init__.py +21 -0
  24. opentrons/cli/__main__.py +5 -0
  25. opentrons/cli/analyze.py +501 -0
  26. opentrons/config/__init__.py +631 -0
  27. opentrons/config/advanced_settings.py +871 -0
  28. opentrons/config/defaults_ot2.py +214 -0
  29. opentrons/config/defaults_ot3.py +499 -0
  30. opentrons/config/feature_flags.py +86 -0
  31. opentrons/config/gripper_config.py +55 -0
  32. opentrons/config/reset.py +203 -0
  33. opentrons/config/robot_configs.py +187 -0
  34. opentrons/config/types.py +183 -0
  35. opentrons/drivers/__init__.py +0 -0
  36. opentrons/drivers/absorbance_reader/__init__.py +11 -0
  37. opentrons/drivers/absorbance_reader/abstract.py +72 -0
  38. opentrons/drivers/absorbance_reader/async_byonoy.py +352 -0
  39. opentrons/drivers/absorbance_reader/driver.py +81 -0
  40. opentrons/drivers/absorbance_reader/hid_protocol.py +161 -0
  41. opentrons/drivers/absorbance_reader/simulator.py +84 -0
  42. opentrons/drivers/asyncio/__init__.py +0 -0
  43. opentrons/drivers/asyncio/communication/__init__.py +22 -0
  44. opentrons/drivers/asyncio/communication/async_serial.py +183 -0
  45. opentrons/drivers/asyncio/communication/errors.py +88 -0
  46. opentrons/drivers/asyncio/communication/serial_connection.py +552 -0
  47. opentrons/drivers/command_builder.py +102 -0
  48. opentrons/drivers/flex_stacker/__init__.py +13 -0
  49. opentrons/drivers/flex_stacker/abstract.py +214 -0
  50. opentrons/drivers/flex_stacker/driver.py +768 -0
  51. opentrons/drivers/flex_stacker/errors.py +68 -0
  52. opentrons/drivers/flex_stacker/simulator.py +309 -0
  53. opentrons/drivers/flex_stacker/types.py +367 -0
  54. opentrons/drivers/flex_stacker/utils.py +19 -0
  55. opentrons/drivers/heater_shaker/__init__.py +5 -0
  56. opentrons/drivers/heater_shaker/abstract.py +76 -0
  57. opentrons/drivers/heater_shaker/driver.py +204 -0
  58. opentrons/drivers/heater_shaker/simulator.py +94 -0
  59. opentrons/drivers/mag_deck/__init__.py +6 -0
  60. opentrons/drivers/mag_deck/abstract.py +44 -0
  61. opentrons/drivers/mag_deck/driver.py +208 -0
  62. opentrons/drivers/mag_deck/simulator.py +63 -0
  63. opentrons/drivers/rpi_drivers/__init__.py +33 -0
  64. opentrons/drivers/rpi_drivers/dev_types.py +94 -0
  65. opentrons/drivers/rpi_drivers/gpio.py +282 -0
  66. opentrons/drivers/rpi_drivers/gpio_simulator.py +127 -0
  67. opentrons/drivers/rpi_drivers/interfaces.py +15 -0
  68. opentrons/drivers/rpi_drivers/types.py +364 -0
  69. opentrons/drivers/rpi_drivers/usb.py +102 -0
  70. opentrons/drivers/rpi_drivers/usb_simulator.py +22 -0
  71. opentrons/drivers/serial_communication.py +151 -0
  72. opentrons/drivers/smoothie_drivers/__init__.py +4 -0
  73. opentrons/drivers/smoothie_drivers/connection.py +51 -0
  74. opentrons/drivers/smoothie_drivers/constants.py +121 -0
  75. opentrons/drivers/smoothie_drivers/driver_3_0.py +1933 -0
  76. opentrons/drivers/smoothie_drivers/errors.py +49 -0
  77. opentrons/drivers/smoothie_drivers/parse_utils.py +143 -0
  78. opentrons/drivers/smoothie_drivers/simulator.py +99 -0
  79. opentrons/drivers/smoothie_drivers/types.py +16 -0
  80. opentrons/drivers/temp_deck/__init__.py +10 -0
  81. opentrons/drivers/temp_deck/abstract.py +54 -0
  82. opentrons/drivers/temp_deck/driver.py +197 -0
  83. opentrons/drivers/temp_deck/simulator.py +57 -0
  84. opentrons/drivers/thermocycler/__init__.py +12 -0
  85. opentrons/drivers/thermocycler/abstract.py +99 -0
  86. opentrons/drivers/thermocycler/driver.py +395 -0
  87. opentrons/drivers/thermocycler/simulator.py +126 -0
  88. opentrons/drivers/types.py +107 -0
  89. opentrons/drivers/utils.py +222 -0
  90. opentrons/execute.py +742 -0
  91. opentrons/hardware_control/__init__.py +65 -0
  92. opentrons/hardware_control/__main__.py +77 -0
  93. opentrons/hardware_control/adapters.py +98 -0
  94. opentrons/hardware_control/api.py +1347 -0
  95. opentrons/hardware_control/backends/__init__.py +7 -0
  96. opentrons/hardware_control/backends/controller.py +400 -0
  97. opentrons/hardware_control/backends/errors.py +9 -0
  98. opentrons/hardware_control/backends/estop_state.py +164 -0
  99. opentrons/hardware_control/backends/flex_protocol.py +497 -0
  100. opentrons/hardware_control/backends/ot3controller.py +1930 -0
  101. opentrons/hardware_control/backends/ot3simulator.py +900 -0
  102. opentrons/hardware_control/backends/ot3utils.py +664 -0
  103. opentrons/hardware_control/backends/simulator.py +442 -0
  104. opentrons/hardware_control/backends/status_bar_state.py +240 -0
  105. opentrons/hardware_control/backends/subsystem_manager.py +431 -0
  106. opentrons/hardware_control/backends/tip_presence_manager.py +173 -0
  107. opentrons/hardware_control/backends/types.py +14 -0
  108. opentrons/hardware_control/constants.py +6 -0
  109. opentrons/hardware_control/dev_types.py +125 -0
  110. opentrons/hardware_control/emulation/__init__.py +0 -0
  111. opentrons/hardware_control/emulation/abstract_emulator.py +21 -0
  112. opentrons/hardware_control/emulation/app.py +56 -0
  113. opentrons/hardware_control/emulation/connection_handler.py +38 -0
  114. opentrons/hardware_control/emulation/heater_shaker.py +150 -0
  115. opentrons/hardware_control/emulation/magdeck.py +60 -0
  116. opentrons/hardware_control/emulation/module_server/__init__.py +8 -0
  117. opentrons/hardware_control/emulation/module_server/client.py +78 -0
  118. opentrons/hardware_control/emulation/module_server/helpers.py +130 -0
  119. opentrons/hardware_control/emulation/module_server/models.py +31 -0
  120. opentrons/hardware_control/emulation/module_server/server.py +110 -0
  121. opentrons/hardware_control/emulation/parser.py +74 -0
  122. opentrons/hardware_control/emulation/proxy.py +241 -0
  123. opentrons/hardware_control/emulation/run_emulator.py +68 -0
  124. opentrons/hardware_control/emulation/scripts/__init__.py +0 -0
  125. opentrons/hardware_control/emulation/scripts/run_app.py +54 -0
  126. opentrons/hardware_control/emulation/scripts/run_module_emulator.py +72 -0
  127. opentrons/hardware_control/emulation/scripts/run_smoothie.py +37 -0
  128. opentrons/hardware_control/emulation/settings.py +119 -0
  129. opentrons/hardware_control/emulation/simulations.py +133 -0
  130. opentrons/hardware_control/emulation/smoothie.py +192 -0
  131. opentrons/hardware_control/emulation/tempdeck.py +69 -0
  132. opentrons/hardware_control/emulation/thermocycler.py +128 -0
  133. opentrons/hardware_control/emulation/types.py +10 -0
  134. opentrons/hardware_control/emulation/util.py +38 -0
  135. opentrons/hardware_control/errors.py +43 -0
  136. opentrons/hardware_control/execution_manager.py +164 -0
  137. opentrons/hardware_control/instruments/__init__.py +5 -0
  138. opentrons/hardware_control/instruments/instrument_abc.py +39 -0
  139. opentrons/hardware_control/instruments/ot2/__init__.py +0 -0
  140. opentrons/hardware_control/instruments/ot2/instrument_calibration.py +152 -0
  141. opentrons/hardware_control/instruments/ot2/pipette.py +777 -0
  142. opentrons/hardware_control/instruments/ot2/pipette_handler.py +995 -0
  143. opentrons/hardware_control/instruments/ot3/__init__.py +0 -0
  144. opentrons/hardware_control/instruments/ot3/gripper.py +420 -0
  145. opentrons/hardware_control/instruments/ot3/gripper_handler.py +173 -0
  146. opentrons/hardware_control/instruments/ot3/instrument_calibration.py +214 -0
  147. opentrons/hardware_control/instruments/ot3/pipette.py +858 -0
  148. opentrons/hardware_control/instruments/ot3/pipette_handler.py +1030 -0
  149. opentrons/hardware_control/module_control.py +332 -0
  150. opentrons/hardware_control/modules/__init__.py +69 -0
  151. opentrons/hardware_control/modules/absorbance_reader.py +373 -0
  152. opentrons/hardware_control/modules/errors.py +7 -0
  153. opentrons/hardware_control/modules/flex_stacker.py +948 -0
  154. opentrons/hardware_control/modules/heater_shaker.py +426 -0
  155. opentrons/hardware_control/modules/lid_temp_status.py +35 -0
  156. opentrons/hardware_control/modules/magdeck.py +233 -0
  157. opentrons/hardware_control/modules/mod_abc.py +245 -0
  158. opentrons/hardware_control/modules/module_calibration.py +93 -0
  159. opentrons/hardware_control/modules/plate_temp_status.py +61 -0
  160. opentrons/hardware_control/modules/tempdeck.py +299 -0
  161. opentrons/hardware_control/modules/thermocycler.py +731 -0
  162. opentrons/hardware_control/modules/types.py +417 -0
  163. opentrons/hardware_control/modules/update.py +255 -0
  164. opentrons/hardware_control/modules/utils.py +73 -0
  165. opentrons/hardware_control/motion_utilities.py +318 -0
  166. opentrons/hardware_control/nozzle_manager.py +422 -0
  167. opentrons/hardware_control/ot3_calibration.py +1171 -0
  168. opentrons/hardware_control/ot3api.py +3227 -0
  169. opentrons/hardware_control/pause_manager.py +31 -0
  170. opentrons/hardware_control/poller.py +112 -0
  171. opentrons/hardware_control/protocols/__init__.py +106 -0
  172. opentrons/hardware_control/protocols/asyncio_configurable.py +11 -0
  173. opentrons/hardware_control/protocols/calibratable.py +45 -0
  174. opentrons/hardware_control/protocols/chassis_accessory_manager.py +90 -0
  175. opentrons/hardware_control/protocols/configurable.py +48 -0
  176. opentrons/hardware_control/protocols/event_sourcer.py +18 -0
  177. opentrons/hardware_control/protocols/execution_controllable.py +33 -0
  178. opentrons/hardware_control/protocols/flex_calibratable.py +96 -0
  179. opentrons/hardware_control/protocols/flex_instrument_configurer.py +52 -0
  180. opentrons/hardware_control/protocols/gripper_controller.py +55 -0
  181. opentrons/hardware_control/protocols/hardware_manager.py +51 -0
  182. opentrons/hardware_control/protocols/identifiable.py +16 -0
  183. opentrons/hardware_control/protocols/instrument_configurer.py +206 -0
  184. opentrons/hardware_control/protocols/liquid_handler.py +266 -0
  185. opentrons/hardware_control/protocols/module_provider.py +16 -0
  186. opentrons/hardware_control/protocols/motion_controller.py +243 -0
  187. opentrons/hardware_control/protocols/position_estimator.py +45 -0
  188. opentrons/hardware_control/protocols/simulatable.py +10 -0
  189. opentrons/hardware_control/protocols/stoppable.py +9 -0
  190. opentrons/hardware_control/protocols/types.py +27 -0
  191. opentrons/hardware_control/robot_calibration.py +224 -0
  192. opentrons/hardware_control/scripts/README.md +28 -0
  193. opentrons/hardware_control/scripts/__init__.py +1 -0
  194. opentrons/hardware_control/scripts/gripper_control.py +208 -0
  195. opentrons/hardware_control/scripts/ot3gripper +7 -0
  196. opentrons/hardware_control/scripts/ot3repl +7 -0
  197. opentrons/hardware_control/scripts/repl.py +187 -0
  198. opentrons/hardware_control/scripts/tc_control.py +97 -0
  199. opentrons/hardware_control/simulator_setup.py +260 -0
  200. opentrons/hardware_control/thread_manager.py +431 -0
  201. opentrons/hardware_control/threaded_async_lock.py +97 -0
  202. opentrons/hardware_control/types.py +792 -0
  203. opentrons/hardware_control/util.py +234 -0
  204. opentrons/legacy_broker.py +53 -0
  205. opentrons/legacy_commands/__init__.py +1 -0
  206. opentrons/legacy_commands/commands.py +483 -0
  207. opentrons/legacy_commands/helpers.py +153 -0
  208. opentrons/legacy_commands/module_commands.py +215 -0
  209. opentrons/legacy_commands/protocol_commands.py +54 -0
  210. opentrons/legacy_commands/publisher.py +155 -0
  211. opentrons/legacy_commands/robot_commands.py +51 -0
  212. opentrons/legacy_commands/types.py +1115 -0
  213. opentrons/motion_planning/__init__.py +32 -0
  214. opentrons/motion_planning/adjacent_slots_getters.py +168 -0
  215. opentrons/motion_planning/deck_conflict.py +396 -0
  216. opentrons/motion_planning/errors.py +35 -0
  217. opentrons/motion_planning/types.py +42 -0
  218. opentrons/motion_planning/waypoints.py +218 -0
  219. opentrons/ordered_set.py +138 -0
  220. opentrons/protocol_api/__init__.py +105 -0
  221. opentrons/protocol_api/_liquid.py +157 -0
  222. opentrons/protocol_api/_liquid_properties.py +814 -0
  223. opentrons/protocol_api/_nozzle_layout.py +31 -0
  224. opentrons/protocol_api/_parameter_context.py +300 -0
  225. opentrons/protocol_api/_parameters.py +31 -0
  226. opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
  227. opentrons/protocol_api/_types.py +43 -0
  228. opentrons/protocol_api/config.py +23 -0
  229. opentrons/protocol_api/core/__init__.py +23 -0
  230. opentrons/protocol_api/core/common.py +33 -0
  231. opentrons/protocol_api/core/core_map.py +74 -0
  232. opentrons/protocol_api/core/engine/__init__.py +22 -0
  233. opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
  234. opentrons/protocol_api/core/engine/deck_conflict.py +348 -0
  235. opentrons/protocol_api/core/engine/exceptions.py +19 -0
  236. opentrons/protocol_api/core/engine/instrument.py +2391 -0
  237. opentrons/protocol_api/core/engine/labware.py +238 -0
  238. opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
  239. opentrons/protocol_api/core/engine/module_core.py +1025 -0
  240. opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
  241. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
  242. opentrons/protocol_api/core/engine/point_calculations.py +64 -0
  243. opentrons/protocol_api/core/engine/protocol.py +1153 -0
  244. opentrons/protocol_api/core/engine/robot.py +139 -0
  245. opentrons/protocol_api/core/engine/stringify.py +74 -0
  246. opentrons/protocol_api/core/engine/transfer_components_executor.py +990 -0
  247. opentrons/protocol_api/core/engine/well.py +241 -0
  248. opentrons/protocol_api/core/instrument.py +459 -0
  249. opentrons/protocol_api/core/labware.py +151 -0
  250. opentrons/protocol_api/core/legacy/__init__.py +11 -0
  251. opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
  252. opentrons/protocol_api/core/legacy/deck.py +369 -0
  253. opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
  254. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
  255. opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
  256. opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
  257. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
  258. opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
  259. opentrons/protocol_api/core/legacy/load_info.py +67 -0
  260. opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
  261. opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
  262. opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
  263. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
  264. opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
  265. opentrons/protocol_api/core/module.py +484 -0
  266. opentrons/protocol_api/core/protocol.py +311 -0
  267. opentrons/protocol_api/core/robot.py +51 -0
  268. opentrons/protocol_api/core/well.py +116 -0
  269. opentrons/protocol_api/core/well_grid.py +45 -0
  270. opentrons/protocol_api/create_protocol_context.py +177 -0
  271. opentrons/protocol_api/deck.py +223 -0
  272. opentrons/protocol_api/disposal_locations.py +244 -0
  273. opentrons/protocol_api/instrument_context.py +3212 -0
  274. opentrons/protocol_api/labware.py +1579 -0
  275. opentrons/protocol_api/module_contexts.py +1425 -0
  276. opentrons/protocol_api/module_validation_and_errors.py +61 -0
  277. opentrons/protocol_api/protocol_context.py +1688 -0
  278. opentrons/protocol_api/robot_context.py +303 -0
  279. opentrons/protocol_api/validation.py +761 -0
  280. opentrons/protocol_engine/__init__.py +155 -0
  281. opentrons/protocol_engine/actions/__init__.py +65 -0
  282. opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
  283. opentrons/protocol_engine/actions/action_handler.py +13 -0
  284. opentrons/protocol_engine/actions/actions.py +302 -0
  285. opentrons/protocol_engine/actions/get_state_update.py +38 -0
  286. opentrons/protocol_engine/clients/__init__.py +5 -0
  287. opentrons/protocol_engine/clients/sync_client.py +174 -0
  288. opentrons/protocol_engine/clients/transports.py +197 -0
  289. opentrons/protocol_engine/commands/__init__.py +757 -0
  290. opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
  291. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
  292. opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
  293. opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
  294. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
  295. opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
  296. opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
  297. opentrons/protocol_engine/commands/aspirate.py +244 -0
  298. opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
  299. opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
  300. opentrons/protocol_engine/commands/blow_out.py +146 -0
  301. opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
  302. opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
  303. opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
  304. opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
  305. opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
  306. opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
  307. opentrons/protocol_engine/commands/command.py +308 -0
  308. opentrons/protocol_engine/commands/command_unions.py +974 -0
  309. opentrons/protocol_engine/commands/comment.py +57 -0
  310. opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
  311. opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
  312. opentrons/protocol_engine/commands/custom.py +67 -0
  313. opentrons/protocol_engine/commands/dispense.py +194 -0
  314. opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
  315. opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
  316. opentrons/protocol_engine/commands/drop_tip.py +232 -0
  317. opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
  318. opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
  319. opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
  320. opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
  321. opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
  322. opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
  323. opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
  324. opentrons/protocol_engine/commands/flex_stacker/store.py +326 -0
  325. opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
  326. opentrons/protocol_engine/commands/get_next_tip.py +134 -0
  327. opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
  328. opentrons/protocol_engine/commands/hash_command_params.py +38 -0
  329. opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
  330. opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
  331. opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
  332. opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
  333. opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
  334. opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
  335. opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
  336. opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
  337. opentrons/protocol_engine/commands/home.py +100 -0
  338. opentrons/protocol_engine/commands/identify_module.py +86 -0
  339. opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
  340. opentrons/protocol_engine/commands/liquid_probe.py +464 -0
  341. opentrons/protocol_engine/commands/load_labware.py +210 -0
  342. opentrons/protocol_engine/commands/load_lid.py +154 -0
  343. opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
  344. opentrons/protocol_engine/commands/load_liquid.py +95 -0
  345. opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
  346. opentrons/protocol_engine/commands/load_module.py +223 -0
  347. opentrons/protocol_engine/commands/load_pipette.py +167 -0
  348. opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
  349. opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
  350. opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
  351. opentrons/protocol_engine/commands/move_labware.py +546 -0
  352. opentrons/protocol_engine/commands/move_relative.py +102 -0
  353. opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
  354. opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
  355. opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
  356. opentrons/protocol_engine/commands/move_to_well.py +119 -0
  357. opentrons/protocol_engine/commands/movement_common.py +338 -0
  358. opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
  359. opentrons/protocol_engine/commands/pipetting_common.py +443 -0
  360. opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
  361. opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
  362. opentrons/protocol_engine/commands/reload_labware.py +90 -0
  363. opentrons/protocol_engine/commands/retract_axis.py +75 -0
  364. opentrons/protocol_engine/commands/robot/__init__.py +70 -0
  365. opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
  366. opentrons/protocol_engine/commands/robot/common.py +18 -0
  367. opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
  368. opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
  369. opentrons/protocol_engine/commands/robot/move_to.py +94 -0
  370. opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
  371. opentrons/protocol_engine/commands/save_position.py +109 -0
  372. opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
  373. opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
  374. opentrons/protocol_engine/commands/set_status_bar.py +89 -0
  375. opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
  376. opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
  377. opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
  378. opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
  379. opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
  380. opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
  381. opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
  382. opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
  383. opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
  384. opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
  385. opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
  386. opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
  387. opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
  388. opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
  389. opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
  390. opentrons/protocol_engine/commands/touch_tip.py +189 -0
  391. opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
  392. opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
  393. opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
  394. opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
  395. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
  396. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
  397. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
  398. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
  399. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
  400. opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
  401. opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
  402. opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
  403. opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
  404. opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
  405. opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
  406. opentrons/protocol_engine/create_protocol_engine.py +193 -0
  407. opentrons/protocol_engine/engine_support.py +28 -0
  408. opentrons/protocol_engine/error_recovery_policy.py +81 -0
  409. opentrons/protocol_engine/errors/__init__.py +191 -0
  410. opentrons/protocol_engine/errors/error_occurrence.py +182 -0
  411. opentrons/protocol_engine/errors/exceptions.py +1308 -0
  412. opentrons/protocol_engine/execution/__init__.py +50 -0
  413. opentrons/protocol_engine/execution/command_executor.py +216 -0
  414. opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
  415. opentrons/protocol_engine/execution/door_watcher.py +119 -0
  416. opentrons/protocol_engine/execution/equipment.py +819 -0
  417. opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
  418. opentrons/protocol_engine/execution/gantry_mover.py +686 -0
  419. opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
  420. opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
  421. opentrons/protocol_engine/execution/labware_movement.py +297 -0
  422. opentrons/protocol_engine/execution/movement.py +349 -0
  423. opentrons/protocol_engine/execution/pipetting.py +607 -0
  424. opentrons/protocol_engine/execution/queue_worker.py +86 -0
  425. opentrons/protocol_engine/execution/rail_lights.py +25 -0
  426. opentrons/protocol_engine/execution/run_control.py +33 -0
  427. opentrons/protocol_engine/execution/status_bar.py +34 -0
  428. opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
  429. opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
  430. opentrons/protocol_engine/execution/tip_handler.py +550 -0
  431. opentrons/protocol_engine/labware_offset_standardization.py +194 -0
  432. opentrons/protocol_engine/notes/__init__.py +17 -0
  433. opentrons/protocol_engine/notes/notes.py +59 -0
  434. opentrons/protocol_engine/plugins.py +104 -0
  435. opentrons/protocol_engine/protocol_engine.py +683 -0
  436. opentrons/protocol_engine/resources/__init__.py +26 -0
  437. opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
  438. opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
  439. opentrons/protocol_engine/resources/file_provider.py +161 -0
  440. opentrons/protocol_engine/resources/fixture_validation.py +58 -0
  441. opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
  442. opentrons/protocol_engine/resources/labware_validation.py +73 -0
  443. opentrons/protocol_engine/resources/model_utils.py +32 -0
  444. opentrons/protocol_engine/resources/module_data_provider.py +44 -0
  445. opentrons/protocol_engine/resources/ot3_validation.py +21 -0
  446. opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
  447. opentrons/protocol_engine/slot_standardization.py +128 -0
  448. opentrons/protocol_engine/state/__init__.py +1 -0
  449. opentrons/protocol_engine/state/_abstract_store.py +27 -0
  450. opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
  451. opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
  452. opentrons/protocol_engine/state/_move_types.py +83 -0
  453. opentrons/protocol_engine/state/_well_math.py +193 -0
  454. opentrons/protocol_engine/state/addressable_areas.py +699 -0
  455. opentrons/protocol_engine/state/command_history.py +309 -0
  456. opentrons/protocol_engine/state/commands.py +1158 -0
  457. opentrons/protocol_engine/state/config.py +39 -0
  458. opentrons/protocol_engine/state/files.py +57 -0
  459. opentrons/protocol_engine/state/fluid_stack.py +138 -0
  460. opentrons/protocol_engine/state/geometry.py +2359 -0
  461. opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
  462. opentrons/protocol_engine/state/labware.py +1459 -0
  463. opentrons/protocol_engine/state/liquid_classes.py +82 -0
  464. opentrons/protocol_engine/state/liquids.py +73 -0
  465. opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
  466. opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
  467. opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
  468. opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
  469. opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
  470. opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
  471. opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
  472. opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
  473. opentrons/protocol_engine/state/modules.py +1500 -0
  474. opentrons/protocol_engine/state/motion.py +373 -0
  475. opentrons/protocol_engine/state/pipettes.py +905 -0
  476. opentrons/protocol_engine/state/state.py +421 -0
  477. opentrons/protocol_engine/state/state_summary.py +36 -0
  478. opentrons/protocol_engine/state/tips.py +420 -0
  479. opentrons/protocol_engine/state/update_types.py +904 -0
  480. opentrons/protocol_engine/state/wells.py +290 -0
  481. opentrons/protocol_engine/types/__init__.py +308 -0
  482. opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
  483. opentrons/protocol_engine/types/command_annotations.py +53 -0
  484. opentrons/protocol_engine/types/deck_configuration.py +81 -0
  485. opentrons/protocol_engine/types/execution.py +96 -0
  486. opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
  487. opentrons/protocol_engine/types/instrument.py +47 -0
  488. opentrons/protocol_engine/types/instrument_sensors.py +47 -0
  489. opentrons/protocol_engine/types/labware.py +131 -0
  490. opentrons/protocol_engine/types/labware_movement.py +22 -0
  491. opentrons/protocol_engine/types/labware_offset_location.py +111 -0
  492. opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
  493. opentrons/protocol_engine/types/liquid.py +40 -0
  494. opentrons/protocol_engine/types/liquid_class.py +59 -0
  495. opentrons/protocol_engine/types/liquid_handling.py +13 -0
  496. opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
  497. opentrons/protocol_engine/types/location.py +194 -0
  498. opentrons/protocol_engine/types/module.py +303 -0
  499. opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
  500. opentrons/protocol_engine/types/run_time_parameters.py +133 -0
  501. opentrons/protocol_engine/types/tip.py +18 -0
  502. opentrons/protocol_engine/types/util.py +21 -0
  503. opentrons/protocol_engine/types/well_position.py +124 -0
  504. opentrons/protocol_reader/__init__.py +37 -0
  505. opentrons/protocol_reader/extract_labware_definitions.py +66 -0
  506. opentrons/protocol_reader/file_format_validator.py +152 -0
  507. opentrons/protocol_reader/file_hasher.py +27 -0
  508. opentrons/protocol_reader/file_identifier.py +284 -0
  509. opentrons/protocol_reader/file_reader_writer.py +90 -0
  510. opentrons/protocol_reader/input_file.py +16 -0
  511. opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
  512. opentrons/protocol_reader/protocol_reader.py +188 -0
  513. opentrons/protocol_reader/protocol_source.py +124 -0
  514. opentrons/protocol_reader/role_analyzer.py +86 -0
  515. opentrons/protocol_runner/__init__.py +26 -0
  516. opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
  517. opentrons/protocol_runner/json_file_reader.py +55 -0
  518. opentrons/protocol_runner/json_translator.py +314 -0
  519. opentrons/protocol_runner/legacy_command_mapper.py +848 -0
  520. opentrons/protocol_runner/legacy_context_plugin.py +116 -0
  521. opentrons/protocol_runner/protocol_runner.py +530 -0
  522. opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
  523. opentrons/protocol_runner/run_orchestrator.py +496 -0
  524. opentrons/protocol_runner/task_queue.py +95 -0
  525. opentrons/protocols/__init__.py +6 -0
  526. opentrons/protocols/advanced_control/__init__.py +0 -0
  527. opentrons/protocols/advanced_control/common.py +38 -0
  528. opentrons/protocols/advanced_control/mix.py +60 -0
  529. opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
  530. opentrons/protocols/advanced_control/transfers/common.py +180 -0
  531. opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
  532. opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
  533. opentrons/protocols/api_support/__init__.py +0 -0
  534. opentrons/protocols/api_support/constants.py +8 -0
  535. opentrons/protocols/api_support/deck_type.py +110 -0
  536. opentrons/protocols/api_support/definitions.py +18 -0
  537. opentrons/protocols/api_support/instrument.py +151 -0
  538. opentrons/protocols/api_support/labware_like.py +233 -0
  539. opentrons/protocols/api_support/tip_tracker.py +175 -0
  540. opentrons/protocols/api_support/types.py +32 -0
  541. opentrons/protocols/api_support/util.py +403 -0
  542. opentrons/protocols/bundle.py +89 -0
  543. opentrons/protocols/duration/__init__.py +4 -0
  544. opentrons/protocols/duration/errors.py +5 -0
  545. opentrons/protocols/duration/estimator.py +628 -0
  546. opentrons/protocols/execution/__init__.py +0 -0
  547. opentrons/protocols/execution/dev_types.py +181 -0
  548. opentrons/protocols/execution/errors.py +40 -0
  549. opentrons/protocols/execution/execute.py +84 -0
  550. opentrons/protocols/execution/execute_json_v3.py +275 -0
  551. opentrons/protocols/execution/execute_json_v4.py +359 -0
  552. opentrons/protocols/execution/execute_json_v5.py +28 -0
  553. opentrons/protocols/execution/execute_python.py +169 -0
  554. opentrons/protocols/execution/json_dispatchers.py +87 -0
  555. opentrons/protocols/execution/types.py +7 -0
  556. opentrons/protocols/geometry/__init__.py +0 -0
  557. opentrons/protocols/geometry/planning.py +297 -0
  558. opentrons/protocols/labware.py +312 -0
  559. opentrons/protocols/models/__init__.py +0 -0
  560. opentrons/protocols/models/json_protocol.py +679 -0
  561. opentrons/protocols/parameters/__init__.py +0 -0
  562. opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
  563. opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
  564. opentrons/protocols/parameters/exceptions.py +34 -0
  565. opentrons/protocols/parameters/parameter_definition.py +272 -0
  566. opentrons/protocols/parameters/types.py +17 -0
  567. opentrons/protocols/parameters/validation.py +267 -0
  568. opentrons/protocols/parse.py +671 -0
  569. opentrons/protocols/types.py +159 -0
  570. opentrons/py.typed +0 -0
  571. opentrons/resources/scripts/lpc21isp +0 -0
  572. opentrons/resources/smoothie-edge-8414642.hex +23010 -0
  573. opentrons/simulate.py +1065 -0
  574. opentrons/system/__init__.py +6 -0
  575. opentrons/system/camera.py +51 -0
  576. opentrons/system/log_control.py +59 -0
  577. opentrons/system/nmcli.py +856 -0
  578. opentrons/system/resin.py +24 -0
  579. opentrons/system/smoothie_update.py +15 -0
  580. opentrons/system/wifi.py +204 -0
  581. opentrons/tools/__init__.py +0 -0
  582. opentrons/tools/args_handler.py +22 -0
  583. opentrons/tools/write_pipette_memory.py +157 -0
  584. opentrons/types.py +618 -0
  585. opentrons/util/__init__.py +1 -0
  586. opentrons/util/async_helpers.py +166 -0
  587. opentrons/util/broker.py +84 -0
  588. opentrons/util/change_notifier.py +47 -0
  589. opentrons/util/entrypoint_util.py +278 -0
  590. opentrons/util/get_union_elements.py +26 -0
  591. opentrons/util/helpers.py +6 -0
  592. opentrons/util/linal.py +178 -0
  593. opentrons/util/logging_config.py +265 -0
  594. opentrons/util/logging_queue_handler.py +61 -0
  595. opentrons/util/performance_helpers.py +157 -0
  596. opentrons-8.6.0a1.dist-info/METADATA +37 -0
  597. opentrons-8.6.0a1.dist-info/RECORD +600 -0
  598. opentrons-8.6.0a1.dist-info/WHEEL +4 -0
  599. opentrons-8.6.0a1.dist-info/entry_points.txt +3 -0
  600. opentrons-8.6.0a1.dist-info/licenses/LICENSE +202 -0
File without changes
@@ -0,0 +1,420 @@
1
+ from __future__ import annotations
2
+
3
+ """ Classes and functions for gripper state tracking
4
+ """
5
+ import logging
6
+ from typing import Any, Optional, Set, Dict, Tuple, Final
7
+
8
+ from opentrons.types import Point
9
+ from opentrons.config import gripper_config
10
+ from opentrons.hardware_control.types import (
11
+ GripperProbe,
12
+ CriticalPoint,
13
+ GripperJawState,
14
+ )
15
+ from opentrons.hardware_control.errors import (
16
+ InvalidCriticalPoint,
17
+ )
18
+ from .instrument_calibration import (
19
+ GripperCalibrationOffset,
20
+ load_gripper_calibration_offset,
21
+ save_gripper_calibration_offset,
22
+ save_gripper_jaw_width_data,
23
+ load_gripper_jaw_width,
24
+ )
25
+
26
+ from ..instrument_abc import AbstractInstrument
27
+ from opentrons.hardware_control.dev_types import AttachedGripper, GripperDict
28
+ from opentrons_shared_data.errors.exceptions import (
29
+ CommandPreconditionViolated,
30
+ MotionFailedError,
31
+ )
32
+
33
+ from opentrons_shared_data.gripper import (
34
+ GripperDefinition,
35
+ GripForceProfile,
36
+ Geometry,
37
+ )
38
+
39
+ RECONFIG_KEYS = {"quirks", "grip_force_profile"}
40
+
41
+ MAX_ACCEPTABLE_JAW_DISPLACEMENT: Final = 20
42
+
43
+ mod_log = logging.getLogger(__name__)
44
+
45
+
46
+ class Gripper(AbstractInstrument[GripperDefinition]):
47
+ """A class to gather and track gripper state and configs.
48
+
49
+ This class should not touch hardware or call back out to the hardware
50
+ control API. Its only purpose is to gather state.
51
+ """
52
+
53
+ def __init__(
54
+ self,
55
+ config: GripperDefinition,
56
+ gripper_cal_offset: GripperCalibrationOffset,
57
+ gripper_id: str,
58
+ ) -> None:
59
+ self._config = config
60
+ self._model = config.model
61
+
62
+ self._geometry = self._config.geometry
63
+ base_offset = Point(*self._geometry.base_offset_from_mount)
64
+ self._jaw_center_offset = (
65
+ Point(*self._geometry.jaw_center_offset_from_base) + base_offset
66
+ )
67
+ #: the distance between the gripper mount and the jaw center at home
68
+ self._front_calibration_pin_offset = (
69
+ Point(*self._geometry.pin_one_offset_from_base) + base_offset
70
+ )
71
+ #: the distance between the gripper mount and the front calibration pin
72
+ #: at home
73
+ self._rear_calibration_pin_offset = (
74
+ Point(*self._geometry.pin_two_offset_from_base) + base_offset
75
+ )
76
+ #: the distance between the gripper mount and the rear calibration pin
77
+ #: at home
78
+ self._calibration_offset = gripper_cal_offset
79
+ #: The output value of calibration - the additional vector added into
80
+ #: the critical point geometry based on gripper mount calibration
81
+ self._gripper_id = gripper_id
82
+ self._state = GripperJawState.UNHOMED
83
+ self._current_jaw_displacement = 0.0
84
+ self._attached_probe: Optional[GripperProbe] = None
85
+ self._log = mod_log.getChild(self._gripper_id)
86
+ self._log.info(
87
+ f"loaded: {self._model}, gripper offset: {self._calibration_offset}"
88
+ )
89
+ self._encoder_position_at_jaw_closed: Optional[float] = None
90
+
91
+ @property
92
+ def grip_force_profile(self) -> GripForceProfile:
93
+ return self._config.grip_force_profile
94
+
95
+ @property
96
+ def geometry(self) -> Geometry:
97
+ return self._geometry
98
+
99
+ @property
100
+ def attached_probe(self) -> Optional[GripperProbe]:
101
+ return self._attached_probe
102
+
103
+ def add_probe(self, probe: GripperProbe) -> None:
104
+ """This is used for finding the critical point during calibration."""
105
+ assert not self.attached_probe
106
+ self._attached_probe = probe
107
+
108
+ def remove_probe(self) -> None:
109
+ assert self.attached_probe
110
+ self._attached_probe = None
111
+
112
+ @property
113
+ def max_allowed_grip_error(self) -> float:
114
+ return self._geometry.max_allowed_grip_error
115
+
116
+ @property
117
+ def _jaw_min(self) -> float:
118
+ return self._config.geometry.jaw_width["min"]
119
+
120
+ @property
121
+ def _jaw_nominal_max(self) -> float:
122
+ return self._config.geometry.jaw_width["max"]
123
+
124
+ @property
125
+ def _jaw_max_offset(self) -> float | None:
126
+ if self._encoder_position_at_jaw_closed is None:
127
+ return None
128
+ return self._jaw_min - (
129
+ self._jaw_nominal_max - (self._encoder_position_at_jaw_closed * 2)
130
+ )
131
+
132
+ @property
133
+ def max_jaw_width(self) -> float:
134
+ return self._config.geometry.jaw_width["max"] + (self._jaw_max_offset or 0)
135
+
136
+ @property
137
+ def min_jaw_width(self) -> float:
138
+ return self._config.geometry.jaw_width["min"]
139
+
140
+ @property
141
+ def jaw_width(self) -> float:
142
+ return self.max_jaw_width - (self.current_jaw_displacement * 2.0)
143
+
144
+ @property
145
+ def current_jaw_displacement(self) -> float:
146
+ """The distance one side of the jaw has traveled from home."""
147
+ return self._current_jaw_displacement
148
+
149
+ @current_jaw_displacement.setter
150
+ def current_jaw_displacement(self, mm: float) -> None:
151
+ max_mm = self.max_jaw_displacement() + 2.0
152
+ if mm > max_mm:
153
+ self._log.warning(
154
+ f"jaw displacement {round(mm, 1)} mm exceeds max expected value: "
155
+ f"{max_mm} mm, setting value to max value instead."
156
+ )
157
+ self._current_jaw_displacement = min(mm, max_mm)
158
+
159
+ @property
160
+ def default_grip_force(self) -> float:
161
+ return self.grip_force_profile.default_grip_force
162
+
163
+ @property
164
+ def default_idle_force(self) -> float:
165
+ return self.grip_force_profile.default_idle_force
166
+
167
+ @property
168
+ def default_home_force(self) -> float:
169
+ return self.grip_force_profile.default_home_force
170
+
171
+ def max_jaw_displacement(self) -> float:
172
+ geometry = self._config.geometry
173
+ return (self.max_jaw_width - geometry.jaw_width["min"]) / 2
174
+
175
+ @property
176
+ def state(self) -> GripperJawState:
177
+ return self._state
178
+
179
+ @state.setter
180
+ def state(self, s: GripperJawState) -> None:
181
+ self._state = s
182
+
183
+ @property
184
+ def config(self) -> GripperDefinition:
185
+ return self._config
186
+
187
+ def update_config_item(self, elements: Dict[str, Any]) -> None:
188
+ raise NotImplementedError("Update config is not supported at this time.")
189
+
190
+ @property
191
+ def model(self) -> str:
192
+ return repr(self._model)
193
+
194
+ @property
195
+ def gripper_id(self) -> str:
196
+ return self._gripper_id
197
+
198
+ def reload_configurations(self) -> None:
199
+ return None
200
+
201
+ def update_jaw_open_position_from_closed_position(
202
+ self, jaw_at_closed: float | None
203
+ ) -> None:
204
+ """Update the estimation of the jaw position at open based on reading it at closed.
205
+
206
+ This is necessary because the gripper jaw has a well-defined positional hard stop
207
+ when fully closed and empty but _not_ when open. The open position can vary unit to
208
+ unit. You can calibrate this out by reading the position of the encoder when the jaw
209
+ is closed, and then altering the logical open position so that it is whatever it needs
210
+ to be for the logical closed position to be the same as the config.
211
+ """
212
+ if jaw_at_closed is None:
213
+ self._encoder_position_at_jaw_closed = jaw_at_closed
214
+ return
215
+ if (
216
+ abs((jaw_at_closed * 2) - (self._jaw_nominal_max - self._jaw_min))
217
+ > MAX_ACCEPTABLE_JAW_DISPLACEMENT
218
+ ):
219
+ raise MotionFailedError(
220
+ message="Gripper jaw calibration out of bounds",
221
+ detail={
222
+ "type": "gripper-jaw-calibration-out-of-bounds",
223
+ "actual-displacement": str(jaw_at_closed * 2),
224
+ "nominal-displacement": str(self._jaw_nominal_max - self._jaw_min),
225
+ },
226
+ )
227
+ save_gripper_jaw_width_data(
228
+ gripper_id=self._gripper_id,
229
+ encoder_position_at_closed=jaw_at_closed,
230
+ )
231
+ self._encoder_position_at_jaw_closed = jaw_at_closed
232
+ self._log.info(
233
+ f"Gripper max jaw offset is now {self._jaw_max_offset} from input position {jaw_at_closed}"
234
+ )
235
+
236
+ @property
237
+ def has_jaw_width_calibration(self) -> bool:
238
+ if self._encoder_position_at_jaw_closed is not None:
239
+ return True
240
+ else:
241
+ load_gripper_jaw_width_data = load_gripper_jaw_width(
242
+ gripper_id=self._gripper_id
243
+ )
244
+ if load_gripper_jaw_width_data.encoder_position_at_jaw_closed is not None:
245
+ # update class members with data from the robot
246
+ self.update_jaw_open_position_from_closed_position(
247
+ jaw_at_closed=load_gripper_jaw_width_data.encoder_position_at_jaw_closed
248
+ )
249
+ return True
250
+ return False
251
+
252
+ def reset_offset(self, to_default: bool) -> None:
253
+ """Tempoarily reset the gripper offsets to default values."""
254
+ if to_default:
255
+ self._calibration_offset = load_gripper_calibration_offset(gripper_id=None)
256
+ else:
257
+ self._calibration_offset = load_gripper_calibration_offset(
258
+ gripper_id=self._gripper_id
259
+ )
260
+
261
+ def reset_jaw_width_calibration(self, to_default: bool) -> None:
262
+ """Reset the gripper jaw width measurement in the protocol engine."""
263
+ if to_default:
264
+ loaded_jaw_width_data = load_gripper_jaw_width(gripper_id=None)
265
+ else:
266
+ loaded_jaw_width_data = load_gripper_jaw_width(gripper_id=self._gripper_id)
267
+ self.update_jaw_open_position_from_closed_position(
268
+ jaw_at_closed=loaded_jaw_width_data.encoder_position_at_jaw_closed
269
+ )
270
+
271
+ def save_offset(self, delta: Point) -> GripperCalibrationOffset:
272
+ """Save a new gripper offset."""
273
+ save_gripper_calibration_offset(self.gripper_id, delta)
274
+ self._calibration_offset = load_gripper_calibration_offset(self.gripper_id)
275
+ return self._calibration_offset
276
+
277
+ def check_calibration_pin_location_is_accurate(self) -> None:
278
+ if not self.attached_probe:
279
+ raise CommandPreconditionViolated(
280
+ "Cannot calibrate gripper without attaching a calibration probe",
281
+ detail={
282
+ "probe": str(self._attached_probe),
283
+ "jaw_state": str(self.state),
284
+ },
285
+ )
286
+ if self.state != GripperJawState.GRIPPING:
287
+ raise CommandPreconditionViolated(
288
+ "Cannot calibrate gripper if jaw is not in gripping state",
289
+ detail={
290
+ "probe": str(self._attached_probe),
291
+ "jaw_state": str(self.state),
292
+ },
293
+ )
294
+
295
+ def critical_point(self, cp_override: Optional[CriticalPoint] = None) -> Point:
296
+ """
297
+ The vector from the gripper mount to the critical point, which is selectable
298
+ between the center of the gripper engagement volume and the calibration pins.
299
+ """
300
+ if cp_override in [CriticalPoint.NOZZLE, CriticalPoint.TIP]:
301
+ raise InvalidCriticalPoint(cp_override.name, "gripper")
302
+
303
+ if not self._attached_probe:
304
+ cp = cp_override or CriticalPoint.GRIPPER_JAW_CENTER
305
+ else:
306
+ if self._attached_probe is GripperProbe.REAR:
307
+ cp = cp_override or CriticalPoint.GRIPPER_REAR_CALIBRATION_PIN
308
+ else:
309
+ cp = cp_override or CriticalPoint.GRIPPER_FRONT_CALIBRATION_PIN
310
+
311
+ if cp in [CriticalPoint.GRIPPER_JAW_CENTER, CriticalPoint.XY_CENTER]:
312
+ return self._jaw_center_offset + Point(*self._calibration_offset.offset)
313
+ elif cp == CriticalPoint.GRIPPER_FRONT_CALIBRATION_PIN:
314
+ self.check_calibration_pin_location_is_accurate()
315
+ return (
316
+ self._front_calibration_pin_offset
317
+ + Point(*self._calibration_offset.offset)
318
+ + Point(y=self.current_jaw_displacement)
319
+ - Point(y=(self._jaw_max_offset or 0))
320
+ )
321
+ elif cp == CriticalPoint.GRIPPER_REAR_CALIBRATION_PIN:
322
+ self.check_calibration_pin_location_is_accurate()
323
+ return (
324
+ self._rear_calibration_pin_offset
325
+ + Point(*self._calibration_offset.offset)
326
+ - Point(y=self.current_jaw_displacement)
327
+ + Point(y=(self._jaw_max_offset or 0))
328
+ )
329
+ else:
330
+ raise InvalidCriticalPoint(cp.name, "gripper")
331
+
332
+ def duty_cycle_by_force(self, newton: float) -> float:
333
+ return gripper_config.duty_cycle_by_force(newton, self.grip_force_profile)
334
+
335
+ def __str__(self) -> str:
336
+ return f"{self._config.display_name}"
337
+
338
+ def __repr__(self) -> str:
339
+ return f"<{self.__class__.__name__}: {self._config.display_name} {id(self)}"
340
+
341
+ def as_dict(self) -> GripperDict:
342
+ d: GripperDict = {
343
+ "model": self._config.model,
344
+ "gripper_id": self._gripper_id,
345
+ "display_name": self._config.display_name,
346
+ "state": self._state,
347
+ "calibration_offset": self._calibration_offset,
348
+ }
349
+ return d
350
+
351
+
352
+ def _reload_gripper(
353
+ new_config: GripperDefinition,
354
+ attached_instr: Gripper,
355
+ cal_offset: GripperCalibrationOffset,
356
+ ) -> Tuple[Gripper, bool]:
357
+ # Once we have determined that the new and attached grippers
358
+ # are similar enough that we might skip, see if the configs
359
+ # match closely enough.
360
+ # Returns a gripper object
361
+ if new_config == attached_instr.config:
362
+ # Same config, good enough
363
+ return attached_instr, True
364
+ else:
365
+ newdict = new_config.model_dump()
366
+ olddict = attached_instr.config.model_dump()
367
+ changed: Set[str] = set()
368
+ for k in newdict.keys():
369
+ if newdict[k] != olddict[k]:
370
+ changed.add(k)
371
+ if changed.intersection(RECONFIG_KEYS):
372
+ # Something has changed that requires reconfig
373
+ # we shoud recalibrate the jaw as well
374
+ return (
375
+ Gripper(
376
+ new_config,
377
+ cal_offset,
378
+ attached_instr._gripper_id,
379
+ ),
380
+ False,
381
+ )
382
+ else:
383
+ # update just the cal offset and update info
384
+ attached_instr._calibration_offset = cal_offset
385
+ return attached_instr, True
386
+
387
+
388
+ def compare_gripper_config_and_check_skip(
389
+ freshly_detected: AttachedGripper,
390
+ attached: Optional[Gripper],
391
+ cal_offset: GripperCalibrationOffset,
392
+ ) -> Tuple[Optional[Gripper], bool]:
393
+ """
394
+ Given the gripper config for an attached gripper (if any) freshly read
395
+ from disk, and any attached instruments,
396
+
397
+ - Compare the new and configured gripper configs
398
+ - Load the new configs if they differ
399
+ - Return a bool indicating whether hardware reconfiguration may be
400
+ skipped
401
+ """
402
+ config = freshly_detected.get("config")
403
+ serial = freshly_detected.get("id") or ""
404
+
405
+ if not config and not attached:
406
+ # nothing attached now, nothing used to be attached, nothing
407
+ # to reconfigure
408
+ return attached, True
409
+
410
+ if config and attached:
411
+ # something was attached and something is attached. are they
412
+ # the same? we can tell by comparing serials
413
+ if serial == attached.gripper_id:
414
+ # similar enough to check
415
+ return _reload_gripper(config, attached, cal_offset)
416
+
417
+ if config:
418
+ return Gripper(config, cal_offset, serial), False
419
+ else:
420
+ return None, False
@@ -0,0 +1,173 @@
1
+ from typing import Optional
2
+ import logging
3
+ import math
4
+
5
+ from opentrons.types import Point
6
+ from .instrument_calibration import (
7
+ GripperCalibrationOffset,
8
+ load_gripper_calibration_offset,
9
+ )
10
+ from opentrons.hardware_control.dev_types import GripperDict
11
+ from opentrons.hardware_control.types import (
12
+ CriticalPoint,
13
+ GripperJawState,
14
+ GripperProbe,
15
+ )
16
+ from opentrons.hardware_control.errors import InvalidCriticalPoint
17
+ from opentrons_shared_data.errors.exceptions import (
18
+ GripperNotPresentError,
19
+ CommandPreconditionViolated,
20
+ )
21
+ from .gripper import Gripper
22
+
23
+
24
+ MOD_LOG = logging.getLogger(__name__)
25
+
26
+
27
+ class GripperHandler:
28
+ GH_LOG = MOD_LOG.getChild("GripperHandler")
29
+
30
+ def __init__(self, gripper: Optional[Gripper] = None):
31
+ self._gripper = gripper
32
+ self._log = self.GH_LOG.getChild(str(id(self)))
33
+
34
+ def has_gripper(self) -> bool:
35
+ return bool(self._gripper)
36
+
37
+ def get_gripper(self) -> Gripper:
38
+ gripper = self._gripper
39
+ if not gripper:
40
+ raise GripperNotPresentError(
41
+ message="Cannot perform action without gripper attached"
42
+ )
43
+ return gripper
44
+
45
+ def reset_gripper(self) -> None:
46
+ """Reset the internal state of the gripper."""
47
+ og_gripper = self._gripper
48
+ if not og_gripper:
49
+ return
50
+ new_gripper = Gripper(
51
+ og_gripper.config,
52
+ load_gripper_calibration_offset(og_gripper.gripper_id),
53
+ og_gripper.gripper_id,
54
+ )
55
+ self._gripper = new_gripper
56
+
57
+ async def reset(self) -> None:
58
+ self._gripper = None
59
+
60
+ @property
61
+ def gripper(self) -> Optional[Gripper]:
62
+ return self._gripper
63
+
64
+ @gripper.setter
65
+ def gripper(self, gripper: Optional[Gripper] = None) -> None:
66
+ self._gripper = gripper
67
+
68
+ def reset_instrument_offset(self, to_default: bool) -> None:
69
+ """
70
+ Temporarily reset the gripper offsets to default values.
71
+ """
72
+ gripper = self.get_gripper()
73
+ gripper.reset_offset(to_default)
74
+ gripper.reset_jaw_width_calibration(to_default)
75
+
76
+ def save_instrument_offset(self, delta: Point) -> GripperCalibrationOffset:
77
+ """
78
+ Save a new instrument offset.
79
+ :param delta: The offset to set for the pipette.
80
+ """
81
+ gripper = self.get_gripper()
82
+ self._log.info(f"Saving gripper {gripper.gripper_id} offset: {delta}")
83
+ return gripper.save_offset(delta)
84
+
85
+ def get_critical_point(self, cp_override: Optional[CriticalPoint] = None) -> Point:
86
+ if not self._gripper:
87
+ raise GripperNotPresentError()
88
+ if cp_override == CriticalPoint.MOUNT:
89
+ raise InvalidCriticalPoint(
90
+ cp_override.name,
91
+ "gripper",
92
+ "The gripper mount may not be moved directly.",
93
+ )
94
+ return self._gripper.critical_point(cp_override)
95
+
96
+ def get_gripper_dict(self) -> Optional[GripperDict]:
97
+ if not self._gripper:
98
+ # TODO (spp, 2023-04-19): Should this raise an error if fetching info of
99
+ # gripper that's not attached, like we do with pipettes?
100
+ return None
101
+ else:
102
+ return self._gripper.as_dict()
103
+
104
+ def get_attached_probe(self) -> Optional[GripperProbe]:
105
+ return self.get_gripper().attached_probe
106
+
107
+ def add_probe(self, probe: GripperProbe) -> None:
108
+ """This is used for finding the critical point during calibration."""
109
+ gripper = self.get_gripper()
110
+ current_probe = self.get_attached_probe()
111
+ if not current_probe:
112
+ gripper.add_probe(probe)
113
+ else:
114
+ self._log.warning("add probe called with a probe already attached.")
115
+
116
+ def remove_probe(self) -> None:
117
+ gripper = self.get_gripper()
118
+ current_probe = self.get_attached_probe()
119
+ if current_probe:
120
+ gripper.remove_probe()
121
+ else:
122
+ self._log.warning("remove probe called without a probe attached")
123
+
124
+ def check_ready_for_calibration(self) -> None:
125
+ """Raise an exception if a probe is not attached before calibration."""
126
+ gripper = self.get_gripper()
127
+ gripper.check_calibration_pin_location_is_accurate()
128
+
129
+ def check_ready_for_jaw_move(self, command: str) -> None:
130
+ """Raise an exception if it is not currently valid to move the jaw."""
131
+ gripper = self.get_gripper()
132
+ if gripper.state == GripperJawState.UNHOMED:
133
+ raise CommandPreconditionViolated(
134
+ message=f"Cannot {command} gripper jaw before homing",
135
+ detail={
136
+ "command": command,
137
+ "jaw_state": str(gripper.state),
138
+ },
139
+ )
140
+
141
+ def is_ready_for_idle(self) -> bool:
142
+ """Gripper can idle when the jaw is not currently gripping."""
143
+ gripper = self.get_gripper()
144
+ if gripper.state == GripperJawState.UNHOMED:
145
+ self._log.warning(
146
+ "Gripper jaw is not homed and cannot move to idle position."
147
+ )
148
+ return False
149
+ return gripper.state != GripperJawState.GRIPPING
150
+
151
+ def is_ready_for_jaw_home(self) -> bool:
152
+ """Raise an exception if it is not currently valid to home the jaw."""
153
+ gripper = self.get_gripper()
154
+ if gripper.state == GripperJawState.GRIPPING and not math.isclose(
155
+ gripper.jaw_width, gripper.geometry.jaw_width["min"], abs_tol=5.0
156
+ ):
157
+ return False
158
+ return True
159
+
160
+ def set_jaw_state(self, state: GripperJawState) -> None:
161
+ self.get_gripper().state = state
162
+
163
+ def get_duty_cycle_by_grip_force(self, newton: float) -> float:
164
+ gripper = self.get_gripper()
165
+ return gripper.duty_cycle_by_force(newton)
166
+
167
+ def set_jaw_displacement(self, mm: float) -> None:
168
+ gripper = self.get_gripper()
169
+ gripper.current_jaw_displacement = mm
170
+
171
+ def is_valid_jaw_width(self, mm: float) -> bool:
172
+ conf = self.get_gripper().geometry
173
+ return conf.jaw_width["min"] <= mm <= conf.jaw_width["max"]