Skip to content

Commit

Permalink
fix phony bounds & handle retract better
Browse files Browse the repository at this point in the history
  • Loading branch information
ahiuchingau committed Feb 12, 2024
1 parent 1d61e62 commit eb88723
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 46 deletions.
17 changes: 8 additions & 9 deletions api/src/opentrons/hardware_control/backends/ot3controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -1155,16 +1155,15 @@ async def watch(self, loop: asyncio.AbstractEventLoop) -> None:
def axis_bounds(self) -> OT3AxisMap[Tuple[float, float]]:
"""Get the axis bounds."""
# TODO (AL, 2021-11-18): The bounds need to be defined
phony_bounds = (0, 300)
return {
Axis.Z_L: phony_bounds,
Axis.Z_R: phony_bounds,
Axis.P_L: phony_bounds,
Axis.P_R: phony_bounds,
Axis.X: phony_bounds,
Axis.Y: phony_bounds,
Axis.Z_G: phony_bounds,
Axis.Q: phony_bounds,
Axis.Z_L: (0, 300),
Axis.Z_R: (0, 300),
Axis.P_L: (0, 200),
Axis.P_R: (0, 200),
Axis.X: (0, 550),
Axis.Y: (0, 550),
Axis.Z_G: (0, 300),
Axis.Q: (0, 200),
}

def engaged_axes(self) -> OT3AxisMap[bool]:
Expand Down
79 changes: 42 additions & 37 deletions api/src/opentrons/hardware_control/ot3api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1303,29 +1303,34 @@ async def _cache_and_maybe_retract_mount(self, mount: OT3Mount) -> None:
Disengage the 96-channel and gripper mount if retracted. Re-engage
the 96-channel or gripper mount if it is about to move.
"""
if self.is_idle_mount(mount):
# home the left/gripper mount if it is current disengaged
await self.home_z(mount)

if mount != self._last_moved_mount and self._last_moved_mount:
await self.retract(self._last_moved_mount, 10)

# disengage Axis.Z_L motor and engage the brake to lower power
# consumption and reduce the chance of the 96-channel pipette dropping
if (
self.gantry_load == GantryLoad.HIGH_THROUGHPUT
and self._last_moved_mount == OT3Mount.LEFT
):
await self.disengage_axes([Axis.Z_L])
# if gripper exists and it's not the moving mount, it should retract
if (
self.has_gripper()
and mount != OT3Mount.GRIPPER
and not self.is_idle_mount(OT3Mount.GRIPPER)
):
await self.retract(OT3Mount.GRIPPER, 10)
await self.disengage_axes([Axis.Z_G])
await self.idle_gripper()

# disegnage Axis.Z_G when we can to reduce the chance of
# the gripper dropping
if self._last_moved_mount == OT3Mount.GRIPPER:
await self.disengage_axes([Axis.Z_G])
# if 96-channel pipette is attached and not being moved, it should retract
if (
mount != OT3Mount.LEFT
and self._gantry_load == GantryLoad.HIGH_THROUGHPUT
and not self.is_idle_mount(OT3Mount.LEFT)
):
await self.retract(OT3Mount.LEFT, 10)
await self.disengage_axes([Axis.Z_L])

if mount != OT3Mount.GRIPPER:
await self.idle_gripper()
# if the last moved mount is not covered in neither of the above scenario,
# simply retract the last moved mount
if self._last_moved_mount and not self.is_idle_mount(self._last_moved_mount):
if mount != self._last_moved_mount:
await self.retract(self._last_moved_mount, 10)

# finally, home the current left/gripper mount to prepare for movement
if self.is_idle_mount(mount):
await self.home_z(mount)
self._last_moved_mount = mount

async def prepare_for_mount_movement(
Expand Down Expand Up @@ -1499,7 +1504,7 @@ async def _home_axis(self, axis: Axis) -> None:
else:
await self.engage_axes([axis])

if encoder_ok:
if encoder_ok and motor_engaged:
await self._update_position_estimation([axis])
# refresh motor and encoder statuses after position estimation update
motor_ok = self._backend.check_motor_status([axis])
Expand Down Expand Up @@ -1542,22 +1547,21 @@ async def _home_axis(self, axis: Axis) -> None:

async def _home(self, axes: Sequence[Axis]) -> None:
"""Home one axis at a time."""
async with self._motion_lock:
for axis in axes:
try:
if axis == Axis.G:
await self.home_gripper_jaw()
elif axis == Axis.Q:
await self._backend.home([axis], self.gantry_load)
else:
await self._home_axis(axis)
except BaseException as e:
self._log.exception(f"Homing failed: {e}")
self._current_position.clear()
raise
for axis in axes:
try:
if axis == Axis.G:
await self.home_gripper_jaw()
elif axis == Axis.Q:
await self._backend.home([axis], self.gantry_load)
else:
await self._cache_current_position()
await self._cache_encoder_position()
await self._home_axis(axis)
except BaseException as e:
self._log.exception(f"Homing failed: {e}")
self._current_position.clear()
raise
else:
await self._cache_current_position()
await self._cache_encoder_position()

@ExecutionManagerProvider.wait_for_running
async def home(
Expand Down Expand Up @@ -1588,7 +1592,8 @@ async def home(
if (ax in checked_axes and self._backend.axis_is_present(ax))
]
self._log.info(f"home was called with {axes} generating sequence {home_seq}")
await self._home(home_seq)
async with self._motion_lock:
await self._home(home_seq)

def get_engaged_axes(self) -> Dict[Axis, bool]:
"""Which axes are engaged and holding."""
Expand Down

0 comments on commit eb88723

Please sign in to comment.