Skip to content

OT-2 (legacy): fix _current_channel_position, and add move_channel_to - #1238

Closed
miikee wants to merge 1 commit into
PyLabRobot:mainfrom
Cheshire-Labs:u6-ot2-position
Closed

OT-2 (legacy): fix _current_channel_position, and add move_channel_to#1238
miikee wants to merge 1 commit into
PyLabRobot:mainfrom
Cheshire-Labs:u6-ot2-position

Conversation

@miikee

@miikee miikee commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

_current_channel_position calls ot_api.lh.save_position, which ot_api
does not define. Every caller therefore raises, so move_channel_x,
move_channel_y and move_channel_z on the OT-2 backend cannot work at all
today: they always fail with RuntimeError: Failed to query current pipette position.

It now enqueues savePosition itself and polls the command the way ot_api's
own command wrapper does. The poll awaits rather than sleeping, so a robot that
never answers does not hold the event loop for the whole 30s budget.

With the read working, move_channel_to moves a channel to an absolute
position and holds whichever axes are left out. Chaining the per-axis calls was
the only way to reach an arbitrary point before, and each of those descends
separately, so a three-axis move could clip labware between the steps. This
lifts to the traversal height and travels once. get_channel_position exposes
the read.

Not verified on an OT-2. I do not have one. The savePosition command and
its response shape are the same ones a Flex uses, where they are hardware
verified, and the new tests fake the robot at its command queue so they pin the
params a real robot would receive.

Known gap I did not want to fold in silently: move_channel_x/y/z still
duplicate the same three lines rather than delegating to move_channel_to.
Delegating would change what those three do on the wire (a coordinated move
instead of a single-axis one), which is a behaviour change I would rather
propose separately than smuggle into a fix. Happy to do it here if you would
prefer.

Draft, and independent of my PreciseFlex PRs. A second OT-2 PR follows this
one, bounding every request and taking it off the event loop.

_current_channel_position called ot_api.lh.save_position, which ot_api does not
define, so every caller raised: move_channel_x, move_channel_y and
move_channel_z could not work at all. It now enqueues savePosition itself and
polls the command the way ot_api's own command wrapper does. The poll awaits
rather than sleeping, so a robot that never answers does not hold the event
loop for the whole 30s budget.

With the read working, move_channel_to moves a channel to an absolute position
and holds whichever axes are left out. Chaining the per-axis calls was the only
way to reach an arbitrary point before, and each of those descends separately,
so a three-axis move could clip labware between the steps. This lifts to the
traversal height and travels once. get_channel_position exposes the read.

Not verified on an OT-2. The savePosition command and its response shape are
the same ones a Flex uses, where they are hardware verified.
@miikee

miikee commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #1240, which carries this commit plus the request-bounding work that builds on it. Verified: this branch's tip is an ancestor of #1240's head, so nothing is dropped.

@miikee miikee closed this Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant