Skip to content

Commit

Permalink
Recover from pickUpTip false-positives.
Browse files Browse the repository at this point in the history
Missing tests.
  • Loading branch information
SyntaxColoring committed Oct 21, 2024
1 parent a2b7628 commit b59f51c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 12 deletions.
10 changes: 8 additions & 2 deletions api/src/opentrons/protocol_engine/commands/pick_up_tip.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing_extensions import Literal


from ..errors import ErrorOccurrence, TipNotAttachedError
from ..errors import ErrorOccurrence, PickUpTipTipNotAttachedError
from ..resources import ModelUtils
from ..state import update_types
from ..types import PickUpTipWellLocation, DeckPoint
Expand Down Expand Up @@ -140,7 +140,12 @@ async def execute(
labware_id=labware_id,
well_name=well_name,
)
except TipNotAttachedError as e:
except PickUpTipTipNotAttachedError as e:
state_update_if_false_positive = update_types.StateUpdate()
state_update_if_false_positive.update_pipette_tip_state(
pipette_id=pipette_id,
tip_geometry=e.tip_geometry,
)
state_update.mark_tips_as_used(
pipette_id=pipette_id, labware_id=labware_id, well_name=well_name
)
Expand All @@ -157,6 +162,7 @@ async def execute(
],
),
state_update=state_update,
state_update_if_false_positive=state_update_if_false_positive,
)
else:
state_update.update_pipette_tip_state(
Expand Down
2 changes: 2 additions & 0 deletions api/src/opentrons/protocol_engine/errors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
InvalidSpecificationForRobotTypeError,
InvalidLoadPipetteSpecsError,
TipNotAttachedError,
PickUpTipTipNotAttachedError,
TipAttachedError,
CommandDoesNotExistError,
LabwareNotLoadedError,
Expand Down Expand Up @@ -88,6 +89,7 @@
"InvalidSpecificationForRobotTypeError",
"InvalidLoadPipetteSpecsError",
"TipNotAttachedError",
"PickUpTipTipNotAttachedError",
"TipAttachedError",
"CommandDoesNotExistError",
"LabwareNotLoadedError",
Expand Down
23 changes: 22 additions & 1 deletion api/src/opentrons/protocol_engine/errors/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
"""Protocol engine exceptions."""

from __future__ import annotations

from logging import getLogger
from typing import Any, Dict, Optional, Union, Iterator, Sequence
from typing import Any, Dict, Final, Optional, Union, Iterator, Sequence, TYPE_CHECKING

from opentrons_shared_data.errors import ErrorCodes
from opentrons_shared_data.errors.exceptions import EnumeratedError, PythonException

if TYPE_CHECKING:
from opentrons.protocol_engine.types import TipGeometry


log = getLogger(__name__)


Expand Down Expand Up @@ -132,6 +138,21 @@ def __init__(
super().__init__(ErrorCodes.UNEXPECTED_TIP_REMOVAL, message, details, wrapping)


class PickUpTipTipNotAttachedError(TipNotAttachedError):
"""Raised from TipHandler.pick_up_tip().
This is like TipNotAttachedError except that it carries some extra information
about the attempted operation.
"""

tip_geometry: Final[TipGeometry]
"""The tip geometry that would have been on the pipette, had the operation succeeded."""

def __init__(self, tip_geometry: TipGeometry) -> None:
super().__init__()
self.tip_geometry = tip_geometry


class TipAttachedError(ProtocolEngineError):
"""Raised when a tip shouldn't be attached, but is."""

Expand Down
23 changes: 14 additions & 9 deletions api/src/opentrons/protocol_engine/execution/tip_handler.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""Tip pickup and drop procedures."""
from typing import Optional, Dict
from typing import Final, Optional, Dict
from typing_extensions import Protocol as TypingProtocol

from opentrons.hardware_control import HardwareControlAPI
from opentrons.hardware_control.types import FailedTipStateCheck, InstrumentProbeType
from opentrons.protocol_engine.errors.exceptions import PickUpTipTipNotAttachedError
from opentrons.types import Mount

from opentrons_shared_data.errors.exceptions import (
Expand Down Expand Up @@ -72,7 +73,7 @@ async def pick_up_tip(
Tip geometry of the picked up tip.
Raises:
TipNotAttachedError
PickUpTipTipNotAttachedError
"""
...

Expand Down Expand Up @@ -245,11 +246,19 @@ async def pick_up_tip(
nominal_fallback=nominal_tip_geometry.length,
)

tip_geometry = TipGeometry(
length=actual_tip_length,
diameter=nominal_tip_geometry.diameter,
volume=nominal_tip_geometry.volume,
)

await self._hardware_api.tip_pickup_moves(
mount=hw_mount, presses=None, increment=None
)
# Allow TipNotAttachedError to propagate.
await self.verify_tip_presence(pipette_id, TipPresenceStatus.PRESENT)
try:
await self.verify_tip_presence(pipette_id, TipPresenceStatus.PRESENT)
except TipNotAttachedError as e:
raise PickUpTipTipNotAttachedError(tip_geometry=tip_geometry) from e

# todo(mm, 2024-10-21): This sequence of cache_tip(), set_current_tiprack_diameter(),
# and set_working_volume() is almost the same as self.add_tip(), except one uses
Expand All @@ -268,11 +277,7 @@ async def pick_up_tip(
tip_volume=nominal_tip_geometry.volume,
)

return TipGeometry(
length=actual_tip_length,
diameter=nominal_tip_geometry.diameter,
volume=nominal_tip_geometry.volume,
)
return tip_geometry

async def drop_tip(self, pipette_id: str, home_after: Optional[bool]) -> None:
"""See documentation on abstract base class."""
Expand Down

0 comments on commit b59f51c

Please sign in to comment.