Skip to content

New Embodiment : support for Agibot-X2#112

Open
devsolotech wants to merge 5 commits intoNVlabs:mainfrom
devsolotech:agibot-x2
Open

New Embodiment : support for Agibot-X2#112
devsolotech wants to merge 5 commits intoNVlabs:mainfrom
devsolotech:agibot-x2

Conversation

@devsolotech
Copy link
Copy Markdown

Add Agibot X2 Ultra (31 DOF) Embodiment to GEAR-SONIC

This PR integrates the Agibot X2 Ultra humanoid (31 DOF) into the GEAR-SONIC whole-body control pipeline, covering the full path from robot description to SONIC training to MuJoCo sim-to-sim deployment.

What's included

Robot description

  • URDF, MJCF, and STL meshes for the X2 Ultra under robot_description/
  • Robot config (x2_ultra.py) with actuator groups, joint limits from vendor specs, and IsaacLab/MuJoCo index mappings (round-trip verified)
  • X2UltraConverter in order_converter.py for joint-order translation between URDF, IsaacLab, and MuJoCo conventions

SONIC training pipeline

  • Generalized the codebase beyond Unitree G1 (29 DOF) to support arbitrary DOF counts
  • Refactored convert_soma_csv_to_motion_lib.py with --robot flag and per-robot DOF axis/joint constants
  • Added factory functions (get_converter_for_skeleton, get_converter_for_mjcf) to order_converter.py; replaced hardcoded G1 DOF checks with dynamic num_dof
  • X2 experiment configs: full training (sonic_x2_ultra.yaml), smoke test (sonic_x2_ultra_smoke.yaml), tokenizer, actor-critic, and aux loss configs

Joint ordering fix

  • Fixed IsaacLab's alphabetical BFS traversal ordering -- head_yaw_link ("h") precedes left/right_shoulder_pitch_link ("l"/"r") at the same depth. The previous mapping assumed URDF XML order, causing head and shoulder DOFs to be cross-contaminated.
  • Documented the alphabetical BFS pitfall in conventions.md and new_embodiments.md

MuJoCo sim-to-sim deployment

  • eval_x2_mujoco.py -- runs a trained SONIC checkpoint in MuJoCo with Reference State Initialization, IsaacLab-faithful proprioception, FSQ quantization, and auto-reset on fall
  • dump_isaaclab_step0.py -- captures IsaacLab's step-0 obs/encoder/FSQ/decoder/action for side-by-side debugging
  • Fixed a critical sim-to-sim bug: MuJoCo free-joint qvel[3:6] is body-local (not world), which was silently double-rotating angular velocity and corrupting proprioception every step
  • docs/source/user_guide/sim2sim_mujoco.md -- documents 10 IsaacLab-vs-MuJoCo gotchas with symptoms, debugging recipes, and a symptom-to-cause table

Sim-to-sim deployment guide

Added docs/source/user_guide/sim2sim_mujoco.md -- a comprehensive guide for deploying trained SONIC checkpoints from IsaacLab to MuJoCo. Documents 10 IsaacLab-vs-MuJoCo gotchas discovered during this bring-up, 8 of which correspond to real bugs fixed in the code. Includes a symptom-to-cause lookup table and a step-by-step debugging recipe using dump_isaaclab_step0.py.

Results

IsaacLab MuJoCo (sim-to-sim)
X2 Ultra walking in IsaacLab X2 Ultra walking in MuJoCo

- URDF, MJCF, and STL meshes under robot_description/
- Robot config with actuator groups, joint limits from vendor specs,
  and IsaacLab/MuJoCo index mappings (round-trip verified)
- X2UltraConverter in order_converter.py
- Registered in robot_mapping and experiment config (sonic_x2_ultra.yaml)
- KP/KD use H2 motor constants as initial estimates pending vendor data

Made-with: Cursor
Generalize SONIC codebase to support robots beyond Unitree G1 (29 DOF):

- Refactor convert_soma_csv_to_motion_lib.py for multi-robot support with
  --robot flag, per-robot DOF axis/joint constants, and MJCF selection
- Add factory functions to order_converter.py (get_converter_for_skeleton,
  get_converter_for_mjcf) and move shared properties to base class
- Replace hardcoded G1 DOF check in motion_lib_base.py with dynamic num_dof
- Use dynamic converter selection in commands.py and token_losses.py instead
  of hardcoded G1Converter
- Add X2 Ultra experiment config with correct body names and motion file
- Add X2-specific smoke test configs: tokenizer (unitoken_x2_teleop_noz),
  actor-critic (x2_teleop_mlp_v1), aux losses (x2_recon_and_teleop_latent),
  and experiment YAML (sonic_x2_ultra_smoke) for 2-encoder training without
  SMPL data

Made-with: Cursor
…versal

Isaac Lab sorts sibling bodies alphabetically within each BFS level, so
head_yaw_link ("h") precedes left/right_shoulder_pitch_link ("l"/"r") at
the same depth. The previous mapping arrays assumed URDF XML order, which
caused head and shoulder DOFs to be cross-contaminated — arms appeared
bent inward while legs and waist looked correct.

Also documents the alphabetical BFS pitfall in conventions.md and
new_embodiments.md to prevent the same issue when onboarding future robots.

Made-with: Cursor
eval_x2_mujoco.py runs a trained SONIC checkpoint in MuJoCo with
Reference State Initialization, IsaacLab-faithful proprioception
(term order from PolicyCfg dataclass, history primed via broadcast-
fill), correct tokenizer obs in body frame, FSQ quantization in the
actor forward path, and auto-reset on fall. dump_isaaclab_step0.py
captures IsaacLab's step-0 obs/encoder/FSQ/decoder/action for
side-by-side debugging.

The biggest sim-to-sim bug fixed during bring-up: MuJoCo free-joint
qvel[3:6] is body-local, not world. Both the RSI write and the
per-step base_ang_vel read had to be corrected to stop double-
rotating the angular velocity, which had been silently corrupting
the proprioception every step.

docs/source/user_guide/sim2sim_mujoco.md catalogs ten such
IsaacLab vs. MuJoCo gotchas with symptoms, debugging recipe, and a
symptom-to-cause table so the next embodiment doesn't have to
rediscover them.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants