Skip to content

Commit

Permalink
fix get_channels_y_positions, use C0 in position_channels_in_y_direction
Browse files Browse the repository at this point in the history
  • Loading branch information
rickwierenga committed Jan 18, 2025
1 parent cc0b9d2 commit 92b7057
Showing 1 changed file with 29 additions and 20 deletions.
49 changes: 29 additions & 20 deletions pylabrobot/liquid_handling/backends/hamilton/STAR.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import asyncio
import datetime
import enum
import functools
Expand Down Expand Up @@ -7541,14 +7540,33 @@ async def get_channels_y_positions(self) -> Dict[int, float]:
command="RY",
fmt="ry#### (n)",
)
return {channel_idx: round(y / 10, 2) for channel_idx, y in enumerate(resp["ry"])}
y_positions = [round(y / 10, 2) for y in resp["ry"]]

# sometimes there is (likely) a floating point error and channels are reported to be
# less than 9mm apart. (When you set channels using position_channels_in_y_direction,
# it will raise an error.) The minimum y is 6mm, so we fix that first (in case that
# values is misreported). Then, we traverse the list in reverse and set the min_diff.
if y_positions[-1] < 5.8:
raise RuntimeError(
"Channels are reported to be too close to the front of the machine. "
"The known minimum is 6, which will be fixed automatically for 5.8<y<6. "
f"Reported values: {y_positions}."
)
elif 5.8 <= y_positions[-1] < 6:
y_positions[-1] = 6.0

min_diff = 9.0
for i in range(len(y_positions) - 2, -1, -1):
if y_positions[i] - y_positions[i + 1] < min_diff:
y_positions[i] = y_positions[i + 1] + min_diff

return {channel_idx: y for channel_idx, y in enumerate(y_positions)}

async def position_channels_in_y_direction(self, ys: Dict[int, float]):
"""position all channels simultaneously in the Y direction. There is a command for this (C0OY),
but I couldn't get it to work, so this sends commands to the individual channels instead.
"""position all channels simultaneously in the Y direction.
Args:
ys: A dictionary mapping channel index to the desired Y position in mm. The channel index is
ys: A dictionary mapping channel index to the desired Y position in mm. The channel index is
0-indexed from the back.
"""

Expand All @@ -7564,20 +7582,11 @@ async def position_channels_in_y_direction(self, ys: Dict[int, float]):
):
raise ValueError("Channels must be at least 9mm apart and in descending order")

def _channel_y_to_steps(y: float) -> int:
# for PX modules
mm_per_step = 0.046302083
return round(y / mm_per_step)

await asyncio.gather(
*(
self.send_command(
module=f"P{STAR.channel_id(channel_idx)}",
command="YA",
ya=f"{_channel_y_to_steps(y):05}",
)
for channel_idx, y in channel_locations.items()
)
yp = " ".join([f"{round(y*10):04}" for y in channel_locations.values()])
return await self.send_command(
module="C0",
command="JY",
yp=yp,
)

async def get_channels_z_positions(self) -> Dict[int, float]:
Expand Down Expand Up @@ -7668,7 +7677,7 @@ async def step_off_foil(
# Quick checks before movement.
assert channel_locations[0] <= 650, "Channel 0 would hit the back of the robot"
assert (
channel_locations[self.num_channels - 1] >= 0
channel_locations[self.num_channels - 1] >= 6
), "Channel N would hit the front of the robot"

try:
Expand Down

0 comments on commit 92b7057

Please sign in to comment.