Skip to content

Commit 8720acd

Browse files
authored
fix(api): Correctly update engine state during tracking aspirate/dispense (#20195)
# Overview We were not appending the aspirate/dispense result to the move result. This means that the engine's state was not getting updated with the current labware, so the *_while_tracking commands were not updating the pipettes current location. This means that if you did an action in labware_1, then did a aspirate/dispense_while_tracking in labware_2 and then moved back to labware_1 the engine would think that the pipettes current location was still in labware 1 and it would calculate the safe Z movement and properly use waypoints to travel back to labware_1.
1 parent 0e5bc49 commit 8720acd

File tree

4 files changed

+84
-39
lines changed

4 files changed

+84
-39
lines changed

api/src/opentrons/protocol_engine/commands/aspirate_while_tracking.py

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,17 @@ async def execute(self, params: AspirateWhileTrackingParams) -> _ExecuteReturn:
147147
model_utils=self._model_utils,
148148
movement_delay=params.movement_delay,
149149
)
150+
state_update.append(aspirate_result.state_update)
150151
if isinstance(aspirate_result, DefinedErrorData):
152+
state_update.set_liquid_operated(
153+
labware_id=params.labwareId,
154+
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
155+
params.labwareId,
156+
params.wellName,
157+
params.pipetteId,
158+
),
159+
volume_added=CLEAR,
160+
)
151161
if isinstance(aspirate_result.public, OverpressureError):
152162
return DefinedErrorData(
153163
public=OverpressureError(
@@ -156,15 +166,7 @@ async def execute(self, params: AspirateWhileTrackingParams) -> _ExecuteReturn:
156166
wrappedErrors=aspirate_result.public.wrappedErrors,
157167
errorInfo=aspirate_result.public.errorInfo,
158168
),
159-
state_update=aspirate_result.state_update.set_liquid_operated(
160-
labware_id=params.labwareId,
161-
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
162-
params.labwareId,
163-
params.wellName,
164-
params.pipetteId,
165-
),
166-
volume_added=CLEAR,
167-
),
169+
state_update=state_update,
168170
state_update_if_false_positive=aspirate_result.state_update_if_false_positive,
169171
)
170172
elif isinstance(aspirate_result.public, StallOrCollisionError):
@@ -175,15 +177,7 @@ async def execute(self, params: AspirateWhileTrackingParams) -> _ExecuteReturn:
175177
wrappedErrors=aspirate_result.public.wrappedErrors,
176178
errorInfo=aspirate_result.public.errorInfo,
177179
),
178-
state_update=aspirate_result.state_update.set_liquid_operated(
179-
labware_id=params.labwareId,
180-
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
181-
params.labwareId,
182-
params.wellName,
183-
params.pipetteId,
184-
),
185-
volume_added=CLEAR,
186-
),
180+
state_update=state_update,
187181
state_update_if_false_positive=aspirate_result.state_update_if_false_positive,
188182
)
189183

@@ -200,7 +194,7 @@ async def execute(self, params: AspirateWhileTrackingParams) -> _ExecuteReturn:
200194
volume=aspirate_result.public.volume,
201195
position=result_deck_point,
202196
),
203-
state_update=aspirate_result.state_update.set_liquid_operated(
197+
state_update=state_update.set_liquid_operated(
204198
labware_id=params.labwareId,
205199
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
206200
params.labwareId,

api/src/opentrons/protocol_engine/commands/dispense_while_tracking.py

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,17 @@ async def execute(self, params: DispenseWhileTrackingParams) -> _ExecuteReturn:
143143
model_utils=self._model_utils,
144144
movement_delay=params.movement_delay,
145145
)
146-
146+
state_update.append(dispense_result.state_update)
147147
if isinstance(dispense_result, DefinedErrorData):
148+
state_update.set_liquid_operated(
149+
labware_id=params.labwareId,
150+
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
151+
params.labwareId,
152+
params.wellName,
153+
params.pipetteId,
154+
),
155+
volume_added=CLEAR,
156+
)
148157
if isinstance(dispense_result.public, OverpressureError):
149158
return DefinedErrorData(
150159
public=OverpressureError(
@@ -153,15 +162,7 @@ async def execute(self, params: DispenseWhileTrackingParams) -> _ExecuteReturn:
153162
wrappedErrors=dispense_result.public.wrappedErrors,
154163
errorInfo=dispense_result.public.errorInfo,
155164
),
156-
state_update=dispense_result.state_update.set_liquid_operated(
157-
labware_id=params.labwareId,
158-
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
159-
params.labwareId,
160-
params.wellName,
161-
params.pipetteId,
162-
),
163-
volume_added=CLEAR,
164-
),
165+
state_update=state_update,
165166
state_update_if_false_positive=dispense_result.state_update_if_false_positive,
166167
)
167168
elif isinstance(dispense_result.public, StallOrCollisionError):
@@ -172,15 +173,7 @@ async def execute(self, params: DispenseWhileTrackingParams) -> _ExecuteReturn:
172173
wrappedErrors=dispense_result.public.wrappedErrors,
173174
errorInfo=dispense_result.public.errorInfo,
174175
),
175-
state_update=dispense_result.state_update.set_liquid_operated(
176-
labware_id=params.labwareId,
177-
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
178-
params.labwareId,
179-
params.wellName,
180-
params.pipetteId,
181-
),
182-
volume_added=CLEAR,
183-
),
176+
state_update=state_update,
184177
state_update_if_false_positive=dispense_result.state_update_if_false_positive,
185178
)
186179

@@ -197,7 +190,7 @@ async def execute(self, params: DispenseWhileTrackingParams) -> _ExecuteReturn:
197190
volume=dispense_result.public.volume,
198191
position=result_deck_point,
199192
),
200-
state_update=dispense_result.state_update.set_liquid_operated(
193+
state_update=state_update.set_liquid_operated(
201194
labware_id=params.labwareId,
202195
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
203196
params.labwareId,

api/tests/opentrons/protocol_engine/commands/test_aspirate_while_tracking.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
WellOrigin,
3737
WellOffset,
3838
DeckPoint,
39+
LabwareWellId,
3940
)
4041
from opentrons.protocol_engine.state import update_types
4142

@@ -195,6 +196,13 @@ async def test_aspirate_while_tracking_implementation(
195196
pipette_id="pipette-id-abc",
196197
fluid=AspiratedFluid(kind=FluidKind.LIQUID, volume=123),
197198
),
199+
pipette_location=update_types.PipetteLocationUpdate(
200+
pipette_id="pipette-id-abc",
201+
new_location=LabwareWellId(
202+
labware_id="funky-labware", well_name="funky-well"
203+
),
204+
new_deck_point=DeckPoint(x=4, y=5, z=6),
205+
),
198206
),
199207
)
200208
else:
@@ -213,6 +221,13 @@ async def test_aspirate_while_tracking_implementation(
213221
well_names=["A3", "A4"],
214222
volume_added=-246.0,
215223
),
224+
pipette_location=update_types.PipetteLocationUpdate(
225+
pipette_id="pipette-id-abc",
226+
new_location=LabwareWellId(
227+
labware_id="funky-labware", well_name="funky-well"
228+
),
229+
new_deck_point=DeckPoint(x=4, y=5, z=6),
230+
),
216231
),
217232
)
218233

@@ -465,6 +480,13 @@ async def test_overpressure_error(
465480
pipette_aspirated_fluid=update_types.PipetteUnknownFluidUpdate(
466481
pipette_id="pipette-id-abc"
467482
),
483+
pipette_location=update_types.PipetteLocationUpdate(
484+
pipette_id="pipette-id-abc",
485+
new_location=LabwareWellId(
486+
labware_id="funky-labware", well_name="funky-well"
487+
),
488+
new_deck_point=DeckPoint(x=4, y=5, z=6),
489+
),
468490
),
469491
)
470492
else:
@@ -484,5 +506,12 @@ async def test_overpressure_error(
484506
well_names=["A3", "A4"],
485507
volume_added=update_types.CLEAR,
486508
),
509+
pipette_location=update_types.PipetteLocationUpdate(
510+
pipette_id="pipette-id-abc",
511+
new_location=LabwareWellId(
512+
labware_id="funky-labware", well_name="funky-well"
513+
),
514+
new_deck_point=DeckPoint(x=4, y=5, z=6),
515+
),
487516
),
488517
)

api/tests/opentrons/protocol_engine/commands/test_dispense_while_tracking.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
WellOrigin,
3232
WellOffset,
3333
DeckPoint,
34+
LabwareWellId,
3435
)
3536
from opentrons.protocol_engine.state import update_types
3637

@@ -191,6 +192,13 @@ async def test_dispense_while_tracking_implementation(
191192
ready_to_aspirate=update_types.PipetteAspirateReadyUpdate(
192193
pipette_id="pipette-id-abc", ready_to_aspirate=False
193194
),
195+
pipette_location=update_types.PipetteLocationUpdate(
196+
pipette_id="pipette-id-abc",
197+
new_location=LabwareWellId(
198+
labware_id="funky-labware", well_name="funky-well"
199+
),
200+
new_deck_point=DeckPoint(x=4, y=5, z=6),
201+
),
194202
),
195203
)
196204
else:
@@ -212,6 +220,13 @@ async def test_dispense_while_tracking_implementation(
212220
well_names=["A3", "A4"],
213221
volume_added=84.0,
214222
),
223+
pipette_location=update_types.PipetteLocationUpdate(
224+
pipette_id="pipette-id-abc",
225+
new_location=LabwareWellId(
226+
labware_id="funky-labware", well_name="funky-well"
227+
),
228+
new_deck_point=DeckPoint(x=4, y=5, z=6),
229+
),
215230
),
216231
)
217232

@@ -354,6 +369,13 @@ async def test_overpressure_error(
354369
ready_to_aspirate=update_types.PipetteAspirateReadyUpdate(
355370
pipette_id="pipette-id", ready_to_aspirate=False
356371
),
372+
pipette_location=update_types.PipetteLocationUpdate(
373+
pipette_id="pipette-id",
374+
new_location=LabwareWellId(
375+
labware_id="funky-labware", well_name="funky-well"
376+
),
377+
new_deck_point=DeckPoint(x=4, y=5, z=6),
378+
),
357379
),
358380
)
359381
else:
@@ -376,6 +398,13 @@ async def test_overpressure_error(
376398
ready_to_aspirate=update_types.PipetteAspirateReadyUpdate(
377399
pipette_id="pipette-id", ready_to_aspirate=False
378400
),
401+
pipette_location=update_types.PipetteLocationUpdate(
402+
pipette_id="pipette-id",
403+
new_location=LabwareWellId(
404+
labware_id="funky-labware", well_name="funky-well"
405+
),
406+
new_deck_point=DeckPoint(x=4, y=5, z=6),
407+
),
379408
),
380409
state_update_if_false_positive=update_types.StateUpdate(),
381410
)

0 commit comments

Comments
 (0)