Skip to content

Shutdown must not stand the robot back up, and quack opens the beak - #170

Open
sankalpsthakur wants to merge 1 commit into
pollen-robotics:mainfrom
sankalpsthakur:cursor/shutdown-sit-no-init-2926
Open

Shutdown must not stand the robot back up, and quack opens the beak#170
sankalpsthakur wants to merge 1 commit into
pollen-robotics:mainfrom
sankalpsthakur:cursor/shutdown-sit-no-init-2926

Conversation

@sankalpsthakur

Copy link
Copy Markdown

Fixes #159 and #153.

Shutdown sit, then init (#159)

robot.shutdown sits, then the same tick used to stand the robot back up.

The snapshot is taken at the top of the tick. Sit completion goes limp (Bringup::Limp, torque off, enabled cleared) and calls poweroff(). The enable-driven bring-up still saw that tick's stale snapshot.enabled == true with a loaded controller, so it wrote torque on and ramped home — the thing that looks like "goes to init".

request_relax already documents this class of bug. Shutdown missed the same-tick stale snapshot, and robot.init was unguarded once the sequence had gone limp.

This:

  • ignores robot.init while powered_off or a shutdown sit is in flight
  • skips enable-driven bring-up for the rest of that sequence
  • sets Bringup::Limp on the no-sit power-off path too (the sit-complete path already did)

The sit-with-policy path needs ONNX, so CI cannot run it. The sibling path is tested: no policy → immediate power-off (no sit), then robot.init must not re-enable torque.

robotctl quack opens the beak (#153)

The pad already opens the mouth via the analog triggers. CLI quack only sent RobotSound(Chirp), and mouth writes were gated on driving, so the visible half of "which duck is this" was missing — the same class of bug the theremin already had.

A one-shot now holds the beak fully open for 450 ms (the wav is ~200 ms; the servo is slower). That hold is set even if aplay fails, skipped on the blocking goodbye peck, and never taken while a ride/theremin/chorale owns the PCM.

On a sitting-but-torqued robot (enabled + Ready), the mouth is written without requiring driving, same gate as the theremin.

Clippy

Dropped a duplicate #[cfg(test)] on the chorale test module so RUSTFLAGS="-D warnings" cargo clippy -p robotd --all-targets passes.

What this is not

Default policy.gain stays 200, I/D pinned at 0 — that matches the RL prototype. This does not retune Dynamixel P-gain.

Test plan

  • cargo test -p robotd (99 unit tests + 7 updater_gate; includes shutdown_then_init_must_not_stand_the_robot_back_up, a_one_shot_opens_the_beak, a_ride_does_not_open_the_beak_for_a_skipped_one_shot)
  • RUSTFLAGS="-D warnings" cargo clippy -p robotd --all-targets
  • On a real duck: robot shutdown sits and stays down (does not ramp home); later robot init does not stand it up until a new power-on
  • robotctl quack on a torqued robot opens the beak as well as calling

A sit-then-power-off went limp with this tick's snapshot still showing
enabled, so the enable-driven bring-up ramped home immediately (pollen-robotics#159).
Ignore robot.init for the rest of that sequence, and go Limp on the
no-sit path too.

robotctl quack was voice-only; the pad already opens the mouth via the
triggers. Hold the beak open for a one-shot so you can tell which duck
answered (pollen-robotics#153).

Drop a duplicate #[cfg(test)] in chorale so clippy -D warnings passes.

Assisted-by: Cursor Grok 4.6
@apirrone
apirrone self-requested a review August 29, 2026 08:17
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.

[bug] when shutting down, it sits down (normal) but then goes to init (the bug)

1 participant