Skip to content

Commit 7bd07bf

Browse files
authored
fix(api): Ensure thermocycler dodge waypoints can account for fixtures (#19089)
# Overview Covers RESC-476 Originally we just hardcoded to Slot 5/C2 when planning waypoints to dodge the thermocycler. This PR adds in logic to find an appropriate fixtures and center over its first addressable area instead, which fixes out issue for magnetic blocks. Of note, this potentially causes issues if we add new center slot fixtures that have a bunch of whacky addressable areas that are offset from the center of the cutout. Think about how the flex stacker's addressable areas skew way off the deck from their cutout origin, we could see similar behavior here in the future. For now I think this is really fine given the reality of what fixtures we allow there, but I've left a todo explaining the issue and we may need to address it in the future if we want more foolproof solution. ## Test Plan and Hands on Testing - [x] Run the following protocol on Flex, ensure we don't raise the "Addressable area C2 not in deck config" error: ``` def run(protocol_context: ProtocolContext): trash = protocol_context.load_trash_bin("A3") thermo = protocol_context.load_module("thermocyclerModuleV2") mag_block = protocol_context.load_module('magneticBlockV1', location='C2') tiprack1 = protocol_context.load_labware(load_name="opentrons_flex_96_tiprack_200ul", location="B3", adapter="opentrons_flex_96_tiprack_adapter") plate = protocol_context.load_labware('nest_96_wellplate_200ul_flat', "C1") instrument = protocol_context.load_instrument('flex_96channel_1000', mount="right", tip_racks=[tiprack1]) instrument.pick_up_tip() instrument.aspirate(200, plate.wells_by_name()["A1"]) instrument.dispense(200, plate.wells_by_name()["A1"]) instrument.drop_tip() ``` ## Changelog Modified geometry waypoint planning to dodge thermocycler using dynamic fixtures. ## Review requests ## Risk assessment Low/Medium - this fixes the issue, but at what cost?!?!?! Not really any cost for now, but as mentioned above if we ever introduce a fixture in the center slot with whacky addressable areas it will mess up the waypoint planning again.
1 parent 56c186b commit 7bd07bf

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

api/src/opentrons/protocol_engine/state/geometry.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,14 +1096,36 @@ def get_extra_waypoints(
10961096
if self._modules.should_dodge_thermocycler(
10971097
from_slot=from_slot, to_slot=to_slot
10981098
):
1099-
middle_slot = DeckSlotName.SLOT_5.to_equivalent_for_robot_type(
1100-
self._config.robot_type
1101-
)
1102-
middle_slot_center = (
1103-
self._addressable_areas.get_addressable_area_center(
1104-
addressable_area_name=middle_slot.id,
1099+
1100+
middle_slot_fixture = (
1101+
self._addressable_areas.get_fixture_by_deck_slot_name(
1102+
DeckSlotName.SLOT_C2
11051103
)
11061104
)
1105+
if middle_slot_fixture is None:
1106+
middle_slot = DeckSlotName.SLOT_5.to_equivalent_for_robot_type(
1107+
self._config.robot_type
1108+
)
1109+
middle_slot_center = (
1110+
self._addressable_areas.get_addressable_area_center(
1111+
addressable_area_name=middle_slot.id,
1112+
)
1113+
)
1114+
else:
1115+
# todo(chb, 2025-07-30): For now we're defaulting to the first addressable area for these center slot fixtures, but
1116+
# if we ever introduce a fixture in the center slot with many addressable areas that aren't "centered" over the deck
1117+
# slot we will enter up generating a pretty whacky movement path (potentially dangerous).
1118+
middle_slot_center = self._addressable_areas.get_addressable_area_center(
1119+
addressable_area_name=middle_slot_fixture[
1120+
"providesAddressableAreas"
1121+
][
1122+
deck_configuration_provider.get_cutout_id_by_deck_slot_name(
1123+
DeckSlotName.SLOT_C2
1124+
)
1125+
][
1126+
0
1127+
],
1128+
)
11071129
return [(middle_slot_center.x, middle_slot_center.y)]
11081130
return []
11091131

0 commit comments

Comments
 (0)