Skip to content

Commit 446da56

Browse files
feat(app): Only follow rear tip sensor during calibration setup (#14984)
1 parent 4c89730 commit 446da56

File tree

14 files changed

+103
-29
lines changed

14 files changed

+103
-29
lines changed

api/src/opentrons/hardware_control/backends/ot3controller.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,10 +1524,10 @@ async def teardown_tip_detector(self, mount: OT3Mount) -> None:
15241524
async def get_tip_status(
15251525
self,
15261526
mount: OT3Mount,
1527-
ht_operational_sensor: Optional[InstrumentProbeType] = None,
1527+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
15281528
) -> TipStateType:
15291529
return await self.tip_presence_manager.get_tip_status(
1530-
mount, ht_operational_sensor
1530+
mount, follow_singular_sensor
15311531
)
15321532

15331533
def current_tip_state(self, mount: OT3Mount) -> Optional[bool]:

api/src/opentrons/hardware_control/backends/ot3simulator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ def subsystems(self) -> Dict[SubSystem, SubSystemState]:
783783
async def get_tip_status(
784784
self,
785785
mount: OT3Mount,
786-
ht_operational_sensor: Optional[InstrumentProbeType] = None,
786+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
787787
) -> TipStateType:
788788
return TipStateType(self._sim_tip_state[mount])
789789

api/src/opentrons/hardware_control/backends/tip_presence_manager.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,21 +116,21 @@ def current_tip_state(self, mount: OT3Mount) -> Optional[bool]:
116116
@staticmethod
117117
def _get_tip_presence(
118118
results: List[tip_types.TipNotification],
119-
ht_operational_sensor: Optional[InstrumentProbeType] = None,
119+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
120120
) -> TipStateType:
121121
"""
122-
We can use ht_operational_sensor used to specify that we only care
122+
We can use follow_singular_sensor used to specify that we only care
123123
about the status of one tip presence sensor on a high throughput
124124
pipette, and the other is allowed to be different.
125125
"""
126-
if ht_operational_sensor:
127-
target_sensor_id = sensor_id_for_instrument(ht_operational_sensor)
126+
if follow_singular_sensor:
127+
target_sensor_id = sensor_id_for_instrument(follow_singular_sensor)
128128
for r in results:
129129
if r.sensor == target_sensor_id:
130130
return TipStateType(r.presence)
131131
# raise an error if requested sensor response isn't found
132132
raise GeneralError(
133-
message=f"Requested status for sensor {ht_operational_sensor} not found."
133+
message=f"Requested status for sensor {follow_singular_sensor} not found."
134134
)
135135
# more than one sensor reported, we have to check if their states match
136136
if len(set(r.presence for r in results)) > 1:
@@ -142,11 +142,11 @@ def _get_tip_presence(
142142
async def get_tip_status(
143143
self,
144144
mount: OT3Mount,
145-
ht_operational_sensor: Optional[InstrumentProbeType] = None,
145+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
146146
) -> TipStateType:
147147
detector = self.get_detector(mount)
148148
return self._get_tip_presence(
149-
await detector.request_tip_status(), ht_operational_sensor
149+
await detector.request_tip_status(), follow_singular_sensor
150150
)
151151

152152
def get_detector(self, mount: OT3Mount) -> TipDetector:

api/src/opentrons/hardware_control/ot3api.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,7 +2072,7 @@ async def _high_throughput_check_tip(self) -> AsyncIterator[None]:
20722072
async def get_tip_presence_status(
20732073
self,
20742074
mount: Union[top_types.Mount, OT3Mount],
2075-
ht_operational_sensor: Optional[InstrumentProbeType] = None,
2075+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
20762076
) -> TipStateType:
20772077
"""
20782078
Check tip presence status. If a high throughput pipette is present,
@@ -2087,18 +2087,18 @@ async def get_tip_presence_status(
20872087
):
20882088
await stack.enter_async_context(self._high_throughput_check_tip())
20892089
result = await self._backend.get_tip_status(
2090-
real_mount, ht_operational_sensor
2090+
real_mount, follow_singular_sensor
20912091
)
20922092
return result
20932093

20942094
async def verify_tip_presence(
20952095
self,
20962096
mount: Union[top_types.Mount, OT3Mount],
20972097
expected: TipStateType,
2098-
ht_operational_sensor: Optional[InstrumentProbeType] = None,
2098+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
20992099
) -> None:
21002100
real_mount = OT3Mount.from_mount(mount)
2101-
status = await self.get_tip_presence_status(real_mount, ht_operational_sensor)
2101+
status = await self.get_tip_presence_status(real_mount, follow_singular_sensor)
21022102
if status != expected:
21032103
raise FailedTipStateCheck(expected, status.value)
21042104

api/src/opentrons/hardware_control/protocols/flex_instrument_configurer.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""Flex-specific extensions to instrument configuration."""
2-
from typing import Union
2+
from typing import Union, Optional
33
from typing_extensions import Protocol
44

55
from .types import MountArgType
@@ -9,6 +9,7 @@
99
)
1010
from opentrons.hardware_control.types import (
1111
TipStateType,
12+
InstrumentProbeType,
1213
)
1314
from opentrons.hardware_control.instruments.ot3.instrument_calibration import (
1415
PipetteOffsetSummary,
@@ -42,7 +43,10 @@ async def get_tip_presence_status(
4243
...
4344

4445
async def verify_tip_presence(
45-
self, mount: MountArgType, expected: TipStateType
46+
self,
47+
mount: MountArgType,
48+
expected: TipStateType,
49+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
4650
) -> None:
4751
"""Check tip presence status and raise if it does not match `expected`."""
4852
...

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from .pipetting_common import PipetteIdMixin
99
from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate
1010

11-
from ..types import TipPresenceStatus
11+
from ..types import TipPresenceStatus, InstrumentSensorId
1212

1313
if TYPE_CHECKING:
1414
from ..execution import TipHandler
@@ -23,6 +23,9 @@ class VerifyTipPresenceParams(PipetteIdMixin):
2323
expectedState: TipPresenceStatus = Field(
2424
..., description="The expected tip presence status on the pipette."
2525
)
26+
followSingularSensor: Optional[InstrumentSensorId] = Field(
27+
default=None, description="The sensor id to follow if the other can be ignored."
28+
)
2629

2730

2831
class VerifyTipPresenceResult(BaseModel):
@@ -47,10 +50,16 @@ async def execute(self, params: VerifyTipPresenceParams) -> VerifyTipPresenceRes
4750
"""Verify if tip presence is as expected for the requested pipette."""
4851
pipette_id = params.pipetteId
4952
expected_state = params.expectedState
53+
follow_singular_sensor = (
54+
InstrumentSensorId.to_instrument_probe_type(params.followSingularSensor)
55+
if params.followSingularSensor
56+
else None
57+
)
5058

5159
await self._tip_handler.verify_tip_presence(
5260
pipette_id=pipette_id,
5361
expected=expected_state,
62+
follow_singular_sensor=follow_singular_sensor,
5463
)
5564

5665
return VerifyTipPresenceResult()

api/src/opentrons/protocol_engine/execution/tip_handler.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing_extensions import Protocol as TypingProtocol
44

55
from opentrons.hardware_control import HardwareControlAPI
6-
from opentrons.hardware_control.types import FailedTipStateCheck
6+
from opentrons.hardware_control.types import FailedTipStateCheck, InstrumentProbeType
77
from opentrons_shared_data.errors.exceptions import (
88
CommandPreconditionViolated,
99
CommandParameterLimitViolated,
@@ -74,7 +74,10 @@ async def get_tip_presence(self, pipette_id: str) -> TipPresenceStatus:
7474
"""Get tip presence status on the pipette."""
7575

7676
async def verify_tip_presence(
77-
self, pipette_id: str, expected: TipPresenceStatus
77+
self,
78+
pipette_id: str,
79+
expected: TipPresenceStatus,
80+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
7881
) -> None:
7982
"""Verify the expected tip presence status."""
8083

@@ -237,7 +240,10 @@ async def get_tip_presence(self, pipette_id: str) -> TipPresenceStatus:
237240
return TipPresenceStatus.UNKNOWN
238241

239242
async def verify_tip_presence(
240-
self, pipette_id: str, expected: TipPresenceStatus
243+
self,
244+
pipette_id: str,
245+
expected: TipPresenceStatus,
246+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
241247
) -> None:
242248
"""Verify the expecterd tip presence status of the pipette.
243249
@@ -247,7 +253,9 @@ async def verify_tip_presence(
247253
try:
248254
ot3api = ensure_ot3_hardware(hardware_api=self._hardware_api)
249255
hw_mount = self._state_view.pipettes.get_mount(pipette_id).to_hw_mount()
250-
await ot3api.verify_tip_presence(hw_mount, expected.to_hw_state())
256+
await ot3api.verify_tip_presence(
257+
hw_mount, expected.to_hw_state(), follow_singular_sensor
258+
)
251259
except HardwareNotSupportedError:
252260
# Tip presence sensing is not supported on the OT2
253261
pass
@@ -332,7 +340,10 @@ async def add_tip(self, pipette_id: str, tip: TipGeometry) -> None:
332340
assert False, "TipHandler.add_tip should not be used with virtual pipettes"
333341

334342
async def verify_tip_presence(
335-
self, pipette_id: str, expected: TipPresenceStatus
343+
self,
344+
pipette_id: str,
345+
expected: TipPresenceStatus,
346+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
336347
) -> None:
337348
"""Verify tip presence.
338349

api/src/opentrons/protocol_engine/types.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010

1111
from opentrons_shared_data.pipette.dev_types import PipetteNameType
1212
from opentrons.types import MountType, DeckSlotName, StagingSlotName
13-
from opentrons.hardware_control.types import TipStateType as HwTipStateType
13+
from opentrons.hardware_control.types import (
14+
TipStateType as HwTipStateType,
15+
InstrumentProbeType,
16+
)
1417
from opentrons.hardware_control.modules import (
1518
ModuleType as ModuleType,
1619
)
@@ -830,6 +833,22 @@ class QuadrantNozzleLayoutConfiguration(BaseModel):
830833
] # cutout_id, cutout_fixture_id, opentrons_module_serial_number
831834

832835

836+
class InstrumentSensorId(str, Enum):
837+
"""Primary and secondary sensor ids."""
838+
839+
PRIMARY = "primary"
840+
SECONDARY = "secondary"
841+
BOTH = "both"
842+
843+
def to_instrument_probe_type(self) -> InstrumentProbeType:
844+
"""Convert to InstrumentProbeType."""
845+
return {
846+
InstrumentSensorId.PRIMARY: InstrumentProbeType.PRIMARY,
847+
InstrumentSensorId.SECONDARY: InstrumentProbeType.SECONDARY,
848+
InstrumentSensorId.BOTH: InstrumentProbeType.BOTH,
849+
}[self]
850+
851+
833852
class TipPresenceStatus(str, Enum):
834853
"""Tip presence status reported by a pipette."""
835854

api/tests/opentrons/protocol_engine/execution/test_tip_handler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,11 +413,11 @@ async def test_verify_tip_presence_on_ot3(
413413
decoy.when(mock_state_view.pipettes.get_mount("pipette-id")).then_return(
414414
MountType.LEFT
415415
)
416-
await subject.verify_tip_presence("pipette-id", expected)
416+
await subject.verify_tip_presence("pipette-id", expected, None)
417417

418418
decoy.verify(
419419
await ot3_hardware_api.verify_tip_presence(
420-
Mount.LEFT, expected.to_hw_state()
420+
Mount.LEFT, expected.to_hw_state(), None
421421
)
422422
)
423423

app/src/organisms/LabwarePositionCheck/AttachProbe.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,11 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => {
9696
const verifyCommands: CreateCommand[] = [
9797
{
9898
commandType: 'verifyTipPresence',
99-
params: { pipetteId: pipetteId, expectedState: 'present' },
99+
params: {
100+
pipetteId: pipetteId,
101+
expectedState: 'present',
102+
followSingularSensor: 'primary',
103+
},
100104
},
101105
]
102106
const homeCommands: CreateCommand[] = [

0 commit comments

Comments
 (0)