microduck-bow

A bow for the Microduck (Pollen Robotics). Episodic, phase-driven policy (10 s cycle, 6.1 s gesture, hand-back at 7 s), trained with pollen-robotics/microduck_rl on a custom task (Mjlab-Bow-Flat-MicroDuck).

The gesture: the beak comes down to 2 cm above the floor without touching it, with the legs bending symmetrically during the descent; the head turns about 83° to the left and back; the knees bend; the duck stands back up.

Installing on the robot

This is a phase-encoded policy: it goes into the ground_pick slot (the ground-pick button triggers it), not into a skill (policy add refuses non-constant encodings).

sudo robotctl policy load ground_pick <user>/microduck-bow

Back to the official ground pick: sudo robotctl policy reset ground_pick.

The daemon drives the phase with the period set in robotd.toml and hands back at φ = 0.7 (the official set's value, not configurable). The policy is trained on a 10 s cycle whose gesture fills the first 6.1 s: with ground_pick_period = 10.0, the hand-back lands at 7 s, after the rise.

sudo robotctl policy load ground_pick <user>/microduck-bow
# then in /etc/robot/robotd.toml: ground_pick_period = 10.0

The video in the Video Preview panel shows one full cycle in simulation (mjlab / MuJoCo Warp, BAM actuators), 11 s.

Rehearsal in simulation

With the official walking and standing policies from pollen-robotics/microduck-policies (press G to trigger the bow):

uv run scripts/infer_policy.py --walking alpha_walking.onnx --standing alpha_stand.onnx \
    --ground-pick policy.onnx --ground-pick-period 10.0 --ground-pick-end-phase 0.7 --new-cmd-obs

Evaluation (simulation)

Headless rollout, 256 environments × 20 s, no pushes (mjlab 1.3.0, BAM XL330 actuator model):

Metric Value
Falls 0 %
Beak contact with the floor none (minimum height 1.8 cm, head/floor force ≤ 0.16 N)
Clean hover (beak never below 1.5 cm, no contact force) 90 % of cycles
Left/right leg symmetry during the descent 1.2° mean mirror error
Head yaw reached 83°
Knee bend before the rise 62° / 61°
Trunk tilt at the lowest point 33°

Provenance

Checkpoint model_499.pt of run v8_hover_sym (500 iterations, warm-started from the previous version). Version lineage: v1 → v2 (force cap, strict feet, sliding descent target) → v4 (contact-force band) → v5 (no second contact) → v6 (knee bend) → v7 (10 s period for the daemon's 0.7 cutoff) → v8 (no contact, symmetric legs). The ONNX graph embeds the observation normalizer (exported with scripts/export.py); the training checkpoint is not included.

Downloads last month
33
Video Preview
loading