Skip to content

Rename key to label and add hierarchical labels (#1592)#1632

Merged
eric-heiden merged 26 commits into
newton-physics:mainfrom
adenzler-nvidia:adenzler/rename-key-to-label
Feb 19, 2026
Merged

Rename key to label and add hierarchical labels (#1592)#1632
eric-heiden merged 26 commits into
newton-physics:mainfrom
adenzler-nvidia:adenzler/rename-key-to-label

Conversation

@adenzler-nvidia

@adenzler-nvidia adenzler-nvidia commented Feb 13, 2026

Copy link
Copy Markdown
Member

Summary

Implements #1592: Rename entity identifier attributes from *_key to *_label and unify label generation across importers with hierarchical /-separated paths.

  • Rename key → label across the entire codebase (clean break, no backwards compat shims). Affects body_key, joint_key, shape_key, articulation_key, equality_constraint_key, constraint_mimic_key attributes, 30+ add_* method signatures, selection API, sensors, and MuJoCo solver.
  • Hierarchical labels in importers:
  • URDF: flat {robot_name}/{entity_name} (e.g., panda/base_link)
  • MJCF: XPath-style {model}/worldbody/{body}/... (e.g., humanoid/worldbody/torso/shoulder)
  • USD: preserves existing prim paths (already hierarchical)
  • label_prefix parameter on add_builder() and add_world() for composing multiple robot instances with distinct labels (e.g., left/arm/worldbody/link vs right/arm/worldbody/link)
  • MJCF importer O(1) lookups: added body_name_to_idx, site_name_to_idx, joint_name_to_idx dicts to avoid linear scans through hierarchical label lists for tendon, actuator, and constraint resolution
  • MuJoCo solver export fix: replace / with _ in element names since MuJoCo interprets / as path separators

Summary by CodeRabbit

  • Refactor

    • Renamed public identifiers from "key" → "label" across builder APIs and model attributes; plotting/validation now use labels; added label-prefix propagation for hierarchical naming.
  • Documentation

    • Updated docs, tutorials, and examples to use label-based API conventions.
  • Chores

    • Added contributor guidance recommending new commits (avoid amending/force-push) when iterating on PR feedback.

Rename all entity identifier attributes from *_key to *_label in the
core library: builder.py, model.py, selection.py, importers, sensors,
solver, and geometry. This reflects that these identifiers are
user-defined labels, not unique keys.

- Rename shape_key, body_key, joint_key, articulation_key,
  equality_constraint_key, constraint_mimic_key to *_label
- Rename key= parameter to label= in all add_* methods
- Rename get_name_from_key() to get_name_from_label()
- Rename find_matching_ids(keys=) to find_matching_ids(labels=)
- Rename _match_elem_key() to _match_elem_label()
- Rename show_body_keys/show_joint_keys/show_shape_keys to *_labels
- Rename tendon_key to tendon_label in MuJoCo solver

Refs: newton-physics#1592
URDF importer: Generate flat hierarchical labels with
{articulation_label}/{entity_name} format (e.g., panda/base_link).
URDF XML has no body nesting so flat prefix is the natural form.

MJCF importer: Generate XPath-style hierarchical labels from the
nested body tree (e.g., humanoid/worldbody/torso/upper_arm).
Add body_name_to_idx and site_name_to_idx dicts for O(1) lookups
instead of linear scans through builder label lists.

Builder: Add label_prefix parameter to add_builder() and add_world()
that prepends a prefix to all entity labels from the source builder,
enabling composition of multiple robot instances with distinct labels.

Refs: newton-physics#1592
Add patterns for:
- .claude/ and .mcp.json (Claude Code project config)
- Shell dotfiles, .gitconfig, .ripgreprc (sandbox placeholders)
- /HEAD, /config, /hooks, /objects, /refs (sandbox git stubs)
- Fix .vscode and .idea patterns to match both files and dirs
Document that network access requires disabling the sandbox
so the user gets an approval prompt.
Add option to skip Warp kernel cache clearing before test runs.
This avoids interference between parallel sessions and reduces
turnaround time during iterative development.

Document cache configuration advice in AGENTS.md.
Update all test and example files to use the renamed label API:
- Rename *_key attributes to *_label and key= params to label=
- Update expected label values for hierarchical format from
  URDF (flat: {robot}/{name}) and MJCF (XPath: {model}/worldbody/...)
- Add joint_name_to_idx dict in MJCF importer for O(1) lookups
  of joints by raw MJCF name (tendons, actuators, constraints)
- Fix MuJoCo solver export to replace / with _ in element names
  since MuJoCo interprets / as path separators
- Fix examples that look up body/joint indices by name to handle
  hierarchical labels

Refs: newton-physics#1592
Prefer new commits over amending when addressing PR feedback
to avoid force-pushing and make reviews easier to follow.
Update the introduction notebook and sites/sensors concept pages
to use label= instead of key= in code examples.
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@codecov

codecov Bot commented Feb 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.84906% with 30 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
newton/_src/sim/builder.py 81.39% 16 Missing ⚠️
newton/_src/utils/import_mjcf.py 77.35% 12 Missing ⚠️
newton/_src/solvers/mujoco/solver_mujoco.py 94.11% 1 Missing ⚠️
newton/_src/utils/import_usd.py 95.23% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@eric-heiden eric-heiden linked an issue Feb 13, 2026 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Renamed public identifiers and keyword parameters from "key" → "label" across builder, model, importers, solvers, sensors, docs, examples, and tests; added hierarchical label propagation (label_prefix / articulation_label) in importers and propagated labels through replication/finalization. Documentation and notebooks updated.

Changes

Cohort / File(s) Summary
Core Builder & Model
newton/_src/sim/builder.py, newton/_src/sim/model.py
Renamed public method params and Model attributes from *_key → *_label (body, shape, joint, articulation, equality_constraint, constraint_mimic). Added label_prefix to world/add_builder/add_world and propagated labels through replication and finalization.
Importers — MJCF
newton/_src/utils/import_mjcf.py
Added hierarchical labeling (label_prefix/root_label_path/articulation_label), threaded label context into parse functions, replaced key-based lookups with label-based mappings, and added name→index maps for bodies/sites/joints/shapes.
Importers — URDF & USD
newton/_src/utils/import_urdf.py, newton/_src/utils/import_usd.py
Generate hierarchical labels (articulation_label/make_label), pass label to ModelBuilder calls (add_body/add_link/add_joint_*), and change returned payloads/maps to use label/articulation_label.
Solvers — MuJoCo
newton/_src/solvers/mujoco/solver_mujoco.py
Renamed public attributes/params from *_key → *_label (tendon, body, shape, joint); updated name construction, lookups, and API param shape_keys→shape_labels.
Sensors & Utilities
newton/_src/sensors/*, newton/_src/utils/selection.py, newton/_src/geometry/inertia.py
Replaced key-based helpers with label-based equivalents (e.g., _match_elem_key→_match_elem_label, get_name_from_key→get_name_from_label). Updated internal usages and function signatures to accept body_label/elem_label.
Importer plumbing & propagation
newton/_src/utils/import_*
Propagated label_prefix/root_label_path/articulation_label into deeper parse/process functions; updated logs, lookups, and finalization to emit label-based identifiers.
Docs & Guides
AGENTS.md, docs/concepts/sensors.rst, docs/concepts/sites.rst, docs/tutorials/00_introduction.ipynb
Updated examples to use label instead of key for add_site/add_body/add_shape_*; added AGENTS.md guideline about preferring new commits over amending when iterating; formatting tweaks in notebook.
Examples
newton/examples/...
Systematically replaced key=... with label=... across builder calls (add_body/add_site/add_shape_/add_joint_/add_articulation/add_rod/add_rod_graph) and updated runtime lookups to use *_label fields.
Tests
newton/tests/...
Updated tests to use label-based attributes/params (model.body_label/model.joint_label/model.shape_label/articulation_label), adjusted expected hierarchical paths, and adapted helpers and lookups to label semantics.
Minor example/test tweaks
multiple example/test files
Numerous call-site-only edits switching keyword name key→label and replacing model._key reads with model._label; some index-lookups changed to endswith/name-search over labels.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • eric-heiden
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 78.13% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely summarizes the primary change: renaming entity identifiers from 'key' to 'label' and adding hierarchical label support throughout the codebase.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (7)
newton/_src/sensors/sensor_contact.py (1)

370-389: ⚠️ Potential issue | 🟡 Minor

Fix type hint for elem_label parameter: should be list[str], not dict[str, Any].

The type hint on line 374 is incorrect. The Model class initializes body_label and shape_label as empty lists ([]), not dicts. All callers pass these list attributes to _match_elem_label, and the method iterates over them with enumerate(elem_label), expecting sequential integer indices paired with string elements. The current dict[str, Any] type hint is misleading and will cause type checker warnings.

Recommended fix
     def _match_elem_label(
         cls,
         match_fn: Callable[[str, str], bool],
         model: Model,
-        elem_label: dict[str, Any],
+        elem_label: list[str],
         pattern: str | list[str],
     ) -> list[int]:
newton/_src/solvers/mujoco/solver_mujoco.py (1)

3039-3123: ⚠️ Potential issue | 🟠 Major

Sanitize shape labels for MuJoCo names and remove shape_key usage.
model.shape_label can include “/”, and model.shape_key is expected to be removed by the rename. This can yield invalid MuJoCo names or raise AttributeError for HFIELDs. Use a sanitized label once and reuse it for geom and hfield names.

🔧 Suggested fix
-                name = f"{model.shape_label[shape]}_{shape}"
+                shape_label = model.shape_label[shape].replace("/", "_")
+                name = f"{shape_label}_{shape}"
...
-                    hfield_name = f"{model.shape_key[shape]}_{shape}"
+                    hfield_name = f"{shape_label}_{shape}"
Does MuJoCo allow '/' characters in geom or hfield names, or are they treated as path separators?
newton/_src/utils/import_usd.py (1)

1298-1364: ⚠️ Potential issue | 🟡 Minor

Replace #! comments to avoid Ruff shebang errors.

Ruff treats #! mid-file as a shebang (EXE003/EXE005). Converting these to standard comments will clear lint.

Proposed fix
-                #! it may be possible that a joint is filtered out in the middle of
-                #! a chain of joints, which results in a disconnected graph
-                #! we should raise an error in this case
+                # NOTE: It may be possible that a joint is filtered out in the middle of
+                # a chain of joints, which results in a disconnected graph.
+                # Consider raising an error in this case.
newton/_src/utils/import_mjcf.py (2)

777-783: ⚠️ Potential issue | 🟠 Major

Fix heightfield insertion: label is not accepted by add_shape_heightfield.

CI shows ModelBuilder.add_shape_heightfield() rejects the label kwarg. This is a runtime error in MJCF import. Either extend add_shape_heightfield to accept label or drop it here.

Minimal fix (drop label for now)
-                hfield_kwargs = {k: v for k, v in shape_kwargs.items() if k != "body"}
+                hfield_kwargs = {k: v for k, v in shape_kwargs.items() if k not in ("body", "label")}

1152-1528: ⚠️ Potential issue | 🟡 Minor

Sanitize freejoint names to keep actuator/constraint lookups consistent.

Other joint names are normalized with sanitize_name, but freejoint_name is not. If a freejoint contains - or other normalized characters, later lookups (which sanitize names) will miss it.

Proposed fix
-            freejoint_name = freejoint_tags[0].attrib.get("name", f"{body_name}_freejoint")
+            freejoint_name = sanitize_name(
+                freejoint_tags[0].attrib.get("name", f"{body_name}_freejoint")
+            )
newton/_src/sim/builder.py (2)

1949-2013: ⚠️ Potential issue | 🟠 Major

Persist world labels (and attributes) instead of dropping them.
label is never stored, so the API/docstring promise of a default world label is currently a no‑op (and Ruff flags it as unused). Please persist world labels (and attributes if intended).

🛠️ Proposed fix (store world metadata)
@@ class ModelBuilder.__init__(...)
-        # Per-world gravity vectors, populated when worlds are created via begin_world()
-        # Each entry is a tuple (gx, gy, gz) representing the gravity vector for that world
-        self.world_gravity: list[tuple[float, float, float]] = []
+        # Per-world gravity vectors, populated when worlds are created via begin_world()
+        # Each entry is a tuple (gx, gy, gz) representing the gravity vector for that world
+        self.world_gravity: list[tuple[float, float, float]] = []
+        self.world_label: list[str] = []
+        self.world_attributes: list[dict[str, Any]] = []
@@ def begin_world(...):
-        # Store world metadata if needed (for future use)
-        # Note: We might want to add world_label and world_attributes lists in __init__ if needed
-        # For now, we just track the world index
+        # Store world metadata
+        world_label = label or f"world_{self.current_world}"
+        self.world_label.append(world_label)
+        self.world_attributes.append(attributes or {})

4938-4979: ⚠️ Potential issue | 🔴 Critical

Rename keylabel in add_shape_heightfield to avoid runtime error.
CI is failing with “ModelBuilder.add_shape() got an unexpected keyword argument 'key'.” This method still uses key and forwards it to add_shape, which now expects label.

🐛 Proposed fix
-    def add_shape_heightfield(
+    def add_shape_heightfield(
         self,
         xform: Transform | None = None,
         heightfield: Any | None = None,  # Heightfield type, using Any to avoid circular import
         scale: Vec3 | None = None,
         cfg: ShapeConfig | None = None,
-        key: str | None = None,
+        label: str | None = None,
         custom_attributes: dict[str, Any] | None = None,
     ) -> int:
@@
-            key (str | None): An optional unique key for identifying the shape. If `None`, a default key is automatically generated. Defaults to `None`.
+            label (str | None): An optional unique label for identifying the shape. If `None`, a default label is automatically generated. Defaults to `None`.
@@
-            key=key,
+            label=label,
             custom_attributes=custom_attributes,
         )
🤖 Fix all issues with AI agents
In `@newton/_src/solvers/mujoco/solver_mujoco.py`:
- Around line 1738-1743: The code is using model.body_label[target_idx] to build
target_name which can be wrong when bodies were de-duplicated; create and use a
dedicated mapping from Newton body index to the final MuJoCo body name (e.g.,
body_mapping or body_name_mapping) similar to the existing joint_mapping used
elsewhere, populate it when bodies are created (using the de-duplicated name /
body_name_counts logic), and replace the model.body_label lookup in the
BODY-actuator branch (the code that computes target_name from target_idx in
solver_mujoco.py) to fetch the correct name from that mapping.
- Around line 3638-3648: The equality constraints created after
mjc_eq_to_newton_jnt mapping use raw model.body_label values which may contain
"/" and are inconsistent with other constraints; update the two eq.name1 and
eq.name2 assignments in the second equality block (the one created via
spec.add_equality(objtype=mujoco.mjtObj.mjOBJ_BODY) with eq.type =
mujoco.mjtEq.mjEQ_CONNECT) to use get_body_name(...) instead of direct
model.body_label[...] so the child/parent names are sanitized (replace "/" with
"_")—i.e., call get_body_name(model, joint_child[j]) and get_body_name(model,
joint_parent[j]) (or the appropriate index variant used elsewhere) for eq.name1
and eq.name2 respectively.

In `@newton/_src/utils/import_mjcf.py`:
- Around line 1846-1854: The geom lookup fails because builder.shape_label
contains hierarchical labels while geom1_name/geom2_name are short names; update
the ValueError handling in the block around geom1_idx/geom2_idx resolution to
attempt a suffix or exact match: when builder.shape_label.index(geom_name)
raises ValueError, search builder.shape_label for entries where label ==
geom_name or label.endswith("/" + geom_name) (or other suffix match), select the
unique match (or the first if multiple) and set geom1_idx/geom2_idx accordingly;
if no match is found preserve the existing verbose warning ("Warning: <pair>
references unknown geom ...") and continue. Ensure you update both lookup
locations (for geom1_name and geom2_name) and use the same matching logic.

In `@newton/_src/utils/import_urdf.py`:
- Around line 558-564: Replace the short triple-quoted description in the
make_label function with a Google-style docstring: document the function purpose
in one line, add an Args section describing the parameter name: str, and a
Returns section describing the returned str (hierarchical label of the form
"{articulation_label}/{name}" or name if articulation_label is falsy). Reference
the existing symbols make_label and articulation_label when describing the
return behavior so reviewers can locate the change.
🧹 Nitpick comments (10)
newton/tests/test_robot_composer.py (1)

223-225: Consider providing a default or wrapping next() for a clearer failure message.

If the MJCF importer changes the label format or the asset changes, next() without a default raises a bare StopIteration, which produces a confusing traceback in test output. This same pattern repeats at lines 290 and 353.

A small helper or a default + assertion would make failures self-explanatory:

💡 Optional: clearer error on lookup failure
-        ee_body_idx = next(
-            i for i, lbl in enumerate(ur5e_with_robotiq_gripper.body_label) if lbl.endswith("/wrist_3_link")
-        )
+        ee_body_idx = next(
+            (i for i, lbl in enumerate(ur5e_with_robotiq_gripper.body_label) if lbl.endswith("/wrist_3_link")),
+            None,
+        )
+        assert ee_body_idx is not None, "Could not find body with label ending in '/wrist_3_link'"

Same applies to lines 290 and 353.

newton/tests/test_sites_mjcf_import.py (1)

49-49: Local variable still uses old key terminology after API rename.

The local variable shape_keys holds model.shape_label but retains the old naming. For consistency with the API rename, consider renaming it to shape_labels across all six test methods.

♻️ Example diff (applies similarly in all six occurrences)
-        shape_keys = model.shape_label
+        shape_labels = model.shape_label

And update all subsequent references from shape_keys[i] to shape_labels[i].

Also applies to: 93-93, 125-125, 150-150, 200-200, 233-233

newton/examples/contacts/example_sdf.py (1)

275-283: Nit: the local variable is still named gear_key (line 272).

The loop unpacks into gear_key and the comment on line 38 still says "filename -> key". Consider renaming to gear_label for consistency with the broader rename, though both are on unchanged lines so this is purely cosmetic.

newton/examples/ik/example_ik_cube_stacking.py (1)

459-484: Consider renaming the local variable key to label for consistency.

The local variable key on line 459 is passed as label=key on line 484. While functionally correct, renaming it to label would better align with the broader rename and reduce confusion.

Suggested diff
-            key = f"world_{world_id}/cube_{i}"
+            label = f"world_{world_id}/cube_{i}"
             ...
-            scene.add_shape_box(body=mesh_body, hx=half_size, hy=half_size, hz=half_size, cfg=shape_cfg, label=key)
+            scene.add_shape_box(body=mesh_body, hx=half_size, hy=half_size, hz=half_size, cfg=shape_cfg, label=label)
             ...
             if i == 0:
-                self.cube_colors[key] = [0.8, 0.2, 0.2]
+                self.cube_colors[label] = [0.8, 0.2, 0.2]
             elif i == 1:
-                self.cube_colors[key] = [0.2, 0.8, 0.2]
+                self.cube_colors[label] = [0.2, 0.8, 0.2]
             elif i == 2:
-                self.cube_colors[key] = [0.2, 0.2, 0.8]
+                self.cube_colors[label] = [0.2, 0.2, 0.8]
             else:
-                self.cube_colors[key] = [0.2, 0.2, 0.2]
+                self.cube_colors[label] = [0.2, 0.2, 0.2]
newton/tests/test_sites_usd_import.py (1)

84-84: Nit: local variable and comments still use "key" terminology.

The attribute was renamed to shape_label, but local variables (shape_keys on lines 84, 162, 240, 289, 358) and comments (e.g., line 167: "is in the key") still reference "key". Consider renaming to shape_labels / label for consistency with the new API.

newton/tests/test_jacobian_mass_matrix.py (1)

397-412: Stale variable name and comment after the key→label rename.

The loop variable key (line 398) and the comment "different keys" (line 397) should be updated to reflect the new label terminology for consistency with the API rename.

♻️ Suggested rename
-    # Create 2 pendulums with different keys
-    for i, key in enumerate(["robot_a", "robot_b"]):
+    # Create 2 pendulums with different labels
+    for i, label in enumerate(["robot_a", "robot_b"]):
-        builder.add_articulation([j1], label=key)
+        builder.add_articulation([j1], label=label)
newton/examples/sensors/example_sensor_contact.py (1)

102-102: Stale local variable names after the key→label rename.

obj_key (line 159) and the comprehension variable key (line 102) still use "key" terminology while the data source is now shape_label. Consider renaming for consistency (e.g., obj_label, label).

Also applies to: 159-162

newton/tests/test_mujoco_general_actuators.py (1)

74-79: find_joint_by_name uses suffix matching — inconsistent with other test files.

Other test files in this PR (e.g., test_import_usd.py line 2193, test_import_mjcf.py line 3049) look up joints via direct builder.joint_label.index(joint_name) with the full hierarchical label. Here, suffix matching via endswith works but is fragile — it could match unintended labels if two joints share the same leaf name (e.g., robot_a/.../joint_motor and robot_b/.../joint_motor).

Consider using full hierarchical labels in the callers (like test_combined_joint_per_dof_actuators already does at line 565) to keep a consistent lookup pattern across the test suite.

newton/tests/test_mujoco_solver.py (1)

5064-5066: Make the label lookup failure more explicit.

next(...) will raise StopIteration without context if the label is missing. A small guard makes failures clearer and easier to debug.

🧩 Suggested tweak for clearer diagnostics
-            newton_body_idx = next(i for i, lbl in enumerate(model.body_label) if lbl.endswith(f"/{body_name}"))
+            newton_body_idx = next(
+                (i for i, lbl in enumerate(model.body_label) if lbl.endswith(f"/{body_name}")), None
+            )
+            self.assertIsNotNone(
+                newton_body_idx,
+                f"Body label ending with '/{body_name}' not found in model.body_label",
+            )
newton/examples/robot/example_robot_panda_hydro.py (1)

103-107: Minor: find_body is called twice for the same finger bodies.

find_body("fr3_leftfinger") and find_body("fr3_rightfinger") are called at lines 104–105 (for the finger_body_indices set) and again at lines 140–141 (for the pad attachment). Consider reusing the results from the first call to avoid redundant linear scans.

♻️ Suggested refactor
+        left_finger_idx = find_body("fr3_leftfinger")
+        right_finger_idx = find_body("fr3_rightfinger")
+        hand_idx = find_body("fr3_hand")
         # Disable SDF collisions on all panda links except the fingers and hand
         finger_body_indices = {
-            find_body("fr3_leftfinger"),
-            find_body("fr3_rightfinger"),
-            find_body("fr3_hand"),
+            left_finger_idx,
+            right_finger_idx,
+            hand_idx,
         }
         ...
         # Add gripper pads
         if self.scene in [SceneType.PEN, SceneType.CUBE]:
-            left_finger_idx = find_body("fr3_leftfinger")
-            right_finger_idx = find_body("fr3_rightfinger")

Also applies to: 140-141

Comment thread newton/_src/solvers/mujoco/solver_mujoco.py
Comment thread newton/_src/solvers/mujoco/solver_mujoco.py Outdated
Comment thread newton/_src/utils/import_mjcf.py Outdated
Comment thread newton/_src/utils/import_urdf.py

Copilot AI left a comment

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.

Pull request overview

This PR implements issue #1592 by renaming entity identifier attributes from *_key to *_label throughout the codebase and introducing hierarchical label generation with /-separated paths. This is a breaking API change with no backward compatibility.

Changes:

  • Renamed all *_key attributes to *_label (body_key → body_label, joint_key → joint_label, shape_key → shape_label, etc.)
  • Implemented hierarchical labels in importers: URDF uses {robot_name}/{entity_name}, MJCF uses {model}/worldbody/{body}/... XPath-style paths, USD preserves existing prim paths
  • Added label_prefix parameter to add_builder() and add_world() for composing multiple robot instances
  • Updated MuJoCo solver export to replace / with _ in element names since MuJoCo interprets / as path separators
  • Added O(1) lookup dictionaries in MJCF importer (body_name_to_idx, site_name_to_idx, joint_name_to_idx) for efficient entity resolution

Reviewed changes

Copilot reviewed 65 out of 65 changed files in this pull request and generated no comments.

Show a summary per file
File Description
newton/_src/sim/model.py Core model attribute renames: shape_key → shape_label, body_key → body_label, joint_key → joint_label, articulation_key → articulation_label, equality_constraint_key → equality_constraint_label, constraint_mimic_key → constraint_mimic_label
newton/_src/utils/selection.py Updated selection API to use label terminology, renamed get_name_from_key → get_name_from_label
newton/_src/utils/import_usd.py Updated USD importer to use label terminology throughout, preserves USD prim paths as labels
newton/_src/utils/import_urdf.py Updated URDF importer with hierarchical labels {robot_name}/{entity_name}
newton/_src/utils/import_mjcf.py Updated MJCF importer with XPath-style hierarchical labels, added O(1) lookup dictionaries for efficient resolution
newton/_src/solvers/mujoco/solver_mujoco.py Updated MuJoCo solver to use label attributes and apply .replace("/", "_") to avoid path separator conflicts
newton/_src/sensors/*.py Updated sensor implementations to use shape_label and body_label
newton/_src/geometry/inertia.py Renamed body_key parameter to body_label
newton/tests/*.py Comprehensive test updates to reflect new label terminology and hierarchical label formats
newton/examples/*.py Example updates to use label parameter in API calls
docs/*.{rst,ipynb} Documentation updates reflecting the API changes

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…-to-label

# Conflicts:
#	newton/_src/sim/model.py
#	newton/_src/utils/selection.py
#	newton/examples/contacts/example_sdf.py

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
newton/examples/contacts/example_sdf.py (1)

197-203: ⚠️ Potential issue | 🔴 Critical

self.model.body_key was not renamed to self.model.body_label — will raise AttributeError in gears scene

This block in __init__ was missed during the key → label rename. Since the PR removes body_key with no backward-compat shim, accessing self.model.body_key at runtime will immediately crash whenever scene == "gears".

🐛 Proposed fix
-            for body_idx, key in enumerate(self.model.body_key):
-                if key == "gear_large":
+            for body_idx, label in enumerate(self.model.body_label):
+                if label == "gear_large":
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/examples/contacts/example_sdf.py` around lines 197 - 203, In the
__init__ block handling the "gears" scene, replace references to the removed
attribute self.model.body_key with the new self.model.body_label so the loop
uses the correct list of body labels; specifically update the loop that
currently reads "for body_idx, key in enumerate(self.model.body_key):" to
iterate "for body_idx, key in enumerate(self.model.body_label):" and keep the
rest of the logic (matching joint_child, using joint_qd_start and setting
joint_f) unchanged so no AttributeError occurs when scene == "gears".
newton/_src/utils/import_mjcf.py (1)

1699-1712: ⚠️ Potential issue | 🟡 Minor

Sanitize joint names before joint_name_to_idx lookups.
The map is keyed by sanitized names; raw MJCF names containing - won’t resolve in equality constraints or tendons.

🛠️ Suggested fix
-            joint1_name = joint.attrib.get("joint1")
-            joint2_name = joint.attrib.get("joint2")
+            joint1_name = sanitize_name(joint.attrib.get("joint1", "")) if joint.attrib.get("joint1") else None
+            joint2_name = sanitize_name(joint.attrib.get("joint2", "")) if joint.attrib.get("joint2") else None
@@
-                joint_name = joint_elem.attrib.get("joint")
+                joint_name = sanitize_name(joint_elem.attrib.get("joint", ""))

Also applies to: 1950-1961

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

In `@newton/_src/utils/import_mjcf.py` around lines 1699 - 1712, The equality
joint parsing uses raw MJCF names for joint1/joint2 but the joint_name_to_idx
map keys are sanitized; before doing the lookups in the block that handles
equality.findall("joint") (and the similar block around lines 1950-1961),
normalize/sanitize joint1_name and joint2_name with the same sanitizer used when
building joint_name_to_idx (e.g., call the existing
sanitize_name/sanitize_joint_name helper or the function used earlier in this
file) and use the sanitized values in joint_name_to_idx.get(...) so names
containing '-' resolve correctly.
newton/_src/utils/import_usd.py (1)

2285-2343: ⚠️ Potential issue | 🟠 Major

Add request timeouts and improve error handling for HTTP downloads.
Blocking HTTP calls without timeouts can hang; also catch RequestException for clearer error reporting. The codebase consistently uses timeout=10 for HTTP operations (see import_urdf.py:51 and texture.py:47).

🛡️ Suggested fix
-    response = requests.get(url, allow_redirects=True)
-    if response.status_code != 200:
-        raise RuntimeError(f"Failed to download USD file. Status code: {response.status_code}")
+    try:
+        response = requests.get(url, allow_redirects=True, timeout=10)
+        response.raise_for_status()
+    except requests.RequestException as exc:
+        raise RuntimeError(f"Failed to download USD file: {exc}") from exc
@@
-            response = requests.get(f"{url_folder}/{refname}", allow_redirects=True)
-            if response.status_code != 200:
-                print(f"Failed to download reference {refname}. Status code: {response.status_code}")
-                continue
+            try:
+                response = requests.get(f"{url_folder}/{refname}", allow_redirects=True, timeout=10)
+                response.raise_for_status()
+            except requests.RequestException:
+                print(f"Failed to download reference {refname}.")
+                continue
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/_src/utils/import_usd.py` around lines 2285 - 2343, The HTTP downloads
use bare requests.get without timeouts and a broad except; update both
requests.get calls (the initial download that writes target_filename and the
reference-download inside the for loop that writes ref_filename) to include
timeout=10, replace the generic except Exception with catching
requests.exceptions.RequestException (and log/print the exception detail, e.g.,
include str(e) in the message), and keep the existing status_code checks; ensure
you still handle non-200 responses the same way and include the exception info
when logging failures to download references or the main URL so failures are
clearer.
newton/_src/solvers/mujoco/solver_mujoco.py (1)

3134-3205: ⚠️ Potential issue | 🟠 Major

Replace deprecated shape_key usage in hfield naming.
model.shape_key will no longer exist after the key→label rename, so HFIELD exports will fail. Also keep name normalization consistent with other MuJoCo entities.

🛠️ Proposed fix
-                name = f"{model.shape_label[shape]}_{shape}"
+                sanitized_label = model.shape_label[shape].replace("/", "_")
+                name = f"{sanitized_label}_{shape}"
...
-                    hfield_name = f"{model.shape_key[shape]}_{shape}"
+                    hfield_name = name
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/_src/solvers/mujoco/solver_mujoco.py` around lines 3134 - 3205, The
hfield export is using the removed model.shape_key which will break exports;
change the hfield naming to use model.shape_label instead and normalize it the
same way other MuJoCo entities are named (match the earlier pattern used for
"name" like f"{model.shape_label[shape]}_{shape}"). Update the hfield_name
construction (used before calling spec.add_hfield and in
geom_params["hfieldname"]) to derive from model.shape_label[shape] and the shape
id, preserving the same normalization/formatting used elsewhere in this
function.
newton/_src/sim/builder.py (2)

4363-4440: ⚠️ Potential issue | 🔴 Critical

Update add_shape_heightfield to use label after the rename

add_shape() now takes label, but add_shape_heightfield() still forwards key=.... That will raise a TypeError at runtime. Rename the parameter and pass label.

🐛 Proposed fix
@@
-    def add_shape_heightfield(
+    def add_shape_heightfield(
         self,
         xform: Transform | None = None,
         heightfield: Any | None = None,  # Heightfield type, using Any to avoid circular import
         scale: Vec3 | None = None,
         cfg: ShapeConfig | None = None,
-        key: str | None = None,
+        label: str | None = None,
         custom_attributes: dict[str, Any] | None = None,
     ) -> int:
@@
-            key (str | None): An optional unique key for identifying the shape. If `None`, a default key is automatically generated. Defaults to `None`.
+            label (str | None): An optional unique label for identifying the shape. If `None`, a default label is automatically generated. Defaults to `None`.
@@
-            key=key,
+            label=label,
             custom_attributes=custom_attributes,
         )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/_src/sim/builder.py` around lines 4363 - 4440, The add_shape method
now expects parameter label but add_shape_heightfield still uses key, causing a
TypeError when it forwards key to add_shape; update add_shape_heightfield (and
any internal callers) to rename the parameter from key to label and forward
label=<value> to add_shape (or pass the label positional argument) so the
signature and forwarded argument match the new add_shape(label=...) usage;
ensure the shape_label storage (self.shape_label.append(...)) still works with
the new label name.

2010-2075: ⚠️ Potential issue | 🟡 Minor

Persist world labels/attributes or remove the params

begin_world() accepts label and attributes but never stores them (the TODO confirms this), so callers silently lose the metadata and Ruff flags label as unused. Either persist them (and optionally expose on Model) or drop the params/docs until supported.

✅ Suggested fix (store metadata on the builder)
@@
-        self.world_count = 0
+        self.world_count = 0
+        self.world_label: list[str] = []
+        self.world_attributes: list[dict[str, Any]] = []
@@
-        # Store world metadata if needed (for future use)
-        # Note: We might want to add world_label and world_attributes lists in __init__ if needed
-        # For now, we just track the world index
+        # Store world metadata
+        world_label = label or f"world_{self.current_world}"
+        self.world_label.append(world_label)
+        self.world_attributes.append(dict(attributes) if attributes else {})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/_src/sim/builder.py` around lines 2010 - 2075, The begin_world method
accepts label and attributes but doesn't persist them causing unused-parameter
warnings; fix by adding storage fields (e.g., self.world_labels: list[str |
None] and self.world_attributes: list[dict[str, Any] | None]) in the builder's
__init__, then append the incoming label and attributes inside begin_world (use
None if not provided) alongside the existing self.world_gravity.append(...) call
so metadata is retained for later exposure (e.g., on Model) and the
label/attributes parameters are actually used.
🧹 Nitpick comments (5)
newton/examples/contacts/example_sdf.py (1)

38-38: Stale comment still references "key"

Minor nit — the inline comment # Gear mesh files available (filename -> key) and the local variable gear_key at line 290 are cosmetically out of date now that the PR standardises on "label" terminology.

♻️ Optional cleanup
-# Gear mesh files available (filename -> key)
+# Gear mesh files available (filename -> label)
GEAR_FILES = [
    ...
]
-        for _, (gear_filename, gear_key) in enumerate(GEAR_FILES):
+        for _, (gear_filename, gear_label) in enumerate(GEAR_FILES):
             ...
-            label=gear_key,
+            label=gear_label,

And in _init_test_tracking (lines 354-355):

-                bolt_key = f"bolt_{i}_{j}"
-                nut_key = f"nut_{i}_{j}"
+                bolt_label = f"bolt_{i}_{j}"
+                nut_label = f"nut_{i}_{j}"
-                if bolt_key in self.model.body_label:
-                    self.bolt_body_indices.append(self.model.body_label.index(bolt_key))
-                if nut_key in self.model.body_label:
-                    self.nut_body_indices.append(self.model.body_label.index(nut_key))
+                if bolt_label in self.model.body_label:
+                    self.bolt_body_indices.append(self.model.body_label.index(bolt_label))
+                if nut_label in self.model.body_label:
+                    self.nut_body_indices.append(self.model.body_label.index(nut_label))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/examples/contacts/example_sdf.py` at line 38, Update the stale "key"
terminology to "label": change the inline comment "# Gear mesh files available
(filename -> key)" to something like "# Gear mesh files available (filename ->
label)", rename the local variable gear_key (and any related uses) to
gear_label, and likewise update references inside the _init_test_tracking
function where "key" is used (e.g., lines around _init_test_tracking) so all
identifiers, comments, and logging consistently use "label" instead of "key".
repro_ur5e_explosion.py (2)

183-202: Broad except Exception catches and a deferred import traceback.

Ruff (BLE001) flags the bare except Exception at lines 186, 192, and 198. For a repro script this is tolerable, but using BaseException or at minimum logging the traceback consistently for all three tests would give more diagnostic signal. The import traceback at line 199 is also better placed at the top of the file alongside the other imports.

♻️ Suggested cleanup
+import traceback
 import numpy as np
 ...

 if __name__ == "__main__":
     ...
     try:
         test_native_mujoco()
-    except Exception as e:
+    except Exception as e:  # noqa: BLE001
         print(f"  ERROR: {e}")
+        traceback.print_exc()

     ...
     try:
         test_mujoco_warp()
-    except Exception as e:
+    except Exception as e:  # noqa: BLE001
         print(f"  ERROR: {e}")
+        traceback.print_exc()

     ...
     try:
         test_newton_gpu()
-    except Exception as e:
-        import traceback
-        print(f"  ERROR: {e}")
-        traceback.print_exc()
+    except Exception as e:  # noqa: BLE001
+        print(f"  ERROR: {e}")
+        traceback.print_exc()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@repro_ur5e_explosion.py` around lines 183 - 202, The three try/except blocks
around test_native_mujoco(), test_mujoco_warp(), and test_newton_gpu() use broad
"except Exception" and one lazily imports traceback inside the handler; replace
the broad catches with a consistent diagnostic handler that logs the full
traceback for all failures (e.g., catch Exception as e and call
traceback.print_exc() or use logging.exception) and move "import traceback" to
the module imports at the top so all three blocks provide the same detailed
error output; update the handlers for test_native_mujoco, test_mujoco_warp, and
test_newton_gpu accordingly.

57-57: Prefer SolverMuJoCo._mujoco_warp over a direct import mujoco_warp.

Direct import mujoco_warp creates a hard dependency that will break the entire script when MuJoCo Warp is absent, rather than producing a clean skip.

-    import mujoco_warp as mjw
+    mjw = newton.solvers.SolverMuJoCo._mujoco_warp
+    if mjw is None:
+        print("  MuJoCo Warp not available, skipping.")
+        return

Based on learnings: "Tests should prefer SolverMuJoCo._mujoco_warp over direct 'import mujoco_warp' to avoid hard dependencies and allow clean skips when MJWarp is absent."

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

In `@repro_ur5e_explosion.py` at line 57, Replace the top-level direct import of
mujoco_warp with the test's use of SolverMuJoCo._mujoco_warp: remove the line
"import mujoco_warp" and update any references that relied on the module in
repro_ur5e_explosion.py to obtain the module via SolverMuJoCo._mujoco_warp
(checking for None and skipping or failing gracefully if it's not available) so
the script no longer creates a hard dependency on mujoco_warp.
newton/tests/test_equality_constraints.py (1)

42-42: Nit: stale variable name eq_keys after the rename.

The variable now holds equality_constraint_label values; renaming it to eq_labels would make the intent clear.

♻️ Trivial rename
-        eq_keys = self.model.equality_constraint_label
+        eq_labels = self.model.equality_constraint_label
         ...
-        c_site_idx = eq_keys.index("c_site")
+        c_site_idx = eq_labels.index("c_site")
         ...
-        w_site_idx = eq_keys.index("w_site")
+        w_site_idx = eq_labels.index("w_site")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/tests/test_equality_constraints.py` at line 42, Rename the stale
variable eq_keys to eq_labels where it's assigned from equality_constraint_label
(and update all subsequent references/usages in the same scope, e.g., in the
test function or class) so the name reflects that it holds labels rather than
keys; ensure no remaining references to eq_keys remain and run the tests to
confirm no name errors.
newton/tests/test_import_usd.py (1)

750-758: *Optional: rename expected_*_keys variables to _labels.
With the API now label-based, renaming these variables would reduce cognitive overhead.

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

In `@newton/tests/test_import_usd.py` around lines 750 - 758, The tests still use
variable names expected_body_keys and expected_joint_keys while the API is
label-based; rename these variables to expected_body_labels and
expected_joint_labels throughout the test (including the assertions that
reference builder.body_label and builder.joint_label and any
f-strings/messages), update any imports or fixtures that set them, and ensure
all references and assertion messages are changed consistently so
builder.body_label is compared to expected_body_labels and builder.joint_label
to expected_joint_labels.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/plans/2026-02-16-geom-margin-thickness.md`:
- Line 3: Remove the model-specific prefix "**For Claude:**" from the plan line
that currently reads "**For Claude:** REQUIRED SUB-SKILL: Use
superpowers:executing-plans to implement this plan task-by-task." Locate that
exact string in docs/plans/2026-02-16-geom-margin-thickness.md and either delete
the "For Claude:" prefix so it reads "REQUIRED SUB-SKILL: Use
superpowers:executing-plans to implement this plan task-by-task." or reword to a
tool-agnostic statement like "REQUIRED SUB-SKILL: Use
superpowers:executing-plans to implement this plan task-by-task." ensuring no
model-specific mentions remain.
- Line 13: The heading "Task 1: MJCF Import — parse `margin` to `thickness`" is
at H3 and causes a level jump from H1 to H3; change that header to H2 (prepend
"## ") or insert an H2 parent section above so the document follows incremental
heading levels and fixes markdownlint warnings.

In `@newton/_src/utils/import_mjcf.py`:
- Around line 1189-1191: Sanitize the freejoint_name before appending so it
matches the sanitized form used for other joints and works with actuator/tendon
lookups: after computing freejoint_name from freejoint_tags[0].attrib.get(...),
run the same sanitization routine used elsewhere (e.g., replace spaces and '-'
with '_' and trim/normalize characters) and then append the sanitized name to
joint_name and joint_armature as currently done.

In `@newton/_src/utils/import_usd.py`:
- Around line 1360-1363: The three comment lines immediately above the
conditional that checks "if any(re.match(p, joint_path) for p in ignore_paths)"
use "#!" which Ruff flags as misplaced shebangs (EXE003/EXE005); change those
"#!" comment prefixes to standard "#" (or "# !") so they are treated as normal
comments (update the comment block that starts with "#! it may be possible..."
near the if any(re.match...) check).

In `@newton/_src/utils/selection.py`:
- Around line 232-233: Add a Google-style docstring to the get_name_from_label
function that succinctly describes that it returns the final path segment from a
slash-delimited label, documents the parameter (label: str) and the return value
(str), and includes a short example or note about behavior with trailing slashes
or empty input; place this docstring immediately above the def
get_name_from_label(label: str) and follow the repository's Google-style
sections (Args, Returns, and optionally Examples).

In `@newton/examples/robot/example_robot_anymal_c_walk.py`:
- Around line 162-164: The loop over initial_q uses next(...) without a default,
causing StopIteration if a joint name isn't found; update the lookup to use
next((i for i, lbl in enumerate(builder.joint_label) if
lbl.endswith(f"/{name}")), None) and explicitly raise a ValueError including the
missing joint name (name) when the result is None before assigning
builder.joint_q[idx + 6] = value so failures report which joint label is
missing.

In `@newton/tests/test_import_usd.py`:
- Around line 2436-2439: Update the test's docstring/description to use the term
"label" instead of "key" to match the call site where the test passes label=;
locate the test around the assertions referencing builder._add_base_joint,
joint_id, builder.joint_count and builder.joint_label and change any wording
that says "key" to "label" so the description accurately reflects the parameter
being tested.

In `@repro_ur5e_explosion.py`:
- Around line 1-13: This file appears to be a local debug artifact: move
repro_ur5e_explosion.py into a dedicated folder like repro/ or sandbox/ (or add
it to .gitignore if it must remain local), replace the hardcoded XML_PATH
constant with a CLI-configurable argument (use argparse to accept --xml-path,
defaulting to a relative path or None) and ensure NUM_STEPS remains configurable
if desired, and add the required SPDX copyright header for 2026 at the top of
the file; update any README or usage notes accordingly.

In `@repro_ur5e_explosion.xml`:
- Around line 1-3: The file repro_ur5e_explosion.xml contains a hardcoded
absolute meshdir (meshdir="/home/adenzler/...") which breaks portability; update
the mujoco root element (model="ur5e") to reference a relative path or a
configurable location (e.g., ../assets/mujoco_menagerie or use an
environment-variable/token placeholder) instead of the absolute path, and move
the file into a dedicated repro/ or scratch/ directory (or add it to .gitignore)
so repo root isn't polluted and asset lookup is reproducible across machines.

---

Outside diff comments:
In `@newton/_src/sim/builder.py`:
- Around line 4363-4440: The add_shape method now expects parameter label but
add_shape_heightfield still uses key, causing a TypeError when it forwards key
to add_shape; update add_shape_heightfield (and any internal callers) to rename
the parameter from key to label and forward label=<value> to add_shape (or pass
the label positional argument) so the signature and forwarded argument match the
new add_shape(label=...) usage; ensure the shape_label storage
(self.shape_label.append(...)) still works with the new label name.
- Around line 2010-2075: The begin_world method accepts label and attributes but
doesn't persist them causing unused-parameter warnings; fix by adding storage
fields (e.g., self.world_labels: list[str | None] and self.world_attributes:
list[dict[str, Any] | None]) in the builder's __init__, then append the incoming
label and attributes inside begin_world (use None if not provided) alongside the
existing self.world_gravity.append(...) call so metadata is retained for later
exposure (e.g., on Model) and the label/attributes parameters are actually used.

In `@newton/_src/solvers/mujoco/solver_mujoco.py`:
- Around line 3134-3205: The hfield export is using the removed model.shape_key
which will break exports; change the hfield naming to use model.shape_label
instead and normalize it the same way other MuJoCo entities are named (match the
earlier pattern used for "name" like f"{model.shape_label[shape]}_{shape}").
Update the hfield_name construction (used before calling spec.add_hfield and in
geom_params["hfieldname"]) to derive from model.shape_label[shape] and the shape
id, preserving the same normalization/formatting used elsewhere in this
function.

In `@newton/_src/utils/import_mjcf.py`:
- Around line 1699-1712: The equality joint parsing uses raw MJCF names for
joint1/joint2 but the joint_name_to_idx map keys are sanitized; before doing the
lookups in the block that handles equality.findall("joint") (and the similar
block around lines 1950-1961), normalize/sanitize joint1_name and joint2_name
with the same sanitizer used when building joint_name_to_idx (e.g., call the
existing sanitize_name/sanitize_joint_name helper or the function used earlier
in this file) and use the sanitized values in joint_name_to_idx.get(...) so
names containing '-' resolve correctly.

In `@newton/_src/utils/import_usd.py`:
- Around line 2285-2343: The HTTP downloads use bare requests.get without
timeouts and a broad except; update both requests.get calls (the initial
download that writes target_filename and the reference-download inside the for
loop that writes ref_filename) to include timeout=10, replace the generic except
Exception with catching requests.exceptions.RequestException (and log/print the
exception detail, e.g., include str(e) in the message), and keep the existing
status_code checks; ensure you still handle non-200 responses the same way and
include the exception info when logging failures to download references or the
main URL so failures are clearer.

In `@newton/examples/contacts/example_sdf.py`:
- Around line 197-203: In the __init__ block handling the "gears" scene, replace
references to the removed attribute self.model.body_key with the new
self.model.body_label so the loop uses the correct list of body labels;
specifically update the loop that currently reads "for body_idx, key in
enumerate(self.model.body_key):" to iterate "for body_idx, key in
enumerate(self.model.body_label):" and keep the rest of the logic (matching
joint_child, using joint_qd_start and setting joint_f) unchanged so no
AttributeError occurs when scene == "gears".

---

Duplicate comments:
In `@newton/_src/solvers/mujoco/solver_mujoco.py`:
- Around line 3709-3722: The loop creating equality constraints uses raw
model.body_label instead of the sanitized get_body_name() helper; update both
places where eq.name1 and eq.name2 are assigned in the joints_loop block (the
two spec.add_equality calls) to call get_body_name(model.body_label[...]) for
joint_parent[j] and joint_child[j] so names are normalized consistently (ensure
mjc_eq_to_newton_jnt mapping still uses eq.id after the first equality as
before).
- Around line 1815-1819: The BODY actuator code is building target_name from
model.body_label (via target_name = model.body_label[target_idx].replace("/",
"_")), which can differ from the de-duplicated MuJoCo body names and break
lookups; change the lookup to use the de-duplicated mapping created when bodies
were constructed (e.g., use the stored body-name mapping variable created at
body creation time such as body_name_map or body_name_mapping) instead of
model.body_label, and keep the existing invalid-index check and replacement of
"/" with "_" only if the stored mapping doesn't already provide sanitized names;
update the reference at the BODY actuator handling (mujoco_act_idx, target_idx,
target_name) to use body_name_map[target_idx].

In `@newton/_src/utils/import_mjcf.py`:
- Around line 1849-1862: The geom lookup fails when labels are hierarchical
because builder.shape_label.index() requires an exact full-label match; update
the lookup for geom1_name and geom2_name to first try exact index via
builder.shape_label.index(name) and if that raises ValueError, fall back to
search for labels that either equal the short name (last component after
separators like '/' or '.') or end with the short name (use endswith) and pick
the first match; keep the existing verbose warning/continue behavior if no match
is found. Reference builder.shape_label, geom1_name, geom2_name and the
try/except blocks around the index lookups to implement this two-step (exact
then suffix/short-name) matching.

In `@repro_ur5e_two_robots.xml`:
- Around line 1-3: The <compiler> element currently hardcodes
meshdir="/home/adenzler/git/mujoco_menagerie" which breaks portability; change
the meshdir attribute in the repro_ur5e_two_robots.xml <compiler> element (model
"ur5e_x2") to a portable solution such as a relative path (e.g.,
"mujoco_menagerie"), an environment-variable reference (e.g., use a ${MESH_DIR}
token substituted at runtime), or remove the attribute and rely on a
project-relative lookup so the file no longer depends on an absolute
user-specific path.

---

Nitpick comments:
In `@newton/examples/contacts/example_sdf.py`:
- Line 38: Update the stale "key" terminology to "label": change the inline
comment "# Gear mesh files available (filename -> key)" to something like "#
Gear mesh files available (filename -> label)", rename the local variable
gear_key (and any related uses) to gear_label, and likewise update references
inside the _init_test_tracking function where "key" is used (e.g., lines around
_init_test_tracking) so all identifiers, comments, and logging consistently use
"label" instead of "key".

In `@newton/tests/test_equality_constraints.py`:
- Line 42: Rename the stale variable eq_keys to eq_labels where it's assigned
from equality_constraint_label (and update all subsequent references/usages in
the same scope, e.g., in the test function or class) so the name reflects that
it holds labels rather than keys; ensure no remaining references to eq_keys
remain and run the tests to confirm no name errors.

In `@newton/tests/test_import_usd.py`:
- Around line 750-758: The tests still use variable names expected_body_keys and
expected_joint_keys while the API is label-based; rename these variables to
expected_body_labels and expected_joint_labels throughout the test (including
the assertions that reference builder.body_label and builder.joint_label and any
f-strings/messages), update any imports or fixtures that set them, and ensure
all references and assertion messages are changed consistently so
builder.body_label is compared to expected_body_labels and builder.joint_label
to expected_joint_labels.

In `@repro_ur5e_explosion.py`:
- Around line 183-202: The three try/except blocks around test_native_mujoco(),
test_mujoco_warp(), and test_newton_gpu() use broad "except Exception" and one
lazily imports traceback inside the handler; replace the broad catches with a
consistent diagnostic handler that logs the full traceback for all failures
(e.g., catch Exception as e and call traceback.print_exc() or use
logging.exception) and move "import traceback" to the module imports at the top
so all three blocks provide the same detailed error output; update the handlers
for test_native_mujoco, test_mujoco_warp, and test_newton_gpu accordingly.
- Line 57: Replace the top-level direct import of mujoco_warp with the test's
use of SolverMuJoCo._mujoco_warp: remove the line "import mujoco_warp" and
update any references that relied on the module in repro_ur5e_explosion.py to
obtain the module via SolverMuJoCo._mujoco_warp (checking for None and skipping
or failing gracefully if it's not available) so the script no longer creates a
hard dependency on mujoco_warp.

Comment thread docs/plans/2026-02-16-geom-margin-thickness.md Outdated
Comment thread docs/plans/2026-02-16-geom-margin-thickness.md Outdated
Comment thread newton/_src/utils/import_mjcf.py Outdated
Comment thread newton/_src/utils/import_usd.py Outdated
Comment thread newton/_src/utils/selection.py
Comment thread newton/examples/robot/example_robot_anymal_c_walk.py
Comment thread newton/tests/test_import_usd.py
Comment thread repro_ur5e_explosion.py Outdated
Comment thread repro_ur5e_explosion.xml Outdated
Comment thread repro_ur5e_explosion.xml Outdated
Comment thread docs/plans/2026-02-16-geom-margin-thickness.md Outdated
These files were unintentionally included in the merge commit:
- repro_ur5e_explosion.py
- repro_ur5e_explosion.xml
- repro_ur5e_two_robots.xml
- docs/plans/2026-02-16-geom-margin-thickness.md
- Use get_body_name() for loop-joint equality constraints to sanitize
  "/" in hierarchical labels (solver_mujoco.py)
- Fix pair geom lookup to support hierarchical labels via suffix
  matching (import_mjcf.py)
- Sanitize freejoint names with sanitize_name() for consistency with
  other joint types (import_mjcf.py)
- Replace #! comment prefixes with # to fix Ruff shebang lint
  (import_usd.py)
- Add Google-style docstrings for make_label and get_name_from_label
- Improve next() call with default + ValueError for missing joints
  (example_robot_anymal_c_walk.py)
- Fix test docstring "key" -> "label" (test_import_usd.py)
@adenzler-nvidia

Copy link
Copy Markdown
Member Author

Thanks for catching these unnecessary files - removed them and addressed to coderabbit comments. Creating an issue for the body_name de-duplication issue raised.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
newton/_src/solvers/mujoco/solver_mujoco.py (1)

3130-3205: ⚠️ Potential issue | 🟠 Major

Replace shape_key with shape_label for heightfield names.

The shape_key API is deprecated; use shape_label instead to align with the current label-based API.

🛠️ Suggested fix
-                    hfield_name = f"{model.shape_key[shape]}_{shape}"
+                    hfield_name = f"{model.shape_label[shape]}_{shape}"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/_src/solvers/mujoco/solver_mujoco.py` around lines 3130 - 3205,
Replace the deprecated model.shape_key usage when building the heightfield name
in the hfield handling block: use model.shape_label[shape] instead of
model.shape_key[shape] (the relevant code is in the hfield branch where
hfield_name is constructed, near symbols model, spec.add_hfield, and
geom_params["hfieldname"]). Ensure the new f-string uses
model.shape_label[shape] so the heightfield name follows the current label-based
API.
🧹 Nitpick comments (4)
newton/examples/robot/example_robot_anymal_c_walk.py (1)

167-168: Address the TRY003 Ruff warning: move exception message to a variable.

♻️ Proposed fix
-            if idx is None:
-                raise ValueError(f"Joint '{name}' not found in builder.joint_label")
+            if idx is None:
+                msg = f"Joint '{name}' not found in builder.joint_label"
+                raise ValueError(msg)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/examples/robot/example_robot_anymal_c_walk.py` around lines 167 - 168,
The ValueError raise triggers TRY003; refactor the exception message into a
separate variable before raising: create a variable (e.g., msg = f"Joint
'{name}' not found in builder.joint_label") and then raise ValueError(msg) where
the current code checks "if idx is None" (referencing idx, name and
builder.joint_label) so the message string is not constructed directly inside
the raise expression.
newton/_src/utils/import_usd.py (1)

1460-1473: Redundant path_body_map updates after add_body calls.

add_body() already writes path_body_map[label] = b at line 570. The explicit assignments on lines 1468 and 1473 set the identical key–value pair a second time and can be removed.

♻️ Suggested cleanup
         if parent >= 0 and parent not in inserted_bodies:
             b = add_body(**body_data[parent])
             inserted_bodies.add(parent)
             art_bodies.append(b)
-            path_body_map[body_data[parent]["label"]] = b
         if child >= 0 and child not in inserted_bodies:
             b = add_body(**body_data[child])
             inserted_bodies.add(child)
             art_bodies.append(b)
-            path_body_map[body_data[child]["label"]] = b
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/_src/utils/import_usd.py` around lines 1460 - 1473, Remove the
redundant explicit assignments to path_body_map after add_body: inside the
bodies_follow_joint_ordering block that iterates sorted_joints and uses
joint_edges/jid, call add_body(**body_data[parent]) and
add_body(**body_data[child]) as before, but delete the subsequent lines that set
path_body_map[body_data[...]["label"]] = b because add_body already updates
path_body_map; keep the inserted_bodies tracking and appending to art_bodies
unchanged (affecting functions/variables add_body, path_body_map, body_data,
inserted_bodies, art_bodies, joint_edges, sorted_joints).
newton/tests/test_import_usd.py (2)

718-757: Rename expected_body_keys/expected_joint_keys parameters to expected_body_labels/expected_joint_labels.

The inner test_filtering function's parameter names still use the old _keys convention while every call site already passes USD-path label lists. The stale names also propagate into the assertion error messages.

✏️ Proposed fix
     def test_filtering(
         msg,
         ignore_paths,
         bodies_follow_joint_ordering,
         expected_articulation_count,
         expected_joint_types,
-        expected_body_keys,
-        expected_joint_keys,
+        expected_body_labels,
+        expected_joint_labels,
     ):
         ...
         self.assertEqual(
             builder.body_label,
-            expected_body_keys,
-            f"Expected {expected_body_keys} bodies after filtering ..., got {builder.body_label}",
+            expected_body_labels,
+            f"Expected {expected_body_labels} bodies after filtering ..., got {builder.body_label}",
         )
         self.assertEqual(
             builder.joint_label,
-            expected_joint_keys,
-            f"Expected {expected_joint_keys} joints after filtering ..., got {builder.joint_label}",
+            expected_joint_labels,
+            f"Expected {expected_joint_labels} joints after filtering ..., got {builder.joint_label}",
         )

All call sites (lines ~772-854) pass positional keyword arguments expected_body_keys= / expected_joint_keys= — those call sites need the same rename.

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

In `@newton/tests/test_import_usd.py` around lines 718 - 757, Rename the inner
helper function test_filtering's parameters expected_body_keys and
expected_joint_keys to expected_body_labels and expected_joint_labels (within
test_joint_filtering), update all references inside that function (assertion
messages and uses of builder.body_label/builder.joint_label) to use the new
names, and update every call site that passes expected_body_keys= or
expected_joint_keys= to use expected_body_labels= and expected_joint_labels= so
parameter names remain consistent with the USD-path label semantics.

2449-2559: Stale _key naming in verify_usdphysics_parser local variables and comment.

The comment (Line 2450) and local variables body_key_to_idx (Line 2451), shape_key_to_idx (Line 2452), joint_key_to_idx (Line 2504), and the loop variable key (Line 2559) all still use the old key terminology while they are built from *_label attributes.

✏️ Proposed fix
-        # since the key is generated from USD paths we can assume that keys are unique
-        body_key_to_idx = dict(zip(model.body_label, range(model.body_count), strict=False))
-        shape_key_to_idx = dict(zip(model.shape_label, range(model.shape_count), strict=False))
+        # since labels are USD prim paths we can assume they are unique
+        body_label_to_idx = dict(zip(model.body_label, range(model.body_count), strict=False))
+        shape_label_to_idx = dict(zip(model.shape_label, range(model.shape_count), strict=False))
-        joint_key_to_idx = dict(zip(model.joint_label, range(model.joint_count), strict=False))
+        joint_label_to_idx = dict(zip(model.joint_label, range(model.joint_count), strict=False))
-        for j, key in enumerate(model.joint_label):
-            prim = stage.GetPrimAtPath(key)
+        for j, label in enumerate(model.joint_label):
+            prim = stage.GetPrimAtPath(label)

All downstream uses of these variables (body_key_to_idx, shape_key_to_idx, joint_key_to_idx) need corresponding renames.

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

In `@newton/tests/test_import_usd.py` around lines 2449 - 2559, The test uses
stale "key" naming in verify_usdphysics_parser: rename body_key_to_idx,
shape_key_to_idx, joint_key_to_idx and the loop variable key (and any related
comment) to reflect they are derived from labels (e.g., body_label_to_idx,
shape_label_to_idx, joint_label_to_idx, and rename loop variable to joint_label
or lbl); update all downstream references (body_key_to_idx -> body_label_to_idx
in body presence, body_colliders, mass checks; shape_key_to_idx where used;
joint_key_to_idx in joint lookup and joints_found) and rename the comment at the
top accordingly so identifiers and comments consistently reference "label"
instead of "key".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@newton/_src/utils/import_mjcf.py`:
- Around line 1839-1844: The helper _find_shape_idx currently scans
builder.shape_label from index 0 and can return shapes belonging to previous
imports; change it to only search shapes added during the current parse_mjcf
invocation by iterating from start_shape_count up to the current length of
builder.shape_label (use start_shape_count as the lower bound for the loop and
still return the absolute index into builder.shape_label), ensuring <pair>
lookups only match shapes created in this import; keep the None return if no
match is found.

In `@newton/_src/utils/selection.py`:
- Around line 900-906: The tendon_names list is being filled with full
hierarchical labels directly; instead, when populating inside the loop that
currently checks hasattr(mujoco_attrs, "tendon_label") and iterates
arti_tendon_ids, call the existing helper get_name_from_label() on
mujoco_attrs.tendon_label[tendon_idx] and append its result (so tendon_names
stores leaf names consistent with joint_names/link_names/shape_names); keep the
existing fallback self.tendon_names.append(f"tendon_{tendon_idx}") for
out-of-range indices and do this change in the same block that references
mujoco_attrs.tendon_label and arti_tendon_ids.

In `@newton/tests/test_import_usd.py`:
- Line 2430: The test function name is inconsistent with its docstring: rename
the function symbol from test_add_base_joint_custom_key to
test_add_base_joint_custom_label in the test file so the name matches the
updated docstring; update any local references or uses (e.g., direct calls or
markers) of test_add_base_joint_custom_key to the new name to keep test
discovery and references consistent.
- Line 4813: The use of next(...) without a default can raise StopIteration;
update each occurrence (e.g., the body_idx assignment using next(i for i, name
in enumerate(model.body_label) if "FloatingBody" in name) and the similar
patterns at the other two locations) to supply a default (e.g., next(..., None))
and then assert the result is not None, raising a clear AssertionError message
like "FloatingBody not found in model.body_label" to give a descriptive failure
instead of StopIteration.

---

Outside diff comments:
In `@newton/_src/solvers/mujoco/solver_mujoco.py`:
- Around line 3130-3205: Replace the deprecated model.shape_key usage when
building the heightfield name in the hfield handling block: use
model.shape_label[shape] instead of model.shape_key[shape] (the relevant code is
in the hfield branch where hfield_name is constructed, near symbols model,
spec.add_hfield, and geom_params["hfieldname"]). Ensure the new f-string uses
model.shape_label[shape] so the heightfield name follows the current label-based
API.

---

Duplicate comments:
In `@newton/_src/solvers/mujoco/solver_mujoco.py`:
- Around line 1815-1819: The code derives target_name from model.body_label
which is wrong when MuJoCo de-duplicates body names; instead look up the MuJoCo
body name using the de-duplicated mapping created during body creation (the same
map used elsewhere, e.g. body_name_map / self.body_to_mujoco or
newton_to_mujoco_name_map) rather than model.body_label; replace the
model.body_label access in the actuator handling (symbols: target_idx,
model.body_label, target_name, mujoco_act_idx) with a lookup like
target_mujoco_name = body_name_map[target_idx] (then sanitize with .replace("/",
"_")), and keep the same bounds/validation logic around target_idx. Ensure you
reference the existing mapping variable used when bodies were created rather
than introducing a separate, inconsistent lookup.

In `@newton/_src/utils/import_mjcf.py`:
- Around line 1189-1190: No change required — the freejoint name is now
sanitized consistently with other joints; confirm sanitize_name is used in the
freejoint handling (freejoint_name variable) and that the sanitized name is
appended to joint_name, so no further edits are needed.

In `@newton/_src/utils/import_usd.py`:
- Around line 1360-1363: The review notes a leftover duplicate marker token
"[duplicate_comment]" after the comment block around the joint filtering check
(see variables joint_path and ignore_paths); remove that stray token so the
comment is clean and only uses standard `#` comments, ensuring no dangling
review artifacts remain near the if any(re.match(p, joint_path) for p in
ignore_paths) check in import_usd.py.

In `@newton/_src/utils/selection.py`:
- Around line 232-241: The docstring for get_name_from_label is updated to
Google-style and is fine as-is; no functional changes required—keep the current
implementation of get_name_from_label(label: str) returning label.split("/")[-1]
and the existing docstring.

---

Nitpick comments:
In `@newton/_src/utils/import_usd.py`:
- Around line 1460-1473: Remove the redundant explicit assignments to
path_body_map after add_body: inside the bodies_follow_joint_ordering block that
iterates sorted_joints and uses joint_edges/jid, call
add_body(**body_data[parent]) and add_body(**body_data[child]) as before, but
delete the subsequent lines that set path_body_map[body_data[...]["label"]] = b
because add_body already updates path_body_map; keep the inserted_bodies
tracking and appending to art_bodies unchanged (affecting functions/variables
add_body, path_body_map, body_data, inserted_bodies, art_bodies, joint_edges,
sorted_joints).

In `@newton/examples/robot/example_robot_anymal_c_walk.py`:
- Around line 167-168: The ValueError raise triggers TRY003; refactor the
exception message into a separate variable before raising: create a variable
(e.g., msg = f"Joint '{name}' not found in builder.joint_label") and then raise
ValueError(msg) where the current code checks "if idx is None" (referencing idx,
name and builder.joint_label) so the message string is not constructed directly
inside the raise expression.

In `@newton/tests/test_import_usd.py`:
- Around line 718-757: Rename the inner helper function test_filtering's
parameters expected_body_keys and expected_joint_keys to expected_body_labels
and expected_joint_labels (within test_joint_filtering), update all references
inside that function (assertion messages and uses of
builder.body_label/builder.joint_label) to use the new names, and update every
call site that passes expected_body_keys= or expected_joint_keys= to use
expected_body_labels= and expected_joint_labels= so parameter names remain
consistent with the USD-path label semantics.
- Around line 2449-2559: The test uses stale "key" naming in
verify_usdphysics_parser: rename body_key_to_idx, shape_key_to_idx,
joint_key_to_idx and the loop variable key (and any related comment) to reflect
they are derived from labels (e.g., body_label_to_idx, shape_label_to_idx,
joint_label_to_idx, and rename loop variable to joint_label or lbl); update all
downstream references (body_key_to_idx -> body_label_to_idx in body presence,
body_colliders, mass checks; shape_key_to_idx where used; joint_key_to_idx in
joint lookup and joints_found) and rename the comment at the top accordingly so
identifiers and comments consistently reference "label" instead of "key".

Comment thread newton/_src/utils/import_mjcf.py
Comment thread newton/_src/utils/selection.py
Comment thread newton/tests/test_import_usd.py Outdated
Comment thread newton/tests/test_import_usd.py Outdated
@adenzler-nvidia

Copy link
Copy Markdown
Member Author

Re: BODY actuator body-name mapping comment — this is a pre-existing issue unrelated to the key→label rename. Filed as #1679 to track separately.

Resolve merge conflicts in test_collision_pipeline.py (use new
Mesh.create_sphere API with label= parameter) and
test_mujoco_solver.py (keep both qpos and body transform checks).

Fix remaining key→label renames from upstream changes:
- builder.add_shape_heightfield: key→label parameter
- solver_mujoco: shape_key→shape_label, sanitize hfield name
- example_sdf: body_key→body_label with suffix matching
- test_selection: articulation_key→articulation_label
- test_import_mjcf: body_key→body_label with suffix matching
- test_mujoco_solver: body_key→body_label with suffix matching

Address unresolved PR review comments:
- Scope _find_shape_idx to current import via start_shape_count
- Use get_name_from_label for tendon_names consistency
- Rename test_add_base_joint_custom_key→custom_label
- Add next() default + assertIsNotNone for all bare next() calls
Resolve merge conflicts from upstream SDF API changes (newton-physics#1644):
- builder.py: remove add_shape_sdf (deleted upstream)
- example_robot_panda_hydro.py: adopt new SDF build pattern with labels
- test_collision_pipeline.py: use mesh.build_sdf() with labels

Fix NameError in test_ref_coordinate_conversion by using
solver._mujoco_warp instead of bare mujoco_warp import.
Also fix test_body_transforms_match_mujoco for consistency.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
newton/_src/solvers/mujoco/solver_mujoco.py (1)

3109-3172: ⚠️ Potential issue | 🟡 Minor

Sanitize geom/site names for consistency with other element names.

Lines 3110–3172 show an inconsistency in name sanitization: geom and site names (line 3110) use raw model.shape_label[shape] without replacing "/" with "", while bodies (line 3305), joints (line 3340), and hfield names (line 3172) all sanitize "/" to "". Although MuJoCo itself permits "/" in name attributes per its MJCF specification, the inconsistency should be resolved to maintain uniformity across all exported element names.

Extract the sanitized label once and reuse it:

🔧 Proposed fix
-                name = f"{model.shape_label[shape]}_{shape}"
+                shape_label = model.shape_label[shape].replace("/", "_")
+                name = f"{shape_label}_{shape}"
...
-                    hfield_name = f"{model.shape_label[shape].replace('/', '_')}_{shape}"
+                    hfield_name = f"{shape_label}_{shape}"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/_src/solvers/mujoco/solver_mujoco.py` around lines 3109 - 3172, The
shape/site naming uses raw model.shape_label[shape] (variable name) which causes
inconsistency; replace "/" with "_" once into a sanitized_label (e.g.,
sanitized_label = model.shape_label[shape].replace('/', '_')) and use that when
forming the site name and geom name (the name variable used for site_params and
geom_params) so site handling (site_params + body.add_site) and geom handling
(geom_params + spec.add_hfield) use the same sanitized label format as bodies
and joints.
newton/examples/basic/example_basic_joints.py (1)

227-244: ⚠️ Potential issue | 🟡 Minor

LGTM for label-based index lookup; fix unused q argument in the ball-joint lambda.

model.body_label.index(...) is a valid O(n) list lookup and will raise ValueError clearly if a label is missing — appropriate for test/example code.

Ruff (ARG005) flags the unused q argument at line 243:

lambda q, qd: abs(wp.dot(wp.spatial_bottom(qd), wp.vec3(0.0, 0.0, 1.0))) < 1e-3,
🛠️ Proposed fix
-            lambda q, qd: abs(wp.dot(wp.spatial_bottom(qd), wp.vec3(0.0, 0.0, 1.0))) < 1e-3,
+            lambda _q, qd: abs(wp.dot(wp.spatial_bottom(qd), wp.vec3(0.0, 0.0, 1.0))) < 1e-3,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/examples/basic/example_basic_joints.py` around lines 227 - 244, The
lambda passed to newton.examples.test_body_state for the "ball motion on sphere"
test currently declares an unused parameter q which triggers Ruff ARG005; update
the lambda signature to use an underscore-prefixed name for the unused argument
(e.g., _q, q_unused) or remove it if allowed, keeping the body using only qd
(the call inside newton.examples.test_body_state should still accept two args);
change the lambda at the "ball motion on sphere" call so the unused first
parameter is named with an underscore to satisfy the linter while preserving
behavior.
newton/_src/utils/import_mjcf.py (1)

1580-1723: ⚠️ Potential issue | 🟠 Major

Avoid silently binding constraints to world on unknown names.
The equality-constraint lookups use dict.get(..., -1) and joint/tendon lookups don’t sanitize names. That can silently map unknown names to world or drop intended joints when MJCF names include -/spaces. Prefer sanitize_name + explicit checks that warn/skip when a name isn’t found (similar to actuator handling). Consider applying the same body-name validation to both connect and weld blocks.

🛠️ Suggested fix
-                body1_idx = body_name_to_idx.get(body1_name, -1) if body1_name else -1
-                body2_idx = body_name_to_idx.get(body2_name, -1) if body2_name else -1
+                body1_idx = body_name_to_idx.get(body1_name) if body1_name else -1
+                if body1_name and body1_idx is None:
+                    if verbose:
+                        print(f"Warning: Connect constraint references unknown body '{body1_name}', skipping")
+                    continue
+                if body2_name in (None, "worldbody"):
+                    body2_idx = -1
+                else:
+                    body2_idx = body_name_to_idx.get(body2_name)
+                    if body2_idx is None:
+                        if verbose:
+                            print(f"Warning: Connect constraint references unknown body '{body2_name}', skipping")
+                        continue
@@
-            joint1_idx = joint_name_to_idx.get(joint1_name, -1) if joint1_name else -1
-            joint2_idx = joint_name_to_idx.get(joint2_name, -1) if joint2_name else -1
+            joint1_name = sanitize_name(joint1_name) if joint1_name else None
+            joint2_name = sanitize_name(joint2_name) if joint2_name else None
+            joint1_idx = joint_name_to_idx.get(joint1_name)
+            joint2_idx = joint_name_to_idx.get(joint2_name) if joint2_name else None
+            if joint1_idx is None or (joint2_name and joint2_idx is None):
+                if verbose:
+                    missing = joint1_name if joint1_idx is None else joint2_name
+                    print(f"Warning: Joint constraint references unknown joint '{missing}', skipping")
+                continue
@@
-                joint_idx = joint_name_to_idx.get(joint_name)
+                joint_name = sanitize_name(joint_name)
+                joint_idx = joint_name_to_idx.get(joint_name)

Also applies to: 1966-1968

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

In `@newton/_src/utils/import_mjcf.py` around lines 1580 - 1723, Lookup code for
equality constraints (functions/blocks using body_name_to_idx,
joint_name_to_idx, and site-based logic) currently uses dict.get(..., -1) and
unsanitized names which can silently bind to world or drop constraints; update
these sites (the connect block that calls
builder.add_equality_constraint_connect, the weld block that calls
builder.add_equality_constraint_weld, and the joint block that calls
builder.add_equality_constraint_joint) to first sanitize incoming names with
sanitize_name, then explicitly check presence in the corresponding index maps
(body_name_to_idx, joint_name_to_idx) and use get_site_body_and_anchor for
sites, and if a name is missing emit a verbose warning and skip the constraint
instead of using -1; apply the same validation pattern used for actuators
(sanitize -> existence check -> warn/continue) to all body/joint lookups
mentioned.
newton/_src/sim/builder.py (1)

2010-2075: ⚠️ Potential issue | 🟡 Minor

begin_world() label is currently a no-op.

Line 2012: label is documented but never stored or used (Ruff ARG002), so callers can’t retrieve world labels. Either persist it (and optionally attributes) or remove the parameter/docs until supported.

🛠️ Proposed fix (store world labels)
@@
-        self.world_gravity: list[tuple[float, float, float]] = []
+        self.world_gravity: list[tuple[float, float, float]] = []
+        self.world_label: list[str] = []
@@ def begin_world(
-        # Store world metadata if needed (for future use)
-        # Note: We might want to add world_label and world_attributes lists in __init__ if needed
-        # For now, we just track the world index
+        # Store world label for lookup/debugging
+        self.world_label.append(label or f"world_{self.current_world}")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/_src/sim/builder.py` around lines 2010 - 2075, The begin_world label
parameter is unused; persist labels (and optionally attributes) by adding
storage fields (e.g., self.world_labels and self.world_attributes) in __init__,
append the provided label (or generated default like f"world_{index}") and
attributes to those lists inside begin_world, and ensure other code referencing
worlds can read from these lists; also update the docstring/comments to reflect
the stored label behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@newton/tests/test_mujoco_solver.py`:
- Around line 5058-5064: The test iterates over body names ["child1","child2"]
which don't exist in the MJCF; update the lookup to use the actual body names
defined in the MJCF (e.g., ["base","child"]) or derive them dynamically from the
MJCF so the loop that computes newton_body_idx (using model.body_label) and
mjc_body_idx (using mjc_body_to_newton) finds valid indices; change the
body_name list used in that loop accordingly to fix the failing assertions.
- Around line 5051-5053: The test calls solver.update_newton_state(model, state,
solver.mjw_data, eval_fk=False) but SolverMuJoCo.update_newton_state does not
accept an eval_fk kwarg; remove the unsupported eval_fk argument so the call
matches other tests and the method signature (use
solver.update_newton_state(model, state, solver.mjw_data) instead); locate the
call by searching for update_newton_state in the test file and update the
invocation to omit eval_fk so it no longer raises a TypeError.
- Around line 5049-5050: Replace the undefined global mujoco_warp reference with
the cached module on the solver instance: use solver._mujoco_warp. Specifically,
in the test where mujoco_warp.kinematics(solver.mjw_model, solver.mjw_data) is
called, call solver._mujoco_warp.kinematics(...) instead so the cached module
from SolverMuJoCo is used and the F821 undefined name error is avoided.

---

Outside diff comments:
In `@newton/_src/sim/builder.py`:
- Around line 2010-2075: The begin_world label parameter is unused; persist
labels (and optionally attributes) by adding storage fields (e.g.,
self.world_labels and self.world_attributes) in __init__, append the provided
label (or generated default like f"world_{index}") and attributes to those lists
inside begin_world, and ensure other code referencing worlds can read from these
lists; also update the docstring/comments to reflect the stored label behavior.

In `@newton/_src/solvers/mujoco/solver_mujoco.py`:
- Around line 3109-3172: The shape/site naming uses raw model.shape_label[shape]
(variable name) which causes inconsistency; replace "/" with "_" once into a
sanitized_label (e.g., sanitized_label = model.shape_label[shape].replace('/',
'_')) and use that when forming the site name and geom name (the name variable
used for site_params and geom_params) so site handling (site_params +
body.add_site) and geom handling (geom_params + spec.add_hfield) use the same
sanitized label format as bodies and joints.

In `@newton/_src/utils/import_mjcf.py`:
- Around line 1580-1723: Lookup code for equality constraints (functions/blocks
using body_name_to_idx, joint_name_to_idx, and site-based logic) currently uses
dict.get(..., -1) and unsanitized names which can silently bind to world or drop
constraints; update these sites (the connect block that calls
builder.add_equality_constraint_connect, the weld block that calls
builder.add_equality_constraint_weld, and the joint block that calls
builder.add_equality_constraint_joint) to first sanitize incoming names with
sanitize_name, then explicitly check presence in the corresponding index maps
(body_name_to_idx, joint_name_to_idx) and use get_site_body_and_anchor for
sites, and if a name is missing emit a verbose warning and skip the constraint
instead of using -1; apply the same validation pattern used for actuators
(sanitize -> existence check -> warn/continue) to all body/joint lookups
mentioned.

In `@newton/examples/basic/example_basic_joints.py`:
- Around line 227-244: The lambda passed to newton.examples.test_body_state for
the "ball motion on sphere" test currently declares an unused parameter q which
triggers Ruff ARG005; update the lambda signature to use an underscore-prefixed
name for the unused argument (e.g., _q, q_unused) or remove it if allowed,
keeping the body using only qd (the call inside newton.examples.test_body_state
should still accept two args); change the lambda at the "ball motion on sphere"
call so the unused first parameter is named with an underscore to satisfy the
linter while preserving behavior.

Comment thread newton/tests/test_mujoco_solver.py Outdated
Comment thread newton/tests/test_mujoco_solver.py Outdated
Comment thread newton/tests/test_mujoco_solver.py Outdated
Remove unsupported eval_fk kwarg from update_newton_state call
(method signature doesn't accept it). Fix body name list to match
the MJCF which defines "child", not "child1"/"child2".

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
newton/_src/utils/import_mjcf.py (2)

1707-1719: ⚠️ Potential issue | 🟠 Major

Equality constraint joint names not sanitized — lookup will fail for names with hyphens.

joint_name_to_idx stores sanitized names (via sanitize_name at line 1222), but joint1_name / joint2_name here are raw from XML. If a joint name contains -, the lookup returns -1, silently creating a constraint referencing an invalid joint index.

Proposed fix
             joint1_name = joint.attrib.get("joint1")
             joint2_name = joint.attrib.get("joint2")
+            if joint1_name:
+                joint1_name = sanitize_name(joint1_name)
+            if joint2_name:
+                joint2_name = sanitize_name(joint2_name)
             polycoef = joint.attrib.get("polycoef", "0 1 0 0 0")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/_src/utils/import_mjcf.py` around lines 1707 - 1719, The equality
block is using raw XML joint names (joint1_name / joint2_name) to look up
indices in joint_name_to_idx, but stored keys were sanitized with sanitize_name;
fix by applying sanitize_name to joint1_name and joint2_name before performing
the lookup (in the loop that processes equality.findall("joint") alongside
parse_common_attributes and parse_custom_attributes), then use those sanitized
names to compute joint1_idx and joint2_idx so constraints reference the correct
indices.

1960-1979: ⚠️ Potential issue | 🟠 Major

Tendon joint names not sanitized — same lookup mismatch as equality constraints.

joint_name from joint_elem.attrib.get("joint") is raw, but joint_name_to_idx stores sanitized names. This causes the tendon to silently skip joints whose names contain -.

Proposed fix
                 joint_name = joint_elem.attrib.get("joint")
                 coef_str = joint_elem.attrib.get("coef", "1.0")

                 if not joint_name:
                     if verbose:
                         print(f"Warning: <joint> in tendon '{tendon_name}' missing joint attribute, skipping")
                     continue

+                joint_name = sanitize_name(joint_name)
                 # Look up joint index by name
                 joint_idx = joint_name_to_idx.get(joint_name)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/_src/utils/import_mjcf.py` around lines 1960 - 1979, The code is using
raw joint names from joint_elem.attrib ("joint_name") but joint_name_to_idx keys
are stored as sanitized names, so sanitize joint_name before lookup; update the
block in import_mjcf.py that handles joint entries (variables joint_elem,
joint_name, joint_name_to_idx) to apply the same sanitization/normalization
function used when building joint_name_to_idx to joint_name (e.g., call the
existing sanitize/normalize helper used elsewhere in this module) before doing
joint_name_to_idx.get(joint_name), so tendon joints with characters like '-'
resolve correctly instead of being skipped.
newton/_src/sim/builder.py (1)

2019-2084: ⚠️ Potential issue | 🟡 Minor

Persist or remove the new label parameter in begin_world().
label is documented but never stored or used, so callers silently lose it (also matches the Ruff unused-arg warning). Please wire it into builder state or drop it until supported.

💡 Suggested fix
@@ class ModelBuilder.__init__
-        # Per-world gravity vectors, populated when worlds are created via begin_world()
-        # Each entry is a tuple (gx, gy, gz) representing the gravity vector for that world
-        self.world_gravity: list[tuple[float, float, float]] = []
+        # Per-world metadata
+        self.world_label: list[str] = []
+        # Per-world gravity vectors, populated when worlds are created via begin_world()
+        # Each entry is a tuple (gx, gy, gz) representing the gravity vector for that world
+        self.world_gravity: list[tuple[float, float, float]] = []
@@ def begin_world(...):
-        # Store world metadata if needed (for future use)
-        # Note: We might want to add world_label and world_attributes lists in __init__ if needed
-        # For now, we just track the world index
+        world_label = label or f"world_{self.current_world}"
+        self.world_label.append(world_label)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/_src/sim/builder.py` around lines 2019 - 2084, The new label parameter
on begin_world is documented but never stored; either persist it or remove it.
To persist, add a world_labels list to the builder's state (initialize in
__init__) and append the provided label (or default generated label like
f"world_{self.current_world}") inside begin_world; ensure references use
begin_world and world_labels so later code can access labels. Alternatively, if
labels are not needed yet, remove the label parameter and its docs from
begin_world and eliminate any unused-arg warnings referencing begin_world.
🧹 Nitpick comments (4)
newton/tests/test_collision_pipeline.py (1)

192-192: shape_label indexed by body index — coincidentally correct, but fragile.

body is a body index (0 or 1) while shape_label is a shape-indexed array. This works only because the test adds exactly one shape per body in the same order, making body index == shape index. Adding a second shape to either body would silently surface the wrong label.

Consider a more explicit lookup via the body→shape mapping, e.g.:

♻️ Suggested fix
-        body_name = f"body {body} ({self.model.shape_label[body]})"
+        # Find the first shape belonging to `body` for diagnostic labelling
+        shape_idx = next(
+            (i for i, b in enumerate(self.model.shape_body.numpy()) if b == body),
+            body,
+        )
+        body_name = f"body {body} ({self.model.shape_label[shape_idx]})"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/tests/test_collision_pipeline.py` at line 192, The current test
constructs body_name using self.model.shape_label indexed by the body index
(body) which only works because each body currently has exactly one shape;
change it to look up the shape index(s) for that body and use the correct shape
label (e.g., map body → shape index via the model's body→shape mapping or list
such as self.model.body_shapes/body_to_shapes and then pick the appropriate
shape index like the first shape for that body) before indexing
self.model.shape_label so the label comes from the actual shape(s) belonging to
that body rather than assuming body==shape index.
newton/_src/utils/import_mjcf.py (2)

891-901: Site names stored unsanitized in site_name_to_idx — inconsistent with body/joint pattern.

body_name_to_idx and joint_name_to_idx store sanitized names (via sanitize_name), but site_name_to_idx stores raw names. While equality constraint lookups for sites also use raw names (so lookups work), this inconsistency could cause subtle issues if site names with hyphens are used in other contexts that expect sanitized names.

Suggested fix
             site_shapes.append(s)
-            site_name_to_idx[site_name] = s
+            site_name_to_idx[sanitize_name(site_name)] = s

If applied, also sanitize site names in get_site_body_and_anchor and connect/weld site lookups:

+            site1 = sanitize_name(site1)  # Match sanitized storage
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/_src/utils/import_mjcf.py` around lines 891 - 901, site_name_to_idx
currently stores raw site_name (in the builder.add_site block) which is
inconsistent with body_name_to_idx and joint_name_to_idx that use sanitize_name;
update the site handling to call sanitize_name(site_name) when creating
site_label keys and when storing in site_name_to_idx, and propagate the same
sanitized names to lookup sites in get_site_body_and_anchor and wherever
connect/weld site lookups occur so all site storage and lookup use sanitized
names consistently (reference symbols: site_name_to_idx, builder.add_site,
get_site_body_and_anchor, sanitize_name, body_name_to_idx, joint_name_to_idx,
connect/weld site lookup locations).

1586-1598: Silent fallback to world body when constraint body name not found.

body_name_to_idx.get(body1_name, -1) returns -1 (world) if the body name is not found. This silently creates a constraint anchored to the world instead of the intended body, potentially hiding misspelled body names. The same pattern appears in weld constraints (lines 1649–1650).

Consider adding a warning when a named body isn't found but is non-empty, similar to how the <exclude> path handles missing bodies.

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

In `@newton/_src/utils/import_mjcf.py` around lines 1586 - 1598, The code silently
falls back to world (index -1) when a body name lookup fails
(body_name_to_idx.get(..., -1)), causing misspelled or missing body names to
produce constraints against the world; update the body resolution used by
builder.add_equality_constraint_connect (and the similar weld constraint
resolution) to detect when body1_name or body2_name is non-empty but not present
in body_name_to_idx, emit a warning/error (using the module logger or existing
warning mechanism used for the <exclude> path) that includes the missing name
and context (e.g., common["name"] or articulation_label), and only then decide
whether to keep the -1 fallback or abort; ensure you reference body_name_to_idx,
body1_name, body2_name, builder.add_equality_constraint_connect, and the weld
constraint resolution when making the change.
newton/examples/robot/example_robot_panda_hydro.py (1)

112-113: find_body raises opaque StopIteration on missing body — prefer ValueError.

next(generator) without a default propagates StopIteration directly, which gives no indication of which body name was missing. For example code running in __init__, a missing body label would surface as a confusing StopIteration rather than a clear error.

🛡️ Proposed fix
-        def find_body(name):
-            return next(i for i, lbl in enumerate(builder.body_label) if lbl.endswith(f"/{name}"))
+        def find_body(name):
+            idx = next((i for i, lbl in enumerate(builder.body_label) if lbl.endswith(f"/{name}")), None)
+            if idx is None:
+                raise ValueError(f"No body with label ending '/{name}' found in builder")
+            return idx
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@newton/examples/robot/example_robot_panda_hydro.py` around lines 112 - 113,
The helper find_body currently calls next(...) without a default which lets
StopIteration bubble up; change it to search builder.body_label safely (e.g.,
using next(generator, None) or a for loop) and if no matching label is found
raise a ValueError with a clear message including the requested name and
possibly available labels; update the function name find_body to return the
index on success and raise ValueError(f"body '{name}' not found; available:
{builder.body_label}") on failure so callers get a descriptive error instead of
StopIteration.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@newton/examples/contacts/example_sdf.py`:
- Around line 362-365: _init_test_tracking currently checks for exact matches of
bolt_key/nut_key against self.model.body_label which fails when labels are
namespaced by replicate()/label_prefix; update the logic that populates
bolt_body_indices and nut_body_indices to mirror the gear handling by matching
either exact or suffixed labels (e.g., treat a label as matching if lbl ==
bolt_key or lbl.endswith(f"/{bolt_key}") ), locating the index via the matched
label in self.model.body_label and appending it; ensure the same change is
applied for nut_key so test_final() iterates over the correct indices even when
labels are prefixed.

---

Outside diff comments:
In `@newton/_src/sim/builder.py`:
- Around line 2019-2084: The new label parameter on begin_world is documented
but never stored; either persist it or remove it. To persist, add a world_labels
list to the builder's state (initialize in __init__) and append the provided
label (or default generated label like f"world_{self.current_world}") inside
begin_world; ensure references use begin_world and world_labels so later code
can access labels. Alternatively, if labels are not needed yet, remove the label
parameter and its docs from begin_world and eliminate any unused-arg warnings
referencing begin_world.

In `@newton/_src/utils/import_mjcf.py`:
- Around line 1707-1719: The equality block is using raw XML joint names
(joint1_name / joint2_name) to look up indices in joint_name_to_idx, but stored
keys were sanitized with sanitize_name; fix by applying sanitize_name to
joint1_name and joint2_name before performing the lookup (in the loop that
processes equality.findall("joint") alongside parse_common_attributes and
parse_custom_attributes), then use those sanitized names to compute joint1_idx
and joint2_idx so constraints reference the correct indices.
- Around line 1960-1979: The code is using raw joint names from
joint_elem.attrib ("joint_name") but joint_name_to_idx keys are stored as
sanitized names, so sanitize joint_name before lookup; update the block in
import_mjcf.py that handles joint entries (variables joint_elem, joint_name,
joint_name_to_idx) to apply the same sanitization/normalization function used
when building joint_name_to_idx to joint_name (e.g., call the existing
sanitize/normalize helper used elsewhere in this module) before doing
joint_name_to_idx.get(joint_name), so tendon joints with characters like '-'
resolve correctly instead of being skipped.

---

Nitpick comments:
In `@newton/_src/utils/import_mjcf.py`:
- Around line 891-901: site_name_to_idx currently stores raw site_name (in the
builder.add_site block) which is inconsistent with body_name_to_idx and
joint_name_to_idx that use sanitize_name; update the site handling to call
sanitize_name(site_name) when creating site_label keys and when storing in
site_name_to_idx, and propagate the same sanitized names to lookup sites in
get_site_body_and_anchor and wherever connect/weld site lookups occur so all
site storage and lookup use sanitized names consistently (reference symbols:
site_name_to_idx, builder.add_site, get_site_body_and_anchor, sanitize_name,
body_name_to_idx, joint_name_to_idx, connect/weld site lookup locations).
- Around line 1586-1598: The code silently falls back to world (index -1) when a
body name lookup fails (body_name_to_idx.get(..., -1)), causing misspelled or
missing body names to produce constraints against the world; update the body
resolution used by builder.add_equality_constraint_connect (and the similar weld
constraint resolution) to detect when body1_name or body2_name is non-empty but
not present in body_name_to_idx, emit a warning/error (using the module logger
or existing warning mechanism used for the <exclude> path) that includes the
missing name and context (e.g., common["name"] or articulation_label), and only
then decide whether to keep the -1 fallback or abort; ensure you reference
body_name_to_idx, body1_name, body2_name,
builder.add_equality_constraint_connect, and the weld constraint resolution when
making the change.

In `@newton/examples/robot/example_robot_panda_hydro.py`:
- Around line 112-113: The helper find_body currently calls next(...) without a
default which lets StopIteration bubble up; change it to search
builder.body_label safely (e.g., using next(generator, None) or a for loop) and
if no matching label is found raise a ValueError with a clear message including
the requested name and possibly available labels; update the function name
find_body to return the index on success and raise ValueError(f"body '{name}'
not found; available: {builder.body_label}") on failure so callers get a
descriptive error instead of StopIteration.

In `@newton/tests/test_collision_pipeline.py`:
- Line 192: The current test constructs body_name using self.model.shape_label
indexed by the body index (body) which only works because each body currently
has exactly one shape; change it to look up the shape index(s) for that body and
use the correct shape label (e.g., map body → shape index via the model's
body→shape mapping or list such as self.model.body_shapes/body_to_shapes and
then pick the appropriate shape index like the first shape for that body) before
indexing self.model.shape_label so the label comes from the actual shape(s)
belonging to that body rather than assuming body==shape index.

Comment thread newton/examples/contacts/example_sdf.py
Resolve conflicts in test files where main added new tests using
the old _key naming while this branch renamed to _label. Also
resolved method-to-function refactoring conflicts in test_import_usd
and duplicate test methods in test_model.
Resolve conflict in test_import_mjcf.py where main removed the
ensure_nonstatic_links test while this branch kept it with _label
naming.
The ensure_nonstatic_links option was removed from importers in
upstream main (dc06012). Drop the corresponding test that was
incorrectly kept during the merge.
Resolve conflicts in solver_mujoco.py: keep main's method rename
to _color_collision_shapes (private) with this branch's shape_labels
parameter naming.
Upstream/main added new tests using the old `key=` parameter name
and the public `update_newton_state()` method. Since this branch
renamed key→label and privatized the method, the auto-merge
produced code that compiled but failed at runtime.

- test_model.py: key= → label= in add_joint_revolute,
  add_shape_sphere, add_shape_box, add_shape_capsule, and
  add_constraint_mimic calls
- test_mujoco_solver.py: update_newton_state → _update_newton_state

@eric-heiden eric-heiden left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks!

@eric-heiden eric-heiden added this pull request to the merge queue Feb 19, 2026
Merged via the queue into newton-physics:main with commit b8b3e0a Feb 19, 2026
22 checks passed
vastsoun added a commit to vastsoun/newton that referenced this pull request Mar 3, 2026
* [Warp Raytrace] Added device parameter (newton-physics#1544)

* [Warp Raytrace] Added device parameter to previously overlooked call (newton-physics#1545)

* SolverMuJoCo: Fix tolerance clamping in update_solver_options_kernel (newton-physics#1546)

* Change default shape_ke to align with MuJoCo, parse geom solref from MJCF for contact stiffness/damping (newton-physics#1491)

Signed-off-by: Alain Denzler <adenzler@nvidia.com>

* Fix log_shapes broadcasting for length-1 warp arrays (newton-physics#1550)

* Fix XPBD restitution particle index (newton-physics#1557)

* Out-of-Bound memory read in example_diffsim_bear newton-physics#1386 (newton-physics#1533)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Add versioned documentation deployment to GitHub Pages (newton-physics#1560)

* Fix broken documentation links after versioned docs deployment (newton-physics#1566)

* VBD New Features (newton-physics#1479)

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* Add banners to membership verification workflow steps (newton-physics#1569)

* Support cable junctions (newton-physics#1519)

Signed-off-by: JC <jumyungc@nvidia.com>

* Rename parameter I to inertia newton-physics#1543 (newton-physics#1551)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Fix example_robot_anymal_c_walk.py (newton-physics#1574)

* Change everywhere linesearch to iterative (newton-physics#1573)

* Remove standard collision pipeline (newton-physics#1538)

* USD Plumbing MJC solver attributes through resolver and custom attribute framework (newton-physics#1463)

Signed-off-by: Milad Rakhsha <mrakhsha@nvidia.com>
Signed-off-by: Milad-Rakhsha-NV <167464435+Milad-Rakhsha-NV@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: adenzler-nvidia <adenzler@nvidia.com>

* Fix child shape filtering (newton-physics#1559)

* Fix ViewerRerun ignoring hidden parameter in log_mesh and log_instances (newton-physics#1555)

* Make NxN and SAP broad phase respect filtered pairs (newton-physics#1554)

* Add --quiet flag to examples to suppress Warp messages (newton-physics#1585)

* Defer resolution of MESH_MAXHULLVERT default in importers (newton-physics#1587)

* Fix TypeError when finalizing SDF geometry with device kwarg (newton-physics#1586)

* Make MESH_MAXHULLVERT a static class attribute Mesh.MAX_HULL_VERTICES. (newton-physics#1598)

* Significant non-determinism in unified collision pipeline for anymal_c_walking example newton-physics#1505 (newton-physics#1588)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Add test for non-contiguous case (newton-physics#1549)

* Fix nightly Warp CI to resolve pre-release builds (newton-physics#1606)

* Verify default class and value handling (newton-physics#1556)

* SolverMuJoCo: Expand geom_margin to avoid OOB read with heterogeneous worlds (newton-physics#1607)

* Fix bug in control clear method (newton-physics#1602)

* Enable Use of Newton IK in Lab newton-physics#662 (newton-physics#1539)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Fix import  of non-articulated joints (newton-physics#1535)

* Deduplicate _process_joint_custom_attributes frequency handling (newton-physics#1584)

* Add CI check for stale API docs and fix local build warnings (newton-physics#1570)

* Update Pillow 12.0.0 to 12.1.1 (newton-physics#1612)

* Prepare handling of mimic constraints in Newton (newton-physics#1523)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Support floating,  base_joint and parent_body arguments for importers (newton-physics#1498)

* Fix contact buffer memory overestimation (newton-physics#1614)

* Configure banned-module-level-imports for ruff (newton-physics#1583)

* Explicit `Contacts` instantiation with `Model.contacts()` and `CollisionPipeline.contacts()` (newton-physics#1445)

* Fix the quadruped benchmark regression (newton-physics#1615)

* Change default ignore_inertial_definitions from True to False (newton-physics#1537)

* Finalize the Recording API (newton-physics#1600)

* SolverMuJoCo: Fix ccd_iterations default (newton-physics#1631)

* update gitignore to ignore Claude Code sandbox files (newton-physics#1628)

* Add mimic joint support to SolverMuJoCo (newton-physics#1627)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Add --no-cache-clear flag to test runner (newton-physics#1629)

* Update MuJoCo and MuJoCo Warp to 3.5.0 release (newton-physics#1633)

* Improve inertia parsing from USD (newton-physics#1605)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* Remove standalone .typos.toml in favor of pyproject.toml config (newton-physics#1642)

* Heightfield support newton-physics#1189 (newton-physics#1547)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Example_robot_policy: Replace ValueError with clean error for missing PhysX policy (newton-physics#1636)

Co-authored-by: Viktor Reutskyy <33062116+vreutskyy@users.noreply.github.com>

* Avoid unnecessary inflation of the contact reduction voxel aabb (newton-physics#1650)

* Rename num_worlds to world_count (newton-physics#1634)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Support parsing autolimits from MJCF (newton-physics#1651)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Fix particle-shape restitution ignoring body velocity (newton-physics#1273) (newton-physics#1580)

* Add overflow warnings for narrow-phase collision buffers (newton-physics#1643)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Documentation: add units to model/state docstrings (newton-physics#1649)

* fix(viewer): add missing JointType.BALL support to contact line kernel (newton-physics#1640)

* Make terrain mesh visual-only in anymal C walking example (newton-physics#1660)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Fix initialization of collider state in MPM finite difference mode (newton-physics#1652)

* docs: document ModelBuilder.default_shape_cfg (newton-physics#1662)

* Finalize the collision API (newton-physics#1581)

* Remove hardcoded subnet ID from AWS workflow (newton-physics#1664)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Attempt to fix AWS config (newton-physics#1666)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Update AWS workflows to g7e.2xlarge with multi-AZ failover (newton-physics#1669)

* fix(viewer-usd): disambiguate log_points colors for N=3 warp arrays (newton-physics#1661)

* Viewer gl optimizations (newton-physics#1656)

Signed-off-by: Miles Macklin <mmacklin@nvidia.com>
Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>

* docs: add articulation workflow guidance and regression check (newton-physics#1663)

* fix(examples): propagate IK solution to model state in Franka example (newton-physics#1637)

* fix(deps,docs): bump nbconvert to 7.17.0 and fix ArticulationView doctest (newton-physics#1670)

* Cleanup and improve some example (newton-physics#1625)

Signed-off-by: adenzler-nvidia <adenzler@nvidia.com>
Co-authored-by: adenzler-nvidia <adenzler@nvidia.com>

* Handle zero-mass bodies and flip ensure_nonstatic_links default (newton-physics#1635)

* Additional testing for ArticulationView (newton-physics#1527)

Co-authored-by: Eric Heiden <eheiden@nvidia.com>

* Update warp-lang nightly to 1.12.0.dev20260217 (newton-physics#1677)

* Change default friction coefficients to match MuJoCo (newton-physics#1681)

* Refactor mesh creation functions (newton-physics#1654)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Parse joint frictionloss from MJCF (newton-physics#1680)

* Fix free joint body_pos and add ref/qpos0 support for MuJoCo solver (newton-physics#1645)

* Fix root shapes in ArticulationView with fixed base (newton-physics#1639)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Use model collision methods and remove `create_collision_pipeline` from examples (newton-physics#1648)

Co-authored-by: nvtw <110816143+nvtw@users.noreply.github.com>

* Fix XPBD apply_joint_forces ignoring child joint transform (newton-physics#1582)

* Adjust SDF API (newton-physics#1644)

Co-authored-by: Eric Heiden <eheiden@nvidia.com>

* Optimize test suite runtime (~18% faster) (newton-physics#1689)

* Remove ensure_nonstatic_links option from importers (newton-physics#1682)

Signed-off-by: adenzler-nvidia <adenzler@nvidia.com>

* SolverMuJoCo: Add geom_margin support, align thickness default with MuJoCo and schemas (newton-physics#1653)

* refactor: privatize non-public solver internals (newton-physics#1683)

* Fix option parsing with multiple <option> elements from includes (newton-physics#1692)

* Bump warp-lang nightly and newton-usd-schemas (newton-physics#1693)

* Get rid of tkinter dependency (newton-physics#1676)

* Fix SDF example contact buffer overflow (newton-physics#1695)

* Fix implicit biastype for position/velocity actuator shortcuts (newton-physics#1678)

* Fix include processor to respect meshdir/texturedir (newton-physics#1685)

* Reduce cold-cache Warp compile time for geometry modules (newton-physics#1618)

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: adenzler-nvidia <adenzler@nvidia.com>

* Fix xyzw-to-wxyz quaternion conversion in body inertia kernel (newton-physics#1694)

* Rename key to label and add hierarchical labels (newton-physics#1592) (newton-physics#1632)

* Expose geometry SDF helpers on public API (newton-physics#1684)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Improve custom frequency handling from USD, parse MuJoCo actuators and tendons (newton-physics#1510)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Collapse fixed joints with non articulated bodies (newton-physics#1608)

* Fix renaming joint_key -> joint_label (newton-physics#1700)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Bump .python-version from 3.11 to 3.12 (newton-physics#1702)

* Replace CITATION.md with CITATION.cff (newton-physics#1706)

* Respect MJCF contype=conaffinity=0 via collision_group=0 (newton-physics#1703)

* Make ViewerUSD reuse existing USD layers for the same output path (newton-physics#1704)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Remove dead up-axis conversion from MuJoCo solver (newton-physics#1707)

* Skip IK cube stacking example test (newton-physics#1713)

* Fix global pairs (world=-1) not exported to MuJoCo spec (newton-physics#1705)

* Reduce the memory consumption of hydroelastic contacts (newton-physics#1609)

* Fix flakiness cube stacking (newton-physics#1714)

* Fix collision shapes not toggleable in viewer UI (newton-physics#1715)

* Fix softbody examples table layout in README (newton-physics#1716)

* Standardize sensor APIs: label matching, keyword args, and update() method naming (newton-physics#1665)

* Fix intermittent crash in parallel test runner from Manager proxy race (newton-physics#1721)

* Clean up inertia.py function arguments to match Mesh.create_* API (newton-physics#1719)

* Reduce default test runner verbosity (newton-physics#1723)

* Add menagerie comparison tests for SolverMuJoCo (newton-physics#1720)

Signed-off-by: Alain Denzler <adenzler@nvidia.com>
Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Co-authored-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Co-authored-by: Viktor Reutskyy <33062116+vreutskyy@users.noreply.github.com>

* Add spatial tendon support for MuJoCo solver (newton-physics#1687)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Expose qfrc_actuator from mujoco (newton-physics#1698)

* Skip non-MODEL custom attributes in finalize validation (newton-physics#1734)

* Resolve inheritrange for position actuators in MJCF parser (newton-physics#1727)

* Support dampratio for position/velocity actuator shortcuts (newton-physics#1722)

* Limit concurrency to 1 (newton-physics#1736)

* Add a helper method for checking applied usd (newton-physics#1731)

* Enhance playback URL handling in ViewerViser (newton-physics#1742)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Removed RenderShapeType (newton-physics#1748)

* Override only MassAPI attributes that have been authored (newton-physics#1688)

* Integration of newton-actuators  (newton-physics#1342)

Signed-off-by: jvonmuralt <jvonmuralt@nvidia.com>

* Fix ArticulationView crash with fixed-joint-only articulations (newton-physics#1726)

* Improve retrieval of Jupyter base URL in ViewerViser (newton-physics#1750)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Disable dynamics testing for UR5e and Apollo tests to avoid CI flakiness (newton-physics#1755)

* Margin and Gap rename (newton-physics#1732)

* Vbd Demos Fixing (newton-physics#1740)

* Fix ViewerViser.log_lines method (newton-physics#1764)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Update warp-lang dependency to 1.12.0rc1 (newton-physics#1763)

* Fix fromto capsule/cylinder orientation in MJCF parser (newton-physics#1741)

* fix: multi-world particle BVH indexing (newton-physics#1641)

Co-authored-by: Eric Heiden <eheiden@nvidia.com>

* Clean up unused and internal-only kwargs in SolverMuJoCo (newton-physics#1766)

* Parsing of the mimic joint and contact gap/margin from newton schemas (newton-physics#1690)

Signed-off-by: Milad Rakhsha <mrakhsha@nvidia.com>

* API Refactor v2 (newton-physics#1749)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Support explicit geom mass attributes in MJCF (newton-physics#1744)

* Bump flask and werkzeug in lockfile for security (newton-physics#1769)

Co-authored-by: Cursor <cursoragent@cursor.com>

* Split MJCF worldbody root bodies into separate articulations (newton-physics#1754)

* Expose VBD rigid contact forces for solver coupling (newton-physics#1745)

Signed-off-by: JC <jumyungc@nvidia.com>

* Add MJCF ellipsoid geom import and regression test (newton-physics#1772)

Co-authored-by: Cursor <cursoragent@cursor.com>

* Weld equality constraints parsed from mjcf are given Nan as the default value of torquescale. The correct default should be 1.0 (newton-physics#1760)

* Improve picking accuracy and stability (newton-physics#1712)

* Franka cloth demo improvement (newton-physics#1765)

* Support computing sensing object transforms & API cleanup (newton-physics#1759)

* Remove threading workaround (newton-physics#1751)

* [Warp Raytrace] Consolidated ray intersect functions, renamed Options to Config (newton-physics#1767)

* Improve README example gallery for PyPI compatibility (newton-physics#1776)

* Fix issue with mesh in rerun viewer (newton-physics#1768)

* Add PhysxMimicJointAPI parsing to USD importer (newton-physics#1735)

* Move some math functions to Warp (newton-physics#1717)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Add test to ensure MJCF xform argument is relative (newton-physics#1777)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Emit diaginertia instead of fullinertia for diagonal body inertia (newton-physics#1780)

* Change default joint armature from 0.01 to 0 (newton-physics#1782)

* Fix default kp/kv for position and velocity actuators (newton-physics#1786)

* Lock body inertia after explicit MJCF <inertial> element (newton-physics#1784)

* Fix for MJCF actuator custom attributes (newton-physics#1783)

* Bump version to 0.2.3

Prepare the package metadata for the v0.2.3 release tag.

* Fix ViewerRerun rendering of instances from hidden meshes (newton-physics#1788)

* API cleanup (newton-physics#1789)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* BODY actuator target name bypasses body name de-duplication in SolverMuJoCo (newton-physics#1729)

* Use default density for visual geoms in MJCF import (newton-physics#1781)

* Fix GL viewer crash on Wayland (newton-physics#1793)

* Make USD xform parameter control absolute articulation placement (newton-physics#1771)

* Fix CUDA context corruption in SDF implementation (newton-physics#1792)

* Bump mujoco-warp dependency to 3.5.0.2 (newton-physics#1779)

* Fix MuJoCo margin/gap conversion (newton-physics#1785)

* Bump version to 1.1.0.dev0 (newton-physics#1798)

* Missing unittest.main added back to test_import_mjcf.py.  Helps with F5 debugging in VS Code. (newton-physics#1796)

* Improve H1 example (newton-physics#1801)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Fix ViewerViser.set_camera() (newton-physics#1805)

* Rename examples to follow prefix-first naming convention (newton-physics#1802)

* Improve MuJoCo actuator domain randomization (newton-physics#1773)

* Restore in_cup test in hydro example (newton-physics#1775)

* Fix `newton.geometry` imports and change of Mesh maxhullverts global constant

* Adapt to having both margin and gap arrays for each geom/shape

* Fix for newton.geometry API changes in primitive/narrowphase.py

* Fix removal of `BroadPhaseMode` IntEnum and revert to newton-sytle string literals

* WIP: Adapt geometry/unified.py to fix breaking changes to `newton.geometry` API

* First pass of API adjustments

* Patch more gaps (with respect to margin and gap renaming)

* GeoType.SDF was removed - reflect that in Kamino

* Introduce CoM position offsets w.r.t body frame and operations to convert between body CoM state and generic local body-fixed reference frames.

* Add caching of per-entity labels/names/keys in the Model subcontainers

* Remove SDF shape wrapper since it's now internal to mesh handling in CD pipelines

* Fix USD test assets

* Add Newton <--> Kamino joint type conversion operations and per-space default limit constants

* Add some cleanup to geometry and unified CD + UTs

* Add Newton <--> Kamino shape type conversion operations

* Apply new default joint coord limit constants to limits.py

* Adapt foubrar model builder and USD asset to produce the same result in sim example

* Purge "physical" goems and collapse all into a single group, and purge geometry "layers"

* Disable allocation per-joint wrenches by default and make them optional

* Make `Model` a dataclass

* Separate ModelData* containers into own `core/data.py` module

* Fix imports of ModelData

* Rename `Model` as `ModelKamino`

* Rename `ModelData` as `DataKamino`

* Rename `State` as `StateKamino`

* Rename `Control` as `ControlKamino`

* Rename `Limits` as `LimitsKamino`

* Rename `Contacts` as `ContactsKamino`

* Rename `ModelBuilder` as `ModelBuilderKamino`

* Make imports in test utilities relative

* Revise CD meta-data attributes and their computation in GeometryModel and ModelBuilderKamino

* Revise primitive CD pipeline

* Revise unified CD pipeline

* Revise CD front-end interfaces

* Fix UTs and relevant utils for interface changes to CD

* Change to `wp.DeviceLike` to account for upcoming deprecation of `Devicelike`

* Depracate legacy HDF5 data io (will be replaced in the future)

* Fix banned imports at module level

* Modify USD importer to detect articulations and order geoms and joints similarly to how the Newton `parse_usd` function does.

* Add conversion operation from `newton.Model` to `ModelKamino`

* Add data, state and control container conversions

* Add SolverKamino wrapper that fullfils newton integration interface

* Add newton integration examples

* Add SolverKamino to newton solver module imports

* WIP: fix problem with lambda_j being allocated for only kinematic constraints and failing on array copying

* Fix banned git import in benchmark

* Rename *Settings to *Config (#213)

* Rename SolverKaminoSettings -> SolverKaminoConfig

* Rename DualProblemSettings -> DualProblemConfig

* Rename CollisionDetectorSettings -> CollisionDetectorConfig

* Rename PADMMSettings -> PADMMConfig

* Rename ForwardKinematicsSolverSettings -> ForwardKinematicsSolverConfig

* Rename SimulatorSettings -> SimulatorConfig

* Add check for model compatibility in SolverKamino (#209)

* Fix device assignment in sparse CG test on CPU (#216)

* Replace Enum-type config attributes with Literal (#215)

* Replace warmstart mode config param with literal

* Replace contact warmstart mode config param with literal

* Replace rotation correction config param with literal

* Replace penalty update config param with literal

* Replace FK preconditioner option config param with literal

* Add post-init checks for dual/PADMM configs

* Rename FKPreconditionerOptions to FKPreconditionerType

* Remove WorldDescriptor from ModelKamino (#219)

* Add geom index offset array to model info

* Replace access to world description in model

* Remove world descriptor from model

* Fix computation of kinematics residual with sparse Jacobian (#220)

* Migrates `ModelKaminoSize` to it's own module to avoid circular dependency between core/model.py and core/state.py and rename it as `SizeKamino`.

* WIP: Fix SolverKamino wrapper

* Fix circular dependency in conversions.py

* Fix some broken unit tests and WIP to fix fourbar contact conversions and rendering

* Make some conversions @staticmethods instead, because they dont need common class attributes

* Fix declaration of custom state attributes and their conversion to/from newton and kamino

* WIP: Debug model conversion and newton sim examples

* Rename and cleanup start index array of per-world geoms

* Model conversion and newton sim examples now work.

* Make gravity conversion operation re-usable

* Migrates boxes_fourbar builder using newton.ModelBuilder to it's own module to prepare for migration.

* Use gravity conversion utility func in SolverKamino

* Add reusable joint-parameterization conversion utility

* Remove world-descriptor from model converter

* Rename helper converter that handles entity-local transforms

* Add some cleanup to DR Legs, ANYmal D and basic four-bar examples

* Fix module-level imports of additional kamino-specific development dependencies

* Fix module-level imports of additional kamino-specific development dependencies

* Fix erroneous merge conflict.

---------

Signed-off-by: Alain Denzler <adenzler@nvidia.com>
Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Signed-off-by: JC <jumyungc@nvidia.com>
Signed-off-by: Milad Rakhsha <mrakhsha@nvidia.com>
Signed-off-by: Milad-Rakhsha-NV <167464435+Milad-Rakhsha-NV@users.noreply.github.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Miles Macklin <mmacklin@nvidia.com>
Signed-off-by: adenzler-nvidia <adenzler@nvidia.com>
Signed-off-by: jvonmuralt <jvonmuralt@nvidia.com>
Co-authored-by: Daniela Hase <116915287+daniela-hase@users.noreply.github.com>
Co-authored-by: adenzler-nvidia <adenzler@nvidia.com>
Co-authored-by: Viktor Reutskyy <33062116+vreutskyy@users.noreply.github.com>
Co-authored-by: Eric Shi <97630937+shi-eric@users.noreply.github.com>
Co-authored-by: Anka Chen <AnkaChan@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: JC-nvidia <116605903+jumyungc@users.noreply.github.com>
Co-authored-by: Kenny Vilella <kvilella@nvidia.com>
Co-authored-by: nvtw <110816143+nvtw@users.noreply.github.com>
Co-authored-by: Milad-Rakhsha-NV <167464435+Milad-Rakhsha-NV@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Lennart Röstel <65088822+lenroe@users.noreply.github.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>
Co-authored-by: jvonmuralt <jvonmuralt@nvidia.com>
Co-authored-by: camevor <camevor@nvidia.com>
Co-authored-by: mzamoramora-nvidia <mzamoramora@nvidia.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Alessandro Roncone <alecive87@gmail.com>
Co-authored-by: gdaviet <57617656+gdaviet@users.noreply.github.com>
Co-authored-by: Miles Macklin <mmacklin@nvidia.com>
Co-authored-by: Gordon Yeoman <gyeomannvidia@users.noreply.github.com>
Co-authored-by: Lukasz Wawrzyniak <lwawrzyniak@nvidia.com>
Co-authored-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Co-authored-by: Lorenzo Terenzi <lorenzoterenzi96@gmail.com>
Co-authored-by: smollerNV <164020096+smollerNV@users.noreply.github.com>
Co-authored-by: twidmer <twidmer@nvidia.com>
Co-authored-by: Christian Schumacher <christian.schumacher@disney.com>
Co-authored-by: Guirec-Maloisel <25688871+Guirec-Maloisel@users.noreply.github.com>
vastsoun added a commit to vastsoun/newton that referenced this pull request Mar 4, 2026
* [Warp Raytrace] Added device parameter (newton-physics#1544)

* [Warp Raytrace] Added device parameter to previously overlooked call (newton-physics#1545)

* SolverMuJoCo: Fix tolerance clamping in update_solver_options_kernel (newton-physics#1546)

* Change default shape_ke to align with MuJoCo, parse geom solref from MJCF for contact stiffness/damping (newton-physics#1491)

Signed-off-by: Alain Denzler <adenzler@nvidia.com>

* Fix log_shapes broadcasting for length-1 warp arrays (newton-physics#1550)

* Fix XPBD restitution particle index (newton-physics#1557)

* Out-of-Bound memory read in example_diffsim_bear newton-physics#1386 (newton-physics#1533)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Add versioned documentation deployment to GitHub Pages (newton-physics#1560)

* Fix broken documentation links after versioned docs deployment (newton-physics#1566)

* VBD New Features (newton-physics#1479)

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* Add banners to membership verification workflow steps (newton-physics#1569)

* Support cable junctions (newton-physics#1519)

Signed-off-by: JC <jumyungc@nvidia.com>

* Rename parameter I to inertia newton-physics#1543 (newton-physics#1551)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Fix example_robot_anymal_c_walk.py (newton-physics#1574)

* Change everywhere linesearch to iterative (newton-physics#1573)

* Remove standard collision pipeline (newton-physics#1538)

* USD Plumbing MJC solver attributes through resolver and custom attribute framework (newton-physics#1463)

Signed-off-by: Milad Rakhsha <mrakhsha@nvidia.com>
Signed-off-by: Milad-Rakhsha-NV <167464435+Milad-Rakhsha-NV@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: adenzler-nvidia <adenzler@nvidia.com>

* Fix child shape filtering (newton-physics#1559)

* Fix ViewerRerun ignoring hidden parameter in log_mesh and log_instances (newton-physics#1555)

* Make NxN and SAP broad phase respect filtered pairs (newton-physics#1554)

* Add --quiet flag to examples to suppress Warp messages (newton-physics#1585)

* Defer resolution of MESH_MAXHULLVERT default in importers (newton-physics#1587)

* Fix TypeError when finalizing SDF geometry with device kwarg (newton-physics#1586)

* Make MESH_MAXHULLVERT a static class attribute Mesh.MAX_HULL_VERTICES. (newton-physics#1598)

* Significant non-determinism in unified collision pipeline for anymal_c_walking example newton-physics#1505 (newton-physics#1588)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Add test for non-contiguous case (newton-physics#1549)

* Fix nightly Warp CI to resolve pre-release builds (newton-physics#1606)

* Verify default class and value handling (newton-physics#1556)

* SolverMuJoCo: Expand geom_margin to avoid OOB read with heterogeneous worlds (newton-physics#1607)

* Fix bug in control clear method (newton-physics#1602)

* Enable Use of Newton IK in Lab newton-physics#662 (newton-physics#1539)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Fix import  of non-articulated joints (newton-physics#1535)

* Deduplicate _process_joint_custom_attributes frequency handling (newton-physics#1584)

* Add CI check for stale API docs and fix local build warnings (newton-physics#1570)

* Update Pillow 12.0.0 to 12.1.1 (newton-physics#1612)

* Prepare handling of mimic constraints in Newton (newton-physics#1523)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Support floating,  base_joint and parent_body arguments for importers (newton-physics#1498)

* Fix contact buffer memory overestimation (newton-physics#1614)

* Configure banned-module-level-imports for ruff (newton-physics#1583)

* Explicit `Contacts` instantiation with `Model.contacts()` and `CollisionPipeline.contacts()` (newton-physics#1445)

* Fix the quadruped benchmark regression (newton-physics#1615)

* Change default ignore_inertial_definitions from True to False (newton-physics#1537)

* Finalize the Recording API (newton-physics#1600)

* SolverMuJoCo: Fix ccd_iterations default (newton-physics#1631)

* update gitignore to ignore Claude Code sandbox files (newton-physics#1628)

* Add mimic joint support to SolverMuJoCo (newton-physics#1627)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Add --no-cache-clear flag to test runner (newton-physics#1629)

* Update MuJoCo and MuJoCo Warp to 3.5.0 release (newton-physics#1633)

* Improve inertia parsing from USD (newton-physics#1605)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* Remove standalone .typos.toml in favor of pyproject.toml config (newton-physics#1642)

* Heightfield support newton-physics#1189 (newton-physics#1547)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Example_robot_policy: Replace ValueError with clean error for missing PhysX policy (newton-physics#1636)

Co-authored-by: Viktor Reutskyy <33062116+vreutskyy@users.noreply.github.com>

* Avoid unnecessary inflation of the contact reduction voxel aabb (newton-physics#1650)

* Rename num_worlds to world_count (newton-physics#1634)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Support parsing autolimits from MJCF (newton-physics#1651)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Fix particle-shape restitution ignoring body velocity (newton-physics#1273) (newton-physics#1580)

* Add overflow warnings for narrow-phase collision buffers (newton-physics#1643)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Documentation: add units to model/state docstrings (newton-physics#1649)

* fix(viewer): add missing JointType.BALL support to contact line kernel (newton-physics#1640)

* Make terrain mesh visual-only in anymal C walking example (newton-physics#1660)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Fix initialization of collider state in MPM finite difference mode (newton-physics#1652)

* docs: document ModelBuilder.default_shape_cfg (newton-physics#1662)

* Finalize the collision API (newton-physics#1581)

* Remove hardcoded subnet ID from AWS workflow (newton-physics#1664)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Attempt to fix AWS config (newton-physics#1666)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Update AWS workflows to g7e.2xlarge with multi-AZ failover (newton-physics#1669)

* fix(viewer-usd): disambiguate log_points colors for N=3 warp arrays (newton-physics#1661)

* Viewer gl optimizations (newton-physics#1656)

Signed-off-by: Miles Macklin <mmacklin@nvidia.com>
Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>

* docs: add articulation workflow guidance and regression check (newton-physics#1663)

* fix(examples): propagate IK solution to model state in Franka example (newton-physics#1637)

* fix(deps,docs): bump nbconvert to 7.17.0 and fix ArticulationView doctest (newton-physics#1670)

* Cleanup and improve some example (newton-physics#1625)

Signed-off-by: adenzler-nvidia <adenzler@nvidia.com>
Co-authored-by: adenzler-nvidia <adenzler@nvidia.com>

* Handle zero-mass bodies and flip ensure_nonstatic_links default (newton-physics#1635)

* Additional testing for ArticulationView (newton-physics#1527)

Co-authored-by: Eric Heiden <eheiden@nvidia.com>

* Update warp-lang nightly to 1.12.0.dev20260217 (newton-physics#1677)

* Change default friction coefficients to match MuJoCo (newton-physics#1681)

* Refactor mesh creation functions (newton-physics#1654)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Parse joint frictionloss from MJCF (newton-physics#1680)

* Fix free joint body_pos and add ref/qpos0 support for MuJoCo solver (newton-physics#1645)

* Fix root shapes in ArticulationView with fixed base (newton-physics#1639)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Use model collision methods and remove `create_collision_pipeline` from examples (newton-physics#1648)

Co-authored-by: nvtw <110816143+nvtw@users.noreply.github.com>

* Fix XPBD apply_joint_forces ignoring child joint transform (newton-physics#1582)

* Adjust SDF API (newton-physics#1644)

Co-authored-by: Eric Heiden <eheiden@nvidia.com>

* Optimize test suite runtime (~18% faster) (newton-physics#1689)

* Remove ensure_nonstatic_links option from importers (newton-physics#1682)

Signed-off-by: adenzler-nvidia <adenzler@nvidia.com>

* SolverMuJoCo: Add geom_margin support, align thickness default with MuJoCo and schemas (newton-physics#1653)

* refactor: privatize non-public solver internals (newton-physics#1683)

* Fix option parsing with multiple <option> elements from includes (newton-physics#1692)

* Bump warp-lang nightly and newton-usd-schemas (newton-physics#1693)

* Get rid of tkinter dependency (newton-physics#1676)

* Fix SDF example contact buffer overflow (newton-physics#1695)

* Fix implicit biastype for position/velocity actuator shortcuts (newton-physics#1678)

* Fix include processor to respect meshdir/texturedir (newton-physics#1685)

* Reduce cold-cache Warp compile time for geometry modules (newton-physics#1618)

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: adenzler-nvidia <adenzler@nvidia.com>

* Fix xyzw-to-wxyz quaternion conversion in body inertia kernel (newton-physics#1694)

* Rename key to label and add hierarchical labels (newton-physics#1592) (newton-physics#1632)

* Expose geometry SDF helpers on public API (newton-physics#1684)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Improve custom frequency handling from USD, parse MuJoCo actuators and tendons (newton-physics#1510)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Collapse fixed joints with non articulated bodies (newton-physics#1608)

* Fix renaming joint_key -> joint_label (newton-physics#1700)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Bump .python-version from 3.11 to 3.12 (newton-physics#1702)

* Replace CITATION.md with CITATION.cff (newton-physics#1706)

* Respect MJCF contype=conaffinity=0 via collision_group=0 (newton-physics#1703)

* Make ViewerUSD reuse existing USD layers for the same output path (newton-physics#1704)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Remove dead up-axis conversion from MuJoCo solver (newton-physics#1707)

* Skip IK cube stacking example test (newton-physics#1713)

* Fix global pairs (world=-1) not exported to MuJoCo spec (newton-physics#1705)

* Reduce the memory consumption of hydroelastic contacts (newton-physics#1609)

* Fix flakiness cube stacking (newton-physics#1714)

* Fix collision shapes not toggleable in viewer UI (newton-physics#1715)

* Fix softbody examples table layout in README (newton-physics#1716)

* Standardize sensor APIs: label matching, keyword args, and update() method naming (newton-physics#1665)

* Fix intermittent crash in parallel test runner from Manager proxy race (newton-physics#1721)

* Clean up inertia.py function arguments to match Mesh.create_* API (newton-physics#1719)

* Reduce default test runner verbosity (newton-physics#1723)

* Add menagerie comparison tests for SolverMuJoCo (newton-physics#1720)

Signed-off-by: Alain Denzler <adenzler@nvidia.com>
Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Co-authored-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Co-authored-by: Viktor Reutskyy <33062116+vreutskyy@users.noreply.github.com>

* Add spatial tendon support for MuJoCo solver (newton-physics#1687)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Expose qfrc_actuator from mujoco (newton-physics#1698)

* Skip non-MODEL custom attributes in finalize validation (newton-physics#1734)

* Resolve inheritrange for position actuators in MJCF parser (newton-physics#1727)

* Support dampratio for position/velocity actuator shortcuts (newton-physics#1722)

* Limit concurrency to 1 (newton-physics#1736)

* Add a helper method for checking applied usd (newton-physics#1731)

* Enhance playback URL handling in ViewerViser (newton-physics#1742)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Removed RenderShapeType (newton-physics#1748)

* Override only MassAPI attributes that have been authored (newton-physics#1688)

* Integration of newton-actuators  (newton-physics#1342)

Signed-off-by: jvonmuralt <jvonmuralt@nvidia.com>

* Fix ArticulationView crash with fixed-joint-only articulations (newton-physics#1726)

* Improve retrieval of Jupyter base URL in ViewerViser (newton-physics#1750)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Disable dynamics testing for UR5e and Apollo tests to avoid CI flakiness (newton-physics#1755)

* Margin and Gap rename (newton-physics#1732)

* Vbd Demos Fixing (newton-physics#1740)

* Fix ViewerViser.log_lines method (newton-physics#1764)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Update warp-lang dependency to 1.12.0rc1 (newton-physics#1763)

* Fix fromto capsule/cylinder orientation in MJCF parser (newton-physics#1741)

* fix: multi-world particle BVH indexing (newton-physics#1641)

Co-authored-by: Eric Heiden <eheiden@nvidia.com>

* Clean up unused and internal-only kwargs in SolverMuJoCo (newton-physics#1766)

* Parsing of the mimic joint and contact gap/margin from newton schemas (newton-physics#1690)

Signed-off-by: Milad Rakhsha <mrakhsha@nvidia.com>

* API Refactor v2 (newton-physics#1749)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Support explicit geom mass attributes in MJCF (newton-physics#1744)

* Bump flask and werkzeug in lockfile for security (newton-physics#1769)

Co-authored-by: Cursor <cursoragent@cursor.com>

* Split MJCF worldbody root bodies into separate articulations (newton-physics#1754)

* Expose VBD rigid contact forces for solver coupling (newton-physics#1745)

Signed-off-by: JC <jumyungc@nvidia.com>

* Add MJCF ellipsoid geom import and regression test (newton-physics#1772)

Co-authored-by: Cursor <cursoragent@cursor.com>

* Weld equality constraints parsed from mjcf are given Nan as the default value of torquescale. The correct default should be 1.0 (newton-physics#1760)

* Improve picking accuracy and stability (newton-physics#1712)

* Franka cloth demo improvement (newton-physics#1765)

* Support computing sensing object transforms & API cleanup (newton-physics#1759)

* Remove threading workaround (newton-physics#1751)

* [Warp Raytrace] Consolidated ray intersect functions, renamed Options to Config (newton-physics#1767)

* Improve README example gallery for PyPI compatibility (newton-physics#1776)

* Fix issue with mesh in rerun viewer (newton-physics#1768)

* Add PhysxMimicJointAPI parsing to USD importer (newton-physics#1735)

* Move some math functions to Warp (newton-physics#1717)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Add test to ensure MJCF xform argument is relative (newton-physics#1777)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Emit diaginertia instead of fullinertia for diagonal body inertia (newton-physics#1780)

* Change default joint armature from 0.01 to 0 (newton-physics#1782)

* Fix default kp/kv for position and velocity actuators (newton-physics#1786)

* Lock body inertia after explicit MJCF <inertial> element (newton-physics#1784)

* Fix for MJCF actuator custom attributes (newton-physics#1783)

* Bump version to 0.2.3

Prepare the package metadata for the v0.2.3 release tag.

* Fix ViewerRerun rendering of instances from hidden meshes (newton-physics#1788)

* API cleanup (newton-physics#1789)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* BODY actuator target name bypasses body name de-duplication in SolverMuJoCo (newton-physics#1729)

* Use default density for visual geoms in MJCF import (newton-physics#1781)

* Fix GL viewer crash on Wayland (newton-physics#1793)

* Make USD xform parameter control absolute articulation placement (newton-physics#1771)

* Fix CUDA context corruption in SDF implementation (newton-physics#1792)

* Bump mujoco-warp dependency to 3.5.0.2 (newton-physics#1779)

* Fix MuJoCo margin/gap conversion (newton-physics#1785)

* Bump version to 1.1.0.dev0 (newton-physics#1798)

* Missing unittest.main added back to test_import_mjcf.py.  Helps with F5 debugging in VS Code. (newton-physics#1796)

* Improve H1 example (newton-physics#1801)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Fix ViewerViser.set_camera() (newton-physics#1805)

* Rename examples to follow prefix-first naming convention (newton-physics#1802)

* Improve MuJoCo actuator domain randomization (newton-physics#1773)

* Restore in_cup test in hydro example (newton-physics#1775)

* Fix `newton.geometry` imports and change of Mesh maxhullverts global constant

* Adapt to having both margin and gap arrays for each geom/shape

* Fix for newton.geometry API changes in primitive/narrowphase.py

* Fix removal of `BroadPhaseMode` IntEnum and revert to newton-sytle string literals

* WIP: Adapt geometry/unified.py to fix breaking changes to `newton.geometry` API

* First pass of API adjustments

* Patch more gaps (with respect to margin and gap renaming)

* GeoType.SDF was removed - reflect that in Kamino

* Introduce CoM position offsets w.r.t body frame and operations to convert between body CoM state and generic local body-fixed reference frames.

* Add caching of per-entity labels/names/keys in the Model subcontainers

* Remove SDF shape wrapper since it's now internal to mesh handling in CD pipelines

* Fix USD test assets

* Add Newton <--> Kamino joint type conversion operations and per-space default limit constants

* Add some cleanup to geometry and unified CD + UTs

* Add Newton <--> Kamino shape type conversion operations

* Apply new default joint coord limit constants to limits.py

* Adapt foubrar model builder and USD asset to produce the same result in sim example

* Purge "physical" goems and collapse all into a single group, and purge geometry "layers"

* Disable allocation per-joint wrenches by default and make them optional

* Make `Model` a dataclass

* Separate ModelData* containers into own `core/data.py` module

* Fix imports of ModelData

* Rename `Model` as `ModelKamino`

* Rename `ModelData` as `DataKamino`

* Rename `State` as `StateKamino`

* Rename `Control` as `ControlKamino`

* Rename `Limits` as `LimitsKamino`

* Rename `Contacts` as `ContactsKamino`

* Rename `ModelBuilder` as `ModelBuilderKamino`

* Make imports in test utilities relative

* Revise CD meta-data attributes and their computation in GeometryModel and ModelBuilderKamino

* Revise primitive CD pipeline

* Revise unified CD pipeline

* Revise CD front-end interfaces

* Fix UTs and relevant utils for interface changes to CD

* Change to `wp.DeviceLike` to account for upcoming deprecation of `Devicelike`

* Depracate legacy HDF5 data io (will be replaced in the future)

* Fix banned imports at module level

* Modify USD importer to detect articulations and order geoms and joints similarly to how the Newton `parse_usd` function does.

* Add conversion operation from `newton.Model` to `ModelKamino`

* Add data, state and control container conversions

* Add SolverKamino wrapper that fullfils newton integration interface

* Add newton integration examples

* Add SolverKamino to newton solver module imports

* WIP: fix problem with lambda_j being allocated for only kinematic constraints and failing on array copying

* Fix banned git import in benchmark

* Rename *Settings to *Config (#213)

* Rename SolverKaminoSettings -> SolverKaminoConfig

* Rename DualProblemSettings -> DualProblemConfig

* Rename CollisionDetectorSettings -> CollisionDetectorConfig

* Rename PADMMSettings -> PADMMConfig

* Rename ForwardKinematicsSolverSettings -> ForwardKinematicsSolverConfig

* Rename SimulatorSettings -> SimulatorConfig

* Add check for model compatibility in SolverKamino (#209)

* Fix device assignment in sparse CG test on CPU (#216)

* Replace Enum-type config attributes with Literal (#215)

* Replace warmstart mode config param with literal

* Replace contact warmstart mode config param with literal

* Replace rotation correction config param with literal

* Replace penalty update config param with literal

* Replace FK preconditioner option config param with literal

* Add post-init checks for dual/PADMM configs

* Rename FKPreconditionerOptions to FKPreconditionerType

* Remove WorldDescriptor from ModelKamino (#219)

* Add geom index offset array to model info

* Replace access to world description in model

* Remove world descriptor from model

* Fix computation of kinematics residual with sparse Jacobian (#220)

* Migrates `ModelKaminoSize` to it's own module to avoid circular dependency between core/model.py and core/state.py and rename it as `SizeKamino`.

* WIP: Fix SolverKamino wrapper

* Fix circular dependency in conversions.py

* Fix some broken unit tests and WIP to fix fourbar contact conversions and rendering

* Make some conversions @staticmethods instead, because they dont need common class attributes

* Fix declaration of custom state attributes and their conversion to/from newton and kamino

* WIP: Debug model conversion and newton sim examples

* Rename and cleanup start index array of per-world geoms

* Model conversion and newton sim examples now work.

* Make gravity conversion operation re-usable

* Migrates boxes_fourbar builder using newton.ModelBuilder to it's own module to prepare for migration.

* Use gravity conversion utility func in SolverKamino

* Add reusable joint-parameterization conversion utility

* Remove world-descriptor from model converter

* Rename helper converter that handles entity-local transforms

* Add some cleanup to DR Legs, ANYmal D and basic four-bar examples

* Fix module-level imports of additional kamino-specific development dependencies

* Fix module-level imports of additional kamino-specific development dependencies

* Fix erroneous merge conflict.

---------

Signed-off-by: Alain Denzler <adenzler@nvidia.com>
Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Signed-off-by: JC <jumyungc@nvidia.com>
Signed-off-by: Milad Rakhsha <mrakhsha@nvidia.com>
Signed-off-by: Milad-Rakhsha-NV <167464435+Milad-Rakhsha-NV@users.noreply.github.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Miles Macklin <mmacklin@nvidia.com>
Signed-off-by: adenzler-nvidia <adenzler@nvidia.com>
Signed-off-by: jvonmuralt <jvonmuralt@nvidia.com>
Co-authored-by: Daniela Hase <116915287+daniela-hase@users.noreply.github.com>
Co-authored-by: adenzler-nvidia <adenzler@nvidia.com>
Co-authored-by: Viktor Reutskyy <33062116+vreutskyy@users.noreply.github.com>
Co-authored-by: Eric Shi <97630937+shi-eric@users.noreply.github.com>
Co-authored-by: Anka Chen <AnkaChan@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: JC-nvidia <116605903+jumyungc@users.noreply.github.com>
Co-authored-by: Kenny Vilella <kvilella@nvidia.com>
Co-authored-by: nvtw <110816143+nvtw@users.noreply.github.com>
Co-authored-by: Milad-Rakhsha-NV <167464435+Milad-Rakhsha-NV@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Lennart Röstel <65088822+lenroe@users.noreply.github.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>
Co-authored-by: jvonmuralt <jvonmuralt@nvidia.com>
Co-authored-by: camevor <camevor@nvidia.com>
Co-authored-by: mzamoramora-nvidia <mzamoramora@nvidia.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Alessandro Roncone <alecive87@gmail.com>
Co-authored-by: gdaviet <57617656+gdaviet@users.noreply.github.com>
Co-authored-by: Miles Macklin <mmacklin@nvidia.com>
Co-authored-by: Gordon Yeoman <gyeomannvidia@users.noreply.github.com>
Co-authored-by: Lukasz Wawrzyniak <lwawrzyniak@nvidia.com>
Co-authored-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Co-authored-by: Lorenzo Terenzi <lorenzoterenzi96@gmail.com>
Co-authored-by: smollerNV <164020096+smollerNV@users.noreply.github.com>
Co-authored-by: twidmer <twidmer@nvidia.com>
Co-authored-by: Christian Schumacher <christian.schumacher@disney.com>
Co-authored-by: Guirec-Maloisel <25688871+Guirec-Maloisel@users.noreply.github.com>
vastsoun added a commit to vastsoun/newton that referenced this pull request Mar 4, 2026
* [Warp Raytrace] Added device parameter (newton-physics#1544)

* [Warp Raytrace] Added device parameter to previously overlooked call (newton-physics#1545)

* SolverMuJoCo: Fix tolerance clamping in update_solver_options_kernel (newton-physics#1546)

* Change default shape_ke to align with MuJoCo, parse geom solref from MJCF for contact stiffness/damping (newton-physics#1491)

Signed-off-by: Alain Denzler <adenzler@nvidia.com>

* Fix log_shapes broadcasting for length-1 warp arrays (newton-physics#1550)

* Fix XPBD restitution particle index (newton-physics#1557)

* Out-of-Bound memory read in example_diffsim_bear newton-physics#1386 (newton-physics#1533)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Add versioned documentation deployment to GitHub Pages (newton-physics#1560)

* Fix broken documentation links after versioned docs deployment (newton-physics#1566)

* VBD New Features (newton-physics#1479)

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* Add banners to membership verification workflow steps (newton-physics#1569)

* Support cable junctions (newton-physics#1519)

Signed-off-by: JC <jumyungc@nvidia.com>

* Rename parameter I to inertia newton-physics#1543 (newton-physics#1551)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Fix example_robot_anymal_c_walk.py (newton-physics#1574)

* Change everywhere linesearch to iterative (newton-physics#1573)

* Remove standard collision pipeline (newton-physics#1538)

* USD Plumbing MJC solver attributes through resolver and custom attribute framework (newton-physics#1463)

Signed-off-by: Milad Rakhsha <mrakhsha@nvidia.com>
Signed-off-by: Milad-Rakhsha-NV <167464435+Milad-Rakhsha-NV@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: adenzler-nvidia <adenzler@nvidia.com>

* Fix child shape filtering (newton-physics#1559)

* Fix ViewerRerun ignoring hidden parameter in log_mesh and log_instances (newton-physics#1555)

* Make NxN and SAP broad phase respect filtered pairs (newton-physics#1554)

* Add --quiet flag to examples to suppress Warp messages (newton-physics#1585)

* Defer resolution of MESH_MAXHULLVERT default in importers (newton-physics#1587)

* Fix TypeError when finalizing SDF geometry with device kwarg (newton-physics#1586)

* Make MESH_MAXHULLVERT a static class attribute Mesh.MAX_HULL_VERTICES. (newton-physics#1598)

* Significant non-determinism in unified collision pipeline for anymal_c_walking example newton-physics#1505 (newton-physics#1588)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Add test for non-contiguous case (newton-physics#1549)

* Fix nightly Warp CI to resolve pre-release builds (newton-physics#1606)

* Verify default class and value handling (newton-physics#1556)

* SolverMuJoCo: Expand geom_margin to avoid OOB read with heterogeneous worlds (newton-physics#1607)

* Fix bug in control clear method (newton-physics#1602)

* Enable Use of Newton IK in Lab newton-physics#662 (newton-physics#1539)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Fix import  of non-articulated joints (newton-physics#1535)

* Deduplicate _process_joint_custom_attributes frequency handling (newton-physics#1584)

* Add CI check for stale API docs and fix local build warnings (newton-physics#1570)

* Update Pillow 12.0.0 to 12.1.1 (newton-physics#1612)

* Prepare handling of mimic constraints in Newton (newton-physics#1523)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Support floating,  base_joint and parent_body arguments for importers (newton-physics#1498)

* Fix contact buffer memory overestimation (newton-physics#1614)

* Configure banned-module-level-imports for ruff (newton-physics#1583)

* Explicit `Contacts` instantiation with `Model.contacts()` and `CollisionPipeline.contacts()` (newton-physics#1445)

* Fix the quadruped benchmark regression (newton-physics#1615)

* Change default ignore_inertial_definitions from True to False (newton-physics#1537)

* Finalize the Recording API (newton-physics#1600)

* SolverMuJoCo: Fix ccd_iterations default (newton-physics#1631)

* update gitignore to ignore Claude Code sandbox files (newton-physics#1628)

* Add mimic joint support to SolverMuJoCo (newton-physics#1627)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Add --no-cache-clear flag to test runner (newton-physics#1629)

* Update MuJoCo and MuJoCo Warp to 3.5.0 release (newton-physics#1633)

* Improve inertia parsing from USD (newton-physics#1605)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* Remove standalone .typos.toml in favor of pyproject.toml config (newton-physics#1642)

* Heightfield support newton-physics#1189 (newton-physics#1547)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Example_robot_policy: Replace ValueError with clean error for missing PhysX policy (newton-physics#1636)

Co-authored-by: Viktor Reutskyy <33062116+vreutskyy@users.noreply.github.com>

* Avoid unnecessary inflation of the contact reduction voxel aabb (newton-physics#1650)

* Rename num_worlds to world_count (newton-physics#1634)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Support parsing autolimits from MJCF (newton-physics#1651)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Fix particle-shape restitution ignoring body velocity (newton-physics#1273) (newton-physics#1580)

* Add overflow warnings for narrow-phase collision buffers (newton-physics#1643)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Documentation: add units to model/state docstrings (newton-physics#1649)

* fix(viewer): add missing JointType.BALL support to contact line kernel (newton-physics#1640)

* Make terrain mesh visual-only in anymal C walking example (newton-physics#1660)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Fix initialization of collider state in MPM finite difference mode (newton-physics#1652)

* docs: document ModelBuilder.default_shape_cfg (newton-physics#1662)

* Finalize the collision API (newton-physics#1581)

* Remove hardcoded subnet ID from AWS workflow (newton-physics#1664)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Attempt to fix AWS config (newton-physics#1666)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Update AWS workflows to g7e.2xlarge with multi-AZ failover (newton-physics#1669)

* fix(viewer-usd): disambiguate log_points colors for N=3 warp arrays (newton-physics#1661)

* Viewer gl optimizations (newton-physics#1656)

Signed-off-by: Miles Macklin <mmacklin@nvidia.com>
Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>

* docs: add articulation workflow guidance and regression check (newton-physics#1663)

* fix(examples): propagate IK solution to model state in Franka example (newton-physics#1637)

* fix(deps,docs): bump nbconvert to 7.17.0 and fix ArticulationView doctest (newton-physics#1670)

* Cleanup and improve some example (newton-physics#1625)

Signed-off-by: adenzler-nvidia <adenzler@nvidia.com>
Co-authored-by: adenzler-nvidia <adenzler@nvidia.com>

* Handle zero-mass bodies and flip ensure_nonstatic_links default (newton-physics#1635)

* Additional testing for ArticulationView (newton-physics#1527)

Co-authored-by: Eric Heiden <eheiden@nvidia.com>

* Update warp-lang nightly to 1.12.0.dev20260217 (newton-physics#1677)

* Change default friction coefficients to match MuJoCo (newton-physics#1681)

* Refactor mesh creation functions (newton-physics#1654)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Parse joint frictionloss from MJCF (newton-physics#1680)

* Fix free joint body_pos and add ref/qpos0 support for MuJoCo solver (newton-physics#1645)

* Fix root shapes in ArticulationView with fixed base (newton-physics#1639)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Use model collision methods and remove `create_collision_pipeline` from examples (newton-physics#1648)

Co-authored-by: nvtw <110816143+nvtw@users.noreply.github.com>

* Fix XPBD apply_joint_forces ignoring child joint transform (newton-physics#1582)

* Adjust SDF API (newton-physics#1644)

Co-authored-by: Eric Heiden <eheiden@nvidia.com>

* Optimize test suite runtime (~18% faster) (newton-physics#1689)

* Remove ensure_nonstatic_links option from importers (newton-physics#1682)

Signed-off-by: adenzler-nvidia <adenzler@nvidia.com>

* SolverMuJoCo: Add geom_margin support, align thickness default with MuJoCo and schemas (newton-physics#1653)

* refactor: privatize non-public solver internals (newton-physics#1683)

* Fix option parsing with multiple <option> elements from includes (newton-physics#1692)

* Bump warp-lang nightly and newton-usd-schemas (newton-physics#1693)

* Get rid of tkinter dependency (newton-physics#1676)

* Fix SDF example contact buffer overflow (newton-physics#1695)

* Fix implicit biastype for position/velocity actuator shortcuts (newton-physics#1678)

* Fix include processor to respect meshdir/texturedir (newton-physics#1685)

* Reduce cold-cache Warp compile time for geometry modules (newton-physics#1618)

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: adenzler-nvidia <adenzler@nvidia.com>

* Fix xyzw-to-wxyz quaternion conversion in body inertia kernel (newton-physics#1694)

* Rename key to label and add hierarchical labels (newton-physics#1592) (newton-physics#1632)

* Expose geometry SDF helpers on public API (newton-physics#1684)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Improve custom frequency handling from USD, parse MuJoCo actuators and tendons (newton-physics#1510)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Collapse fixed joints with non articulated bodies (newton-physics#1608)

* Fix renaming joint_key -> joint_label (newton-physics#1700)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>

* Bump .python-version from 3.11 to 3.12 (newton-physics#1702)

* Replace CITATION.md with CITATION.cff (newton-physics#1706)

* Respect MJCF contype=conaffinity=0 via collision_group=0 (newton-physics#1703)

* Make ViewerUSD reuse existing USD layers for the same output path (newton-physics#1704)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Remove dead up-axis conversion from MuJoCo solver (newton-physics#1707)

* Skip IK cube stacking example test (newton-physics#1713)

* Fix global pairs (world=-1) not exported to MuJoCo spec (newton-physics#1705)

* Reduce the memory consumption of hydroelastic contacts (newton-physics#1609)

* Fix flakiness cube stacking (newton-physics#1714)

* Fix collision shapes not toggleable in viewer UI (newton-physics#1715)

* Fix softbody examples table layout in README (newton-physics#1716)

* Standardize sensor APIs: label matching, keyword args, and update() method naming (newton-physics#1665)

* Fix intermittent crash in parallel test runner from Manager proxy race (newton-physics#1721)

* Clean up inertia.py function arguments to match Mesh.create_* API (newton-physics#1719)

* Reduce default test runner verbosity (newton-physics#1723)

* Add menagerie comparison tests for SolverMuJoCo (newton-physics#1720)

Signed-off-by: Alain Denzler <adenzler@nvidia.com>
Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Co-authored-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Co-authored-by: Viktor Reutskyy <33062116+vreutskyy@users.noreply.github.com>

* Add spatial tendon support for MuJoCo solver (newton-physics#1687)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>

* Expose qfrc_actuator from mujoco (newton-physics#1698)

* Skip non-MODEL custom attributes in finalize validation (newton-physics#1734)

* Resolve inheritrange for position actuators in MJCF parser (newton-physics#1727)

* Support dampratio for position/velocity actuator shortcuts (newton-physics#1722)

* Limit concurrency to 1 (newton-physics#1736)

* Add a helper method for checking applied usd (newton-physics#1731)

* Enhance playback URL handling in ViewerViser (newton-physics#1742)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Removed RenderShapeType (newton-physics#1748)

* Override only MassAPI attributes that have been authored (newton-physics#1688)

* Integration of newton-actuators  (newton-physics#1342)

Signed-off-by: jvonmuralt <jvonmuralt@nvidia.com>

* Fix ArticulationView crash with fixed-joint-only articulations (newton-physics#1726)

* Improve retrieval of Jupyter base URL in ViewerViser (newton-physics#1750)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Disable dynamics testing for UR5e and Apollo tests to avoid CI flakiness (newton-physics#1755)

* Margin and Gap rename (newton-physics#1732)

* Vbd Demos Fixing (newton-physics#1740)

* Fix ViewerViser.log_lines method (newton-physics#1764)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Update warp-lang dependency to 1.12.0rc1 (newton-physics#1763)

* Fix fromto capsule/cylinder orientation in MJCF parser (newton-physics#1741)

* fix: multi-world particle BVH indexing (newton-physics#1641)

Co-authored-by: Eric Heiden <eheiden@nvidia.com>

* Clean up unused and internal-only kwargs in SolverMuJoCo (newton-physics#1766)

* Parsing of the mimic joint and contact gap/margin from newton schemas (newton-physics#1690)

Signed-off-by: Milad Rakhsha <mrakhsha@nvidia.com>

* API Refactor v2 (newton-physics#1749)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Support explicit geom mass attributes in MJCF (newton-physics#1744)

* Bump flask and werkzeug in lockfile for security (newton-physics#1769)

Co-authored-by: Cursor <cursoragent@cursor.com>

* Split MJCF worldbody root bodies into separate articulations (newton-physics#1754)

* Expose VBD rigid contact forces for solver coupling (newton-physics#1745)

Signed-off-by: JC <jumyungc@nvidia.com>

* Add MJCF ellipsoid geom import and regression test (newton-physics#1772)

Co-authored-by: Cursor <cursoragent@cursor.com>

* Weld equality constraints parsed from mjcf are given Nan as the default value of torquescale. The correct default should be 1.0 (newton-physics#1760)

* Improve picking accuracy and stability (newton-physics#1712)

* Franka cloth demo improvement (newton-physics#1765)

* Support computing sensing object transforms & API cleanup (newton-physics#1759)

* Remove threading workaround (newton-physics#1751)

* [Warp Raytrace] Consolidated ray intersect functions, renamed Options to Config (newton-physics#1767)

* Improve README example gallery for PyPI compatibility (newton-physics#1776)

* Fix issue with mesh in rerun viewer (newton-physics#1768)

* Add PhysxMimicJointAPI parsing to USD importer (newton-physics#1735)

* Move some math functions to Warp (newton-physics#1717)

Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Add test to ensure MJCF xform argument is relative (newton-physics#1777)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Emit diaginertia instead of fullinertia for diagonal body inertia (newton-physics#1780)

* Change default joint armature from 0.01 to 0 (newton-physics#1782)

* Fix default kp/kv for position and velocity actuators (newton-physics#1786)

* Lock body inertia after explicit MJCF <inertial> element (newton-physics#1784)

* Fix for MJCF actuator custom attributes (newton-physics#1783)

* Bump version to 0.2.3

Prepare the package metadata for the v0.2.3 release tag.

* Fix ViewerRerun rendering of instances from hidden meshes (newton-physics#1788)

* API cleanup (newton-physics#1789)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* BODY actuator target name bypasses body name de-duplication in SolverMuJoCo (newton-physics#1729)

* Use default density for visual geoms in MJCF import (newton-physics#1781)

* Fix GL viewer crash on Wayland (newton-physics#1793)

* Make USD xform parameter control absolute articulation placement (newton-physics#1771)

* Fix CUDA context corruption in SDF implementation (newton-physics#1792)

* Bump mujoco-warp dependency to 3.5.0.2 (newton-physics#1779)

* Fix MuJoCo margin/gap conversion (newton-physics#1785)

* Bump version to 1.1.0.dev0 (newton-physics#1798)

* Missing unittest.main added back to test_import_mjcf.py.  Helps with F5 debugging in VS Code. (newton-physics#1796)

* Improve H1 example (newton-physics#1801)

Signed-off-by: Eric Heiden <eric-heiden@outlook.com>

* Fix ViewerViser.set_camera() (newton-physics#1805)

* Rename examples to follow prefix-first naming convention (newton-physics#1802)

* Improve MuJoCo actuator domain randomization (newton-physics#1773)

* Restore in_cup test in hydro example (newton-physics#1775)

* Fix `newton.geometry` imports and change of Mesh maxhullverts global constant

* Adapt to having both margin and gap arrays for each geom/shape

* Fix for newton.geometry API changes in primitive/narrowphase.py

* Fix removal of `BroadPhaseMode` IntEnum and revert to newton-sytle string literals

* WIP: Adapt geometry/unified.py to fix breaking changes to `newton.geometry` API

* First pass of API adjustments

* Patch more gaps (with respect to margin and gap renaming)

* GeoType.SDF was removed - reflect that in Kamino

* Introduce CoM position offsets w.r.t body frame and operations to convert between body CoM state and generic local body-fixed reference frames.

* Add caching of per-entity labels/names/keys in the Model subcontainers

* Remove SDF shape wrapper since it's now internal to mesh handling in CD pipelines

* Fix USD test assets

* Add Newton <--> Kamino joint type conversion operations and per-space default limit constants

* Add some cleanup to geometry and unified CD + UTs

* Add Newton <--> Kamino shape type conversion operations

* Apply new default joint coord limit constants to limits.py

* Adapt foubrar model builder and USD asset to produce the same result in sim example

* Purge "physical" goems and collapse all into a single group, and purge geometry "layers"

* Disable allocation per-joint wrenches by default and make them optional

* Make `Model` a dataclass

* Separate ModelData* containers into own `core/data.py` module

* Fix imports of ModelData

* Rename `Model` as `ModelKamino`

* Rename `ModelData` as `DataKamino`

* Rename `State` as `StateKamino`

* Rename `Control` as `ControlKamino`

* Rename `Limits` as `LimitsKamino`

* Rename `Contacts` as `ContactsKamino`

* Rename `ModelBuilder` as `ModelBuilderKamino`

* Make imports in test utilities relative

* Revise CD meta-data attributes and their computation in GeometryModel and ModelBuilderKamino

* Revise primitive CD pipeline

* Revise unified CD pipeline

* Revise CD front-end interfaces

* Fix UTs and relevant utils for interface changes to CD

* Change to `wp.DeviceLike` to account for upcoming deprecation of `Devicelike`

* Depracate legacy HDF5 data io (will be replaced in the future)

* Fix banned imports at module level

* Modify USD importer to detect articulations and order geoms and joints similarly to how the Newton `parse_usd` function does.

* Add conversion operation from `newton.Model` to `ModelKamino`

* Add data, state and control container conversions

* Add SolverKamino wrapper that fullfils newton integration interface

* Add newton integration examples

* Add SolverKamino to newton solver module imports

* WIP: fix problem with lambda_j being allocated for only kinematic constraints and failing on array copying

* Fix banned git import in benchmark

* Rename *Settings to *Config (#213)

* Rename SolverKaminoSettings -> SolverKaminoConfig

* Rename DualProblemSettings -> DualProblemConfig

* Rename CollisionDetectorSettings -> CollisionDetectorConfig

* Rename PADMMSettings -> PADMMConfig

* Rename ForwardKinematicsSolverSettings -> ForwardKinematicsSolverConfig

* Rename SimulatorSettings -> SimulatorConfig

* Add check for model compatibility in SolverKamino (#209)

* Fix device assignment in sparse CG test on CPU (#216)

* Replace Enum-type config attributes with Literal (#215)

* Replace warmstart mode config param with literal

* Replace contact warmstart mode config param with literal

* Replace rotation correction config param with literal

* Replace penalty update config param with literal

* Replace FK preconditioner option config param with literal

* Add post-init checks for dual/PADMM configs

* Rename FKPreconditionerOptions to FKPreconditionerType

* Remove WorldDescriptor from ModelKamino (#219)

* Add geom index offset array to model info

* Replace access to world description in model

* Remove world descriptor from model

* Fix computation of kinematics residual with sparse Jacobian (#220)

* Migrates `ModelKaminoSize` to it's own module to avoid circular dependency between core/model.py and core/state.py and rename it as `SizeKamino`.

* WIP: Fix SolverKamino wrapper

* Fix circular dependency in conversions.py

* Fix some broken unit tests and WIP to fix fourbar contact conversions and rendering

* Make some conversions @staticmethods instead, because they dont need common class attributes

* Fix declaration of custom state attributes and their conversion to/from newton and kamino

* WIP: Debug model conversion and newton sim examples

* Rename and cleanup start index array of per-world geoms

* Model conversion and newton sim examples now work.

* Make gravity conversion operation re-usable

* Migrates boxes_fourbar builder using newton.ModelBuilder to it's own module to prepare for migration.

* Use gravity conversion utility func in SolverKamino

* Add reusable joint-parameterization conversion utility

* Remove world-descriptor from model converter

* Rename helper converter that handles entity-local transforms

* Add some cleanup to DR Legs, ANYmal D and basic four-bar examples

* Fix module-level imports of additional kamino-specific development dependencies

* Fix module-level imports of additional kamino-specific development dependencies

* Fix erroneous merge conflict.

---------

Signed-off-by: Alain Denzler <adenzler@nvidia.com>
Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Signed-off-by: JC <jumyungc@nvidia.com>
Signed-off-by: Milad Rakhsha <mrakhsha@nvidia.com>
Signed-off-by: Milad-Rakhsha-NV <167464435+Milad-Rakhsha-NV@users.noreply.github.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Miles Macklin <mmacklin@nvidia.com>
Signed-off-by: adenzler-nvidia <adenzler@nvidia.com>
Signed-off-by: jvonmuralt <jvonmuralt@nvidia.com>
Co-authored-by: Daniela Hase <116915287+daniela-hase@users.noreply.github.com>
Co-authored-by: adenzler-nvidia <adenzler@nvidia.com>
Co-authored-by: Viktor Reutskyy <33062116+vreutskyy@users.noreply.github.com>
Co-authored-by: Eric Shi <97630937+shi-eric@users.noreply.github.com>
Co-authored-by: Anka Chen <AnkaChan@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: JC-nvidia <116605903+jumyungc@users.noreply.github.com>
Co-authored-by: Kenny Vilella <kvilella@nvidia.com>
Co-authored-by: nvtw <110816143+nvtw@users.noreply.github.com>
Co-authored-by: Milad-Rakhsha-NV <167464435+Milad-Rakhsha-NV@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Lennart Röstel <65088822+lenroe@users.noreply.github.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>
Co-authored-by: jvonmuralt <jvonmuralt@nvidia.com>
Co-authored-by: camevor <camevor@nvidia.com>
Co-authored-by: mzamoramora-nvidia <mzamoramora@nvidia.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Alessandro Roncone <alecive87@gmail.com>
Co-authored-by: gdaviet <57617656+gdaviet@users.noreply.github.com>
Co-authored-by: Miles Macklin <mmacklin@nvidia.com>
Co-authored-by: Gordon Yeoman <gyeomannvidia@users.noreply.github.com>
Co-authored-by: Lukasz Wawrzyniak <lwawrzyniak@nvidia.com>
Co-authored-by: Eric Heiden <eric-heiden@outlook.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Co-authored-by: Lorenzo Terenzi <lorenzoterenzi96@gmail.com>
Co-authored-by: smollerNV <164020096+smollerNV@users.noreply.github.com>
Co-authored-by: twidmer <twidmer@nvidia.com>
Co-authored-by: Christian Schumacher <christian.schumacher@disney.com>
Co-authored-by: Guirec-Maloisel <25688871+Guirec-Maloisel@users.noreply.github.com>
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.

Rename "key" to "label"

3 participants