Skip to content

Commit

Permalink
make machine to deck conversion func public hw API
Browse files Browse the repository at this point in the history
  • Loading branch information
Laura-Danielle committed Oct 21, 2024
1 parent 689fcde commit cc1c485
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 57 deletions.
36 changes: 12 additions & 24 deletions api/src/opentrons/hardware_control/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ def _update_door_state(self, door_state: DoorState) -> None:
def _reset_last_mount(self) -> None:
self._last_moved_mount = None

def get_deck_from_machine(self, machine_pos: Dict[Axis, float]) -> Dict[Axis, float]:
return deck_from_machine(
machine_pos=machine_pos,
attitude=self._robot_calibration.deck_calibration.attitude,
offset=top_types.Point(0, 0, 0),
robot_type=cast(RobotType, "OT-2 Standard"),
)

@classmethod
async def build_hardware_controller( # noqa: C901
cls,
Expand Down Expand Up @@ -657,12 +665,7 @@ async def home(self, axes: Optional[List[Axis]] = None) -> None:
async with self._motion_lock:
if smoothie_gantry:
smoothie_pos.update(await self._backend.home(smoothie_gantry))
self._current_position = deck_from_machine(
machine_pos=self._axis_map_from_string_map(smoothie_pos),
attitude=self._robot_calibration.deck_calibration.attitude,
offset=top_types.Point(0, 0, 0),
robot_type=cast(RobotType, "OT-2 Standard"),
)
self._current_position = self.get_deck_from_machine(self._axis_map_from_string_map(smoothie_pos))
for plunger in plungers:
await self._do_plunger_home(axis=plunger, acquire_lock=False)

Expand Down Expand Up @@ -703,12 +706,7 @@ async def current_position(
async with self._motion_lock:
if refresh:
smoothie_pos = await self._backend.update_position()
self._current_position = deck_from_machine(
machine_pos=self._axis_map_from_string_map(smoothie_pos),
attitude=self._robot_calibration.deck_calibration.attitude,
offset=top_types.Point(0, 0, 0),
robot_type=cast(RobotType, "OT-2 Standard"),
)
self._current_position = self.get_deck_from_machine(self._axis_map_from_string_map(smoothie_pos))
if mount == top_types.Mount.RIGHT:
offset = top_types.Point(0, 0, 0)
else:
Expand Down Expand Up @@ -938,12 +936,7 @@ async def retract_axis(self, axis: Axis, margin: float = 10) -> None:

async with self._motion_lock:
smoothie_pos = await self._fast_home(smoothie_ax, margin)
self._current_position = deck_from_machine(
machine_pos=self._axis_map_from_string_map(smoothie_pos),
attitude=self._robot_calibration.deck_calibration.attitude,
offset=top_types.Point(0, 0, 0),
robot_type=cast(RobotType, "OT-2 Standard"),
)
self._current_position = self.get_deck_from_machine(self._axis_map_from_string_map(smoothie_pos))

# Gantry/frame (i.e. not pipette) config API
@property
Expand Down Expand Up @@ -1261,12 +1254,7 @@ async def drop_tip(self, mount: top_types.Mount, home_after: bool = True) -> Non
axes=[ot2_axis_to_string(ax) for ax in move.home_axes],
margin=move.home_after_safety_margin,
)
self._current_position = deck_from_machine(
machine_pos=self._axis_map_from_string_map(smoothie_pos),
attitude=self._robot_calibration.deck_calibration.attitude,
offset=top_types.Point(0, 0, 0),
robot_type=cast(RobotType, "OT-2 Standard"),
)
self._current_position = self.get_deck_from_machine(self._axis_map_from_string_map(smoothie_pos))

for shake in spec.shake_moves:
await self.move_rel(mount, shake[0], speed=shake[1])
Expand Down
12 changes: 9 additions & 3 deletions api/src/opentrons/hardware_control/backends/ot3controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,8 +668,12 @@ def _build_move_node_axis_runner(
)

def _build_move_gear_axis_runner(
self, possible_q_axis_origin, possible_q_axis_target, speed, nodes_in_moves_only
) -> Optional[MoveGroupRunner]:
self,
possible_q_axis_origin: Optional[float],
possible_q_axis_target: Optional[float],
speed: float,
nodes_in_moves_only: bool,
) -> Tuple[Optional[MoveGroupRunner], bool]:
if possible_q_axis_origin is None or possible_q_axis_target is None:
return None, True
tip_motor_move_group = self._build_tip_action_group(
Expand Down Expand Up @@ -744,7 +748,9 @@ async def move(
gather_moving_nodes, all_moving_nodes
)

async def _runner_coroutine(runner: MoveGroupRunner, is_gear_move: bool):
async def _runner_coroutine(
runner: MoveGroupRunner, is_gear_move: bool
) -> Tuple[Dict[NodeId, MotorPositionStatus], bool]:
positions = await runner.run(can_messenger=self._messenger)
return positions, is_gear_move

Expand Down
10 changes: 7 additions & 3 deletions api/src/opentrons/hardware_control/motion_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def target_position_from_absolute(
)
primary_cp = get_critical_point(mount)
primary_z = Axis.by_mount(mount)

target_position = OrderedDict(
(
(Axis.X, abs_position.x - offset.x - primary_cp.x),
Expand Down Expand Up @@ -131,14 +132,15 @@ def target_axis_map_from_absolute(
primary_z = Axis.by_mount(primary_mount)
target_position = OrderedDict()

log.info(f"The primary critical point {primary_cp} and primary_mount {primary_mount} and type {type(primary_cp)}")
log.info(f"The offset {offset} and type is {type(offset)}")
if Axis.X in keys_for_target_position:
target_position[Axis.X] = axis_map[Axis.X] - offset.x - primary_cp.x
if Axis.Y in keys_for_target_position:
target_position[Axis.Y] = axis_map[Axis.Y] - offset.y - primary_cp.y
if primary_z in keys_for_target_position:
target_position[primary_z] = axis_map[primary_z] - offset.z - primary_cp.z
# Since this function is intended to be used in conjunction with `API.move_axes`
# we must leave out the carriage offset subtraction from the target position as
# `move_axes` already does this calculation.
target_position[primary_z] = axis_map[primary_z] - primary_cp.z

target_position.update(
{ax: val for ax, val in axis_map.items() if ax not in Axis.gantry_axes()}
Expand All @@ -158,6 +160,8 @@ def target_axis_map_from_relative(
if ax in axis_map.keys()
)
)
log.info(f"Current position {current_position} and axis map delta {axis_map}")
log.info(f"Relative move target {target_position}")
return target_position


Expand Down
10 changes: 5 additions & 5 deletions api/src/opentrons/hardware_control/ot3api.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ def _update_estop_state(self, event: HardwareEvent) -> "List[Future[None]]":
def _reset_last_mount(self) -> None:
self._last_moved_mount = None

def _deck_from_machine(self, machine_pos: Dict[Axis, float]) -> Dict[Axis, float]:
def get_deck_from_machine(self, machine_pos: Dict[Axis, float]) -> Dict[Axis, float]:
return deck_from_machine(
machine_pos=machine_pos,
attitude=self._robot_calibration.deck_calibration.attitude,
Expand Down Expand Up @@ -1020,14 +1020,14 @@ async def _refresh_jaw_state(self) -> None:

async def _cache_current_position(self) -> Dict[Axis, float]:
"""Cache current position from backend and return in absolute deck coords."""
self._current_position = self._deck_from_machine(
self._current_position = self.get_deck_from_machine(
await self._backend.update_position()
)
return self._current_position

async def _cache_encoder_position(self) -> Dict[Axis, float]:
"""Cache encoder position from backend and return in absolute deck coords."""
self._encoder_position = self._deck_from_machine(
self._encoder_position = self.get_deck_from_machine(
await self._backend.update_encoder_position()
)
if self.has_gripper():
Expand Down Expand Up @@ -2558,7 +2558,7 @@ def get_instrument_max_height(
mount: Union[top_types.Mount, OT3Mount],
critical_point: Optional[CriticalPoint] = None,
) -> float:
carriage_pos = self._deck_from_machine(self._backend.home_position())
carriage_pos = self.get_deck_from_machine(self._backend.home_position())
pos_at_home = self._effector_pos_from_carriage_pos(
OT3Mount.from_mount(mount), carriage_pos, critical_point
)
Expand Down Expand Up @@ -2653,7 +2653,7 @@ async def _liquid_probe_pass(
)
machine_pos = await self._backend.update_position()
machine_pos[Axis.by_mount(mount)] = end_z
deck_end_z = self._deck_from_machine(machine_pos)[Axis.by_mount(mount)]
deck_end_z = self.get_deck_from_machine(machine_pos)[Axis.by_mount(mount)]
offset = offset_for_mount(
mount,
top_types.Point(*self._config.left_mount_offset),
Expand Down
20 changes: 19 additions & 1 deletion api/src/opentrons/hardware_control/protocols/liquid_handler.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from typing import Optional
from typing import Optional, Dict
from typing_extensions import Protocol

from opentrons.types import Point
from opentrons.hardware_control.types import CriticalPoint, Axis
from .types import MountArgType, CalibrationType, ConfigType

from .instrument_configurer import InstrumentConfigurer
Expand All @@ -16,6 +18,22 @@ class LiquidHandler(
Calibratable[CalibrationType],
Protocol[CalibrationType, MountArgType, ConfigType],
):
def critical_point_for(
self,
mount: MountArgType,
cp_override: Optional[CriticalPoint] = None,
) -> Point:
"""
Determine the current critical point for the specified mount.
:param mount: A robot mount that the instrument is on.
:param cp_override: The critical point override to use.
If no critical point override is specified, the robot defaults to nozzle location `A1` or the mount critical point.
:return: Point.
"""
...

async def update_nozzle_configuration_for_mount(
self,
mount: MountArgType,
Expand Down
42 changes: 21 additions & 21 deletions api/tests/opentrons/protocol_engine/execution/test_gantry_mover.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,33 +472,33 @@ async def test_home_z(
],
argvalues=[
[
{MotorAxis.X: 10, MotorAxis.Y: 15, MotorAxis.RIGHT_Z: 20},
{MotorAxis.X: 2, MotorAxis.Y: 1, MotorAxis.RIGHT_Z: 1},
{MotorAxis.X: 10.0, MotorAxis.Y: 15.0, MotorAxis.RIGHT_Z: 20.0},
{MotorAxis.X: 2.0, MotorAxis.Y: 1.0, MotorAxis.RIGHT_Z: 1.0},
False,
Mount.RIGHT,
{HardwareAxis.X: -2, HardwareAxis.Y: 4, HardwareAxis.A: 9},
{HardwareAxis.X: -2, HardwareAxis.Y: 4, HardwareAxis.A: 9},
{HardwareAxis.X: -2.0, HardwareAxis.Y: 4.0, HardwareAxis.A: 9.0},
{HardwareAxis.X: -2.0, HardwareAxis.Y: 4.0, HardwareAxis.A: 9.0},
],
[
{MotorAxis.RIGHT_Z: 20},
{MotorAxis.RIGHT_Z: 20.0},
None,
True,
Mount.RIGHT,
{HardwareAxis.A: 30},
{HardwareAxis.A: 30.0},
{
HardwareAxis.X: 10,
HardwareAxis.Y: 15,
HardwareAxis.Z: 10,
HardwareAxis.A: 30,
HardwareAxis.X: 10.0,
HardwareAxis.Y: 15.0,
HardwareAxis.Z: 10.0,
HardwareAxis.A: 30.0,
},
],
[
{MotorAxis.CLAMP_JAW_96_CHANNEL: 10},
{MotorAxis.CLAMP_JAW_96_CHANNEL: 10.0},
None,
False,
Mount.LEFT,
{HardwareAxis.Q: 10},
{HardwareAxis.Q: 10},
{HardwareAxis.Q: 10.0},
{HardwareAxis.Q: 10.0},
],
],
)
Expand All @@ -514,14 +514,14 @@ async def test_move_axes(
final_position: Dict[HardwareAxis, float],
) -> None:
curr_pos = {
HardwareAxis.X: 10,
HardwareAxis.Y: 15,
HardwareAxis.Z: 10,
HardwareAxis.A: 10,
HardwareAxis.X: 10.0,
HardwareAxis.Y: 15.0,
HardwareAxis.Z: 10.0,
HardwareAxis.A: 10.0,
}
call_count = 0

def _current_position(mount, refresh) -> Dict[HardwareAxis, float]:
def _current_position(mount: Mount, refresh: bool) -> Dict[HardwareAxis, float]:
nonlocal call_count
nonlocal curr_pos
nonlocal final_position
Expand All @@ -543,13 +543,13 @@ def _current_position(mount, refresh) -> Dict[HardwareAxis, float]:
Point(0.5, 0.5, 0.5)
)

decoy.when(mock_hardware_api._deck_from_machine(curr_pos)).then_return(curr_pos)
decoy.when(mock_hardware_api.get_deck_from_machine(curr_pos)).then_return(curr_pos)

decoy.when(mock_hardware_api._deck_from_machine(final_position)).then_return(
decoy.when(mock_hardware_api.get_deck_from_machine(final_position)).then_return(
final_position
)
if not critical_point:
decoy.when(mock_hardware_api._critical_point_for(expected_mount)).then_return(
decoy.when(mock_hardware_api.critical_point_for(expected_mount)).then_return(
Point(1, 1, 1)
)

Expand Down

0 comments on commit cc1c485

Please sign in to comment.