Skip to content

Commit 1055859

Browse files
fix(hardware-testing): Add Flex stacker PVT QC StallGuard thresholds + Use labware_detect from FlexStacker module. (#18741)
1 parent f356149 commit 1055859

File tree

5 files changed

+73
-78
lines changed

5 files changed

+73
-78
lines changed

hardware-testing/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ test-integration: test-production-qc test-examples test-scripts test-gravimetric
152152

153153
.PHONY: test-stacker
154154
test-stacker:
155-
$(python) -m hardware_testing.modules.flex_stacker_dvt_qc --simulate
155+
$(python) -m hardware_testing.modules.flex_stacker_qc --simulate
156156

157157
.PHONY: lint
158158
lint:

hardware-testing/hardware_testing/modules/flex_stacker_qc/__main__.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from .utils import find_stacker_port, get_estop
1919
from opentrons.drivers.rpi_drivers.types import USBPort
2020
from opentrons.hardware_control.modules.flex_stacker import FlexStacker
21-
from opentrons.hardware_control.modules.types import PlatformState
2221

2322

2423
async def build_stacker_report(
@@ -60,16 +59,8 @@ async def _main(cfg: TestConfig) -> None:
6059
ui.print_error("ESTOP is still pressed, cannot start tests")
6160
return
6261

63-
# TODO: This check should be in the basic axes tests
6462
await stacker.home_all()
6563
await stacker._reader.read()
66-
if stacker.platform_state is not PlatformState.UNKNOWN:
67-
ui.print_error("Platform must be removed from the carrier before starting")
68-
ui.get_user_ready(f"Remove platform from {stacker.platform_state.value}")
69-
await stacker._reader.get_platform_sensor_state()
70-
if stacker.platform_state is not PlatformState.UNKNOWN:
71-
ui.print_error("Platform is still detected, cannot start tests")
72-
return
7364

7465
device_info = await stacker._driver.get_device_info()
7566
report.set_tag(device_info.sn if device_info.sn else "UNKNOWN")
@@ -87,11 +78,6 @@ async def _main(cfg: TestConfig) -> None:
8778
report.save_to_disk()
8879
report.print_results()
8980

90-
# Restart the robot server
91-
if not cfg.simulate:
92-
print("Starting the robot server")
93-
subprocess.run(["systemctl restart opentrons-robot-server &"], shell=True)
94-
9581

9682
if __name__ == "__main__":
9783
parser = argparse.ArgumentParser()

hardware-testing/hardware_testing/modules/flex_stacker_qc/test_stallguard.py

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,59 +12,76 @@
1212
from opentrons_shared_data.errors.exceptions import FlexStackerStallError
1313
from opentrons.drivers.flex_stacker.driver import (
1414
STACKER_MOTION_CONFIG,
15+
STALLGUARD_CONFIG,
16+
)
17+
from opentrons.drivers.flex_stacker.types import (
18+
StackerAxis,
19+
Direction,
1520
)
16-
from opentrons.drivers.flex_stacker.types import StackerAxis, Direction
1721

1822
# The distance from limit switch to limit switch, mm
1923
TEST_DISTANCE = {StackerAxis.X: 193.5, StackerAxis.Z: 137}
2024

2125

26+
def generate_test_thresholds(test_axis: StackerAxis) -> List[int]:
27+
"""Generate test thresholds."""
28+
thresholds = []
29+
default_threshold = STALLGUARD_CONFIG[test_axis].threshold
30+
for sgt in range(default_threshold - 2, default_threshold + 3):
31+
thresholds.append(sgt)
32+
return thresholds
33+
34+
35+
def _get_test_tag(test_axis: StackerAxis, sgt: int) -> str:
36+
"""Get test tag."""
37+
return f"stallguard-{test_axis}-SGT-{sgt}"
38+
39+
2240
def build_csv_lines() -> List[Union[CSVLine, CSVLineRepeating]]:
2341
"""Build CSV Lines."""
24-
return [
25-
CSVLine(f"stallguard-{StackerAxis.X}", [CSVResult]),
26-
CSVLine(f"stallguard-{StackerAxis.Z}", [CSVResult]),
27-
]
42+
lines: List[Union[CSVLine, CSVLineRepeating]] = []
43+
for axis in [StackerAxis.X, StackerAxis.Z]:
44+
for sgt in generate_test_thresholds(axis):
45+
lines.append(CSVLine(_get_test_tag(axis, sgt), [CSVResult]))
46+
return lines
2847

2948

3049
async def test_stallguard(
3150
stacker: FlexStacker, test_axis: StackerAxis, report: CSVReport, section: str
3251
) -> None:
3352
"""Test Stall-Guard."""
3453
ui.print_header(f"Testing {test_axis} Axis")
35-
stall_detected = False
36-
try:
37-
await stacker.move_axis(
38-
test_axis,
39-
Direction.RETRACT,
40-
TEST_DISTANCE[test_axis],
41-
STACKER_MOTION_CONFIG[test_axis]["move"].move_params.max_speed,
42-
STACKER_MOTION_CONFIG[test_axis]["move"].move_params.acceleration,
43-
STACKER_MOTION_CONFIG[test_axis]["move"].run_current,
44-
)
45-
except FlexStackerStallError:
46-
ui.print_info("Stall Detected")
47-
stall_detected = True
4854

49-
axis_reset = False
50-
while not axis_reset:
55+
for sgt in generate_test_thresholds(test_axis):
56+
ui.print_header(f"Testing Stallguard Threshold: {sgt}")
57+
await stacker._driver.set_stallguard_threshold(test_axis, True, sgt)
58+
stall_detected = False
5159
try:
52-
# Move the axis off the crash block before re-homing
5360
await stacker.move_axis(
5461
test_axis,
55-
Direction.EXTEND,
56-
20,
57-
STACKER_MOTION_CONFIG[test_axis]["home"].move_params.max_speed,
58-
STACKER_MOTION_CONFIG[test_axis]["home"].move_params.acceleration,
59-
STACKER_MOTION_CONFIG[test_axis]["home"].run_current,
62+
Direction.RETRACT,
63+
TEST_DISTANCE[test_axis],
64+
STACKER_MOTION_CONFIG[test_axis]["move"].move_params.max_speed,
65+
STACKER_MOTION_CONFIG[test_axis]["move"].move_params.acceleration,
66+
STACKER_MOTION_CONFIG[test_axis]["move"].run_current,
6067
)
61-
axis_reset = True
6268
except FlexStackerStallError:
63-
axis_reset = False
69+
ui.print_info("Stall Detected")
70+
stall_detected = True
71+
await stacker._driver.set_stallguard_threshold(test_axis, False, 0)
6472

65-
await stacker.home_axis(test_axis, Direction.EXTEND)
73+
await stacker.home_axis(test_axis, Direction.EXTEND)
6674

67-
report(section, f"stallguard-{test_axis}", [CSVResult.from_bool(stall_detected)])
75+
report(
76+
section,
77+
_get_test_tag(test_axis, sgt),
78+
[CSVResult.from_bool(stall_detected)],
79+
)
80+
81+
# Restore default stallguard threshold
82+
await stacker._driver.set_stallguard_threshold(
83+
test_axis, True, STALLGUARD_CONFIG[test_axis].threshold
84+
)
6885

6986
return
7087

@@ -88,13 +105,6 @@ async def run(stacker: FlexStacker, report: CSVReport, section: str) -> None:
88105
# Test Axes
89106
await test_stallguard(stacker, StackerAxis.X, report, section)
90107
await test_stallguard(stacker, StackerAxis.Z, report, section)
91-
# ui.print_header(f"Testing {StackerAxis.X} Axis")
92-
# x_result = await test_stallguard(stacker, StackerAxis.X)
93-
# report(section, f"stallguard-x", [CSVResult.from_bool(x_result)])
94-
95-
# ui.print_header("Testing Z Axis")
96-
# z_result = await test_stallguard(stacker, StackerAxis.Z)
97-
# report(section, f"stallguard-z", [CSVResult.from_bool(z_result)])
98108

99109
# Prompt operator to remove the crash block
100110
if not stacker.is_simulated:
@@ -109,7 +119,13 @@ async def run(stacker: FlexStacker, report: CSVReport, section: str) -> None:
109119
test_reset = True
110120
except FlexStackerStallError:
111121
# Double check if crash block was actually removed
112-
await stacker.home_axis(StackerAxis.Z, Direction.EXTEND)
113-
await stacker.home_axis(StackerAxis.X, Direction.EXTEND)
122+
await stacker._driver.set_stallguard_threshold(StackerAxis.Z, False, 0)
123+
await stacker._driver.set_stallguard_threshold(StackerAxis.X, False, 0)
124+
await stacker._driver.set_stallguard_threshold(
125+
StackerAxis.Z, True, STALLGUARD_CONFIG[StackerAxis.Z].threshold
126+
)
127+
await stacker._driver.set_stallguard_threshold(
128+
StackerAxis.X, True, STALLGUARD_CONFIG[StackerAxis.X].threshold
129+
)
114130
if not stacker.is_simulated:
115131
ui.get_user_ready("Remove the crash block from the stacker")

hardware-testing/hardware_testing/modules/flex_stacker_qc/test_tof_functional.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@
99
CSVLineRepeating,
1010
CSVResult,
1111
)
12-
from hardware_testing.modules.flex_stacker_dvt_qc.utils import labware_detected
1312

1413
from opentrons.hardware_control.modules.flex_stacker import FlexStacker
15-
from .utils import NUMBER_OF_BINS, NUMBER_OF_ZONES
1614
from opentrons.drivers.flex_stacker.types import (
1715
Direction,
1816
StackerAxis,
@@ -56,6 +54,8 @@ async def test_tof_sensors_labware_detection(
5654
section: str,
5755
sensor: TOFSensor,
5856
labware: str,
57+
axis: StackerAxis,
58+
direction: Direction = Direction.EXTEND,
5959
) -> None:
6060
"""Test that we can detect labware with the TOF sensor."""
6161
open = not await stacker._driver.get_hopper_door_closed()
@@ -74,12 +74,13 @@ async def test_tof_sensors_labware_detection(
7474
return
7575

7676
print(f"Getting histogram for {sensor}.")
77-
bins = list(range(NUMBER_OF_BINS))
78-
zones = list(range(NUMBER_OF_ZONES))
7977
histogram = await stacker._driver.get_tof_histogram(sensor)
80-
diff = labware_detected(histogram.bins, sensor, bins, zones)
78+
79+
print(f"Verifying Labware Presence for {sensor}.")
8180
labware_expected = labware != "empty"
82-
result = labware_expected == bool(diff)
81+
lbw_detected = await stacker.labware_detected(axis, direction)
82+
result = labware_expected == bool(lbw_detected)
83+
8384
report(
8485
section,
8586
f"tof-{sensor.name}-histogram-{labware}",
@@ -105,15 +106,21 @@ async def run(stacker: FlexStacker, report: CSVReport, section: str) -> None:
105106
ui.get_user_ready("Make sure there is no labware on the stacker gripper position")
106107
await stacker.home_axis(StackerAxis.X, Direction.RETRACT)
107108
await test_tof_sensors_labware_detection(
108-
stacker, report, section, TOFSensor.X, "empty"
109+
stacker, report, section, TOFSensor.X, "empty", StackerAxis.X, Direction.RETRACT
109110
)
110111

111112
print("Test that we detect tiprack on the X home position")
112113
await stacker.home_axis(StackerAxis.X, Direction.EXTEND)
113114
ui.get_user_ready("Add 1 tiprack to the stacker X")
114115
await stacker.home_axis(StackerAxis.X, Direction.RETRACT)
115116
await test_tof_sensors_labware_detection(
116-
stacker, report, section, TOFSensor.X, "tiprack"
117+
stacker,
118+
report,
119+
section,
120+
TOFSensor.X,
121+
"tiprack",
122+
StackerAxis.X,
123+
Direction.RETRACT,
117124
)
118125
await stacker.home_axis(StackerAxis.X, Direction.EXTEND)
119126

@@ -123,12 +130,12 @@ async def run(stacker: FlexStacker, report: CSVReport, section: str) -> None:
123130
)
124131
await stacker.close_latch()
125132
await test_tof_sensors_labware_detection(
126-
stacker, report, section, TOFSensor.Z, "empty"
133+
stacker, report, section, TOFSensor.Z, "empty", StackerAxis.Z
127134
)
128135

129136
print("Test that we detect tiprack on the Z")
130137
ui.get_user_ready("Add 1 tiprack to the stacker Z and close the hopper door")
131138
await test_tof_sensors_labware_detection(
132-
stacker, report, section, TOFSensor.Z, "tiprack"
139+
stacker, report, section, TOFSensor.Z, "tiprack", StackerAxis.Z
133140
)
134141
ui.get_user_ready("Please remove all labware from the stacker.")

hardware-testing/hardware_testing/modules/flex_stacker_qc/test_x_axis_basic.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,26 +55,12 @@ async def test_platform_sensors_for_direction(
5555
)
5656

5757

58-
async def platform_is_removed(stacker: FlexStacker) -> bool:
59-
"""Check if the platform is removed from the carrier."""
60-
plus_side = await stacker._driver.get_platform_sensor(Direction.EXTEND)
61-
minus_side = await stacker._driver.get_platform_sensor(Direction.RETRACT)
62-
return not plus_side and not minus_side
63-
64-
6558
async def run(stacker: FlexStacker, report: CSVReport, section: str) -> None:
6659
"""Run."""
67-
if not stacker.is_simulated and not await platform_is_removed(stacker):
68-
print("FAILURE - Cannot start tests with platform on the carrier")
69-
return
70-
7160
await test_limit_switches_per_direction(
7261
stacker, StackerAxis.X, Direction.EXTEND, report, section
7362
)
7463

75-
if not stacker.is_simulated:
76-
ui.get_user_ready("Place the platform on the X carrier")
77-
7864
await test_platform_sensors_for_direction(
7965
stacker, Direction.EXTEND, report, section
8066
)

0 commit comments

Comments
 (0)