Skip to content

Commit a0087ec

Browse files
committed
store
1 parent 5e024a0 commit a0087ec

File tree

1 file changed

+131
-21
lines changed
  • hardware-testing/hardware_testing/production_qc/ninety_six_assembly_qc_ot3

1 file changed

+131
-21
lines changed

hardware-testing/hardware_testing/production_qc/ninety_six_assembly_qc_ot3/test_pressure.py

Lines changed: 131 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,58 @@
11
"""Test Pressure."""
22
from asyncio import sleep
33
from typing import List, Union, Literal
4+
from hardware_testing.drivers.sealed_pressure_fixture import SerialDriver as SealedPressureDriver
5+
from hardware_testing.opentrons_api import helpers_ot3
46

57
from opentrons_hardware.firmware_bindings.constants import SensorId
68

79
from opentrons.hardware_control.ot3api import OT3API
810
from opentrons.hardware_control.backends.ot3utils import sensor_id_for_instrument
911
from opentrons.hardware_control.types import InstrumentProbeType
1012

13+
from opentrons.hardware_control.motion_utilities import target_position_from_relative
14+
1115
from hardware_testing.data import ui
1216
from hardware_testing.opentrons_api import helpers_ot3
13-
from hardware_testing.opentrons_api.types import OT3Mount
17+
from hardware_testing.opentrons_api.types import OT3Mount, Point, Axis
1418
from hardware_testing.data.csv_report import (
1519
CSVReport,
1620
CSVResult,
1721
CSVLine,
1822
CSVLineRepeating,
1923
)
2024

25+
USE_SEALED_FIXTURE = False
26+
USE_SEALED_BLOCK = True
27+
PRIMARY_SEALED_PRESSURE_FIXTURE_POS = Point(362.68, 148.83, 49.4) if USE_SEALED_BLOCK else Point(362.68, 148.83, 44.4) # attached tip
28+
SECOND_SEALED_PRESSURE_FIXTURE_POS = Point(264.71, 212.81, 49.4) if USE_SEALED_BLOCK else Point(264.71, 212.81, 44.4) # attached tip
29+
SET_PRESSURE_TARGET = 100 # read air pressure when the force pressure value is over 100
30+
REACHED_PRESSURE = 0
31+
2132
SECONDS_BETWEEN_READINGS = 0.25
2233
NUM_PRESSURE_READINGS = 10
2334
TIP_VOLUME = 50
2435
ASPIRATE_VOLUME = 2
2536
PRESSURE_READINGS = ["open-pa", "sealed-pa", "aspirate-pa", "dispense-pa"]
2637

38+
SLOT_FOR_PICK_UP_TIP = 5
39+
TIP_RACK_FOR_PICK_UP_TIP = f"opentrons_flex_96_tiprack_{TIP_VOLUME}ul"
40+
A1_OFFSET = Point(x=9 * 11, y=-9 * 7)
41+
H12_OFFSET = Point(x=-9*11, y=9*7)
42+
OFFSET_FOR_1_WELL_LABWARE = Point(x=9 * -11 * 0.5, y=9 * 7 * 0.5)
43+
2744
THRESHOLDS_1000 = {
2845
"open-pa": (
29-
0,
30-
20,
46+
-25,
47+
25,
3148
),
3249
"sealed-pa": (
33-
5,
34-
50,
50+
-30,
51+
30,
3552
),
3653
"aspirate-pa": (
37-
-900,
38-
-500,
54+
-750,
55+
-400,
3956
),
4057
"dispense-pa": (
4158
2500,
@@ -62,8 +79,8 @@
6279
),
6380
}
6481

65-
PROBE_POSITIONS = [InstrumentProbeType.PRIMARY, InstrumentProbeType.SECONDARY]
6682

83+
PROBE_POSITIONS = [InstrumentProbeType.PRIMARY, InstrumentProbeType.SECONDARY]
6784

6885
def _get_test_tag(probe: InstrumentProbeType, reading: str) -> str:
6986
assert reading in PRESSURE_READINGS, f"{reading} not in PRESSURE_READINGS"
@@ -76,7 +93,10 @@ def build_csv_lines() -> List[Union[CSVLine, CSVLineRepeating]]:
7693
for p in PROBE_POSITIONS:
7794
for r in PRESSURE_READINGS:
7895
tag = _get_test_tag(p, r)
79-
lines.append(CSVLine(tag, [float, CSVResult]))
96+
if r == "sealed-pa":
97+
lines.append(CSVLine(tag, [float, CSVResult, float]))
98+
else:
99+
lines.append(CSVLine(tag, [float, CSVResult]))
80100
return lines
81101

82102

@@ -104,9 +124,7 @@ async def _read_from_sensor(
104124
return sum(readings) / num_readings
105125

106126

107-
def check_value(
108-
test_value: float, test_name: str, pipette: Literal[1000, 200]
109-
) -> CSVResult:
127+
def check_value(test_value: float, test_name: str, pipette: Literal[1000, 200]) -> CSVResult:
110128
"""Determine if value is within pass limits."""
111129
if pipette == 1000:
112130
THRESHOLDS = THRESHOLDS_1000
@@ -119,18 +137,77 @@ def check_value(
119137
return CSVResult.PASS
120138
else:
121139
return CSVResult.FAIL
140+
141+
async def calibrate_to_pressue_fixture(api: OT3API, sensor:SealedPressureDriver, fixture_pos:Point):
142+
"""move to suitable height for readding air pressure"""
143+
global REACHED_PRESSURE
144+
await api.move_to(OT3Mount.LEFT, fixture_pos)
145+
debug_target = input(f"Setting target pressure (default: {SET_PRESSURE_TARGET}g): ")
146+
if debug_target.strip() == "":
147+
debug_target = f"{SET_PRESSURE_TARGET}"
148+
while True:
149+
force_pressure = sensor.get_pressure()
150+
# step = -0.06 if abs(float(force_pressure)) > 0.1 else -0.1
151+
step = -0.06
152+
print("Force pressure is: ", force_pressure)
153+
if force_pressure < float(debug_target.strip()):
154+
await api.move_rel(OT3Mount.LEFT, Point(x=0, y=0, z=step))
155+
await sleep(3)
156+
else:
157+
REACHED_PRESSURE = sensor.get_pressure()
158+
ui.print_info(f"Reaching force is {REACHED_PRESSURE}, exit calibration.")
159+
break
122160

123161

124-
async def run(
125-
api: OT3API, report: CSVReport, section: str, pipette: Literal[200, 1000]
162+
async def _partial_pick_up_z_motion(
163+
api: OT3API, current: float, distance: float, speed: float
126164
) -> None:
165+
async with api._backend.motor_current(run_currents={Axis.Z_L: current}):
166+
target_down = target_position_from_relative(
167+
OT3Mount.LEFT, Point(z=-distance), api._current_position
168+
)
169+
await api._move(target_down, speed=speed)
170+
target_up = target_position_from_relative(
171+
OT3Mount.LEFT, Point(z=distance), api._current_position
172+
)
173+
await api._move(target_up)
174+
await api._update_position_estimation([Axis.Z_L])
175+
176+
177+
async def _partial_pick_up(api: OT3API, position: Point, current: float) -> None:
178+
await helpers_ot3.move_to_arched_ot3(
179+
api,
180+
OT3Mount.LEFT,
181+
position,
182+
safe_height=position.z + 10,
183+
)
184+
await _partial_pick_up_z_motion(api, current=current, distance=12, speed=3) # change distance and speed, in case collision detected error
185+
await api.add_tip(OT3Mount.LEFT, helpers_ot3.get_default_tip_length(TIP_VOLUME))
186+
await api.prepare_for_aspirate(OT3Mount.LEFT)
187+
await api.home_z(OT3Mount.LEFT)
188+
189+
async def run(api: OT3API, report: CSVReport, section: str, pipette: Literal[200, 1000]) -> None:
127190
"""Run."""
128191
await api.home_z(OT3Mount.LEFT)
129192
slot_5 = helpers_ot3.get_slot_calibration_square_position_ot3(5)
130193
home_pos = await api.gantry_position(OT3Mount.LEFT)
131194
await api.move_to(OT3Mount.LEFT, slot_5._replace(z=home_pos.z))
195+
if USE_SEALED_FIXTURE:
196+
# init driver
197+
pressure_sensor = SealedPressureDriver()
198+
pressure_sensor.init(9600)
199+
200+
# move to slot
201+
ui.get_user_ready(f"Place tip tack 50ul at slot - {SLOT_FOR_PICK_UP_TIP}")
202+
#await api.add_tip(OT3Mount.LEFT, helpers_ot3.get_default_tip_length(TIP_VOLUME))
132203

204+
tip_rack_pos = helpers_ot3.get_theoretical_a1_position(SLOT_FOR_PICK_UP_TIP, TIP_RACK_FOR_PICK_UP_TIP)
205+
await helpers_ot3.move_to_arched_ot3(api, OT3Mount.LEFT, tip_rack_pos + Point(z=30))
206+
await helpers_ot3.jog_mount_ot3(api, OT3Mount.LEFT)
207+
tip_rack_actual_pos = await api.gantry_position(OT3Mount.LEFT)
208+
133209
for probe in PROBE_POSITIONS:
210+
await helpers_ot3.move_to_arched_ot3(api, OT3Mount.LEFT, tip_rack_pos + Point(z=50))
134211
sensor_id = sensor_id_for_instrument(probe)
135212
ui.print_header(f"Sensor: {probe}")
136213

@@ -148,11 +225,33 @@ async def run(
148225

149226
# SEALED-Pa
150227
sealed_pa = 0.0
151-
api.add_tip(OT3Mount.LEFT, helpers_ot3.get_default_tip_length(TIP_VOLUME))
152-
await api.prepare_for_aspirate(OT3Mount.LEFT)
153228
if not api.is_simulator:
154-
ui.get_user_ready(f"attach {TIP_VOLUME} uL TIP to {probe.name} sensor")
155-
ui.get_user_ready("SEAL tip using your FINGER")
229+
230+
# ui.get_user_ready(f"attach {TIP_VOLUME} uL TIP to {probe.name} sensor")
231+
if probe == InstrumentProbeType.PRIMARY:
232+
offset_pos = A1_OFFSET
233+
fixture_pos = PRIMARY_SEALED_PRESSURE_FIXTURE_POS
234+
elif probe == InstrumentProbeType.SECONDARY:
235+
offset_pos = H12_OFFSET
236+
fixture_pos = SECOND_SEALED_PRESSURE_FIXTURE_POS
237+
else:
238+
raise NameError("offset position miss")
239+
240+
tip_pos = tip_rack_actual_pos + offset_pos
241+
print(f"Tip pos: {tip_pos}")
242+
ui.get_user_ready("Pick up tip")
243+
await _partial_pick_up(api, tip_pos, current=0.1)
244+
await api.prepare_for_aspirate(OT3Mount.LEFT)
245+
if not (USE_SEALED_FIXTURE or USE_SEALED_BLOCK):
246+
ui.get_user_ready("SEAL tip using your FINGER")
247+
else:
248+
await helpers_ot3.move_to_arched_ot3(api, OT3Mount.LEFT, fixture_pos._replace(z=fixture_pos.z + 50))
249+
ui.get_user_ready("Ready for moving to sealed fixture")
250+
if USE_SEALED_FIXTURE:
251+
await calibrate_to_pressue_fixture(api, pressure_sensor, fixture_pos)
252+
else:
253+
await helpers_ot3.move_to_arched_ot3(api, OT3Mount.LEFT, fixture_pos)
254+
156255
try:
157256
sealed_pa = await _read_from_sensor(
158257
api, sensor_id, NUM_PRESSURE_READINGS
@@ -162,7 +261,7 @@ async def run(
162261
break
163262
print(f"sealed-pa: {sealed_pa}")
164263
sealed_result = check_value(sealed_pa, "sealed-pa", pipette)
165-
report(section, _get_test_tag(probe, "sealed-pa"), [sealed_pa, sealed_result])
264+
report(section, _get_test_tag(probe, "sealed-pa"), [sealed_pa, sealed_result, REACHED_PRESSURE])
166265

167266
# ASPIRATE-Pa
168267
aspirate_pa = 0.0
@@ -197,7 +296,18 @@ async def run(
197296
report(
198297
section, _get_test_tag(probe, "dispense-pa"), [dispense_pa, dispense_result]
199298
)
200-
299+
if USE_SEALED_FIXTURE or USE_SEALED_BLOCK:
300+
await helpers_ot3.move_to_arched_ot3(api, OT3Mount.LEFT, fixture_pos._replace(z=fixture_pos.z + 50))
201301
if not api.is_simulator:
202302
ui.get_user_ready("REMOVE tip")
203-
api.remove_tip(OT3Mount.LEFT)
303+
304+
trash_nominal = helpers_ot3.get_slot_calibration_square_position_ot3(12) + Point(z=40)
305+
# center the 96ch of the 1-well labware
306+
trash_nominal += OFFSET_FOR_1_WELL_LABWARE
307+
await helpers_ot3.move_to_arched_ot3(api, OT3Mount.LEFT, trash_nominal + Point(z=20))
308+
await api.move_to(OT3Mount.LEFT, trash_nominal)
309+
await api.drop_tip(OT3Mount.LEFT)
310+
await api.remove_tip(OT3Mount.LEFT)
311+
await api.home()
312+
313+

0 commit comments

Comments
 (0)