From 430ed52c9bf30614cf8ac634a3f840de00245371 Mon Sep 17 00:00:00 2001 From: Alise Au <20424172+ahiuchingau@users.noreply.github.com> Date: Thu, 30 Mar 2023 12:19:00 -0400 Subject: [PATCH] fix(api): we should always call ot3controller.gripper_home_jaw() to home G axis (#12376) --- api/src/opentrons/config/defaults_ot3.py | 4 --- api/src/opentrons/config/types.py | 1 - .../backends/ot3controller.py | 5 +-- api/src/opentrons/hardware_control/ot3api.py | 31 ++++++++----------- api/tests/opentrons/config/ot3_settings.py | 1 - .../opentrons/hardware_control/test_moves.py | 9 +++--- .../hardware_control/test_ot3_api.py | 10 ++++-- 7 files changed, 28 insertions(+), 33 deletions(-) diff --git a/api/src/opentrons/config/defaults_ot3.py b/api/src/opentrons/config/defaults_ot3.py index a74b12e96e3..0751d71104f 100644 --- a/api/src/opentrons/config/defaults_ot3.py +++ b/api/src/opentrons/config/defaults_ot3.py @@ -71,7 +71,6 @@ DEFAULT_RIGHT_MOUNT_OFFSET: Final[Offset] = (40.5, -60.5, 255.675) DEFAULT_GRIPPER_MOUNT_OFFSET: Final[Offset] = (84.55, -12.75, 93.85) DEFAULT_Z_RETRACT_DISTANCE: Final = 2 -DEFAULT_GRIPPER_JAW_HOME_DUTY_CYCLE: Final = 25 DEFAULT_SAFE_HOME_DISTANCE: Final = 5 DEFAULT_MAX_SPEEDS: Final[ByGantryLoad[Dict[OT3AxisKind, float]]] = ByGantryLoad( @@ -380,9 +379,6 @@ def build_with_defaults(robot_settings: Dict[str, Any]) -> OT3Config: z_retract_distance=robot_settings.get( "z_retract_distance", DEFAULT_Z_RETRACT_DISTANCE ), - grip_jaw_home_duty_cycle=robot_settings.get( - "grip_jaw_home_duty_cycle", DEFAULT_GRIPPER_JAW_HOME_DUTY_CYCLE - ), safe_home_distance=robot_settings.get( "safe_home_distance", DEFAULT_SAFE_HOME_DISTANCE ), diff --git a/api/src/opentrons/config/types.py b/api/src/opentrons/config/types.py index 3321c07c8e2..9e4076e1ee0 100644 --- a/api/src/opentrons/config/types.py +++ b/api/src/opentrons/config/types.py @@ -175,7 +175,6 @@ class OT3Config: motion_settings: OT3MotionSettings current_settings: OT3CurrentSettings z_retract_distance: float - grip_jaw_home_duty_cycle: float safe_home_distance: float deck_transform: OT3Transform carriage_offset: Offset diff --git a/api/src/opentrons/hardware_control/backends/ot3controller.py b/api/src/opentrons/hardware_control/backends/ot3controller.py index eaef04da979..91827fd40ea 100644 --- a/api/src/opentrons/hardware_control/backends/ot3controller.py +++ b/api/src/opentrons/hardware_control/backends/ot3controller.py @@ -608,6 +608,9 @@ async def home(self, axes: Sequence[OT3Axis]) -> OT3AxisMap[float]: A dictionary containing the new positions of each axis """ checked_axes = [axis for axis in axes if self._axis_is_present(axis)] + assert ( + OT3Axis.G not in checked_axes + ), "Please home G axis using gripper_home_jaw()" if not checked_axes: return {} @@ -621,8 +624,6 @@ async def home(self, axes: Sequence[OT3Axis]) -> OT3AxisMap[float]: if runner ] positions = await asyncio.gather(*coros) - if OT3Axis.G in checked_axes: - await self.gripper_home_jaw(self._configuration.grip_jaw_home_duty_cycle) if OT3Axis.Q in checked_axes: await self.tip_action( [OT3Axis.Q], diff --git a/api/src/opentrons/hardware_control/ot3api.py b/api/src/opentrons/hardware_control/ot3api.py index dedc84e93d9..a44094b1ae3 100644 --- a/api/src/opentrons/hardware_control/ot3api.py +++ b/api/src/opentrons/hardware_control/ot3api.py @@ -728,12 +728,16 @@ async def home_gripper_jaw(self) -> None: """ Home the jaw of the gripper. """ - gripper = self._gripper_handler.get_gripper() - dc = self._gripper_handler.get_duty_cycle_by_grip_force( - gripper.default_home_force - ) - await self._ungrip(duty_cycle=dc) - gripper.state = GripperJawState.HOMED_READY + try: + gripper = self._gripper_handler.get_gripper() + self._log.info("Homing gripper jaw.") + dc = self._gripper_handler.get_duty_cycle_by_grip_force( + gripper.default_home_force + ) + await self._ungrip(duty_cycle=dc) + gripper.state = GripperJawState.HOMED_READY + except GripperNotAttachedError: + pass async def home_plunger(self, mount: Union[top_types.Mount, OT3Mount]) -> None: """ @@ -1191,8 +1195,9 @@ async def _home(self, axes: Sequence[OT3Axis]) -> None: async with self._motion_lock: for axis in axes: try: - # let backend handle homing gripper jaw and pipette plunger - if axis in [OT3Axis.G, OT3Axis.Q]: + if axis == OT3Axis.G: + await self.home_gripper_jaw() + elif axis == OT3Axis.Q: await self._backend.home([axis]) else: await self._home_axis(axis) @@ -1206,16 +1211,6 @@ async def _home(self, axes: Sequence[OT3Axis]) -> None: else: await self._cache_current_position() await self._cache_encoder_position() - if axis == OT3Axis.G: - try: - self._gripper_handler.set_jaw_state( - GripperJawState.HOMED_READY - ) - self._gripper_handler.set_jaw_displacement( - self._encoder_position[OT3Axis.G] - ) - except GripperNotAttachedError: - pass @ExecutionManagerProvider.wait_for_running async def home( diff --git a/api/tests/opentrons/config/ot3_settings.py b/api/tests/opentrons/config/ot3_settings.py index f4fa2fb3908..8c805f3a154 100644 --- a/api/tests/opentrons/config/ot3_settings.py +++ b/api/tests/opentrons/config/ot3_settings.py @@ -110,7 +110,6 @@ }, "log_level": "NADA", "z_retract_distance": 10, - "grip_jaw_home_duty_cycle": 25, "safe_home_distance": 5, "deck_transform": [[-0.5, 0, 1], [0.1, -2, 4], [0, 0, -1]], "carriage_offset": (1, 2, 3), diff --git a/api/tests/opentrons/hardware_control/test_moves.py b/api/tests/opentrons/hardware_control/test_moves.py index 743799251ee..a09bceb597c 100644 --- a/api/tests/opentrons/hardware_control/test_moves.py +++ b/api/tests/opentrons/hardware_control/test_moves.py @@ -84,19 +84,18 @@ def mock_home(ot3_hardware): async def test_home(ot3_hardware, mock_home): - # this is only valid for Axis G, for other axes, check out test_ot3_api.py with mock.patch("opentrons.hardware_control.ot3api.deck_from_machine") as dfm_mock: - dfm_mock.return_value = {OT3Axis.G: 20} - await ot3_hardware._home([OT3Axis.G]) + dfm_mock.return_value = {OT3Axis.X: 20} + await ot3_hardware._home([OT3Axis.X]) - mock_home.assert_called_once_with([OT3Axis.G]) + mock_home.assert_called_once_with([OT3Axis.X]) assert dfm_mock.call_count == 2 dfm_mock.assert_called_with( mock_home.return_value, ot3_hardware._transforms.deck_calibration.attitude, ot3_hardware._transforms.carriage_offset, ) - assert ot3_hardware._current_position[OT3Axis.G] == 20 + assert ot3_hardware._current_position[OT3Axis.X] == 20 async def test_home_unmet(ot3_hardware, mock_home): diff --git a/api/tests/opentrons/hardware_control/test_ot3_api.py b/api/tests/opentrons/hardware_control/test_ot3_api.py index dce1d11cd72..72929ed509e 100644 --- a/api/tests/opentrons/hardware_control/test_ot3_api.py +++ b/api/tests/opentrons/hardware_control/test_ot3_api.py @@ -420,10 +420,11 @@ async def test_liquid_probe( fake_liquid_settings: LiquidProbeSettings, mock_instrument_handlers: Tuple[Mock], mock_current_position_ot3: AsyncMock, + mock_ungrip: AsyncMock, mock_home_plunger: AsyncMock, ) -> None: + mock_ungrip.return_value = None backend = ot3_hardware.managed_obj._backend - await ot3_hardware.home() mock_move_to.return_value = None @@ -490,9 +491,10 @@ async def test_liquid_sensing_errors( mock_instrument_handlers: Tuple[Mock], mock_current_position_ot3: AsyncMock, mock_home_plunger: AsyncMock, + mock_ungrip: AsyncMock, ) -> None: backend = ot3_hardware.managed_obj._backend - + mock_ungrip.return_value = None await ot3_hardware.home() mock_move_to.return_value = None @@ -787,6 +789,8 @@ async def test_gripper_action( mock_ungrip.assert_called_once() mock_ungrip.reset_mock() await ot3_hardware.home([OT3Axis.G]) + mock_ungrip.assert_called_once() + mock_ungrip.reset_mock() await ot3_hardware.grip(5.0) mock_grip.assert_called_once_with( gc.duty_cycle_by_force(5.0, gripper_config.grip_force_profile), @@ -956,7 +960,9 @@ async def test_save_instrument_offset( async def test_pick_up_tip_full_tiprack( ot3_hardware: ThreadManager[OT3API], mock_instrument_handlers: Tuple[Mock], + mock_ungrip: AsyncMock, ) -> None: + mock_ungrip.return_value = None await ot3_hardware.home() _, pipette_handler = mock_instrument_handlers backend = ot3_hardware.managed_obj._backend