From da7918ec36363ba9f29184b7a1bc72a25346bd46 Mon Sep 17 00:00:00 2001 From: Andy Sigler Date: Mon, 19 Aug 2024 11:51:43 -0400 Subject: [PATCH] fix(api): Speed up unnecessarily slow "prep" plunger motions (#16022) --- api/src/opentrons/hardware_control/ot3api.py | 27 +++++++++---------- .../hardware_control/test_ot3_api.py | 8 +++--- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/api/src/opentrons/hardware_control/ot3api.py b/api/src/opentrons/hardware_control/ot3api.py index fc1216e8c5f..e42578b10dc 100644 --- a/api/src/opentrons/hardware_control/ot3api.py +++ b/api/src/opentrons/hardware_control/ot3api.py @@ -1877,12 +1877,10 @@ async def _move_to_plunger_bottom( With wet tips, the primary concern is leftover droplets inside the tip. These droplets ideally only move down and out of the tip, not up into the tip. - Therefore, it is preferable to use the "blow-out" speed when moving the - plunger down, and the slower "aspirate" speed when moving the plunger up. + Therefore, it is preferable to use the slower "aspirate" speed when + moving the plunger up after a blow-out. - Assume all tips are wet, because we do not differentiate between wet/dry tips. - - When no tip is attached, moving at the max speed is preferable, to save time. + All other situations, moving at the max speed is preferable, to save time. """ checked_mount = OT3Mount.from_mount(mount) instrument = self._pipette_handler.get_pipette(checked_mount) @@ -1895,21 +1893,22 @@ async def _move_to_plunger_bottom( self._current_position, ) pip_ax = Axis.of_main_tool_actuator(checked_mount) - # speed depends on if there is a tip, and which direction to move - if instrument.has_tip_length: + # save time while moving down by using max speed + max_speeds = self.config.motion_settings.default_max_speed + speed_down = max_speeds[self.gantry_load][OT3AxisKind.P] + # upward moves can be max speed, or aspirate speed + # use the (slower) aspirate if there is a tip and we're following a blow-out + plunger_is_below_bottom_pos = ( + self._current_position[pip_ax] > instrument.plunger_positions.bottom + ) + if instrument.has_tip_length and plunger_is_below_bottom_pos: # using slower aspirate flow-rate, to avoid pulling droplets up speed_up = self._pipette_handler.plunger_speed( instrument, instrument.aspirate_flow_rate, "aspirate" ) - # use blow-out flow-rate, so we can push droplets out - speed_down = self._pipette_handler.plunger_speed( - instrument, instrument.blow_out_flow_rate, "dispense" - ) else: - # save time by using max speed - max_speeds = self.config.motion_settings.default_max_speed + # either no tip, or plunger just homed, so tip is dry speed_up = max_speeds[self.gantry_load][OT3AxisKind.P] - speed_down = speed_up # IMPORTANT: Here is our backlash compensation. # The plunger is pre-loaded in the "aspirate" direction backlash_pos = target_pos.copy() diff --git a/api/tests/opentrons/hardware_control/test_ot3_api.py b/api/tests/opentrons/hardware_control/test_ot3_api.py index bb1352d3157..5e79f8ed149 100644 --- a/api/tests/opentrons/hardware_control/test_ot3_api.py +++ b/api/tests/opentrons/hardware_control/test_ot3_api.py @@ -1663,13 +1663,11 @@ async def test_move_to_plunger_bottom( backlash_pos[pip_ax] += pipette.backlash_distance # plunger will move at different speeds, depending on if: - # - no tip attached (max speed) - # - tip attached and moving down (blowout speed) + # - tip not attached (max speed) + # - tip attached and moving down (max speed) # - tip attached and moving up (aspirate speed) expected_speed_no_tip = max_speeds[ot3_hardware.gantry_load][OT3AxisKind.P] - expected_speed_moving_down = ot3_hardware._pipette_handler.plunger_speed( - pipette, pipette.blow_out_flow_rate, "dispense" - ) + expected_speed_moving_down = expected_speed_no_tip expected_speed_moving_up = ot3_hardware._pipette_handler.plunger_speed( pipette, pipette.aspirate_flow_rate, "aspirate" )