Repository navigation
urdf and mjcf joint ranges disagree for 15 of 23 joints (and mjcf torque caps) #4
Description
i diffed the joint ranges in urdf/rpo.urdf against mjcf/rpo.xml (rpo_stairs.xml and rpo_terrain.xml have identical ranges). 15 of the 23 actuated joints disagree. for reference i also pulled the joint limits that deploy enforces (roboparty_inference/robots/rpo/configs/default.yaml) and the v2.0 cad export (rpo_hardware/V2.0/roboto_origin_mechanic/03_URDF/urdf/roboto_origin.urdf).
| joint (left/right) | urdf | mjcf | deploy default.yaml | rpo_hardware v2.0 |
|---|---|---|---|---|
| thigh_roll | l [-0.2, 1.0], r [-1.0, 0.2] | l [-0.2, 2.0], r [-2.0, 0.2] | l [-0.6, 1.0], r [-1.0, 0.6] | same as urdf |
| thigh_pitch | [-2.094, 0.785] | [-2.5, 0.8] | [-1.57, 1.57] | [-1.57, 1.57] |
| knee | [-0.2, 2.5] | [0.0, 2.5] | [-0.2, 2.5] | [-0.2, 2.5] |
| ankle_pitch | [-0.6, 0.6] | [-0.7, 0.7] | [-0.6, 0.6] | [-0.6, 0.6] |
| torso | [-3.14, 3.14] | [-2.62, 2.62] | [-3.14, 3.14] | [-3.14, 3.14] |
| arm_pitch | [-3.14, 1.57] | [-3.14, 2.57] | [-3.14, 1.57] | [-1.57, 1.57] |
| arm_yaw | [-1.57, 1.57] | [-2.6, 2.6] | [-1.57, 1.57] | [-1.57, 1.57] |
| elbow_pitch | [-0.6, 1.57] | [-1.0, 3.57] | [-0.6, 1.57] | [-0.6, 1.57] |
torque: urdf effort is 120 for hips, knees and torso and 27 for ankles and arms. every mjcf motor has ctrlrange="-200 200". the dm driver (roboparty_motors/src/drivers/dm/dm_motor_driver.cpp:7-10) caps DM10010L at 200 and DM4340P at 28, and robot.yaml puts ankles and arms on the DM4340P, so mjcf lets those joints use about 7x the torque the motor can give.
the elbow change looks like it came in with 239066c ("update xml collision", 2026-03-03), which moved elbow_pitch from -1 1.57 to -1 3.57. not sure if that was on purpose.
why it matters:
- robolab trains in isaac from this repo's urdf (
robolab/assets/robots/roboparty.py:41, through thedata/robots/roboparty/rposubmodule). - the mujoco sim2sim scripts load this repo's mjcf (
robolab/scripts/mujoco/sim2sim_rpo.py:312-314, and the amp, parkour, interrupt and attn_enc variants). - deploy shuts the robot down if any joint leaves the default.yaml limits (
roboparty_inference/src/obs_manager.cpp:225-230, "Joint out of limit! Shutting down...").
so a policy can pass sim2sim with its elbow at 2.5 rad, or hip roll at 1.5 rad, and then trip the deploy shutdown on the real robot. sim2sim also allows 200 Nm at the ankles, which hides torque saturation that would happen on hardware.
urdf, deploy and the v2.0 cad mostly agree with each other, so my guess is the urdf is right and the mjcf drifted. there are 3 spots i couldn't settle:
- thigh_pitch: urdf [-2.094, 0.785] vs deploy and cad [-1.57, 1.57]
- thigh_roll: deploy allows 0.6 rad more on the inner side than the urdf
- arm_pitch: cad lower limit is -1.57, urdf and deploy are -3.14
which file should be the source of truth? happy to open a pr that syncs the 3 mjcf files (ranges plus per joint ctrlrange matching the urdf effort) and adds a small cpu check script, which could run in ci, that compares the urdf and mjcf limits and fails on drift.
中文摘要:rpo.urdf 与 mjcf 中 15 个关节的限位及力矩上限不一致,导致 sim2sim 允许的动作在实机部署时会触发关节超限停机。请问以哪个文件为准?可提交 PR 同步并加入一致性检查。
Activity
Luo1imasi commentedon Oct 14, 2026
The software limits on the deployment side vary between policies. Locomotion policies use smaller motion ranges and therefore tighter software limits to avoid collisions with structural components. Policies such as BeyondMimic use larger motion ranges and therefore have little to no software limiting.
We primarily use the URDF for training, so treating the URDF as the source of truth is correct. The MJCF is only used for sim2sim validation, not training, so its joint limits are generally not enforced strictly.