Skip to content

Microduck is a small biped with 14 servos, made by Pollen Robotics. This model comes from microduck_rl by Pollen Robotics, under the Apache-2.0 licence. Not made by Lucen Robotics. Listed as a reference model for simulation.

biped14 joints0.737 kg in simulation50 Hz

Use it from Python

The same download from a script or a notebook.

from lucen import Hub

hub = Hub()
hub.pull("lucen/microduck", "./microduck")

The module comes with the CLI. Python guide.

Microduck, standing in its home pose

Move its joints, or let it fall under gravity, in your browser. About 10 MB the first time. Open the full simulator

README

README.md

Microduck

Microduck is a small biped with 14 servos, made by Pollen Robotics. This model comes from microduck_rl by Pollen Robotics, under the Apache-2.0 licence. The licence text is in LICENSE.

Not made by Lucen Robotics. Listed as a reference model for simulation.

Microduck is about 25 cm tall. Its 14 Dynamixel XL330 servos drive two legs of five joints and a neck and head of four. It was exported from Onshape with onshape-to-robot.

This repo holds the walking model, whose feet alone touch the floor, and its floor scene. The scene has four poses: INIT, STAND, SIT and FOLD.

A check it fails

The robot check stability.settle fails for this robot. It was published anyway, for this reason:

Microduck stands only under its policy. The model's own position servos (kp 0.55 N·m/rad, at most 0.96 N·m) do not hold the standing pose under gravity. The knees sag and it falls within a second, in plain MuJoCo too. Pollen's policies train against a model of the XL330 servo's voltage, which an MJCF cannot carry. So a hold on fixed gains is the wrong test for this robot. The failed check stays on the card, so nobody reads it as a robot that stands on its own.

The robot page shows the failed check, with its date.

How it was set up

The files come from src/mjlab_microduck/robot/microduck in microduck_rl, at commit cb70b79. The robot card was drafted from the model by lucen robot init, as in Add your robot.

The model file does not state the values below. Each one comes from the source beside it.

SettingValueWhere it comes from
Control rate50 Hzpollen-robotics/microduck-policies manifest.json robot.control_hz: 50; mjlab 1.3.0 timestep 0.005 s x decimation 4
Actionoffset from the default posemjlab 1.3.0 velocity task: JointPositionActionCfg(use_default_offset=True)
Action scale1.0microduck_velocity_env_cfg.py: joint_pos_action.scale = 1.0
Default posethe STAND keyframescene_walk.xml's STAND keyframe, which microduck_constants.py's HOME_FRAME matches (its first keyframe, INIT, has every joint at zero)
What a policy sensesjoint positions, joint velocities, base angular velocity, gravity directionmicroduck_velocity_env_cfg.py actor terms: base_lin_vel deleted, USE_PROJECTED_GRAVITY = True
Commandforward, sideways and turning speedthe task's twist command (vx, vy, yaw); its head-pose commands have no slot in the enum
Everything elseread from the model filejoint order, ranges, and kp 0.55 / kv 0 / force limit 0.96 N·m from the MJCF's own chosen_actuator <position> class, which robot_walk.xml annotates as the firmware's "200 kp"; the policies themselves train against BAM's XL330 voltage model (kp_fw 200), which an MJCF cannot carry.

The configs cited above, at the commits read:

No file from the source was changed. This README, the robot card and the robot's pictures are new.