Histochemichael's picture
Document completed mocap and training pipeline
4e113e8 verified
|
Raw History Blame Contribute Delete
5.93 kB

25 Microducks — Electric Slide

This layer extracts two human dancer skeletons, retargets a 38.92-second Electric Slide to Pollen Robotics' Microduck, trains an expressive command policy, generates a 5×5 MuJoCo scene from the official robot_allcollisions.xml, and renders the result at 111 BPM. The official balancing policies and learned command timeline run at 50 Hz while MuJoCo integrates at 200 Hz.

What is included

  • 25 independently named Microduck instances in a centered 5×5 formation.
  • 525 generalized positions and 350 independently named position actuators.
  • Per-duck duplicated IMU/root sensors with unique names.
  • Collision-validated 1.2 m spacing for the final 25-duck performance.
  • A pale studio background, high-contrast checkerboard floor, and soft colored rim lights.
  • Human-motion-derived walking arcs, eight official left/right kick-policy accents, and measured turn sections. Pollen's published walking demo leaves lateral command at zero, so the choreography uses the policy's supported forward and turning gaits rather than pretending an unsupported strafe is a step.
  • A split screen: true front-follow camera on the center magenta duck and a full formation camera.
  • Direct physics diagnostics: foot strikes/liftoffs, falls, double-support gaps, root travel, yaw, minimum spacing, and inter-duck contacts.
  • Optional MP4 rendering and local-audio muxing. No copyrighted audio is bundled.

Human-motion and training pipeline

The local tutorial clip is not committed or uploaded. Derived skeleton data and source-free QA media live in mocap/derived.

uv run --no-project --with ultralytics --with opencv-python-headless --with numpy python electric_slide/mocap/extract_human_pose.py C:\path\to\electric-slide_1m43s-2m22s.mp4 --output electric_slide/mocap/derived

uv run --no-project --with numpy --with scipy --with opencv-python-headless python electric_slide/mocap/annotate_motion.py --pose electric_slide/mocap/derived/human_pose_coco17.npz --output electric_slide/mocap/derived

uv run --no-project --with numpy --with scipy python electric_slide/mocap/retarget_human_motion.py --features electric_slide/mocap/derived/motion_features.npz --output electric_slide/generated/motion_retarget_50hz.npz

Record the physically executed 14-joint teacher and train the expressive human-motion-to-command policy:

uv run --no-project --with mujoco --with numpy --with onnxruntime python electric_slide/training/record_physics_reference.py --output electric_slide/training/artifacts/duck_reference_50hz.npz

uv run python electric_slide/training/train_command_policy.py --retarget electric_slide/generated/motion_retarget_50hz.npz --output electric_slide/training/runs/reproduction --epochs 500 --seed 20260830

uv run --no-project --with numpy --with onnxruntime python electric_slide/training/apply_command_policy.py --retarget electric_slide/generated/motion_retarget_50hz.npz --policy electric_slide/training/runs/reproduction/human_motion_command_policy.onnx --output electric_slide/generated/learned_motion_retarget_50hz.npz

The final safety hierarchy locks the already validated travel/turn channels and kick schedule to the human-derived retarget. The trained model supplies expressive head/body commands, and Pollen's official policies supply balanced joint actions. A direct 61D-to-14D behavior-cloned policy was also trained, but failed closed-loop MuJoCo validation and is intentionally not used.

Generate and validate the MJCF

From the repository root:

python electric_slide/generate_scene.py
python -m unittest discover -s electric_slide/tests -v

Compile-check the generated model using an isolated CPU MuJoCo install:

uv run --no-project --with mujoco --with numpy python -c "import mujoco; m=mujoco.MjModel.from_xml_path('electric_slide/generated/microduck_25_scene.xml'); print(m.nq, m.nu)"

Expected dimensions are 525 350.

Download the official policies

uvx --from huggingface_hub hf download pollen-robotics/microduck-simulator app/public/policies/BEST_alpha_walking.onnx app/public/policies/ball_kick_left.onnx app/public/policies/ball_kick_right.onnx --repo-type space --local-dir electric_slide/official

Run the physics show

uv run --no-project --with mujoco --with numpy --with onnxruntime python electric_slide/physics_show.py --strict --scene electric_slide/generated/microduck_25_scene_1p2m.xml --spacing 1.2

Render a silent 720p MP4:

uv run --no-project --with mujoco --with numpy --with onnxruntime --with imageio --with imageio-ffmpeg python electric_slide/physics_show.py --strict --scene electric_slide/generated/microduck_25_scene_1p2m.xml --spacing 1.2 --width 1920 --height 720 --view split --render electric_slide/generated/electric_slide_25_ducks_learned_split_front.mp4

Mux a locally owned or licensed copy of Candy without adding it to the repository:

uv run --no-project --with mujoco --with numpy --with onnxruntime --with imageio --with imageio-ffmpeg python electric_slide/physics_show.py --strict --render electric_slide/generated/electric_slide_25_ducks_with_audio.mp4 --audio C:\path\to\Candy.mp3 --audio-offset 0

Use --audio-offset to choose the section of the song. The default show length is exactly 72 counts at 111 BPM.

Physics guarantee

After the initial keyframe reset, physics_show.py never writes a free-root pose. Every visible translation and turn comes from actuator targets, ground contact, and MuJoCo dynamics. The strict gate rejects falls, missing foot liftoffs, excessive airtime, insufficient travel, unsafe spacing, or any duck-to-duck contact. The diagnostics JSON is written beside each rendered video.

For real robots, retain the 50 Hz observation/action contract and validate one duck before synchronized deployment. The present spacing is a simulation-show result, not a substitute for physical multi-robot safety testing.