Unhomed motion gate, fast-path home, stop/estop/reset#27
Merged
Conversation
Reported joint positions are unreferenced until homing — the boot state is all-zeros steps, outside J2/J3's limits and physically impossible — so building or collision-checking a trajectory from them produces garbage (found live as a phantom "[54] Self-collision predicted" on the first move from the boot pose). Planned moves (MoveJ/MoveL/MoveC/MoveS/ MoveP, including blends) now raise MOTN_NOT_HOMED with an actionable "run home() first" remedy. Jog/servo/home stay ungated: they don't plan a path from the reported pose, and an unhomed arm may need to be jogged clear of an obstruction before it can home. The planner subprocess tracks homed state like it tracks position: a snapshot rides each PlanCommand while the segment player is idle, and a queued HOME is predicted as homed so a following move plans cleanly. STATUS gains a len-guarded trailing `homed` flag (defaults True for older producers) so clients can seed dry runs; DryRunRobotClient accepts initial_homed and treats home()/teleport() as establishing references, mirroring the live gate in previews. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XbP8n8tzaJXKMjkRxGnoa1
state.reset() recycled next_command_index to 0 while status frames generated before the reset still carried the old completed_index high-water mark — any wait_command on a recycled index was satisfied instantly by such a frame, reporting success for a command that hadn't run. Preserving the counter makes stale frames unable to alias post-reset commands, and removes the settle workaround the unhomed-gate test needed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XbP8n8tzaJXKMjkRxGnoa1
HOME from an already-homed robot re-ran the full firmware switch-seek. The planner now routes it to a normal planned (collision-checked) joint move back to the standby pose, at HOME_RETURN_SPEED_FRAC; the firmware sequence runs only while unhomed. The dry run mirrors the split: seeded homed, home() previews as a real return path; seeded unhomed it stays the instant referencing snap. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XbP8n8tzaJXKMjkRxGnoa1
HALT had two defects: it latched the controller disabled with nothing in the normal flow re-enabling it, and it never actually stopped in-flight motion — the segment player kept playing the active trajectory, rewriting Command_out and fresh speeds every tick, so the "halted" robot drove on to its target and queued moves survived to play out after RESUME. The vocabulary now matches industrial convention (IEC 60204-1): - STOP: cancel active trajectory + queue; controller stays enabled and accepts the next command immediately (Category 2 operational stop). - ESTOP: protective stop — same cancellation plus the disabled latch. Motors stay energized (PAROL6 steppers have no brakes; a de-energized arm sags): the protective stop is the software latch, not motor power. - RESET: clears the latch (was RESUME, which never resumed anything). - RESET_STATE: the old utility RESET (state wipe), renamed to free the name. Both STOP and ESTOP cancel the pipeline in the controller the same way RESET_STATE and the hardware e-stop path always did. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XbP8n8tzaJXKMjkRxGnoa1
home() on a referenced robot is a real planned return move now, so the all-profiles loop was paying for five plan+execute cycles and blew the 45s per-test timeout on slow macOS runners. Teleport pins each profile's start pose instantly without re-testing home. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XbP8n8tzaJXKMjkRxGnoa1
The teleport-paced profile sweep fires acked system commands back-to-back; slow macOS runners held acks past the default 2s window and its retry, so select_profile spuriously reported failure. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XbP8n8tzaJXKMjkRxGnoa1
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XbP8n8tzaJXKMjkRxGnoa1
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.
Refuses planned motion while unhomed; keeps command indices monotonic across reset; fast-paths
home()on a referenced robot into a planned collision-checked return move; replaces halt/resume with stop/estop/reset and makes stops actually cancel the in-flight trajectory (previously the segment player kept playing through a halt, so a "halted" robot drove on to its target). Requires waldoctlfeat/mcp-server(CI branch-matches; release train: waldoctl tag → pin bump here → tag).Written by Claude on behalf of @Jepson2k.
🤖 Generated with Claude Code
https://claude.ai/code/session_01XbP8n8tzaJXKMjkRxGnoa1