Skip to content

Add The Robot Studio SO-101 (SO-ARM100) simulation assets#38

Open
johnnynunez-nv wants to merge 1 commit into
newton-physics:mainfrom
johnnynunez-nv:so101
Open

Add The Robot Studio SO-101 (SO-ARM100) simulation assets#38
johnnynunez-nv wants to merge 1 commit into
newton-physics:mainfrom
johnnynunez-nv:so101

Conversation

@johnnynunez-nv

@johnnynunez-nv johnnynunez-nv commented Apr 23, 2026

Copy link
Copy Markdown

Summary

Adds robot assets for The Robot Studio SO-101, the 6-DoF low-cost manipulator used by the LeRobot project (companion to the existing `franka_emika_panda` / `universal_robots_ur5e` manipulators in this repo).

The folder ships URDF + MJCF + STL meshes from the upstream `TheRobotStudio/SO-ARM100` repository plus the NVIDIA-built structured USD pulled from the Isaac Sim 6.0 asset bucket, so downstream Newton tests can use any of the three formats without an additional dependency on Isaac Sim or a conversion step.

Contents

```
therobotstudio_soarm101/
├── LICENSE # Apache 2.0 (matches both upstream licenses)
├── README.md
├── joints_properties.xml # shared MJCF joint limits / actuator defaults
├── scene.xml # MuJoCo scene wrapping the robot
├── so101_new_calib.urdf # URDF – zero = mid-range of each joint
├── so101_new_calib.xml # MJCF – same calibration
├── assets/ # 13 STL meshes + Onshape .part siblings
└── usd/ # Isaac Sim 6.0 4-layer structured USD
├── .collect.mapping.json # source URL + SHA-1 per redistributed file
├── so101_new_calib.usd # top-level composition
└── configuration/{*_base, *_physics, *_robot, *_sensor}.usd
```

Total footprint ≈ 39 MB (`usd/configuration/so101_new_calib_base.usd` is ≈23 MB of geometry + materials; everything else is KB-sized).

Only the new calibration is vendored (joint zero = mid-range). The legacy old calibration is intentionally omitted because NVIDIA does not publish a USD for it — the bucket listing at `Assets/Isaac/6.0/Isaac/Robots/RobotStudio/` only contains `so100/` and `so101_new_calib/`.

Sources

  • URDF / MJCF / meshes`TheRobotStudio/SO-ARM100` @ `aec17bb`, copied verbatim. Mesh paths already use relative `assets/…` (no `package://`), so the files load directly in MuJoCo / Isaac Lab's URDF and MJCF importers.
  • Structured USD — collected byte-for-byte from the Isaac Sim 6.0 public asset bucket at `Assets/Isaac/6.0/Isaac/Robots/RobotStudio/so101_new_calib/`. Source URLs + SHA-1 hashes recorded in `usd/.collect.mapping.json` (same schema this repo already uses in `universal_robots_ur10/usd/.collect.mapping.json`).

License

Both upstream sources are Apache 2.0:

  • `TheRobotStudio/SO-ARM100` repository carries a top-level Apache 2.0 `LICENSE`.
  • The Isaac Sim 6.0 Robot Assets catalog explicitly tags `RobotStudio/so101_new_calib.usd` as License: Apache 2.0 (distinct from the NVIDIA 3D Content Sharing Agreement used by most other entries in that catalog).

No `NOTICE` file exists in either upstream (verified by probing the S3 bucket at every level and `strings` on the USD crate files); `LICENSE` + README attribution are therefore sufficient to satisfy Apache 2.0 §4. The Isaac Sim application license is orthogonal and does not attach to assets the catalog labels Apache 2.0.

Validation

Headless load of `scene.xml` with `mujoco==3.7.0` parses cleanly:

```
Model loaded:
nq (DoF/pos) = 6
nv (vel) = 6
nbody = 8
njnt = 6
ngeom = 31
nmesh = 13
Joints:
[0] shoulder_pan
[1] shoulder_lift
[2] elbow_flex
[3] wrist_flex
[4] wrist_roll
[5] gripper
```

Joint names match the USD (`configuration/so101_new_calib_physics.usd`), so the URDF/MJCF/USD variants are interchangeable for tests keyed on joint name.

