Skip to content

Fix randomize_rigid_body_material crash with Newton backend#5063

Open
ax-anoop wants to merge 2 commits intoisaac-sim:developfrom
ax-anoop:fix/newton-material-randomization
Open

Fix randomize_rigid_body_material crash with Newton backend#5063
ax-anoop wants to merge 2 commits intoisaac-sim:developfrom
ax-anoop:fix/newton-material-randomization

Conversation

@ax-anoop
Copy link
Copy Markdown

@ax-anoop ax-anoop commented Mar 19, 2026

Summary

randomize_rigid_body_material crashes with AttributeError: 'ArticulationView' object has no attribute 'link_paths' when using the Newton physics backend (presets=newton).

The event term's __init__ unconditionally uses PhysX-specific APIs to compute the number of collision shapes per body:

for link_path in self.asset.root_view.link_paths[0]:
    link_physx_view = self.asset._physics_sim_view.create_rigid_body_view(link_path)
    self.num_shapes_per_body.append(link_physx_view.max_shapes)

Newton's ArticulationView does not expose link_paths, max_shapes, get_material_properties(), or set_material_properties().

Note: The underlying MuJoCo-Warp engine does support runtime friction modification via model.geom_friction — this is a well-established MuJoCo capability used in production RL pipelines. The gap is in IsaacLab's Newton ArticulationView abstraction, which does not yet map these MuJoCo fields to the get/set_material_properties API that the event system expects.

Changes

  • Detect backend support by checking hasattr(self.asset.root_view, "max_shapes") before accessing material APIs
  • Skip gracefully with a logger.warning when the backend lacks support
  • When the backend provides asset.num_shapes_per_body directly (as Newton does), use it instead of the PhysX-specific link_paths workaround
  • Guard __call__ to return early if the backend doesn't support material randomization
  • PhysX behavior is completely unchanged

Reproduction

python scripts/train.py \
  --task Isaac-Velocity-Flat-Anymal-D-v0 \
  --num_envs 16 --max_iterations 1 \
  presets=newton

Crashes with:

AttributeError: 'ArticulationView' object has no attribute 'link_paths'. Did you mean: 'link_names'?

After this fix, Newton training runs successfully with the material randomization event skipped and a warning logged.

Longer-term

Full material randomization on Newton requires exposing MuJoCo-Warp's model.geom_friction (and related geom properties) through the Newton ArticulationView's get_material_properties() / set_material_properties() API. MuJoCo-Warp fully supports runtime per-environment friction modification — the gap is in the IsaacLab abstraction layer, not the physics engine.

Test plan

  • Verified Newton training completes with this fix (presets=newton)
  • Verified PhysX training still works unchanged (default preset)
  • Run existing unit tests for randomize_rigid_body_material

🤖 Generated with Claude Code

The `randomize_rigid_body_material` event term crashes when using the
Newton physics backend because it unconditionally accesses PhysX-specific
APIs (`root_view.link_paths`, `_physics_sim_view.create_rigid_body_view`,
`root_view.max_shapes`) that do not exist on Newton's `ArticulationView`.

Newton's underlying engine (MuJoCo-Warp) does not currently expose
runtime material property APIs (`get_material_properties`,
`set_material_properties`), so full material randomization is not yet
possible on the Newton backend.

This change:
- Detects backend support by checking for `root_view.max_shapes`
- Gracefully skips with a warning when the backend lacks support
- Also uses `asset.num_shapes_per_body` when available (Newton provides
  this property), avoiding the PhysX-specific `link_paths` workaround
- Preserves existing PhysX behavior unchanged
@github-actions github-actions bot added bug Something isn't working documentation Improvements or additions to documentation asset New asset feature or request isaac-sim Related to Isaac Sim team isaac-mimic Related to Isaac Mimic team infrastructure labels Mar 19, 2026
@AntoineRichard AntoineRichard changed the base branch from main to develop March 20, 2026 12:51
@github-actions github-actions bot added the isaac-lab Related to Isaac Lab team label Mar 20, 2026
@ooctipus
Copy link
Copy Markdown
Collaborator

#5098

can you check if this pr resolves your question?

Copy link
Copy Markdown

@isaaclab-review-bot isaaclab-review-bot bot left a comment

Choose a reason for hiding this comment

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

Code Review — PR #5063

Summary: Adds backend detection to randomize_rigid_body_material so it gracefully skips (with a warning) instead of crashing with an AttributeError on the Newton backend. The PhysX path is preserved unchanged.

Verdict: The core fix (detect backend → guard __init__ and __call__) is correct and addresses the crash. The early-return in __call__ is clean. Two concrete issues below, one of which introduces dead code.


Issue 1 — Dead-code branch: hasattr(self.asset, "num_shapes_per_body")

if hasattr(self.asset, "num_shapes_per_body"):
    # Backend (e.g. Newton) provides this directly
    self.num_shapes_per_body = self.asset.num_shapes_per_body

No asset class in IsaacLab (Articulation, RigidObject, or the Newton equivalents) defines a num_shapes_per_body property — confirmed via code search. This branch will never execute. Furthermore, this branch is inside the elif that already requires _supports_material_randomization == True (i.e., root_view.max_shapes exists), so if Newton lacks max_shapes, we never reach this code; and if Newton does have max_shapes, there's no evidence it would also have num_shapes_per_body on the asset.

Suggestion: Remove this branch entirely. If Newton later adds material support, it should implement the standard root_view API (link_paths, max_shapes, get/set_material_properties) so the existing PhysX code path works unchanged. Adding a speculative Newton-specific workaround makes the code harder to maintain.

Issue 2 — Fragile capability detection

Checking hasattr(self.asset.root_view, "max_shapes") is a proxy for "supports material randomization," but what actually matters is whether get_material_properties() and set_material_properties() are available. A backend could hypothetically expose max_shapes (it's a general shape-counting attribute) without implementing material APIs, or vice versa.

Consider checking the actual APIs:

self._supports_material_randomization = (
    hasattr(self.asset.root_view, "get_material_properties")
    and hasattr(self.asset.root_view, "set_material_properties")
)

This is more robust and self-documenting — it says exactly what capability is needed. It would also survive a future Newton update that adds max_shapes before adding material APIs.

Minor — material_buckets allocated unconditionally

When _supports_material_randomization is False, we still sample and store self.material_buckets. This is a trivial amount of memory (not a real problem) but skipping it with an early return after the warning would be slightly cleaner and make the "skip" semantics more obvious.


Overall this is a solid, minimal fix for the crash. Addressing the dead code and the detection mechanism would make it more maintainable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

asset New asset feature or request bug Something isn't working documentation Improvements or additions to documentation infrastructure isaac-lab Related to Isaac Lab team isaac-mimic Related to Isaac Mimic team isaac-sim Related to Isaac Sim team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants