44import logging
55import re
66from abc import ABCMeta
7- from contextlib import asynccontextmanager
7+ from contextlib import asynccontextmanager , contextmanager
88from typing import (
99 Callable ,
1010 Dict ,
@@ -93,7 +93,7 @@ def need_iswap_parked(method: Callable):
9393 async def wrapper (self : "STAR" , * args , ** kwargs ):
9494 if self .iswap_installed and not self .iswap_parked :
9595 await self .park_iswap (
96- minimum_traverse_height_at_beginning_of_a_command = int (self ._traversal_height * 10 )
96+ minimum_traverse_height_at_beginning_of_a_command = int (self ._iswap_traversal_height * 10 )
9797 )
9898
9999 result = await method (self , * args , ** kwargs )
@@ -1164,7 +1164,8 @@ def __init__(
11641164 self ._num_channels : Optional [int ] = None
11651165 self ._core_parked : Optional [bool ] = None
11661166 self ._extended_conf : Optional [dict ] = None
1167- self ._traversal_height : float = 245.0
1167+ self ._channel_traversal_height : float = 245.0
1168+ self ._iswap_traversal_height : float = 245.0
11681169 self .core_adjustment = Coordinate .zero ()
11691170 self ._unsafe = UnSafe (self )
11701171
@@ -1183,7 +1184,13 @@ def num_channels(self) -> int:
11831184 return self ._num_channels
11841185
11851186 def set_minimum_traversal_height (self , traversal_height : float ):
1186- """Set the minimum traversal height for the robot.
1187+ raise NotImplementedError (
1188+ "set_minimum_traversal_height is depricated. use set_minimum_channel_traversal_height or "
1189+ "set_minimum_iswap_traversal_height instead."
1190+ )
1191+
1192+ def set_minimum_channel_traversal_height (self , traversal_height : float ):
1193+ """Set the minimum traversal height for the pip channels.
11871194
11881195 This refers to the bottom of the pipetting channel when no tip is present, or the bottom of the
11891196 tip when a tip is present. This value will be used as the default value for the
@@ -1193,7 +1200,24 @@ def set_minimum_traversal_height(self, traversal_height: float):
11931200
11941201 assert 0 < traversal_height < 285 , "Traversal height must be between 0 and 285 mm"
11951202
1196- self ._traversal_height = traversal_height
1203+ self ._channel_traversal_height = traversal_height
1204+
1205+ def set_minimum_iswap_traversal_height (self , traversal_height : float ):
1206+ """Set the minimum traversal height for the iswap."""
1207+
1208+ assert 0 < traversal_height < 285 , "Traversal height must be between 0 and 285 mm"
1209+
1210+ self ._iswap_traversal_height = traversal_height
1211+
1212+ @contextmanager
1213+ def iswap_minimum_traversal_height (self , traversal_height : float ):
1214+ orig = self ._iswap_traversal_height
1215+ self ._iswap_traversal_height = traversal_height
1216+ try :
1217+ yield
1218+ except Exception as e :
1219+ self ._iswap_traversal_height = orig
1220+ raise e
11971221
11981222 @property
11991223 def module_id_length (self ):
@@ -1367,7 +1391,7 @@ async def setup(
13671391 await self .initialize_pipetting_channels (
13681392 x_positions = [self .extended_conf ["xw" ]], # Tip eject waste X position.
13691393 y_positions = y_positions ,
1370- begin_of_tip_deposit_process = int (self ._traversal_height * 10 ),
1394+ begin_of_tip_deposit_process = int (self ._channel_traversal_height * 10 ),
13711395 end_of_tip_deposit_process = 1220 ,
13721396 z_position_at_end_of_a_command = 3600 ,
13731397 tip_pattern = [True ] * self .num_channels ,
@@ -1388,15 +1412,15 @@ async def setup(
13881412 await self .initialize_iswap ()
13891413
13901414 await self .park_iswap (
1391- minimum_traverse_height_at_beginning_of_a_command = int (self ._traversal_height * 10 )
1415+ minimum_traverse_height_at_beginning_of_a_command = int (self ._iswap_traversal_height * 10 )
13921416 )
13931417
13941418 if self .core96_head_installed and not skip_core96_head :
13951419 core96_head_initialized = await self .request_core_96_head_initialization_status ()
13961420 if not core96_head_initialized :
13971421 await self .initialize_core_96_head (
13981422 trash96 = self .deck .get_trash_area96 (),
1399- z_position_at_the_command_end = self ._traversal_height ,
1423+ z_position_at_the_command_end = self ._channel_traversal_height ,
14001424 )
14011425
14021426 # After setup, STAR will have thrown out anything mounted on the pipetting channels, including
@@ -1449,7 +1473,7 @@ async def pick_up_tips(
14491473 else round (end_tip_pick_up_process * 10 )
14501474 )
14511475 minimum_traverse_height_at_beginning_of_a_command = (
1452- round (self ._traversal_height * 10 )
1476+ round (self ._channel_traversal_height * 10 )
14531477 if minimum_traverse_height_at_beginning_of_a_command is None
14541478 else round (minimum_traverse_height_at_beginning_of_a_command * 10 )
14551479 )
@@ -1526,12 +1550,12 @@ async def drop_tips(
15261550 )
15271551
15281552 minimum_traverse_height_at_beginning_of_a_command = (
1529- round (self ._traversal_height * 10 )
1553+ round (self ._channel_traversal_height * 10 )
15301554 if minimum_traverse_height_at_beginning_of_a_command is None
15311555 else round (minimum_traverse_height_at_beginning_of_a_command * 10 )
15321556 )
15331557 z_position_at_end_of_a_command = (
1534- round (self ._traversal_height * 10 )
1558+ round (self ._channel_traversal_height * 10 )
15351559 if z_position_at_end_of_a_command is None
15361560 else round (z_position_at_end_of_a_command * 10 )
15371561 )
@@ -1869,9 +1893,9 @@ async def aspirate(
18691893 ratio_liquid_rise_to_tip_deep_in = ratio_liquid_rise_to_tip_deep_in ,
18701894 immersion_depth_2nd_section = [round (id_ * 10 ) for id_ in immersion_depth_2nd_section ],
18711895 minimum_traverse_height_at_beginning_of_a_command = round (
1872- (minimum_traverse_height_at_beginning_of_a_command or self ._traversal_height ) * 10
1896+ (minimum_traverse_height_at_beginning_of_a_command or self ._channel_traversal_height ) * 10
18731897 ),
1874- min_z_endpos = round ((min_z_endpos or self ._traversal_height ) * 10 ),
1898+ min_z_endpos = round ((min_z_endpos or self ._channel_traversal_height ) * 10 ),
18751899 )
18761900 except STARFirmwareError as e :
18771901 if plr_e := convert_star_firmware_error_to_plr_error (e ):
@@ -2129,9 +2153,9 @@ async def dispense(
21292153 ],
21302154 limit_curve_index = limit_curve_index ,
21312155 minimum_traverse_height_at_beginning_of_a_command = round (
2132- (minimum_traverse_height_at_beginning_of_a_command or self ._traversal_height ) * 10
2156+ (minimum_traverse_height_at_beginning_of_a_command or self ._channel_traversal_height ) * 10
21332157 ),
2134- min_z_endpos = round ((min_z_endpos or self ._traversal_height ) * 10 ),
2158+ min_z_endpos = round ((min_z_endpos or self ._channel_traversal_height ) * 10 ),
21352159 side_touch_off_distance = side_touch_off_distance ,
21362160 )
21372161 except STARFirmwareError as e :
@@ -2167,9 +2191,11 @@ async def pick_up_tips96(
21672191 tip_pickup_method = tip_pickup_method ,
21682192 z_deposit_position = round (z_deposit_position * 10 ),
21692193 minimum_traverse_height_at_beginning_of_a_command = round (
2170- (minimum_traverse_height_at_beginning_of_a_command or self ._traversal_height ) * 10
2194+ (minimum_traverse_height_at_beginning_of_a_command or self ._channel_traversal_height ) * 10
2195+ ),
2196+ minimum_height_command_end = round (
2197+ (minimum_height_command_end or self ._channel_traversal_height ) * 10
21712198 ),
2172- minimum_height_command_end = round ((minimum_height_command_end or self ._traversal_height ) * 10 ),
21732199 )
21742200
21752201 async def drop_tips96 (
@@ -2194,9 +2220,11 @@ async def drop_tips96(
21942220 y_position = round (position .y * 10 ),
21952221 z_deposit_position = round (z_deposit_position * 10 ),
21962222 minimum_traverse_height_at_beginning_of_a_command = round (
2197- (minimum_traverse_height_at_beginning_of_a_command or self ._traversal_height ) * 10
2223+ (minimum_traverse_height_at_beginning_of_a_command or self ._channel_traversal_height ) * 10
2224+ ),
2225+ minimum_height_command_end = round (
2226+ (minimum_height_command_end or self ._channel_traversal_height ) * 10
21982227 ),
2199- minimum_height_command_end = round ((minimum_height_command_end or self ._traversal_height ) * 10 ),
22002228 )
22012229
22022230 async def aspirate96 (
@@ -2345,9 +2373,9 @@ async def aspirate96(
23452373 y_positions = round (position .y * 10 ),
23462374 aspiration_type = aspiration_type ,
23472375 minimum_traverse_height_at_beginning_of_a_command = round (
2348- (minimum_traverse_height_at_beginning_of_a_command or self ._traversal_height ) * 10
2376+ (minimum_traverse_height_at_beginning_of_a_command or self ._channel_traversal_height ) * 10
23492377 ),
2350- minimal_end_height = round ((minimal_end_height or self ._traversal_height ) * 10 ),
2378+ minimal_end_height = round ((minimal_end_height or self ._channel_traversal_height ) * 10 ),
23512379 lld_search_height = round (lld_search_height * 10 ),
23522380 liquid_surface_at_function_without_lld = round (liquid_height * 10 ),
23532381 pull_out_distance_to_take_transport_air_in_function_without_lld = round (
@@ -2509,9 +2537,9 @@ async def dispense96(
25092537 x_direction = 0 ,
25102538 y_position = round (position .y * 10 ),
25112539 minimum_traverse_height_at_beginning_of_a_command = round (
2512- (minimum_traverse_height_at_beginning_of_a_command or self ._traversal_height ) * 10
2540+ (minimum_traverse_height_at_beginning_of_a_command or self ._channel_traversal_height ) * 10
25132541 ),
2514- minimal_end_height = round ((minimal_end_height or self ._traversal_height ) * 10 ),
2542+ minimal_end_height = round ((minimal_end_height or self ._channel_traversal_height ) * 10 ),
25152543 lld_search_height = round (lld_search_height * 10 ),
25162544 liquid_surface_at_function_without_lld = round (liquid_height * 10 ),
25172545 pull_out_distance_to_take_transport_air_in_function_without_lld = round (
@@ -2649,10 +2677,10 @@ async def core_pick_up_resource(
26492677 plate_width = round (grip_width * 10 ) - 30 ,
26502678 grip_strength = grip_strength ,
26512679 minimum_traverse_height_at_beginning_of_a_command = round (
2652- (minimum_traverse_height_at_beginning_of_a_command or self ._traversal_height ) * 10
2680+ (minimum_traverse_height_at_beginning_of_a_command or self ._channel_traversal_height ) * 10
26532681 ),
26542682 minimum_z_position_at_the_command_end = round (
2655- (minimum_z_position_at_the_command_end or self ._traversal_height ) * 10
2683+ (minimum_z_position_at_the_command_end or self ._channel_traversal_height ) * 10
26562684 ),
26572685 )
26582686
@@ -2689,7 +2717,7 @@ async def core_move_picked_up_resource(
26892717 z_position = round (center .z * 10 ),
26902718 z_speed = round (z_speed * 10 ),
26912719 minimum_traverse_height_at_beginning_of_a_command = round (
2692- (minimum_traverse_height_at_beginning_of_a_command or self ._traversal_height ) * 10
2720+ (minimum_traverse_height_at_beginning_of_a_command or self ._channel_traversal_height ) * 10
26932721 ),
26942722 )
26952723
@@ -2732,10 +2760,10 @@ async def core_release_picked_up_resource(
27322760 z_speed = 500 ,
27332761 open_gripper_position = round (grip_width * 10 ) + 30 ,
27342762 minimum_traverse_height_at_beginning_of_a_command = round (
2735- (minimum_traverse_height_at_beginning_of_a_command or self ._traversal_height ) * 10
2763+ (minimum_traverse_height_at_beginning_of_a_command or self ._channel_traversal_height ) * 10
27362764 ),
27372765 z_position_at_the_command_end = round (
2738- (z_position_at_the_command_end or self ._traversal_height ) * 10
2766+ (z_position_at_the_command_end or self ._channel_traversal_height ) * 10
27392767 ),
27402768 return_tool = return_tool ,
27412769 )
@@ -2786,9 +2814,9 @@ async def pick_up_resource(
27862814 z -= pickup .pickup_distance_from_top
27872815
27882816 traverse_height_at_beginning = (
2789- minimum_traverse_height_at_beginning_of_a_command or self ._traversal_height
2817+ minimum_traverse_height_at_beginning_of_a_command or self ._iswap_traversal_height
27902818 )
2791- z_position_at_the_command_end = z_position_at_the_command_end or self ._traversal_height
2819+ z_position_at_the_command_end = z_position_at_the_command_end or self ._iswap_traversal_height
27922820
27932821 if open_gripper_position is None :
27942822 if use_unsafe_hotel :
@@ -2851,8 +2879,8 @@ async def pick_up_resource(
28512879 resource = pickup .resource ,
28522880 pickup_distance_from_top = pickup .pickup_distance_from_top ,
28532881 offset = pickup .offset ,
2854- minimum_traverse_height_at_beginning_of_a_command = self ._traversal_height ,
2855- minimum_z_position_at_the_command_end = self ._traversal_height ,
2882+ minimum_traverse_height_at_beginning_of_a_command = self ._channel_traversal_height ,
2883+ minimum_z_position_at_the_command_end = self ._channel_traversal_height ,
28562884 channel_1 = channel_1 ,
28572885 channel_2 = channel_2 ,
28582886 grip_strength = core_grip_strength ,
@@ -2868,7 +2896,7 @@ async def move_picked_up_resource(
28682896 location = move .location ,
28692897 resource = move .resource ,
28702898 grip_direction = move .gripped_direction ,
2871- minimum_traverse_height_at_beginning_of_a_command = self ._traversal_height ,
2899+ minimum_traverse_height_at_beginning_of_a_command = self ._iswap_traversal_height ,
28722900 collision_control_level = 1 ,
28732901 acceleration_index_high_acc = 4 ,
28742902 acceleration_index_low_acc = 1 ,
@@ -2877,7 +2905,7 @@ async def move_picked_up_resource(
28772905 await self .core_move_picked_up_resource (
28782906 location = move .location ,
28792907 resource = move .resource ,
2880- minimum_traverse_height_at_beginning_of_a_command = self ._traversal_height ,
2908+ minimum_traverse_height_at_beginning_of_a_command = self ._channel_traversal_height ,
28812909 acceleration_index = 4 ,
28822910 )
28832911
@@ -2897,9 +2925,9 @@ async def drop_resource(
28972925 ):
28982926 if use_arm == "iswap" :
28992927 traversal_height_start = (
2900- minimum_traverse_height_at_beginning_of_a_command or self ._traversal_height
2928+ minimum_traverse_height_at_beginning_of_a_command or self ._iswap_traversal_height
29012929 )
2902- z_position_at_the_command_end = z_position_at_the_command_end or self ._traversal_height
2930+ z_position_at_the_command_end = z_position_at_the_command_end or self ._iswap_traversal_height
29032931 assert (
29042932 drop .resource .get_absolute_rotation ().x == 0
29052933 and drop .resource .get_absolute_rotation ().y == 0
@@ -2996,8 +3024,8 @@ async def drop_resource(
29963024 resource = drop .resource ,
29973025 offset = drop .offset ,
29983026 pickup_distance_from_top = drop .pickup_distance_from_top ,
2999- minimum_traverse_height_at_beginning_of_a_command = self ._traversal_height ,
3000- z_position_at_the_command_end = self ._traversal_height ,
3027+ minimum_traverse_height_at_beginning_of_a_command = self ._channel_traversal_height ,
3028+ z_position_at_the_command_end = self ._channel_traversal_height ,
30013029 # int(previous_location.z + move.resource.get_size_z() / 2) * 10,
30023030 return_tool = return_core_gripper ,
30033031 )
@@ -4665,7 +4693,7 @@ async def get_core(self, p1: int, p2: int):
46654693 pb = f"{ p2 :02} " ,
46664694 tp = f"{ 2350 + self .core_adjustment .z :04} " ,
46674695 tz = f"{ 2250 + self .core_adjustment .z :04} " ,
4668- th = round (self ._traversal_height * 10 ),
4696+ th = round (self ._channel_traversal_height * 10 ),
46694697 tt = "14" ,
46704698 )
46714699 self ._core_parked = False
@@ -4691,8 +4719,8 @@ async def put_core(self):
46914719 yb = f"{ 1065 + self .core_adjustment .y :04} " ,
46924720 tp = f"{ 2150 + self .core_adjustment .z :04} " ,
46934721 tz = f"{ 2050 + self .core_adjustment .z :04} " ,
4694- th = round (self ._traversal_height * 10 ),
4695- te = round (self ._traversal_height * 10 ),
4722+ th = round (self ._channel_traversal_height * 10 ),
4723+ te = round (self ._channel_traversal_height * 10 ),
46964724 )
46974725 self ._core_parked = True
46984726 return command_output
0 commit comments