Test plan

  • Repo maintainer pulls the branch and verifies `scene.xml` loads in their MuJoCo pipeline.
  • `usd/so101_new_calib.usd` loads in the Newton USD pipeline (payload-references `configuration/*.usd` automatically).
  • Mesh paths (`assets/…`) resolve for both URDF and MJCF importers.

Notes for reviewers

  • No companion PR is required in the code repo yet; this is a standalone asset addition analogous to PR Add rubber duck manipulation object #32 ("Add rubber duck manipulation object").
  • Folder name picked by the contributor; happy to rename to `the_robot_studio_so101` (matching the `franka_emika_panda` / `universal_robots_ur5e` manufacturer-first-underscore-separated convention) before merge if preferred.
  • SO-100 (sibling robot under the same `RobotStudio/` prefix, also Apache 2.0) is deliberately not included here; can be added as a separate `therobotstudio_so100/` folder on request.
so101_preview

Summary by CodeRabbit

  • New Features

    • Released SO-ARM 101 robot simulation asset with complete calibrated kinematics and gripper functionality ready for simulation environments.
  • Documentation

    • Added comprehensive asset documentation including folder structure, calibration scope, known limitations, and redistribution guidelines.
  • Chores

    • Added Apache 2.0 license.

Signed-off-by: johnnynunez-nv <johnunez@nvidia.com>
@linux-foundation-easycla

linux-foundation-easycla Bot commented Apr 23, 2026

Copy link
Copy Markdown

CLA Signed

The committers listed above are authorized under a signed CLA.

  • ✅ login: johnnynunez-nv / name: johnnynunez-nv (8ef39eb)

@coderabbitai

coderabbitai Bot commented Apr 23, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This pull request introduces a new robot asset set (therobotstudio_soarm101) comprising licensing documentation, a README describing the asset structure and calibration, and complete robot configuration files (MJCF and URDF) alongside CAD part metadata for a six-jointed robotic arm with a gripper.

Changes

Cohort / File(s) Summary
Legal & Documentation
LICENSE, README.md
Adds Apache License 2.0 terms and comprehensive README detailing folder structure, calibration scope, asset provenance, known limitations, and redistribution requirements for the so101_new_calib asset.
Mesh Part Metadata
meshes/base_motor_holder_so101_v1.part, meshes/base_so101_v2.part, meshes/motor_holder_so101_base_v1.part, meshes/motor_holder_so101_wrist_v1.part, meshes/moving_jaw_so101_v1.part, meshes/rotation_pitch_so101_v1.part, meshes/sts3215_03a_no_horn_v1.part, meshes/sts3215_03a_v1.part, meshes/under_arm_so101_v1.part, meshes/upper_arm_so101_v1.part, meshes/waveshare_mounting_plate_so101_v2.part, meshes/wrist_roll_follower_so101_v1.part, meshes/wrist_roll_pitch_so101_v2.part
Adds JSON metadata files for 13 CAD mesh parts, each containing document identifiers, configuration, part naming, and suppression flags.
MuJoCo Scene Configuration
mjcf/joints_properties.xml, mjcf/scene.xml, mjcf/so101_new_calib.xml
Defines MuJoCo simulation setup with joint/actuator parameter presets (sts3215 servo tuning, backlash joint classes), scene rendering (lighting, materials, ground plane), and complete kinematic tree with inertial properties, geometry, and six revolute joints plus gripper jaw actuator.
Robot Description
urdf/so101_new_calib.urdf
Specifies URDF robot model with materials, complete kinematic chain (base through shoulder, arms, wrist, gripper), inertial/visual/collision geometry per link, six revolute joints with calibrated limits (including 5° offset on elbow flex), one fixed gripper frame joint, and position-control transmission interfaces for each joint.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A six-jointed arm now joins the fold,
With meshes, URDF, and stories told,
From SO-ARM's base to gripper's grip,
Calibrated joints—a perfect flip!
Licensed well, the asset's here to stay. 🤖✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately describes the main change: adding simulation assets for The Robot Studio SO-101 robot, which is the primary objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
therobotstudio_soarm101/mjcf/so101_new_calib.xml (2)

29-32: backlash default class is declared but never referenced.

No joint in this file sets class="backlash", so these defaults are inert — the ±0.5° backlash window, damping, and armature never apply. If this was intended as forward provision for a future backlash-modeled variant, consider dropping it from the vendored model (the upstream definition already lives in joints_properties.xml as historical provenance). Otherwise, if backlash behavior is intended, the joint tree needs companion "_backlash" joints referencing this class.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@therobotstudio_soarm101/mjcf/so101_new_calib.xml` around lines 29 - 32, The
default class "backlash" is declared but never used, so its parameters (range,
damping, armature) have no effect; either remove this unused <default
class="backlash"> block or add companion joints that reference class="backlash"
(typically named with a "_backlash" suffix) so the ±0.5° backlash,
damping="0.01" and armature="0.01" are applied; locate the <default
class="backlash"> entry and either delete it or update the relevant joint
elements to include class="backlash" (e.g., create matching *_backlash joint
elements) so the behavior is actually applied.

167-167: Drop the empty <equality/> block.

No constraints are declared; the tag can be removed without affecting model parsing.

✏️ Proposed cleanup
-  <equality/>
 </mujoco>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@therobotstudio_soarm101/mjcf/so101_new_calib.xml` at line 167, Remove the
empty <equality/> XML element from the MJCF model (it declares no constraints);
locate the solitary <equality/> tag in so101_new_calib.xml and delete it so the
model has no redundant empty constraint block.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@therobotstudio_soarm101/README.md`:
- Around line 67-68: The README claim that "Base collision meshes were removed
upstream" conflicts with the vendored URDF: inspect mjcf/so101_new_calib.xml and
urdf/so101_new_calib.urdf and reconcile them; either remove the <collision>
elements for base_motor_holder_so101_v1, base_so101_v2, sts3215_03a_v1, and
waveshare_mounting_plate_so101_v2 from urdf/so101_new_calib.urdf to match the
MJCF, or update README.md to explicitly state that the MJCF removed base
collisions while the URDF still contains those collision entries so downstream
users understand the format discrepancy. Ensure references to the specific files
(mjcf/so101_new_calib.xml, urdf/so101_new_calib.urdf) and the listed collision
element names are used when making the change.

In `@therobotstudio_soarm101/urdf/so101_new_calib.urdf`:
- Around line 29-76: The URDF's base_link currently contains four <collision>
elements for meshes base_motor_holder_so101_v1.stl, base_so101_v2.stl,
sts3215_03a_v1.stl and waveshare_mounting_plate_so101_v2.stl which disagree with
the MJCF (which only emits visual geoms); to match upstream behavior remove the
four corresponding <collision> blocks from the base_link in so101_new_calib.urdf
(i.e., delete the collision entries that reference those four mesh filenames) so
URDF and MJCF produce equivalent contact behavior, or alternatively update the
README to explicitly document that URDF retains base collision geometry if you
intend to keep them.

---

Nitpick comments:
In `@therobotstudio_soarm101/mjcf/so101_new_calib.xml`:
- Around line 29-32: The default class "backlash" is declared but never used, so
its parameters (range, damping, armature) have no effect; either remove this
unused <default class="backlash"> block or add companion joints that reference
class="backlash" (typically named with a "_backlash" suffix) so the ±0.5°
backlash, damping="0.01" and armature="0.01" are applied; locate the <default
class="backlash"> entry and either delete it or update the relevant joint
elements to include class="backlash" (e.g., create matching *_backlash joint
elements) so the behavior is actually applied.
- Line 167: Remove the empty <equality/> XML element from the MJCF model (it
declares no constraints); locate the solitary <equality/> tag in
so101_new_calib.xml and delete it so the model has no redundant empty constraint
block.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e6e16cea-46b8-47df-af25-1b7555d579a2

📥 Commits

Reviewing files that changed from the base of the PR and between 8e8df07 and 8ef39eb.

📒 Files selected for processing (37)
  • therobotstudio_soarm101/LICENSE
  • therobotstudio_soarm101/README.md
  • therobotstudio_soarm101/meshes/base_motor_holder_so101_v1.part
  • therobotstudio_soarm101/meshes/base_motor_holder_so101_v1.stl
  • therobotstudio_soarm101/meshes/base_so101_v2.part
  • therobotstudio_soarm101/meshes/base_so101_v2.stl
  • therobotstudio_soarm101/meshes/motor_holder_so101_base_v1.part
  • therobotstudio_soarm101/meshes/motor_holder_so101_base_v1.stl
  • therobotstudio_soarm101/meshes/motor_holder_so101_wrist_v1.part
  • therobotstudio_soarm101/meshes/motor_holder_so101_wrist_v1.stl
  • therobotstudio_soarm101/meshes/moving_jaw_so101_v1.part
  • therobotstudio_soarm101/meshes/moving_jaw_so101_v1.stl
  • therobotstudio_soarm101/meshes/rotation_pitch_so101_v1.part
  • therobotstudio_soarm101/meshes/rotation_pitch_so101_v1.stl
  • therobotstudio_soarm101/meshes/sts3215_03a_no_horn_v1.part
  • therobotstudio_soarm101/meshes/sts3215_03a_no_horn_v1.stl
  • therobotstudio_soarm101/meshes/sts3215_03a_v1.part
  • therobotstudio_soarm101/meshes/sts3215_03a_v1.stl
  • therobotstudio_soarm101/meshes/under_arm_so101_v1.part
  • therobotstudio_soarm101/meshes/under_arm_so101_v1.stl
  • therobotstudio_soarm101/meshes/upper_arm_so101_v1.part
  • therobotstudio_soarm101/meshes/upper_arm_so101_v1.stl
  • therobotstudio_soarm101/meshes/waveshare_mounting_plate_so101_v2.part
  • therobotstudio_soarm101/meshes/waveshare_mounting_plate_so101_v2.stl
  • therobotstudio_soarm101/meshes/wrist_roll_follower_so101_v1.part
  • therobotstudio_soarm101/meshes/wrist_roll_follower_so101_v1.stl
  • therobotstudio_soarm101/meshes/wrist_roll_pitch_so101_v2.part
  • therobotstudio_soarm101/meshes/wrist_roll_pitch_so101_v2.stl
  • therobotstudio_soarm101/mjcf/joints_properties.xml
  • therobotstudio_soarm101/mjcf/scene.xml
  • therobotstudio_soarm101/mjcf/so101_new_calib.xml
  • therobotstudio_soarm101/urdf/so101_new_calib.urdf
  • therobotstudio_soarm101/usd/configuration/so101_new_calib_base.usd
  • therobotstudio_soarm101/usd/configuration/so101_new_calib_physics.usd
  • therobotstudio_soarm101/usd/configuration/so101_new_calib_robot.usd
  • therobotstudio_soarm101/usd/configuration/so101_new_calib_sensor.usd
  • therobotstudio_soarm101/usd/so101_new_calib.usd

Comment on lines +67 to +68
- Base collision meshes were removed upstream because they were causing
problematic collision behavior during simulation and planning.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Base-collision claim doesn't match the vendored URDF.

This note says base collision meshes were removed upstream, and mjcf/so101_new_calib.xml indeed has no class="collision" geoms on the base body. However, urdf/so101_new_calib.urdf (lines 29-34, 43-48, 57-62, 71-76) still includes <collision> elements for base_motor_holder_so101_v1, base_so101_v2, sts3215_03a_v1, and waveshare_mounting_plate_so101_v2.

Either the URDF should be brought in line with the MJCF (and this note), or the README should be scoped — e.g., "removed upstream in the MJCF; URDF retains the base collision meshes" — so downstream users of the URDF aren't surprised by different contact behavior between the two formats.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@therobotstudio_soarm101/README.md` around lines 67 - 68, The README claim
that "Base collision meshes were removed upstream" conflicts with the vendored
URDF: inspect mjcf/so101_new_calib.xml and urdf/so101_new_calib.urdf and
reconcile them; either remove the <collision> elements for
base_motor_holder_so101_v1, base_so101_v2, sts3215_03a_v1, and
waveshare_mounting_plate_so101_v2 from urdf/so101_new_calib.urdf to match the
MJCF, or update README.md to explicitly state that the MJCF removed base
collisions while the URDF still contains those collision entries so downstream
users understand the format discrepancy. Ensure references to the specific files
(mjcf/so101_new_calib.xml, urdf/so101_new_calib.urdf) and the listed collision
element names are used when making the change.

Comment on lines +29 to +76
<collision>
<origin xyz="-0.00636471 -9.94414e-05 -0.0024" rpy="1.5708 -1.67685e-15 1.5708"/>
<geometry>
<mesh filename="../meshes/base_motor_holder_so101_v1.stl"/>
</geometry>
</collision>
<!-- Part base_so101_v2 -->
<visual>
<origin xyz="-0.00636471 -8.97657e-09 -0.0024" rpy="1.5708 -2.78073e-29 1.5708"/>
<geometry>
<mesh filename="../meshes/base_so101_v2.stl"/>
</geometry>
<material name="3d_printed"/>
</visual>
<collision>
<origin xyz="-0.00636471 -8.97657e-09 -0.0024" rpy="1.5708 -2.78073e-29 1.5708"/>
<geometry>
<mesh filename="../meshes/base_so101_v2.stl"/>
</geometry>
</collision>
<!-- Part sts3215_03a_v1 -->
<visual>
<origin xyz="0.0263353 -8.97657e-09 0.0437" rpy="-8.21148e-16 7.84513e-18 1.249e-15"/>
<geometry>
<mesh filename="../meshes/sts3215_03a_v1.stl"/>
</geometry>
<material name="sts3215"/>
</visual>
<collision>
<origin xyz="0.0263353 -8.97657e-09 0.0437" rpy="-8.21148e-16 7.84513e-18 1.249e-15"/>
<geometry>
<mesh filename="../meshes/sts3215_03a_v1.stl"/>
</geometry>
</collision>
<!-- Part waveshare_mounting_plate_so101_v2 -->
<visual>
<origin xyz="-0.0309827 -0.000199441 0.0474" rpy="1.5708 -1.35493e-14 1.5708"/>
<geometry>
<mesh filename="../meshes/waveshare_mounting_plate_so101_v2.stl"/>
</geometry>
<material name="3d_printed"/>
</visual>
<collision>
<origin xyz="-0.0309827 -0.000199441 0.0474" rpy="1.5708 -1.35493e-14 1.5708"/>
<geometry>
<mesh filename="../meshes/waveshare_mounting_plate_so101_v2.stl"/>
</geometry>
</collision>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Base-link collision geometry disagrees with the MJCF counterpart.

