Skip to content

Commit 8ba416a

Browse files
authored
fix(api): Use correct PLATFORM_OFFSET and add LATCH_CLEARANCE for store/dispense_labware functions of the FlexStacker. (#18907)
1 parent 13f9e10 commit 8ba416a

File tree

2 files changed

+122
-14
lines changed

2 files changed

+122
-14
lines changed

api/src/opentrons/hardware_control/modules/flex_stacker.py

Lines changed: 113 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,113 @@
7878

7979
# The labware platform will contact the labware this mm before the platform
8080
# touches the +Z endstop.
81-
PLATFORM_OFFSET = 4
81+
PLATFORM_OFFSET = 2.25
82+
83+
# Should put the bottom of the plate above this mm above the latch when dispensing.
84+
# Should put the bottom of the plate this mm below the latch when storing.
85+
LATCH_CLEARANCE = 2.5
86+
87+
# Configs
88+
TOF_DETECTION_CONFIG = {
89+
TOFSensor.X: {
90+
Direction.EXTEND: TOFDetection(
91+
TOFSensor.X,
92+
zones=[5, 6, 7],
93+
bins=list(range(30, 40)),
94+
threshold=1000,
95+
),
96+
Direction.RETRACT: TOFDetection(
97+
TOFSensor.X,
98+
zones=[5, 6, 7],
99+
bins=list(range(17, 30)),
100+
threshold=1000,
101+
),
102+
},
103+
TOFSensor.Z: {
104+
Direction.EXTEND: TOFDetection(
105+
TOFSensor.Z,
106+
zones=[1, 2, 3],
107+
bins=list(range(15, 63)),
108+
threshold=1000,
109+
),
110+
Direction.RETRACT: TOFDetection(
111+
TOFSensor.Z,
112+
zones=[1, 2, 3],
113+
bins=list(range(15, 63)),
114+
threshold=1000,
115+
),
116+
},
117+
}
118+
119+
120+
# Stallguard defaults
121+
STALLGUARD_CONFIG = {
122+
StackerAxis.X: StallGuardParams(StackerAxis.X, True, 0),
123+
StackerAxis.Z: StallGuardParams(StackerAxis.Z, True, 0),
124+
}
125+
126+
STACKER_MOTION_CONFIG = {
127+
StackerAxis.X: {
128+
"home": AxisParams(
129+
run_current=1.5, # mAmps
130+
hold_current=0.75,
131+
move_params=MoveParams(
132+
max_speed=10.0, # mm/s
133+
acceleration=100.0, # mm/s^2
134+
max_speed_discont=40.0, # mm/s
135+
),
136+
),
137+
"move": AxisParams(
138+
run_current=1.2,
139+
hold_current=0.75,
140+
move_params=MoveParams(
141+
max_speed=200.0,
142+
acceleration=1500.0,
143+
max_speed_discont=40.0,
144+
),
145+
),
146+
},
147+
StackerAxis.Z: {
148+
"home": AxisParams(
149+
run_current=1.5,
150+
hold_current=1.5,
151+
move_params=MoveParams(
152+
max_speed=10.0,
153+
acceleration=100.0,
154+
max_speed_discont=25.0,
155+
),
156+
),
157+
"move": AxisParams(
158+
run_current=1.5,
159+
hold_current=1.5,
160+
move_params=MoveParams(
161+
max_speed=150.0,
162+
acceleration=500.0,
163+
max_speed_discont=25.0,
164+
),
165+
),
166+
},
167+
StackerAxis.L: {
168+
"home": AxisParams(
169+
run_current=1.2,
170+
hold_current=0.5,
171+
move_params=MoveParams(
172+
max_speed=100.0,
173+
acceleration=800.0,
174+
max_speed_discont=40.0,
175+
),
176+
),
177+
"move": AxisParams(
178+
run_current=1.2,
179+
hold_current=0.5,
180+
move_params=MoveParams(
181+
max_speed=100.0,
182+
acceleration=800.0,
183+
max_speed_discont=40.0,
184+
),
185+
),
186+
},
187+
}
82188

83189
# Configs
84190
TOF_DETECTION_CONFIG = {
@@ -521,16 +627,12 @@ async def dispense_labware(
521627

522628
# Transfer
523629
await self.open_latch()
524-
# NOTE: When moving from the +Z limit switch down, the PLATFORM_OFFSET makes
525-
# sure the bottom of the next labware is sitting N mm above the latch.
526-
# So when moving the labware_height we dont need to add an additional
527-
# offset to make sure we arent cutting it too close since the labware
528-
# will always be above the latch.
529-
await self.move_axis(StackerAxis.Z, Direction.RETRACT, labware_height)
630+
latch_clear_distance = labware_height + PLATFORM_OFFSET - LATCH_CLEARANCE
631+
await self.move_axis(StackerAxis.Z, Direction.RETRACT, latch_clear_distance)
530632
await self.close_latch()
531633

532634
# Move Z down the rest of the way
533-
z_distance = MAX_TRAVEL[StackerAxis.Z] - labware_height - HOME_OFFSET_SM
635+
z_distance = MAX_TRAVEL[StackerAxis.Z] - latch_clear_distance - HOME_OFFSET_SM
534636
await self.move_axis(StackerAxis.Z, Direction.RETRACT, z_distance)
535637
await self.home_axis(StackerAxis.Z, Direction.RETRACT)
536638

@@ -553,12 +655,13 @@ async def store_labware(
553655
await self.verify_shuttle_labware_presence(Direction.RETRACT, True)
554656

555657
# Move the Z so the labware sits right under any labware already stored
556-
distance = MAX_TRAVEL[StackerAxis.Z] - labware_height - PLATFORM_OFFSET
658+
latch_clear_distance = labware_height + PLATFORM_OFFSET + LATCH_CLEARANCE
659+
distance = MAX_TRAVEL[StackerAxis.Z] - latch_clear_distance
557660
await self.move_axis(StackerAxis.Z, Direction.EXTEND, distance)
558661

559662
await self.open_latch()
560663
# Move the labware the rest of the way at half move speed to increase torque.
561-
remaining_z = labware_height + PLATFORM_OFFSET - HOME_OFFSET_SM
664+
remaining_z = latch_clear_distance - HOME_OFFSET_SM
562665
speed_z = STACKER_MOTION_CONFIG[StackerAxis.Z]["move"].move_params.max_speed / 2
563666
await self.move_axis(StackerAxis.Z, Direction.EXTEND, remaining_z, speed_z)
564667
await self.home_axis(StackerAxis.Z, Direction.EXTEND, speed_z)

api/tests/opentrons/hardware_control/modules/test_hc_flexstacker.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from opentrons.hardware_control import modules, ExecutionManager
1515
from opentrons.drivers.rpi_drivers.types import USBPort
1616
from opentrons.hardware_control.modules.flex_stacker import (
17+
LATCH_CLEARANCE,
1718
MAX_TRAVEL,
1819
HOME_OFFSET_MD,
1920
HOME_OFFSET_SM,
@@ -357,12 +358,13 @@ async def test_store_labware_motion_sequence(
357358
verify_shuttle_labware_presence.assert_any_call(Direction.RETRACT, True)
358359

359360
# Assertions for offset calculation and move_axis
360-
distance = MAX_TRAVEL[StackerAxis.Z] - labware_height - PLATFORM_OFFSET
361+
latch_clear_distance = labware_height + PLATFORM_OFFSET + LATCH_CLEARANCE
362+
distance = MAX_TRAVEL[StackerAxis.Z] - latch_clear_distance
361363
move_axis.assert_any_call(StackerAxis.Z, Direction.EXTEND, distance)
362364

363365
# Verify labware transfer
364366
open_latch.assert_called_once()
365-
z_distance = MAX_TRAVEL[StackerAxis.Z] - distance - HOME_OFFSET_SM
367+
z_distance = latch_clear_distance - HOME_OFFSET_SM
366368
z_speed = STACKER_MOTION_CONFIG[StackerAxis.Z]["move"].move_params.max_speed / 2
367369
move_axis.assert_any_call(StackerAxis.Z, Direction.EXTEND, z_distance, z_speed)
368370
home_axis.assert_any_call(StackerAxis.Z, Direction.EXTEND, z_speed)
@@ -426,11 +428,14 @@ async def test_dispense_labware_motion_sequence(
426428

427429
# Verify labware transfer
428430
open_latch.assert_called_once()
429-
move_axis.assert_any_call(StackerAxis.Z, Direction.RETRACT, labware_height)
431+
latch_clear_distance = labware_height + PLATFORM_OFFSET - LATCH_CLEARANCE
432+
move_axis.assert_any_call(
433+
StackerAxis.Z, Direction.RETRACT, latch_clear_distance
434+
)
430435
close_latch.assert_called_once()
431436

432437
# Assertions for offset calculation and move_axis/home_axis
433-
z_distance = MAX_TRAVEL[StackerAxis.Z] - labware_height - HOME_OFFSET_SM
438+
z_distance = MAX_TRAVEL[StackerAxis.Z] - latch_clear_distance - HOME_OFFSET_SM
434439
move_axis.assert_any_call(StackerAxis.Z, Direction.RETRACT, z_distance)
435440
home_axis.assert_any_call(StackerAxis.Z, Direction.RETRACT)
436441

0 commit comments

Comments
 (0)