How to Configure Head COM Randomization in Microduck RL: A Complete Guide
Enable ENABLE_HEAD_COM_RANDOMIZATION, adjust HEAD_COM_RANDOMIZATION_RANGE for magnitude, and customize HEAD_BODY_NAMES to control which head bodies receive randomized center-of-mass offsets each episode.
Head center-of-mass (COM) randomization is a critical domain-randomization technique in the Microduck RL repository that improves sim-to-real transfer by varying the mass distribution of the robot's head assembly every episode. This training-time randomization forces the policy to become robust to manufacturing tolerances and assembly variations in the real Pollen Robotics Microduck platform.
Understanding Head COM Randomization in Microduck RL
Microduck RL implements non-accumulating head COM randomization through a five-part configuration system in microduck_velocity_env_cfg.py. Unlike physics parameters that drift over time, each episode applies fresh random offsets, ensuring stable long-term training behavior.
Key Implementation Files
src/mjlab_microduck/tasks/microduck_velocity_env_cfg.py— main walking task configuration (lines 30–33, 58–66, 66–72, 420–426, 870–878)src/mjlab_microduck/tasks/microduck_velocity_rollers_env_cfg.py— roller variant with identical randomization setupsrc/mjlab_microduck/tasks/microduck_standup_env_cfg.py— stand-up task configurationsrc/mjlab_microduck/tasks/mdp.py— low-level helper functions for MJCF model manipulationtests/test_swizzle_head_cfg.py— unit tests verifying configuration integrity
Step 1: Enable Head COM Randomization
The boolean flag ENABLE_HEAD_COM_RANDOMIZATION located at src/mjlab_microduck/tasks/microduck_velocity_env_cfg.py#L30-L33 controls whether the feature is active.
# Default configuration (enabled)
ENABLE_HEAD_COM_RANDOMIZATION: bool = True
Setting this to False completely disables the randomization pipeline, useful for deterministic debugging or ablation studies.
Step 2: Configure the Randomization Range
HEAD_COM_RANDOMIZATION_RANGE at src/mjlab_microduck/tasks/microduck_velocity_env_cfg.py#L58-L66 specifies the ± range in meters applied to each head body's COM. The default value is ±0.003 m (3 mm).
# Default 3mm range
HEAD_COM_RANDOMIZATION_RANGE: float = 0.003
# Increased robustness: 5mm range
HEAD_COM_RANDOMIZATION_RANGE: float = 0.005
This value serves as the initial range; curriculum learning typically expands it during training.
Step 3: Specify Affected Head Bodies
HEAD_BODY_NAMES at src/mjlab_microduck/tasks/microduck_velocity_env_cfg.py#L66-L72 defines which bodies undergo COM randomization using regex patterns.
# Default: comprehensive head assembly coverage
HEAD_BODY_NAMES: tuple[str, ...] = (
"neck",
"neck_pitch",
"yaw_roll_motion",
"(bottom_head_shell|jaw_soft)",
)
Each regex matches body names in the MJCF model. The tuple structure allows precise control over which mechanical components experience mass distribution shifts.
Step 4: Wire Randomization into Episode Events
The EventTermCfg named randomize_head_com at src/mjlab_microduck/tasks/microduck_velocity_env_cfg.py#L420-L426 hooks the randomization into the environment's event system, triggering at episode start.
Step 5: Ramp with Curriculum Learning
The CurriculumTermCfg named head_com_range at src/mjlab_microduck/tasks/microduck_velocity_env_cfg.py#L870-L878 progressively increases randomization difficulty:
- Start: ±0.003 m at step 0
- End: ±0.01 m at step 500,000
This curriculum schedule prioritizes early policy stability before introducing challenging mass distributions.
Complete Configuration Example
# Custom microduck_velocity_env_cfg.py excerpt
from mjlab_microduck.tasks.microduck_velocity_env_cfg import (
ENABLE_HEAD_COM_RANDOMIZATION,
HEAD_COM_RANDOMIZATION_RANGE,
HEAD_BODY_NAMES,
)
from mjlab.managers import CurriculumTermCfg, EventTermCfg
# 1. Enable feature
ENABLE_HEAD_COM_RANDOMIZATION = True
# 2. Set 5mm randomization range
HEAD_COM_RANDOMIZATION_RANGE = 0.005
# 3. Restrict to neck and rigid head components
HEAD_BODY_NAMES = (
"neck",
"neck_pitch",
"yaw_roll_motion",
"bottom_head_shell", # note: removed jaw_soft for this variant
)
# 4. Custom curriculum: faster ramp to 10mm
head_com_curriculum = CurriculumTermCfg(
name="head_com_range",
start_step=0,
end_step=300_000, # faster progression
start_val=0.003,
end_val=0.010,
event_name="randomize_head_com",
)
Disabling Head COM Randomization
For reproducible debugging or hardware validation:
# Deterministic configuration
from mjlab_microduck.tasks.microduck_velocity_env_cfg import (
ENABLE_HEAD_COM_RANDOMIZATION,
)
ENABLE_HEAD_COM_RANDOMIZATION = False
# Remove or comment out the curriculum entry to prevent warnings
Advanced: Multi-Task Randomization Strategies
Different Microduck variants implement head COM randomization with task-specific defaults:
| Task File | Default Range | Curriculum End Range |
|---|---|---|
microduck_velocity_env_cfg.py |
±3 mm | ±10 mm |
microduck_velocity_rollers_env_cfg.py |
±3 mm | ±10 mm |
microduck_standup_env_cfg.py |
±3 mm | ±8 mm |
Copy configuration patterns between these files when developing new locomotion behaviors requiring robust head control.
Summary
- Enable/disable head COM randomization via
ENABLE_HEAD_COM_RANDOMIZATIONboolean flag - Control magnitude through
HEAD_COM_RANDOMIZATION_RANGE(meters) andhead_com_rangecurriculum - Select bodies by editing
HEAD_BODY_NAMESregex tuple to match specific MJCF body names - Verify implementation in
microduck_velocity_env_cfg.pylines 30–33, 58–72, 420–426, and 870–878 - Leverage non-accumulating behavior for stable long-duration training runs
Frequently Asked Questions
What happens if I increase HEAD_COM_RANDOMIZATION_RANGE too aggressively?
Excessive range values (above ±15 mm) can destabilize the head control policy, causing training failures or erratic behaviors. The default curriculum smoothly ramps from 3 mm to 10 mm over 500k steps to avoid this. Monitor the head_pose tracking error in TensorBoard when adjusting ranges.
Does head COM randomization affect all Microduck RL tasks?
According to the source code, the walking (microduck_velocity), roller (microduck_velocity_rollers), and stand-up (microduck_standup) tasks all implement head COM randomization. New tasks must explicitly configure randomize_head_com in their event tables and optionally add head_com_range curricula.
Can I randomize COM for other body parts using the same mechanism?
Yes. The mdp.py helper functions support arbitrary body lists. Create a new EventTermCfg with your custom body regex tuple and wire it through a corresponding curriculum term. The head-specific implementation serves as the reference pattern.
How do I verify my head COM randomization configuration is active?
Run the unit test in tests/test_swizzle_head_cfg.py which validates the head_pose command presence and confirms ENABLE_HEAD_COM_RANDOMIZATION is properly honored. Additionally, enable Isaac Sim's visualization to observe COM markers shifting at episode boundaries.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →