Training guide · verbatim from the official docs
SONIC on a new robot: seven files, one mapping
SONIC's training pipeline is designed around the Unitree G1 (29 DOF) but can be extended to other humanoids. The official guide walks through every file you need to touch, using the Unitree H2 (31 DOF) as the concrete example — everything here is transcribed from the Training on New Embodiments doc.
Files you need to add or modify
| File | Action | Purpose |
|---|---|---|
gear_sonic/data/assets/robot_description/urdf/<robot>/ | Add | URDF + mesh files for Isaac Lab simulation |
gear_sonic/data/assets/robot_description/mjcf/<robot>.xml | Add | MuJoCo XML for motion library forward kinematics |
gear_sonic/envs/manager_env/robots/<robot>.py | Add | Robot config: joints, actuators, mappings, action scales |
gear_sonic/envs/manager_env/robots/__init__.py | Modify | Import your new robot module |
gear_sonic/envs/manager_env/modular_tracking_env_cfg.py | Modify | Add robot to robot_mapping dict (~line 998) |
gear_sonic/trl/utils/order_converter.py | Modify | Add converter class for joint/body reordering |
gear_sonic/config/exp/manager/universal_token/all_modes/sonic_<robot>.yaml | Add | Experiment config |
Config YAMLs (terminations, rewards, commands) | Check | Body names must exist on your robot |
The full H2 support ships in the repo as a reference implementation: robot config, URDF + meshes, MJCF, experiment config, H2Converter, and the robot_mapping entry all exist — copy them for your own robot.
Step 1 · Robot model files
gear_sonic/data/assets/robot_description/
|-- urdf/h2/
| |-- h2.urdf
| `-- meshes/ # STL/OBJ mesh files
`-- mjcf/
`-- h2.xml # MuJoCo XML The URDF is loaded by Isaac Lab for physics simulation. The MJCF is used by the motion library to compute forward kinematics on reference motion data. Both must represent the same robot with consistent joint names and tree structure. Make sure your URDF mesh paths are correct — relative paths like meshes/pelvis.stl work best; if your URDF uses package:// paths, update them to match the directory layout.
Step 2 · Robot configuration
Create gear_sonic/envs/manager_env/robots/<robot>.py — the most important file; it defines how your robot integrates with the training pipeline. The articulation config uses Isaac Lab's ArticulationCfg with UrdfFileCfg spawn, init_state, and one ImplicitActuatorCfg group per motor type (legs, arms, waist, feet, etc.). Two init_state notes from the docs:
posz-value is the spawn height — set it so the robot starts standing with feet slightly above ground. Too low = feet clip through ground on first frame.joint_posshould be a stable standing pose, from your robot's real default calibration pose or a MuJoCo keyframe.
Joint and body ordering — the critical part
Isaac Lab and MuJoCo traverse the kinematic tree in different orders. You must define bidirectional index mappings. Get these by loading your URDF in Isaac Lab and your MJCF in MuJoCo, printing the joint/body lists, and computing the reorder indices.
# All bodies in IsaacLab traversal order (including root "pelvis")
H2_ISAACLAB_JOINTS = [
"pelvis",
"left_hip_pitch_link",
"right_hip_pitch_link",
# ... all 32 bodies for H2
]
# Index arrays: position i in the output = position mapping[i] in the input
H2_ISAACLAB_TO_MUJOCO_DOF = [...] # len = num_dof (31 for H2)
H2_MUJOCO_TO_ISAACLAB_DOF = [...]
H2_ISAACLAB_TO_MUJOCO_BODY = [...] # len = num_bodies (32 for H2)
H2_MUJOCO_TO_ISAACLAB_BODY = [...]
H2_ISAACLAB_TO_MUJOCO_MAPPING = {
"isaaclab_joints": H2_ISAACLAB_JOINTS,
"isaaclab_to_mujoco_dof": H2_ISAACLAB_TO_MUJOCO_DOF,
"mujoco_to_isaaclab_dof": H2_MUJOCO_TO_ISAACLAB_DOF,
"isaaclab_to_mujoco_body": H2_ISAACLAB_TO_MUJOCO_BODY,
"mujoco_to_isaaclab_body": H2_MUJOCO_TO_ISAACLAB_BODY,
} Actuator parameters (KP/KD tuning)
The actuator stiffness (KP) and damping (KD) are critical for sim-to-real transfer and training stability. SONIC uses implicit PD actuators in Isaac Lab.
# Derive from motor specs — these need tuning for your robot
NATURAL_FREQ = 10 * 2.0 * 3.1415926535 # 10Hz natural frequency
DAMPING_RATIO = 2.0 # Overdamped for stability
# Per-motor stiffness: KP = armature * omega^2
STIFFNESS_5020 = ARMATURE_5020 * NATURAL_FREQ**2
# Per-motor damping: KD = 2 * zeta * armature * omega
DAMPING_5020 = 2.0 * DAMPING_RATIO * ARMATURE_5020 * NATURAL_FREQ Tuning guidance (verbatim):
- Start with the real motor's armature (rotor inertia) from the datasheet.
- The natural frequency controls responsiveness. 10 Hz is a good starting point for humanoids. Increase for stiffer/faster tracking, decrease for compliance.
- The damping ratio should be >= 1.0 (critically damped or overdamped) to avoid oscillation. 2.0 works well for SONIC.
- Different joint groups need different gains. Hip/knee motors are much stronger than wrist motors. Group joints by motor type (see G1/H2 configs for examples).
- If training is unstable (robot explodes or falls immediately), your KP/KD values are likely wrong — try reducing KP or increasing KD.
- The effort limits (max torque) per joint should match the real motor specs.
Action scale
Action scale maps normalized policy outputs to joint position targets. Compute it from effort limit and stiffness:
{
H2_ACTION_SCALE = }
for joint_name in joint_names:
H2_ACTION_SCALE[joint_name] = effort_limit[joint_name] / stiffness[joint_name] Larger action scale = larger joint movements per policy output. If the robot moves too aggressively, reduce the action scale. Then register the module in robots/__init__.py and add the robot to the robot_mapping dict in modular_tracking_env_cfg.py (around line 998); the string key (e.g. "h2") is what you use as robot.type in the experiment config.
Step 3 · Order converter + body name compatibility
In gear_sonic/trl/utils/order_converter.py, add a converter class (e.g. H2Converter(IsaacLabMuJoCoConverter)) used by the evaluation and export pipeline, wiring the same DOF and body mappings plus the VR tracking and foot contact body names (VR_3POINTS_BODY_NAMES, FOOT_BODY_NAMES). Use lazy imports (inside __init__) to avoid circular dependencies.
Body name compatibility is a common source of errors. The training configs reference specific body names that must exist on your robot — check all of them:
- Command config (
config/manager_env/commands/terms/motion.yaml):anchor_body,vr_3point_body,reward_point_body, and the 14 trackedbody_names. - Termination configs:
ee_body_pos_adaptive.yaml(ankle + wrist links),foot_pos_xyz.yaml(ankle links). - Reward configs:
undesired_contacts.yaml(regex excluding ankle/wrist links from contact penalty),anti_shake_ang_vel.yaml(wrist links +head_link).
If names differ (H2 has head_yaw_link where G1 has head_link), either override the specific fields in your experiment config (recommended) or copy the affected term YAMLs into robot-specific variants. Tip from the docs: run training with num_envs=1 first — Isaac Lab raises a clear error naming the missing body.
Step 4 · Motion data (PKL format)
SONIC expects retargeted motion data as PKL files (joblib format). Each file contains a dict keyed by motion name:
{
"motion_name": {
"root_trans_offset": np.ndarray, # (T, 3) — root translation
"pose_aa": np.ndarray, # (T, num_bodies, 3) — axis-angle per body
"dof": np.ndarray, # (T, num_dof) — joint positions in MuJoCo order
"root_rot": np.ndarray, # (T, 4) — root quaternion (wxyz)
"smpl_joints": np.ndarray, # (T, 24, 3) — SMPL joint positions (optional)
"fps": int, # Frame rate (typically 30)
}
} Important data format notes: num_bodies and num_dof must match your robot (e.g. 32 bodies / 31 DOF for H2); dof values must be in MuJoCo joint order, not IsaacLab order; pose_aa must be in MuJoCo body order; mirrored variants (filename ending in _M.pkl) double your effective dataset size and improve symmetry; smpl_joints is used by the SMPL encoder — set it to zeros if you don't have SMPL data. The motion library loads PKL files recursively from a directory (data/h2_motions/session_01/…).
Step 5 · Source motion data and retargeting
The recommended source is Bones-SEED — a large-scale human motion dataset (142K+ motions, ~288 hours) providing raw BVH files (full-body human motion capture) and G1 retargeted CSVs (already retargeted to the Unitree G1, 29 DOF). For a new robot you need to retarget the raw human motions to your robot's skeleton — the most labor-intensive step. Details and the download commands: data collection page and the Training Data doc.
Retargeting options:
- SOMA Retargeter (recommended) — NVIDIA's BVH-to-humanoid motion retargeting library built with Newton and NVIDIA Warp. Supports any humanoid robot via JSON configuration, includes a viewer for inspecting source and retargeted motions side by side. This is the same tool used to produce the Bones-SEED G1 retargeted data.
- GMR (General Motion Retargeting) — retargets human motions to arbitrary humanoid robots in real time on CPU. Supports any URDF. A lighter-weight alternative.
- This repo's data processing (
gear_sonic/data_process/) — converts retargeted CSVs/BVHs into the PKL format SONIC expects, as the final step after retargeting:# Convert retargeted CSVs to motion library PKLs python gear_sonic/data_process/convert_soma_csv_to_motion_lib.py \ --input /path/to/retargeted_csvs/ \ --output data/my_robot_motions/robot \ --fps 30 --fps_source 120 --individual --num_workers 16 # Filter out motions that are physically impossible for your robot python gear_sonic/data_process/filter_and_copy_bones_data.py \ --source data/my_robot_motions/robot \ --dest data/my_robot_motions/robot_filtered
For SMPL data: pre-computed SMPL for Bones-SEED motions is on Hugging Face (python download_from_hf.py --training); for custom motions extract SMPL joints from BVH with gear_sonic/data_process/extract_soma_joints_from_bvh.py; or set smpl_motion_file: dummy.
Step 6 · Experiment config
Create gear_sonic/config/exp/manager/universal_token/all_modes/sonic_<robot>.yaml — start by copying sonic_release.yaml and modify. Fields to review and potentially override:
robot.type— must match the key inrobot_mappingmotion_lib_cfg.asset.assetFileName— your MJCF filereward_point_body/reward_point_body_offset— key bodies for reward computationvr_3point_body/vr_3point_body_offset— if doing VR teleoperationupper_body_augment_prefixes— remove if your motion data uses different naming- Body names in reward/termination overrides — see the body compatibility section
Step 7 · Train
python gear_sonic/train_agent_trl.py \
+exp=manager/universal_token/all_modes/sonic_h2 \
num_envs=16 headless=False \
++manager_env.commands.motion.motion_lib_cfg.motion_file=<path/to/h2_motions> Start with num_envs=16 headless=False to visually verify the robot loads and motions play correctly, then scale up to num_envs=4096 headless=True for full training. A full training checklist (mappings verified, KP/KD per motor group, mirrored variants, SMPL data) is in the official doc — the full SONIC training flow (installation, finetune from checkpoint, evaluation) is on the training page.