Skip to content

Fix Pink IK USD-to-URDF conversion on aarch64 (#6177)#6181

Merged
kellyguo11 merged 1 commit into
isaac-sim:release/3.0.0-beta2from
kellyguo11:release-pink
Jun 13, 2026
Merged

Fix Pink IK USD-to-URDF conversion on aarch64 (#6177)#6181
kellyguo11 merged 1 commit into
isaac-sim:release/3.0.0-beta2from
kellyguo11:release-pink

Conversation

@kellyguo11

Copy link
Copy Markdown
Contributor

Description

  • Remove the Pink IK runtime dependency on nvidia.srl and use Isaac Sim's built-in isaacsim.asset.exporter.urdf converter.

  • Normalize generated URDF joint limits so Pinocchio accepts Isaac Sim exporter output (effort/velocity defaults and inf cleanup).

  • Align affected GR1T2 and G1-Inspire Pink IK frame names with the link/frame names produced by the Isaac Sim exporter.

  • Remove the nvidia-srl-usd-to-urdf dependency from isaaclab_mimic.

  • python -m py_compile docs/conf.py source/isaaclab/isaaclab/controllers/utils.py source/isaaclab/test/controllers/test_controller_utils.py source/isaaclab_tasks/isaaclab_tasks/contrib/pick_place/nutpour_gr1t2_pink_ik_env_cfg.py source/isaaclab_tasks/isaaclab_tasks/contrib/pick_place/exhaustpipe_gr1t2_pink_ik_env_cfg.py source/isaaclab_tasks/isaaclab_tasks/contrib/pick_place/pickplace_gr1t2_env_cfg.py source/isaaclab_tasks/isaaclab_tasks/contrib/pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py

  • git diff --check

  • Direct mocked smoke test of convert_usd_to_urdf() using Isaac Sim exporter modules.

  • Generated GR1T2 and G1-Inspire URDFs with isaacsim.asset.exporter.urdf, sanitized them with the new utility, and verified Pinocchio can load them and contains the adjusted target frames:

    • GR1T2_fourier_hand_6dof.urdf nq 54 nv 54 missing frames []
    • g1_29dof_inspire_hand.urdf nq 53 nv 53 missing frames []
  • Attempted focused pytest through ./isaaclab.sh -p -m pytest source/isaaclab/test/controllers/test_controller_utils.py -k convert_usd_to_urdf_uses_isaacsim_exporter -q, but this worktree uses system Python and is missing lazy_loader.

  • Attempted Ruff on touched files, but no local Python environment had Ruff installed.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (existing functionality will not work without user modification)
  • Documentation update

Screenshots

Please attach before and after screenshots of the change if applicable.

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with ./isaaclab.sh --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the changelog and the corresponding version in the extension's config/extension.toml file
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

- Remove the Pink IK runtime dependency on `nvidia.srl` and use Isaac
Sim's built-in `isaacsim.asset.exporter.urdf` converter.
- Normalize generated URDF joint limits so Pinocchio accepts Isaac Sim
exporter output (`effort`/`velocity` defaults and `inf` cleanup).
- Align affected GR1T2 and G1-Inspire Pink IK frame names with the
link/frame names produced by the Isaac Sim exporter.
- Remove the `nvidia-srl-usd-to-urdf` dependency from `isaaclab_mimic`.

- `python -m py_compile docs/conf.py
source/isaaclab/isaaclab/controllers/utils.py
source/isaaclab/test/controllers/test_controller_utils.py
source/isaaclab_tasks/isaaclab_tasks/contrib/pick_place/nutpour_gr1t2_pink_ik_env_cfg.py
source/isaaclab_tasks/isaaclab_tasks/contrib/pick_place/exhaustpipe_gr1t2_pink_ik_env_cfg.py
source/isaaclab_tasks/isaaclab_tasks/contrib/pick_place/pickplace_gr1t2_env_cfg.py
source/isaaclab_tasks/isaaclab_tasks/contrib/pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py`
- `git diff --check`
- Direct mocked smoke test of `convert_usd_to_urdf()` using Isaac Sim
exporter modules.
- Generated GR1T2 and G1-Inspire URDFs with
`isaacsim.asset.exporter.urdf`, sanitized them with the new utility, and
verified Pinocchio can load them and contains the adjusted target
frames:
  - `GR1T2_fourier_hand_6dof.urdf nq 54 nv 54 missing frames []`
  - `g1_29dof_inspire_hand.urdf nq 53 nv 53 missing frames []`
- Attempted focused pytest through `./isaaclab.sh -p -m pytest
source/isaaclab/test/controllers/test_controller_utils.py -k
convert_usd_to_urdf_uses_isaacsim_exporter -q`, but this worktree uses
system Python and is missing `lazy_loader`.
- Attempted Ruff on touched files, but no local Python environment had
Ruff installed.
@github-actions github-actions Bot added documentation Improvements or additions to documentation isaac-mimic Related to Isaac Mimic team labels Jun 13, 2026
@greptile-apps

greptile-apps Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the Pink IK USD-to-URDF pipeline on aarch64 by replacing the unavailable nvidia.srl package with Isaac Sim's built-in isaacsim.asset.exporter.urdf converter, then surgically sanitizing only the effort/velocity joint-limit attributes that Pinocchio requires to be finite (the old approach replaced all "inf" substrings globally, which also corrupted lower/upper position limits).

  • Core converter swap (utils.py): UsdToUrdfConverter is now imported lazily inside the conversion block; _sanitize_urdf_for_pinocchio uses xml.etree.ElementTree to patch only non-kinematic limit fields instead of a blanket string replace that would zero out position limits.
  • Dependency cleanup: nvidia-srl-usd-to-urdf removed from isaaclab_mimic/setup.py; nvidia.srl removed from docs/conf.py mock imports; usd-core pin loosened from ==25.11.0 to >=25.11,<26.0 for ARM64 compatibility.
  • Frame name alignment: GR1T2 and G1-Inspire task configs updated to use the un-prefixed link names emitted by the Isaac Sim exporter (e.g. left_hand_pitch_link instead of GR1T2_fourier_hand_6dof_left_hand_pitch_link).

Confidence Score: 4/5

Safe to merge; the changes are well-scoped and tested, with one cosmetic concern around XML comment preservation during URDF sanitization.

The converter swap and sanitization logic are straightforward and backed by a mocked smoke test. The only notable gap is that xml.etree.ElementTree silently drops comments when rewriting the URDF, but Isaac Sim's exporter output is effectively comment-free, so this has no runtime impact today.

source/isaaclab/isaaclab/controllers/utils.py — specifically the _sanitize_urdf_for_pinocchio rewrite path

Important Files Changed

Filename Overview
source/isaaclab/isaaclab/controllers/utils.py Replaces nvidia.srl converter with isaacsim.asset.exporter.urdf; adds _sanitize_urdf_for_pinocchio using ElementTree — comments and XML declaration are silently dropped on rewrite
source/isaaclab/test/controllers/test_controller_utils.py Adds mocked smoke test for the new convert_usd_to_urdf path; correctly validates extension, converter args, return paths, and sanitized limit attributes
source/isaaclab/setup.py Loosens usd-core from ==25.11.0 to >=25.11,<26.0; intentional for aarch64 compatibility but broadens the version range allowed
source/isaaclab_mimic/setup.py Removes nvidia-srl-usd-to-urdf dependency (and its aarch64 guard), cleanly eliminating the broken dependency
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_env_cfg.py Frame names updated from GR1T2_fourier_hand_6dof_* prefix to bare link names matching Isaac Sim exporter output
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py Frame names updated from g1_29dof_rev_1_0_* prefix to bare link names matching Isaac Sim exporter output

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["convert_usd_to_urdf(usd_path, output_path)"] --> B["enable_extension(isaacsim.asset.exporter.urdf)"]
    B --> C{URDF & meshes exist\nand not force_conversion?}
    C -->|Skip| Z["return urdf_output_path, urdf_meshes_output_dir"]
    C -->|Convert| D["makedirs urdf/ and meshes/"]
    D --> E["UsdToUrdfConverter(stage, mesh_dir_name='../meshes', ...)"]
    E --> F["usd_to_urdf.convert(urdf_output_path)"]
    F --> G["_sanitize_urdf_for_pinocchio(urdf_output_path)"]
    G --> H["ET.parse(urdf_path)"]
    H --> I{"effort / velocity\n== inf or None?"}
    I -->|Yes| J["Set attr to '0.'"]
    J --> K{"changed?"}
    I -->|No| K
    K -->|Yes| L["tree.write(urdf_path, encoding='unicode')"]
    K -->|No| Z
    L --> Z
Loading

Reviews (1): Last reviewed commit: "Fix Pink IK USD-to-URDF conversion on aa..." | Re-trigger Greptile

Comment on lines +70 to +80
def _sanitize_urdf_for_pinocchio(urdf_path: str) -> None:
"""Fill Pinocchio-required non-kinematic joint-limit fields in exported URDFs."""
tree = ET.parse(urdf_path)
changed = False
for limit in tree.iter("limit"):
for attr in ("effort", "velocity"):
if limit.get(attr) in {None, "inf", "+inf", "-inf"}:
limit.set(attr, "0.")
changed = True
if changed:
tree.write(urdf_path, encoding="unicode")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 xml.etree.ElementTree silently drops XML comments during parsing. When changed=True, the rewritten file will lose any comments that the Isaac Sim exporter included. While current exporter output appears comment-free, this is a fragile assumption. In Python 3.8+, ET.XMLParser(target=ET.TreeBuilder(insert_comments=True)) preserves comments. Additionally, tree.write(..., encoding="unicode") omits the XML declaration from the original file.

Suggested change
def _sanitize_urdf_for_pinocchio(urdf_path: str) -> None:
"""Fill Pinocchio-required non-kinematic joint-limit fields in exported URDFs."""
tree = ET.parse(urdf_path)
changed = False
for limit in tree.iter("limit"):
for attr in ("effort", "velocity"):
if limit.get(attr) in {None, "inf", "+inf", "-inf"}:
limit.set(attr, "0.")
changed = True
if changed:
tree.write(urdf_path, encoding="unicode")
def _sanitize_urdf_for_pinocchio(urdf_path: str) -> None:
"""Fill Pinocchio-required non-kinematic joint-limit fields in exported URDFs."""
parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True))
tree = ET.parse(urdf_path, parser=parser)
changed = False
for limit in tree.iter("limit"):
for attr in ("effort", "velocity"):
if limit.get(attr) in {None, "inf", "+inf", "-inf"}:
limit.set(attr, "0.")
changed = True
if changed:
tree.write(urdf_path, encoding="unicode", xml_declaration=False)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@kellyguo11
kellyguo11 merged commit b2e3a3d into isaac-sim:release/3.0.0-beta2 Jun 13, 2026
36 of 37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation isaac-mimic Related to Isaac Mimic team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants