Skip to content

Commit 672cdd7

Browse files
committed
debug
1 parent 9303462 commit 672cdd7

File tree

8 files changed

+4427
-5
lines changed

8 files changed

+4427
-5
lines changed

api/src/opentrons/hardware_control/ot3api.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1892,6 +1892,7 @@ async def tip_pickup_moves(
18921892
# the volume chamber and the drop-tip sleeve on p1000.
18931893
# This extra shake ensures those tips are removed
18941894
for rel_point, speed in spec.shake_off_moves:
1895+
18951896
await self.move_rel(realmount, rel_point, speed=speed)
18961897

18971898
if isinstance(self._backend, OT3Simulator):
@@ -1900,9 +1901,62 @@ async def tip_pickup_moves(
19001901
# fixme: really only need this during labware position check so user
19011902
# can verify if a tip is properly attached
19021903
if spec.ending_z_retract_distance:
1904+
print("spec.ending_z_retract_distance",spec.ending_z_retract_distance)
19031905
await self.move_rel(
19041906
realmount, top_types.Point(z=spec.ending_z_retract_distance)
19051907
)
1908+
1909+
async def tip_pickup_moves_96(
1910+
self,
1911+
mount: Union[top_types.Mount, OT3Mount],
1912+
presses: Optional[int] = None,
1913+
increment: Optional[float] = None,
1914+
) -> None:
1915+
"""This is a slightly more barebones variation of pick_up_tip. This is only the motor routine
1916+
directly involved in tip pickup, and leaves any state updates and plunger moves to the caller.
1917+
"""
1918+
realmount = OT3Mount.from_mount(mount)
1919+
instrument = self._pipette_handler.get_pipette(realmount)
1920+
1921+
if (
1922+
self.gantry_load == GantryLoad.HIGH_THROUGHPUT
1923+
and instrument.nozzle_manager.current_configuration.configuration
1924+
== top_types.NozzleConfigurationType.FULL
1925+
):
1926+
spec = self._pipette_handler.plan_ht_pick_up_tip(
1927+
instrument.nozzle_manager.current_configuration.tip_count
1928+
)
1929+
if spec.z_distance_to_tiprack:
1930+
await self.move_rel(
1931+
realmount, top_types.Point(z=spec.z_distance_to_tiprack)
1932+
)
1933+
await self._tip_motor_action(realmount, spec.tip_action_moves)
1934+
else:
1935+
spec = self._pipette_handler.plan_lt_pick_up_tip(
1936+
realmount,
1937+
instrument.nozzle_manager.current_configuration.tip_count,
1938+
presses,
1939+
increment,
1940+
)
1941+
await self._force_pick_up_tip(realmount, spec)
1942+
1943+
# neighboring tips tend to get stuck in the space between
1944+
# the volume chamber and the drop-tip sleeve on p1000.
1945+
# This extra shake ensures those tips are removed
1946+
for rel_point, speed in spec.shake_off_moves:
1947+
await self.move_rel(realmount, rel_point, speed=speed)
1948+
1949+
if isinstance(self._backend, OT3Simulator):
1950+
self._backend._update_tip_state(realmount, True)
1951+
1952+
# fixme: really only need this during labware position check so user
1953+
# can verify if a tip is properly attached
1954+
print("spec.ending_z_retract_distance",spec.ending_z_retract_distance)
1955+
# if spec.ending_z_retract_distance:
1956+
# print("spec.ending_z_retract_distance",spec.ending_z_retract_distance)
1957+
# await self.move_rel(
1958+
# realmount, top_types.Point(z=spec.ending_z_retract_distance)
1959+
# )
19061960

19071961
async def _move_to_plunger_bottom(
19081962
self,
@@ -2303,6 +2357,31 @@ def add_tip_to_instr() -> None:
23032357

23042358
if prep_after:
23052359
await self.prepare_for_aspirate(realmount)
2360+
2361+
async def pick_up_tip_96_fixture(
2362+
self,
2363+
mount: Union[top_types.Mount, OT3Mount],
2364+
tip_length: float,
2365+
presses: Optional[int] = None,
2366+
increment: Optional[float] = None,
2367+
prep_after: bool = True,
2368+
) -> None:
2369+
"""Pick up tip from current location."""
2370+
realmount = OT3Mount.from_mount(mount)
2371+
instrument = self._pipette_handler.get_pipette(realmount)
2372+
2373+
def add_tip_to_instr() -> None:
2374+
instrument.add_tip(tip_length=tip_length)
2375+
instrument.set_current_volume(0)
2376+
2377+
await self._move_to_plunger_bottom(realmount, rate=1.0)
2378+
2379+
await self.tip_pickup_moves_96(mount, presses, increment)
2380+
2381+
add_tip_to_instr()
2382+
2383+
if prep_after:
2384+
await self.prepare_for_aspirate(realmount)
23062385

23072386
def set_current_tiprack_diameter(
23082387
self, mount: Union[top_types.Mount, OT3Mount], tiprack_diameter: float

hardware-testing/hardware_testing/drivers/pressure_fixture.py

Lines changed: 109 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@
1515

1616
FIXTURE_REBOOT_TIME = 2
1717
FIXTURE_NUM_CHANNELS: Final[int] = 8
18+
FIXTURE_NUM_CHANNELS_96: Final[int] = 96
1819
FIXTURE_BAUD_RATE: Final[int] = 115200
1920
FIXTURE_VERSION_REQUIRED = "1.0.0"
21+
FIXTURE_VERSION_REQUIRED2 = "0.0.1"
2022

2123
FIXTURE_CMD_TERMINATOR = "\r\n"
2224
FIXTURE_CMD_GET_VERSION = "VERSION"
2325
FIXTURE_CMD_GET_ALL_PRESSURE = "GETPRESSURE:15"
26+
FIXTURE_CMD_GET_ALL_PRESSURE_96 = "GETPRESSURE:255"
2427

2528
LOCATION_A1_LEFT = Point(x=14.4, y=74.5, z=71.2)
2629
LOCATION_A1_RIGHT = LOCATION_A1_LEFT._replace(x=128 - 14.4)
@@ -40,6 +43,11 @@ def connect(self) -> None:
4043
"""Connect to the Mark10 Force Gauge."""
4144
...
4245

46+
@abstractmethod
47+
def connect_96(self) -> None:
48+
"""Connect to the Mark10 Force Gauge."""
49+
...
50+
4351
@abstractmethod
4452
def disconnect(self) -> None:
4553
"""Disconnect from the Mark10 Force Gauge."""
@@ -54,6 +62,11 @@ def firmware_version(self) -> str:
5462
def read_all_pressure_channel(self) -> List[float]:
5563
"""Read all pressure channels on fixture in Pascals."""
5664
...
65+
@abstractmethod
66+
def read_all_pressure_channel_96(self) -> List[float]:
67+
"""Read all pressure channels on fixture in Pascals."""
68+
...
69+
5770

5871
def position_in_slot(self, side: Literal["left", "right"] = "left") -> Point:
5972
"""Position in slot."""
@@ -101,6 +114,10 @@ def read_all_pressure_channel(self) -> List[float]:
101114
"""Read Pressure for all channels."""
102115
pressure = [random.uniform(2.5, 2) for _ in range(FIXTURE_NUM_CHANNELS)]
103116
return pressure
117+
def read_all_pressure_channel_96(self) -> List[float]:
118+
"""Read Pressure for all channels."""
119+
pressure = [random.uniform(2.5, 2) for _ in range(FIXTURE_NUM_CHANNELS_96)]
120+
return pressure
104121

105122

106123
def connect_to_fixture(
@@ -136,6 +153,38 @@ def connect_to_fixture(
136153
ui.print_info("no fixture found returning simulator")
137154
return SimPressureFixture()
138155

156+
def connect_to_fixture96(
157+
simulate: bool, side: str = "left", autosearch: bool = True
158+
) -> PressureFixtureBase:
159+
"""Try to find and return an presure fixture, if not found return a simulator."""
160+
ui.print_title("Connecting to presure fixture")
161+
if not simulate:
162+
if not autosearch:
163+
port = list_ports_and_select(device_name="Pressure fixture")
164+
fixture = PressureFixture.create(port=port, slot_side=side)
165+
fixture.connect_96()
166+
ui.print_info(f"Found fixture on port {port}")
167+
return fixture
168+
else:
169+
ports = comports()
170+
assert ports
171+
for _port in ports:
172+
port = _port.device # type: ignore[attr-defined]
173+
try:
174+
ui.print_info(
175+
f"Trying to connect to Pressure fixture on port {port}"
176+
)
177+
fixture = PressureFixture.create(port=port, slot_side=side)
178+
fixture.connect_96()
179+
ui.print_info(f"Found fixture on port {port}")
180+
return fixture
181+
except: # noqa: E722
182+
pass
183+
use_sim = ui.get_user_answer("No pressure sensor found, use simulator?")
184+
if not use_sim:
185+
raise SerialException("No sensor found")
186+
ui.print_info("no fixture found returning simulator")
187+
return SimPressureFixture()
139188

140189
class PressureFixture(PressureFixtureBase):
141190
"""OT3 Pressure Fixture Driver."""
@@ -162,9 +211,22 @@ def connect(self) -> None:
162211
# NOTE: device might take a few seconds to boot up
163212
sleep(FIXTURE_REBOOT_TIME)
164213
fw_version = self.firmware_version()
214+
print(f"unexpected pressure-fixture version: {fw_version}")
165215
assert (
166216
fw_version == FIXTURE_VERSION_REQUIRED
167217
), f"unexpected pressure-fixture version: {fw_version}"
218+
219+
def connect_96(self) -> None:
220+
"""Connect."""
221+
self._port.open()
222+
self._port.flushInput()
223+
# NOTE: device might take a few seconds to boot up
224+
sleep(FIXTURE_REBOOT_TIME)
225+
fw_version = self.firmware_version()
226+
print(f"unexpected pressure-fixture version: {fw_version}")
227+
assert (
228+
fw_version == FIXTURE_VERSION_REQUIRED2
229+
), f"unexpected pressure-fixture version: {fw_version}"
168230

169231
def disconnect(self) -> None:
170232
"""Disconnect."""
@@ -190,14 +252,57 @@ def read_all_pressure_channel(self) -> List[float]:
190252
if self._slot_side == "left":
191253
data.reverse() # reverse order, so pipette channel 1 is at index 0
192254
return data
255+
256+
def read_all_pressure_channel_96(self) -> List[float]:
257+
"""Reads from all the channels from the fixture."""
258+
cmd_str = f"{FIXTURE_CMD_GET_ALL_PRESSURE_96}{FIXTURE_CMD_TERMINATOR}"
259+
self._port.write(cmd_str.encode("utf-8"))
260+
response = self._port.readlines()#.decode("utf-8")
261+
datalist = []
262+
for res in response:
263+
res_list = res.decode("utf-8").split(",")[:-1] # ignore the last comma
264+
data_str = [d.split("=")[-1].strip() for d in res_list] # remove PRESSURE=
265+
# for i in range(len(data_str)): # replace all -0.00 with 0.00
266+
# if data_str[i] == "-0.00":
267+
# data_str[i] = "0.00"
268+
data = [float(d) for d in data_str] # convert to float
269+
data.reverse
270+
#print("yuans",data)
271+
# datalist.extend(data)
272+
datalist = data + datalist
273+
# if self._slot_side == "left":
274+
# data.reverse() # reverse order, so pipette channel 1 is at index 0
275+
#print("datalist",datalist)
276+
#datalist.reverse()
277+
return datalist
278+
def print_pressure_datas(self,data_list):
279+
row_labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
280+
col_labels = list(range(1, 13))
281+
cell_width = 9
282+
283+
# 打印表头
284+
print(" " * 3 + "".join(f"{col:>{cell_width}}" for col in col_labels))
285+
286+
# 打印每一行
287+
for i in range(8):
288+
row_data = data_list[i * 12:(i + 1) * 12]
289+
row_str = f"{row_labels[i]}: "
290+
for val in row_data:
291+
try:
292+
row_str += f"{float(val):>{cell_width}.2f}"
293+
except:
294+
row_str += f"{str(val):>{cell_width}}"
295+
print(row_str)
193296

194297

195298
if __name__ == "__main__":
196-
port_name = input("type the port of the device (eg: COM1): ")
299+
port_name = list_ports_and_select(device_name="Pressure fixture")
300+
#port_name = input("type the port of the device (eg: COM1): ")
197301
fixture = PressureFixture.create(port=port_name, slot_side="left")
198-
fixture.connect()
302+
fixture.connect_96()
199303
print(f"Device firmware version: {fixture.firmware_version()}")
200304
while True:
201-
readings = fixture.read_all_pressure_channel()
202-
print(readings)
305+
readings = fixture.read_all_pressure_channel_96()
306+
print("zuihoujieguo:",readings)
307+
fixture.print_pressure_datas(readings)
203308
sleep(0.1)

hardware-testing/hardware_testing/opentrons_api/helpers_ot3.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ async def move_to_arched_ot3(
842842
abs_position: Point,
843843
speed: Optional[float] = None,
844844
safe_height: float = -100.0,
845-
) -> None:
845+
) -> Point:
846846
"""Move OT3 gantry in an arched path."""
847847
z_ax = Axis.by_mount(mount)
848848
max_z = get_endstop_position_ot3(api, mount)[z_ax]
@@ -855,6 +855,7 @@ async def move_to_arched_ot3(
855855
]
856856
for p in points:
857857
await api.move_to(mount=mount, abs_position=p, speed=speed)
858+
return points
858859

859860

860861
class SensorResponseBad(Exception):

0 commit comments

Comments
 (0)