Add STARBackend.channels_probe_z_using_ztouch for parallel force probing#1067
Draft
BioCam wants to merge 2 commits into
Draft
Add STARBackend.channels_probe_z_using_ztouch for parallel force probing#1067BioCam wants to merge 2 commits into
STARBackend.channels_probe_z_using_ztouch for parallel force probing#1067BioCam wants to merge 2 commits into
Conversation
Batched ZH probing across multiple channels, modeled on probe_liquid_heights: plan_batches -> execute_batched -> asyncio.gather over `ztouch_probe_z_height_using_channel`. Channel starts within a batch are staggered by inter_channel_start_delay (default 0.3 s) to decouple contact-force transients on the shared carriage -> creating a "cascading motion". The inner ztouch_probe_z_height_using_channel call receives post_detection_dist=0 and an explicit tip_len so no C0 commands (move_channel_z, request_tip_len_on_channel) serialize the gather. Channel raising is handled by the existing min_traverse_height_during_command / z_position_at_end_of_command kwargs. Outer try/except BaseException lifts all channels to Z safety on any exception (firmware error, KeyboardInterrupt, CancelledError) before re-raising. Aggregated Z is rounded to the firmware z-drive quantum (0.01 mm). Chatterbox stub included.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
The Problem
PyLabRobot has a single-channel force-sensed Z probe (
ztouch_probe_z_height_using_channel, firmware ZH) but no batched, parallel equivalent. Multi-channel workflows that need this measurement currently require careful and time-consuming planning.Concrete needs that surface this gap:
Naively wrapping the primitive in
asyncio.gatherdoes not solve this, because of two parallelism hazards specific to force-sensed probing on the STAR head:Carriage-force cross-talk. All channels share one rigid Z-drive carriage. When channels descend simultaneously, each channel's touchdown produces a force transient that perturbs the PWM-based detection threshold on the others, biasing every measurement after the first to land.
C0-command serialization. The single-channel primitive issues
move_channel_z(firmware JZ via C0) whenpost_detection_dist != 0(TODO: move to PX version), andrequest_tip_len_on_channel(also C0) whentip_len=None. Both route through the master controller and serialize the gather - defeating the parallelism the caller is trying to get.A correct batched implementation has to address both of these explicitly.
PR Content / Solution
Adds
channels_probe_z_using_ztouchto the STAR backend: a batched, parallel force-sensed Z probe that returns the absolute deck-frame Z of whatever solid surface each channel first touches.Architecture
Reuses the same batched-channel orchestration skeleton that
probe_liquid_heightsalready uses for cLLD/pLLD:plan_batchesbuilds channel/X/Y batches,execute_batchedhandles inter-batch X/Y positioning and Z safety, and the per-batch callback fans outztouch_probe_z_height_using_channelacross the batch's channels underasyncio.gather. No reinvention of X/Y partitioning, no-go-zone handling, or inter-batch Z safety.Carriage cross-talk: stagger the channel starts
Within each batch, channel starts are staggered by
inter_channel_start_delay(default 0.3 s) so contact-force transients don't superpose. The stagger lives in a small_delayed(delay, factory)helper that takes a coroutine factory (not a coroutine) to avoid un-awaited-coroutine warnings if the gather is cancelled mid-sleep. Tunable to 0.0 for callers who've validated mechanically isolated geometry.C0-avoidance: keep the gather truly parallel
The inner ZH call receives
post_detection_dist=0and an explicittip_lenso the primitive does not issuemove_channel_zorrequest_tip_len_on_channel. Channel raising between batches and at the end is handled by the existingmin_traverse_height_during_commandandz_position_at_end_of_commandkwargs.Safety and aggregation
Outer
try / except BaseExceptionlifts all channels to Z safety on any exception (firmware error, KeyboardInterrupt, SystemExit, asyncio.CancelledError) before re-raising. Aggregated Z is rounded to the firmware z-drive quantum (0.01 mm) so users don't see float-averaging noise across replicates.Design decisions
post_detection_distkwarg. Using it inside the gather would issue a C0 JZ per channel and serialize the parallelism. Channel raising is already covered bymin_traverse_height_during_command/z_position_at_end_of_command.except BaseException, notexcept Exception. CatchesKeyboardInterrupt,SystemExit, andasyncio.CancelledErrortoo - all cases where channels might be pressing on a surface when control is lost. Matches the pattern already inexecute_batched.inter_channel_start_delaydefault 0.3 s. Empirical default covering a typical ~tens-of-ms contact transient with margin; tunable to 0.0 for callers who don't need the decoupling.