Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions pylabrobot/liquid_handling/backends/hamilton/STAR_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -3112,10 +3112,15 @@ async def move_channel_y(self, channel: int, y: float):
f"(channel {channel - 1} y-position is {round(y, 2)} mm)"
)
else:
# STAR machines appear to lose connection to a channel if y > 635 mm
max_y_pos = 635
if self.iswap_installed:
max_y_pos = await self.iswap_request_module_y()
limit = "iswap module y-position"
else:
# STAR machines do not allow channels y > 635 mm
max_y_pos = 635
limit = "machine limit"
if y > max_y_pos:
raise ValueError(f"channel {channel} y-target must be <= {max_y_pos} mm (machine limit)")
raise ValueError(f"channel {channel} y-target must be <= {max_y_pos} mm ({limit})")

if channel < (self.num_channels - 1):
min_y_pos = await self.request_y_pos_channel_n(channel + 1)
Expand All @@ -3125,7 +3130,7 @@ async def move_channel_y(self, channel: int, y: float):
f"(channel {channel + 1} y-position is {round(y, 2)} mm)"
)
else:
# STAR machines appear to lose connection to a channel if y < 6 mm
# STAR machines do not allow channels y < 6 mm
min_y_pos = 6
if y < min_y_pos:
raise ValueError(f"channel {channel} y-target must be >= {min_y_pos} mm (machine limit)")
Expand Down Expand Up @@ -6476,6 +6481,17 @@ async def move_iswap_y_relative(self, step_size: float, allow_splitting: bool =
allow_splitting: Allow splitting of the movement into multiple steps. Default False.
"""

# check if iswap will hit the first (backmost) channel
# we only need to check for positive step sizes because the iswap is always behind the first channel
if step_size < 0:
y_pos_channel_0 = await self.request_y_pos_channel_n(0)
current_y_pos_iswap = await self.iswap_request_module_y()
if current_y_pos_iswap + step_size < y_pos_channel_0:
raise ValueError(
f"iSWAP will hit the first (backmost) channel. Current iSWAP Y position: {current_y_pos_iswap} mm, "
f"first channel Y position: {y_pos_channel_0} mm, requested step size: {step_size} mm"
)

direction = 0 if step_size >= 0 else 1
max_step_size = 99.9
if abs(step_size) > max_step_size:
Expand Down Expand Up @@ -7213,6 +7229,17 @@ async def request_iswap_position(self) -> Coordinate:
z=(resp["zj"] / 10) * (1 if resp["zd"] == 0 else -1),
)

@staticmethod
def _iswap_y_inc_to_mm(y_inc: int) -> float:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a duplication as well, and has existed in PyLabRobot as y_drive_increment_to_mm for a while

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this is for pip channels, but the conversion is actually the same

mm_per_increment = 0.046302083
return round(y_inc * mm_per_increment, 2)

async def iswap_request_module_y(self) -> float:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a duplication and already exists in PyLabRobot since #666

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, I forgot this exists

"""Request iSWAP module (not gripper) Y position in mm"""
resp = await self.send_command(module="R0", command="RY", fmt="ry##### (n)")
iswap_y_pos = resp["ry"][1] # 0 = FW counter, 1 = HW counter
return STARBackend._iswap_y_inc_to_mm(iswap_y_pos)

async def request_iswap_initialization_status(self) -> bool:
"""Request iSWAP initialization status

Expand Down
Loading