Skip to content

Commit 0bd219f

Browse files
authored
STAR iswap & channel 0 collision checks (#687)
1 parent 7234de0 commit 0bd219f

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

pylabrobot/liquid_handling/backends/hamilton/STAR_backend.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3112,10 +3112,15 @@ async def move_channel_y(self, channel: int, y: float):
31123112
f"(channel {channel - 1} y-position is {round(y, 2)} mm)"
31133113
)
31143114
else:
3115-
# STAR machines appear to lose connection to a channel if y > 635 mm
3116-
max_y_pos = 635
3115+
if self.iswap_installed:
3116+
max_y_pos = await self.iswap_request_module_y()
3117+
limit = "iswap module y-position"
3118+
else:
3119+
# STAR machines do not allow channels y > 635 mm
3120+
max_y_pos = 635
3121+
limit = "machine limit"
31173122
if y > max_y_pos:
3118-
raise ValueError(f"channel {channel} y-target must be <= {max_y_pos} mm (machine limit)")
3123+
raise ValueError(f"channel {channel} y-target must be <= {max_y_pos} mm ({limit})")
31193124

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

6484+
# check if iswap will hit the first (backmost) channel
6485+
# we only need to check for positive step sizes because the iswap is always behind the first channel
6486+
if step_size < 0:
6487+
y_pos_channel_0 = await self.request_y_pos_channel_n(0)
6488+
current_y_pos_iswap = await self.iswap_request_module_y()
6489+
if current_y_pos_iswap + step_size < y_pos_channel_0:
6490+
raise ValueError(
6491+
f"iSWAP will hit the first (backmost) channel. Current iSWAP Y position: {current_y_pos_iswap} mm, "
6492+
f"first channel Y position: {y_pos_channel_0} mm, requested step size: {step_size} mm"
6493+
)
6494+
64796495
direction = 0 if step_size >= 0 else 1
64806496
max_step_size = 99.9
64816497
if abs(step_size) > max_step_size:
@@ -7213,6 +7229,17 @@ async def request_iswap_position(self) -> Coordinate:
72137229
z=(resp["zj"] / 10) * (1 if resp["zd"] == 0 else -1),
72147230
)
72157231

7232+
@staticmethod
7233+
def _iswap_y_inc_to_mm(y_inc: int) -> float:
7234+
mm_per_increment = 0.046302083
7235+
return round(y_inc * mm_per_increment, 2)
7236+
7237+
async def iswap_request_module_y(self) -> float:
7238+
"""Request iSWAP module (not gripper) Y position in mm"""
7239+
resp = await self.send_command(module="R0", command="RY", fmt="ry##### (n)")
7240+
iswap_y_pos = resp["ry"][1] # 0 = FW counter, 1 = HW counter
7241+
return STARBackend._iswap_y_inc_to_mm(iswap_y_pos)
7242+
72167243
async def request_iswap_initialization_status(self) -> bool:
72177244
"""Request iSWAP initialization status
72187245

0 commit comments

Comments
 (0)