Skip to content

Commit

Permalink
chore(merge): Merge head of chore_release into edge (#16161)
Browse files Browse the repository at this point in the history
  • Loading branch information
mjhuff authored Aug 29, 2024
1 parent b0f944a commit 3003a1d
Show file tree
Hide file tree
Showing 87 changed files with 953 additions and 368 deletions.
30 changes: 24 additions & 6 deletions api/docs/static/override_sphinx.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
@import url('https://fonts.googleapis.com/css?family=Open+Sans:300,400,400i,600,700');
@import url('https://fonts.googleapis.com/css?family=Public+Sans:300,400,400i,600,700');
@import url('https://fonts.googleapis.com/css2?family=Reddit+Mono:[email protected]&display=swap');

/* OT NAV */

body {
padding: 0;
margin: 0;
font-family: "Open Sans", "sans-serif";
font-family: "Public Sans", "sans-serif";
}

.highlight-none, .mi, .literal {
Expand Down Expand Up @@ -35,7 +36,18 @@ div.document [id] {

div.body p {
line-height: 20pt;
font-family: "Open Sans", "sans-serif";
font-family: "Public Sans", "sans-serif";
}

pre, tt, code {
font-size: 0.9em;
font-family: "Reddit Mono", "Consolas", "Lucida Console", monospace;
}

/* classes for API Reference docstring signatures */
.sig, .sig-name, code.descname, .sig-prename, .optional, .sig-paren {
font-size: 1em;
font-family: "Reddit Mono", "Consolas", "Lucida Console", monospace;
}

div.body h1 {
Expand Down Expand Up @@ -90,7 +102,13 @@ div.body h2,
div.body h3,
div.body h4,
div.body h5 {
font-family: "Open Sans", "sans-serif";
font-family: "Public Sans", "sans-serif";
}

/* Links need an extra two pixels of padding to compensate between body font height
being 1em and code font height being 0.9em */
a.reference {
padding-bottom: 2px;
}

/* Suppressing the display of the toctrees rendered in the doc body means we
Expand Down Expand Up @@ -193,13 +211,13 @@ div.body p.caption {

ul {
/* margin-left: 0; */
font-family: "Open Sans", "sans-serif";
font-family: "Public Sans", "sans-serif";
}

ul ul {
list-style-type: circle;
margin-left: 30px;
font-family: "Open Sans", "sans-serif";
font-family: "Public Sans", "sans-serif";
}

@media screen and (min-device-width: 320px)and (max-device-width: 640px) {
Expand Down
1 change: 1 addition & 0 deletions api/docs/v2/parameters/use_case_cherrypicking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ The entire start of the ``run()`` function, including a pipette and fixed labwar
instrument_name="flex_1channel_1000",
mount="left",
tip_racks=[tiprack]
)
# load trash bin
trash = protocol.load_trash_bin("A3")
)
Expand Down
57 changes: 41 additions & 16 deletions api/src/opentrons/protocol_api/core/engine/deck_conflict.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,23 +416,48 @@ def _is_within_pipette_extents(
pipette_bounding_box_at_loc: Tuple[Point, Point, Point, Point],
) -> bool:
"""Whether a given point is within the extents of a configured pipette on the specified robot."""
mount = engine_state.pipettes.get_mount(pipette_id)
robot_extent_per_mount = engine_state.geometry.absolute_deck_extents
pip_back_left_bound, pip_front_right_bound, _, _ = pipette_bounding_box_at_loc
pipette_bounds_offsets = engine_state.pipettes.get_pipette_bounding_box(pipette_id)
from_back_right = (
robot_extent_per_mount.back_right[mount]
+ pipette_bounds_offsets.back_right_corner
)
from_front_left = (
robot_extent_per_mount.front_left[mount]
+ pipette_bounds_offsets.front_left_corner
)
channels = engine_state.pipettes.get_channels(pipette_id)
robot_extents = engine_state.geometry.absolute_deck_extents
(
pip_back_left_bound,
pip_front_right_bound,
pip_back_right_bound,
pip_front_left_bound,
) = pipette_bounding_box_at_loc

# Given the padding values accounted for against the deck extents,
# a pipette is within extents when all of the following are true:

# Each corner slot full pickup case:
# A1: Front right nozzle is within the rear and left-side padding limits
# D1: Back right nozzle is within the front and left-side padding limits
# A3 Front left nozzle is within the rear and right-side padding limits
# D3: Back left nozzle is within the front and right-side padding limits
# Thermocycler Column A2: Front right nozzle is within padding limits

if channels == 96:
return (
pip_front_right_bound.y
<= robot_extents.deck_extents.y + robot_extents.padding_rear
and pip_front_right_bound.x >= robot_extents.padding_left_side
and pip_back_right_bound.y >= robot_extents.padding_front
and pip_back_right_bound.x >= robot_extents.padding_left_side
and pip_front_left_bound.y
<= robot_extents.deck_extents.y + robot_extents.padding_rear
and pip_front_left_bound.x
<= robot_extents.deck_extents.x + robot_extents.padding_right_side
and pip_back_left_bound.y >= robot_extents.padding_front
and pip_back_left_bound.x
<= robot_extents.deck_extents.x + robot_extents.padding_right_side
)
# For 8ch pipettes we only check the rear and front extents
return (
from_back_right.x >= pip_back_left_bound.x >= from_front_left.x
and from_back_right.y >= pip_back_left_bound.y >= from_front_left.y
and from_back_right.x >= pip_front_right_bound.x >= from_front_left.x
and from_back_right.y >= pip_front_right_bound.y >= from_front_left.y
pip_front_right_bound.y
<= robot_extents.deck_extents.y + robot_extents.padding_rear
and pip_back_right_bound.y >= robot_extents.padding_front
and pip_front_left_bound.y
<= robot_extents.deck_extents.y + robot_extents.padding_rear
and pip_back_left_bound.y >= robot_extents.padding_front
)


Expand Down
1 change: 0 additions & 1 deletion api/src/opentrons/protocol_api/instrument_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ def aspirate(
and self._96_tip_config_valid()
):
self.require_liquid_presence(well=well)
self.prepare_to_aspirate()

with publisher.publish_context(
broker=self.broker,
Expand Down
1 change: 1 addition & 0 deletions api/src/opentrons/protocol_api/protocol_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,7 @@ def load_instrument(
from the Opentrons App or touchscreen.
:param bool liquid_presence_detection: If ``True``, enable automatic
:ref:`liquid presence detection <lpd>` for Flex 1-, 8-, or 96-channel pipettes.
.. versionadded:: 2.20
"""
instrument_name = validation.ensure_lowercase_name(instrument_name)
Expand Down
14 changes: 14 additions & 0 deletions api/src/opentrons/protocol_engine/state/addressable_areas.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,20 @@ def mount_offsets(self) -> Dict[str, Point]:
"right": Point(x=right_offset[0], y=right_offset[1], z=right_offset[2]),
}

@cached_property
def padding_offsets(self) -> Dict[str, float]:
"""The padding offsets to be applied to the deck extents of the robot."""
rear_offset = self.state.robot_definition["paddingOffsets"]["rear"]
front_offset = self.state.robot_definition["paddingOffsets"]["front"]
left_side_offset = self.state.robot_definition["paddingOffsets"]["leftSide"]
right_side_offset = self.state.robot_definition["paddingOffsets"]["rightSide"]
return {
"rear": rear_offset,
"front": front_offset,
"left_side": left_side_offset,
"right_side": right_side_offset,
}

def get_addressable_area(self, addressable_area_name: str) -> AddressableArea:
"""Get addressable area."""
if not self._state.use_simulated_deck_config:
Expand Down
13 changes: 12 additions & 1 deletion api/src/opentrons/protocol_engine/state/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ class _GripperMoveType(enum.Enum):
class _AbsoluteRobotExtents:
front_left: Dict[MountType, Point]
back_right: Dict[MountType, Point]
deck_extents: Point
padding_rear: float
padding_front: float
padding_left_side: float
padding_right_side: float


_LabwareLocation = TypeVar("_LabwareLocation", bound=LabwareLocation)
Expand Down Expand Up @@ -118,7 +123,13 @@ def absolute_deck_extents(self) -> _AbsoluteRobotExtents:
MountType.RIGHT: self._addressable_areas.deck_extents + right_offset,
}
return _AbsoluteRobotExtents(
front_left=front_left_abs, back_right=back_right_abs
front_left=front_left_abs,
back_right=back_right_abs,
deck_extents=self._addressable_areas.deck_extents,
padding_rear=self._addressable_areas.padding_offsets["rear"],
padding_front=self._addressable_areas.padding_offsets["front"],
padding_left_side=self._addressable_areas.padding_offsets["left_side"],
padding_right_side=self._addressable_areas.padding_offsets["right_side"],
)

def get_labware_highest_z(self, labware_id: str) -> float:
Expand Down
2 changes: 0 additions & 2 deletions api/src/opentrons/protocol_engine/state/pipettes.py
Original file line number Diff line number Diff line change
Expand Up @@ -845,8 +845,6 @@ def get_pipette_bounds_at_specified_move_to_position(
- primary_nozzle_offset
+ pipette_bounds_offsets.front_right_corner
)
# TODO (spp, 2024-02-27): remove back right & front left;
# return only back left and front right points.
pip_back_right_bound = Point(
pip_front_right_bound.x, pip_back_left_bound.y, pip_front_right_bound.z
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,11 @@ def test_deck_conflict_raises_for_bad_pipette_move(
MountType.LEFT: Point(463.7, 433.3, 0.0),
MountType.RIGHT: Point(517.7, 433.3),
},
deck_extents=Point(477.2, 493.8, 0.0),
padding_rear=-181.21,
padding_front=55.8,
padding_left_side=31.88,
padding_right_side=-80.32,
)
)
decoy.when(
Expand Down Expand Up @@ -677,6 +682,11 @@ def test_deck_conflict_raises_for_collision_with_tc_lid(
MountType.LEFT: Point(463.7, 433.3, 0.0),
MountType.RIGHT: Point(517.7, 433.3),
},
deck_extents=Point(477.2, 493.8, 0.0),
padding_rear=-181.21,
padding_front=55.8,
padding_left_side=31.88,
padding_right_side=-80.32,
)
)

Expand All @@ -696,7 +706,7 @@ def test_deck_conflict_raises_for_collision_with_tc_lid(
)
with pytest.raises(
deck_conflict.PartialTipMovementNotAllowedError,
match="collision with thermocycler lid in deck slot A1.",
match="Requested motion with the A12 nozzle partial configuration is outside of robot bounds for the pipette.",
):
deck_conflict.check_safe_for_pipette_movement(
engine_state=mock_state_view,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,6 @@ def test_deck_conflicts_for_96_ch_a12_column_configuration() -> None:
):
instrument.pick_up_tip(badly_placed_tiprack.wells_by_name()["A1"])

with pytest.raises(
PartialTipMovementNotAllowedError, match="outside of robot bounds"
):
# Picking up from A1 in an east-most slot using a configuration with column 12 would
# result in a collision with the side of the robot.
instrument.pick_up_tip(well_placed_tiprack.wells_by_name()["A1"])

instrument.pick_up_tip(well_placed_tiprack.wells_by_name()["A12"])
instrument.aspirate(50, well_placed_labware.wells_by_name()["A4"])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ def test_deck_configuration_setting(
"robotType": "OT-3 Standard",
"models": ["OT-3 Standard"],
"extents": [477.2, 493.8, 0.0],
"paddingOffsets": {
"rear": -177.42,
"front": 51.8,
"leftSide": 31.88,
"rightSide": -80.32,
},
"mountOffsets": {
"left": [-13.5, -60.5, 255.675],
"right": [40.5, -60.5, 255.675],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ def simulated_subject(
"robotType": "OT-3 Standard",
"models": ["OT-3 Standard"],
"extents": [477.2, 493.8, 0.0],
"paddingOffsets": {
"rear": -177.42,
"front": 51.8,
"leftSide": 31.88,
"rightSide": -80.32,
},
"mountOffsets": {
"left": [-13.5, -60.5, 255.675],
"right": [40.5, -60.5, 255.675],
Expand Down Expand Up @@ -101,6 +107,12 @@ def subject(
"robotType": "OT-3 Standard",
"models": ["OT-3 Standard"],
"extents": [477.2, 493.8, 0.0],
"paddingOffsets": {
"rear": -177.42,
"front": 51.8,
"leftSide": 31.88,
"rightSide": -80.32,
},
"mountOffsets": {
"left": [-13.5, -60.5, 255.675],
"right": [40.5, -60.5, 255.675],
Expand All @@ -127,6 +139,12 @@ def test_initial_state_simulated(
"robotType": "OT-3 Standard",
"models": ["OT-3 Standard"],
"extents": [477.2, 493.8, 0.0],
"paddingOffsets": {
"rear": -177.42,
"front": 51.8,
"leftSide": 31.88,
"rightSide": -80.32,
},
"mountOffsets": {
"left": [-13.5, -60.5, 255.675],
"right": [40.5, -60.5, 255.675],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ def get_addressable_area_view(
"robotType": "OT-3 Standard",
"models": ["OT-3 Standard"],
"extents": [477.2, 493.8, 0.0],
"paddingOffsets": {
"rear": -177.42,
"front": 51.8,
"leftSide": 31.88,
"rightSide": -80.32,
},
"mountOffsets": {
"left": [-13.5, -60.5, 255.675],
"right": [40.5, -60.5, 255.675],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ def addressable_area_store(
"robotType": "OT-3 Standard",
"models": ["OT-3 Standard"],
"extents": [477.2, 493.8, 0.0],
"paddingOffsets": {
"rear": -177.42,
"front": 51.8,
"leftSide": 31.88,
"rightSide": -80.32,
},
"mountOffsets": {
"left": [-13.5, -60.5, 255.675],
"right": [40.5, -60.5, 255.675],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ def get_addressable_area_view(
"robotType": "OT-3 Standard",
"models": ["OT-3 Standard"],
"extents": [477.2, 493.8, 0.0],
"paddingOffsets": {
"rear": -177.42,
"front": 51.8,
"leftSide": 31.88,
"rightSide": -80.32,
},
"mountOffsets": {
"left": [-13.5, -60.5, 255.675],
"right": [40.5, -60.5, 255.675],
Expand Down
6 changes: 6 additions & 0 deletions api/tests/opentrons/protocol_engine/state/test_module_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ def get_addressable_area_view(
"robotType": "OT-3 Standard",
"models": ["OT-3 Standard"],
"extents": [477.2, 493.8, 0.0],
"paddingOffsets": {
"rear": -177.42,
"front": 51.8,
"leftSide": 31.88,
"rightSide": -80.32,
},
"mountOffsets": {
"left": [-13.5, -60.5, 255.675],
"right": [40.5, -60.5, 255.675],
Expand Down
6 changes: 6 additions & 0 deletions api/tests/opentrons/protocol_engine/state/test_state_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ def placeholder_error_recovery_policy(*args: object, **kwargs: object) -> Any:
"robotType": "OT-2 Standard",
"models": ["OT-2 Standard", "OT-2 Refresh"],
"extents": [446.75, 347.5, 0.0],
"paddingOffsets": {
"rear": -35.91,
"front": 31.89,
"leftSide": 0,
"rightSide": 0,
},
"mountOffsets": {"left": [-34.0, 0.0, 0.0], "right": [0.0, 0.0, 0.0]},
},
deck_fixed_labware=[],
Expand Down
1 change: 1 addition & 0 deletions app-shell/build/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Welcome to the v8.0.0 release of the Opentrons App!
### Known Issues

- Labware offsets can't be applied to protocols that require selecting a CSV file as a runtime parameter value. Write the protocol in such a way that it passes analysis with or without the CSV file, or run Labware Position Check after confirming parameter values.
- Error recovery can't perform partial tip pickup, because it doesn't account for the pipette nozzle configuration of 8- and 96-channel pipettes. If a recovery step requires partial tip pickup, cancel the protocol instead.

---

Expand Down
Loading

0 comments on commit 3003a1d

Please sign in to comment.