The URDF keeps <collision> elements on base_link for all four base parts (base_motor_holder_so101_v1, base_so101_v2, sts3215_03a_v1, waveshare_mounting_plate_so101_v2), but mjcf/so101_new_calib.xml only emits class="visual" geoms for the same body (lines 38-45, no class="collision") — matching the README note that "Base collision meshes were removed upstream because they were causing problematic collision behavior during simulation and planning."

Result: identical URDF vs. MJCF loads will have materially different contact behavior around the base. If the upstream removal is deliberate, consider stripping the four base <collision> blocks here too so URDF loads match MJCF and the README. Otherwise, please update the README to note the format-specific difference.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@therobotstudio_soarm101/urdf/so101_new_calib.urdf` around lines 29 - 76, The
URDF's base_link currently contains four <collision> elements for meshes
base_motor_holder_so101_v1.stl, base_so101_v2.stl, sts3215_03a_v1.stl and
waveshare_mounting_plate_so101_v2.stl which disagree with the MJCF (which only
emits visual geoms); to match upstream behavior remove the four corresponding
<collision> blocks from the base_link in so101_new_calib.urdf (i.e., delete the
collision entries that reference those four mesh filenames) so URDF and MJCF
produce equivalent contact behavior, or alternatively update the README to
explicitly document that URDF retains base collision geometry if you intend to
keep them.

@preist-nvidia

Copy link
Copy Markdown
Member

Thank you @johnnynunez-nv ! The main issue is that the top-level composition USD should be USDA so that we can easily diff with Git, and have AI agents tweak physics parameters.

@andrewkaufman for input, and we should document this requirement in the readme I think.

@andrewkaufman

Copy link
Copy Markdown
Member

@johnnynunez-nv until we have actual guidelines, see https://github.com/newton-physics/newton-assets/tree/main/unitree_g1 which has several subdirs for different format styles. The usd_structured subdir is akin to what @preist-nvidia is requesting I think, while the usd subdir is a single binary crate file

@johnnynunez

Copy link
Copy Markdown

Thank you @johnnynunez-nv ! The main issue is that the top-level composition USD should be USDA so that we can easily diff with Git, and have AI agents tweak physics parameters.

@andrewkaufman for input, and we should document this requirement in the readme I think.

thanks, i will wait for new isaac sim assets and I will add it here

@shi-eric shi-eric requested a review from eric-heiden May 6, 2026 17:13
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.

4 participants