Primary question: Does the mjlab + BAM + ONNX sim2real recipe transfer to your robot, or is it mainly a reference for Microduck-class bipeds?
RepoDaily adoption score
RepoDaily rates this as 88/100 (strong) for adoption: evidence, installation path, production risk, differentiation, license clarity, and AI/agent fit are scored from the article sources and adoption notes.
4 source(s) across 4 source category/categories, plus a RepoDaily-specific evidence module when available.
5 workflow step(s), 4 next-action step(s), and 2 command/install signal(s) were detected.
Trending momentum is +384 stars, with maintenance/release/issue signals counted when present.
Risk is marked medium, with 4 security note(s) and 4 explicit skip condition(s).
3 opportunity lens item(s), 3 alternative(s), and 4 type-specific section(s) support differentiation.
License source or license wording is present.
3 AI/agent-related signal(s) were detected in the article text and metadata.
Project overview
microduck_rl is the training half of Pollen Robotics' two-repo Microduck layout. This repo holds the reinforcement-learning environments; the companion pollen-robotics/microduck repo holds the runtime that executes trained policies on the physical robot. The robot itself is a ~800 g, ~25 cm biped, and every task in the registry is built around that body: walking with velocity and head-pose commands, standing up from face-down or sitting positions, forward rolls, roller skating on passive wheels, and kicking a 70 mm / 15 g ball with a policy that cannot see the ball.
The technical base is mjlab 1.3.0, which runs MuJoCo through Warp (warp-lang 1.12.0) on CUDA GPUs, with PPO as the training algorithm and a 50 Hz control rate that matches deployment. What separates this repo from a generic environment collection is that the sim2real recipe is explicit: BAM actuator physics from Rhoban's better-actuator-models (branch mjlab_frictionloss), domain randomization, backlash simulation, and a reward-design playbook distilled into AGENTS.md. Trained policies export to ONNX, then either run in CPU MuJoCo via scripts/infer_policy.py or get deployed on the robot by the companion runtime.
It picked up 384 stars in the trending period at rank 18, which is unusual for a repo tied to one vendor's hardware. The reason it travels beyond Microduck owners is that the training loop, the actuator modeling, and the export path are all reusable, and the --hf-jobs flag lets you submit the same train command to Hugging Face Jobs when no local GPU exists.
Why it is trending now
- 384 stars in the period (rank 18) for a hardware-adjacent training repo, with a README that opens on real-robot footage: walking, standup, roulade, and roller skating.
- The complete sim2real recipe is public: BAM actuator physics, domain randomization, backlash simulation, and reward-design notes in AGENTS.md.
- 18 task ids across 13 families, from Mjlab-Velocity-{Flat,Rough}-MicroDuck to Mjlab-Spin-Flat-MicroDuck, all listed live by `uv run list-envs`.
- No local GPU required for a trial run: appending --hf-jobs to any train command submits it to Hugging Face Jobs instead.
- Apache-2.0 licensing, including the patent grant, makes the code safe to fork for other small bipeds.
Problem it solves
- Biped policy training usually means assembling a physics engine, actuator models, terrain randomization, and a deployment bridge by hand — this repo ships that assembly as one pinned stack.
- Idealized actuators hide the gear backlash that breaks sim2real transfers; microduck_rl simulates backlash explicitly instead of hoping randomization covers it.
- Training code and deployment code often sit in private company repos; here the split is visible: this repo trains and exports ONNX, pollen-robotics/microduck runs it on hardware.
- CUDA setup friction is real: the first `uv sync` pulls ~2 GB of CUDA wheels, and on ARM boxes (DGX Spark / GB10, Jetson) uv's default 30 s HTTP timeout can abort the download mid-stream.
How it works
- mjlab runs thousands of parallel MuJoCo environments through Warp on a CUDA GPU; the README's default train command uses 4096 environments.
- PPO learns a policy at 50 Hz — the same rate the real robot's runtime consumes actions.
- BAM (better-actuator-models, import name `bam`) supplies higher-fidelity actuator physics including friction loss; domain randomization and backlash simulation wrap the robot model.
- Checkpoints are tracked through Weights & Biases; `uv run play ... --wandb-run-path <entity/project/run_id>` replays a run in the viewer.
- `scripts/export.py` converts the policy to ONNX, then either the companion repo's runtime deploys it on the robot or `scripts/infer_policy.py --walking output.onnx` drives it in CPU MuJoCo with the keyboard.
Architecture read: one entry point, two repos, three pins
The package is named mjlab-microduck (version 0.1.0) and registers itself as an mjlab task provider through the `mjlab.tasks` entry point pointing at `mjlab_microduck.tasks`. That is the same plugin mechanism mjlab itself uses, so the repo extends the framework rather than forking it. The `train` console script deliberately shadows mjlab's own entry point: behavior is identical, plus a `--hf-jobs` flag that submits the run to Hugging Face Jobs instead of executing locally (implemented in train_cli.py).
Three version decisions define the stack: mjlab==1.3.0, warp-lang==1.12.0, and Python >=3.12,<3.13. The upper bound exists because bam (better-actuator-models) pins requires-python <3.13, and a floating bound once let Hugging Face Jobs pick 3.13.14. The remaining dependencies are onnxruntime>=1.24.4, rustypot>=1.4.2, huggingface_hub>=0.27.0, matplotlib>=3.10.9, and scipy>=1.16.
Command surface: the CLI loop from clone to ONNX
- `uv run list-envs` — prints the live task registry, so you never guess task ids.
- `uv run train Mjlab-Velocity-Flat-MicroDuck --env.scene.num-envs 4096` — trains the main walking task; ~1–2 h for a usable gait at 4096 envs.
- `uv run play Mjlab-Velocity-Flat-MicroDuck --wandb-run-path <entity/project/run_id>` — watches a trained policy in the viewer.
- `uv run scripts/export.py Mjlab-Velocity-Flat-MicroDuck --wandb-run-path <...>` — exports the policy to ONNX for deployment.
- `uv run scripts/infer_policy.py --walking output.onnx` — drives the exported policy in CPU MuJoCo with the keyboard, no GPU needed.
- Resume from a checkpoint: append `--agent.run-name resume --agent.load-checkpoint model_29999.pt --agent.resume True`.
- Any train command accepts `--hf-jobs` to run on Hugging Face Jobs; details live in scripts/hf/README.md.
- On ARM boxes, export `UV_HTTP_TIMEOUT=600` before the first sync or the ~2 GB CUDA wheel download can die at uv's 30 s default timeout.
Maintenance risk: the overrides tell the story
- scipy>=1.16 is declared here because mjlab 1.3.0 imports scipy (terrains/heightfield_terrains.py) without declaring it — a fresh `uv sync` could not even import the package (found 2026-07-21).
- protobuf is overridden to >=4.0,<7.0 because bam pins protobuf<4, which cascades onnx down to 1.17.0 — a version with no wheel that fails to build from source.
- The PyPI stub `zmq==0.0.0` (a bam dependency) ships an invalid wheel missing .dist-info; it is dropped via an always-false marker because only bam.model/bam.actuator are used.
- mujoco must NOT be overridden: mujoco-warp pins mujoco 3.10.x, and a previous override forcing 3.4.0 crashed imports because 3.4.0 lacks mjDSBL_MULTICCD.
- Version 0.1.0 plus fix comments dated 2026-07-21 indicate a young dependency graph; expect the pin set to keep moving.
Try-it path: what a first session looks like
On a CUDA machine the loop fits in one sitting: clone the repo, run `uv sync` (set `UV_HTTP_TIMEOUT=600` first on DGX Spark / GB10 or Jetson), train the velocity task at 4096 environments for one to two hours, replay the run in the viewer, export to ONNX, and finally drive the exported policy in CPU MuJoCo with the keyboard to confirm behavior without hardware. Without a CUDA GPU, the same session runs on Hugging Face Jobs by adding `--hf-jobs`, which keeps trial cost at zero but moves the training run to your Hugging Face account.
Who should pay attention?
Good fit if
- Owners of Microduck hardware who want the reference training pipeline, not just the runtime.
- Engineers porting a walking or fall-recovery policy to a small biped of similar scale (~800 g, ~25 cm).
- Researchers comparing actuator fidelity: BAM friction-loss modeling against idealized torque actuators.
- Anyone who wants a worked example of the mjlab plugin system (`mjlab.tasks` entry points) before writing their own environments.
Skip for now if
- Projects targeting quadrupeds, arms, or drones — every task id here is built around the Microduck biped's morphology.
- Environments locked to Python 3.13+, since bam forces requires-python <3.13.
- Setups unwilling to touch Weights & Biases for run tracking or Hugging Face Jobs for remote training — both are wired into the default loop.
- Production services expecting a stable API; the package sits at 0.1.0 and its override comments record ongoing upstream breakage.
Risks and cautions
Apache-2.0 with reproducible pins, but the dependency graph is fragile in documented ways and the task set targets a single robot.
- Python is capped below 3.13 by a bam pin, which can collide with newer CUDA stacks.
- Four override-dependencies are required for `uv sync` to succeed, each fixing breakage in an upstream package: mjlab's missing scipy, the protobuf/onnx cascade, the invalid zmq wheel, and the mujoco-warp pin.
- Deployment depends on the companion pollen-robotics/microduck runtime; this repo alone only produces ONNX files.
- Package version 0.1.0 with fixes dated 2026-07-21 signals the pin set is still moving.
- Apache-2.0, including the Section 3 patent grant, so commercial use and forking are unambiguous.
- Training runs locally on your GPU by default; `--hf-jobs` sends runs to Hugging Face Jobs and checkpoint replay needs a Weights & Biases run path — both move data to third-party accounts.
- No network-facing services ship with the package; it is a training library plus CLI scripts.
- First install downloads ~2 GB of CUDA wheels from PyPI; the ARM timeout workaround (`UV_HTTP_TIMEOUT=600`) is documented in the README.
Alternatives to compare
| Approach | When to use | Trade-off |
|---|---|---|
NVIDIA Isaac Lab | You want a vendor-maintained GPU RL framework covering many robot models and sensors beyond a single biped. | Free, open source |
legged_gym | You follow the leggedrobotics/ETH pipeline for quadruped locomotion and want the environment style recent papers are written against. | Free, open source |
MuJoCo Playground | You prefer Google DeepMind's MJX/JAX training environments over the Warp-based mjlab stack, with many robots ready to run. | Free, open source |
What this trend reveals
Register a second robot without forking the trainer
Tasks plug in through the `mjlab.tasks` entry point (`mjlab_microduck.tasks`), so another small biped can join the registry by shipping its own package rather than patching this one.
Copy Mjlab-Velocity-Flat-MicroDuck for your MJCF model and confirm the new id appears in `uv run list-envs` output.
Reuse BAM actuator physics outside Microduck
better-actuator-models is pinned from Rhoban's mjlab_frictionloss branch and only bam.model/bam.actuator are imported here — the same models can raise actuator fidelity in any mjlab environment.
Import bam.model in a bare mjlab environment and compare torque traces against an idealized actuator on one joint.
Move policy iteration to Hugging Face Jobs
The `--hf-jobs` flag on the shadowed `train` entry point runs identical commands remotely, turning a laptop into a submission client for 4096-env PPO runs.
Submit a short Mjlab-Spin-Flat-MicroDuck run with `--hf-jobs` and measure queue-to-checkpoint time against a local GPU.
RepoDaily verdict
microduck_rl is not a general-purpose RL framework — it is a complete, opinionated sim2real pipeline for one 800 g biped, and its value is exactly that completeness: BAM actuator physics, domain randomization, backlash simulation, 18 task ids, ONNX export, and a remote-compute escape hatch, all under Apache-2.0. Adopt it if you build small bipeds or want the most legible public example of MuJoCo Warp training that ends on real hardware; treat the pinned dependency graph (Python <3.13, four overrides) as the price of that legibility, and verify your target Python and CUDA stack can live inside it.