--- license: apache-2.0 language: en tags: [microduck, policy, bow, reinforcement-learning, mujoco, onnx] --- # 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 /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 /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.