STARBackend: bound X-arm and channel moves to firmware-resolved x_range#1181
Merged
Conversation
STARBackend: bound X-arm and channel moves to the resolved x_rangeSTARBackend: bound X-arm and channel moves to firmware-resolved x_range
BioCam
marked this pull request as ready for review
July 22, 2026 09:30
BioCam
force-pushed
the
pr2-x-range
branch
8 times, most recently
from
July 22, 2026 11:16
9d6533d to
13171f3
Compare
Enforce the per-arm drive range from XArmInformation on the two X-move entry points. experimental_x_arm_move and move_channel_x now call _check_x_arm_reachable, which reads the x_arm_information property (raising if setup has not resolved the ranges yet) and rejects a target outside the arm's x_range with a clear ValueError before any wire command is sent. Replaces the hardcoded 90-1350mm literal in experimental_x_arm_move, and drops the STARChatterboxBackend move_channel_x stub so the bounds check runs in simulation too. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The simulated X reach used the last rail's position, which stops short of the deck's right edge, so once moves are bounded to the resolved x_range a simulated move to the right of the deck was spuriously rejected. Derive it from the deck width instead. The hardware backend is unaffected: it reads the true drive travel from the RU query.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
experimental_x_arm_moveand the PIP path inmove_channel_xbounded the X target against the fixed literals90.0 <= x <= 1350.0, identical for every machine. Now that #1167 resolves each installed X-drive'sx_rangeat setup, a move can be bounded against the arm's actual reachable travel instead of a one-size constant - which genuinely differs by machine, since a STAR reaches farther in X than a STARLet.This is the first PR of the epic "Safety Systems: Tracking STAR Capabilities" building on #1167.
_check_x_arm_reachable(x, position), which reads the resolvedx_rangeoffextended_conf.left_x_drive/right_x_driveand raisesValueErrorwhenxfalls outside it, or when no arm is installed on that rail.experimental_x_arm_moveand the PIP path inmove_channel_xnow call it, replacing the90.0 <= x <= 1350.0literal.STARChatterboxBackendderives its simulated X reach from the deck width rather than the last rail, so a simulated move to the right of the deck is not spuriously rejected. The hardware backend is unaffected - it reads the true drive travel from theRUquery (firmware-fed on device, estimated only in simulation).The bound is the drive travel range (
x_range), not the widerworkspace_rangethat #1167 also resolves.xis the arm's position at its reference point (its center for a dual-rail arm, the right edge for a single-rail arm), and the channels sit off that reference point, so the reachable workspace extends past where the reference point itself can travel.Scope: this bounds the arm-level (
experimental_x_arm_move) and single-channel (move_channel_x) X primitives.Validating each per-channel
xon the high-level pipetting ops (pick_up_tips/drop_tips/aspirate/dispense) againstx_rangeis a follow-up - it belongs in the shared_ops_to_fw_positionschokepoint and should report every non-compliant channel at once, so it is sequenced with the per-channel tracking work rather than bolted on here (marked with aTODOat that chokepoint).Behaviour: this replaces the fixed
90.0 <= x <= 1350.0literal with the machine's resolvedx_range, which is marginally tighter at both ends (dual-rail left resolves to roughly[95.0, 1340]).So it is a deliberate tightening, not purely additive: an
xin those margins that the old constant accepted now raises rather than reaching the wire, because the fixed bound was never the real per-machine limit.An out-of-range move raises a clear
ValueErrorclient-side, naming the arm and its range, instead of relying on the fixed literal, and a target valid on a STAR but past a STARLet's reach is now correctly rejected on the STARLet.Tests:
TestXArmRangeEnforcement(a target past either end ofx_rangeis rejected and no command is sent, while an in-range target reaches the wire) andTestXArmReachByDeck(a STAR resolves a larger reach than a STARLet, and an X past the STARLet's right edge is accepted on a STAR but rejected on a STARLet).ruff format,ruff check --select I,ruff check, andmypy pylabrobot --check-untyped-defsare clean; the STAR suite passes.