Skip to content

Unhomed motion gate, fast-path home, stop/estop/reset#27

Merged
Jepson2k merged 7 commits into
mainfrom
feat/mcp-server
Jul 20, 2026
Merged

Unhomed motion gate, fast-path home, stop/estop/reset#27
Jepson2k merged 7 commits into
mainfrom
feat/mcp-server

Conversation

@Jepson2k

Copy link
Copy Markdown
Collaborator

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 waldoctl feat/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

Jepson2k and others added 7 commits July 15, 2026 00:19
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
@Jepson2k
Jepson2k merged commit 829c2c7 into main Jul 20, 2026
13 checks passed
@Jepson2k
Jepson2k deleted the feat/mcp-server branch July 20, 2026 02:01
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