Skip to content

Commit ee84505

Browse files
authored
Fix explicit MJCF default class scope (#3687)
1 parent 2fa55dd commit ee84505

3 files changed

Lines changed: 30 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@
139139
- Fix `SolverFeatherstone` BALL joints to apply passive `joint_damping` on all three angular DOFs.
140140
- Fix `eval_ik()` and `SolverSemiImplicit` rounding small float32 revolute-joint angles to zero. (#3434)
141141
- Fix excessive memory usage when importing MJCF or URDF models containing many visual-only shapes with self-collisions disabled.
142+
- Prevent explicit MJCF classes from retaining unrelated `childclass` defaults.
142143
- Fix `FastKitchenG1` ASV metrics to build the kitchen scene instead of a plain G1 model.
143144
- Fix the `diffsim_bear` example crashing with its default CUDA configuration and diverging after a few training iterations.
144145
- Fix masked PID state reset to execute on the integral-state device. (#3447)

newton/_src/utils/import_mjcf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,9 +513,9 @@ def is_ignored_class(name: str) -> bool:
513513
return any(re.match(pattern, name) for pattern in ignore_classes)
514514

515515
def resolve_class_defaults(element_class: str | None, ambient_defaults: dict) -> dict:
516-
"""Merge an element's default class (pre-resolved by resolve_defaults) over the ambient defaults."""
516+
"""Resolve an explicit default class or retain the ambient defaults."""
517517
if element_class is not None and element_class in class_defaults:
518-
return merge_attrib(ambient_defaults, class_defaults[element_class])
518+
return class_defaults[element_class]
519519
return ambient_defaults
520520

521521
def resolve_element_attrib(element, tag: str, ambient_defaults: dict | None = None) -> dict:

newton/tests/test_import_mjcf.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4816,6 +4816,33 @@ def test_default_inheritance(self):
48164816
else:
48174817
self.fail("Model should have mujoco.condim attribute")
48184818

4819+
def test_explicit_class_replaces_childclass(self):
4820+
"""Use an explicit class without retaining sibling childclass defaults."""
4821+
mjcf = """
4822+
<mujoco>
4823+
<default>
4824+
<default class="ambient">
4825+
<geom friction="0.7 0.1 0.01"/>
4826+
</default>
4827+
<default class="explicit">
4828+
<geom size="0.2"/>
4829+
</default>
4830+
</default>
4831+
<worldbody>
4832+
<body childclass="ambient">
4833+
<geom class="explicit"/>
4834+
</body>
4835+
</worldbody>
4836+
</mujoco>
4837+
"""
4838+
builder = newton.ModelBuilder()
4839+
builder.add_mjcf(mjcf)
4840+
4841+
self.assertAlmostEqual(builder.shape_scale[0][0], 0.2)
4842+
self.assertAlmostEqual(builder.shape_material_mu[0], 1.0)
4843+
self.assertAlmostEqual(builder.shape_material_mu_torsional[0], 0.005)
4844+
self.assertAlmostEqual(builder.shape_material_mu_rolling[0], 0.0001)
4845+
48194846

48204847
class TestImportMjcfActuatorsFrames(unittest.TestCase):
48214848
def test_actuatorfrcrange_parsing(self):

0 commit comments

Comments
 (0)