Skip to content

USD: four defects in the Newton schemas v0.4.0 adoption (units, semantics, unread attribute) #3472

Description

@andrewkaufman

Summary

39e44588 ("Update USD support in MuJoCo to Newton USD schemas v0.4.0", unreleased — it sits above the Version 3.11.0 heading in doc/changelog.rst) introduces four defects in the new newton: read paths. Two are angle-unit conversions that are simply missing; the third maps a distance-valued attribute onto a force-valued field; the fourth silently ignores an attribute that controls whether a constraint is active at all.

I wrote the original adoption in #3156, so some of this is my mess to begin with — flagging it now while the change is still unreleased and cheap to correct.

Schema references below are newton-usd-schemas v0.4.0, the version src/experimental/usd/CMakeLists.txt now pins.


1. newton:mimicCoef0 is authored in degrees, read as radians

The schema declares angle-valued units:

newton:mimicCoef0"Offset added after scaling the leader joint's position/angle. […] Units: distance or degrees (matches the joint type for single-DOF joints)"

plugin/usd_decoder/usd_decoder.cc:2166-2172 assigns it straight into mjEQ_JOINT data[0], which is radians for hinge and ball joints:

if (newton_coef0 && newton_coef0.HasAuthoredValue()) {
  float val;
  newton_coef0.Get(&val);
  eq->data[0] = val;        // no degrees -> radians conversion
}

For an angular follower the offset is therefore wrong by a factor of 180/π ≈ 57.3.

Two details make this bite harder than the others:

  • The newton: attribute takes precedence over mjc:coef0 here, so authoring the deprecated attribute is not a workaround.
  • mujoco-usd-converter writes newton:mimicCoef0 with an explicit np.degrees() for hinge/ball followers and does not author mjc:coef0 at all, so there is no fallback path for assets it produces.

Newton hit the identical bug on its own importer and fixed it in newton-physics/newton#3728.

newton:mimicCoef1 is declared dimensionless and is correctly read as-is.

2. newton:damping is authored per-degree, read per-radian

newton:damping"Units: effort * seconds / degrees (angular DOFs) or effort * seconds / distance (linear DOFs)"

usd_decoder.cc:1832-1836:

} else if (newton_damping_authored) {
  float damping;
  newton_damping_attr.Get(&damping);
  mj_joint->damping[0] = damping;   // per-degree value into a per-radian field
}

mjsJoint::damping is per-radian for angular DOFs, so this needs a ×180/π on hinge and ball joints.

This one is currently masked: precedence in ParseMjcPhysicsJointAPI is the opposite of the mimic case — mjc:damping wins when both are authored — so producers that write both (as the converter does) still get correct behaviour today, with a deprecation warning. It becomes a silent 57.3× under-damping the moment mjc:damping is removed, which the changelog states is the plan.

newton:armature (mass · distance²) and newton:friction (effort) carry no per-angle term and are correctly read as-is.

3. newton:contactAdhesion is a distance, geom.adhesion is a force

These are different physical quantities:

definition units
newton:contactAdhesion "Contact adhesion distance. When two surfaces are within this distance, an attractive force pulls them together." distance
mjsGeom::adhesion (XMLreference) "Adhesive force of contacts with this geom, in units of force." force

usd_decoder.cc:1920-1929 assigns one to the other:

// Contact adhesion: newton:contactAdhesion -> geom->adhesion
if (val >= 0.0f) {
  geom->adhesion = val;
}

Newton's own implementation agrees with its schema — Model.shape_material_ka is documented as "Shape contact adhesion distance [m]". So a value authored as metres of interaction range is consumed as newtons of pull-off force, and no scalar conversion can reconcile the two.

Notably, MuJoCo already documents the correct target for the distance concept, in the adhesion entry itself:

"To let adhesion act across a small separation (attraction at a distance), set gap to the desired interaction range. This can be used to model magnets."

which suggests newton:contactAdhesiongeom.gap, and that MJCF's force-valued adhesion has no generic equivalent in the Newton schema at all.

4. newton:mimicEnabled is never read, and physics:jointEnabled is not a substitute

NewtonMimicAPI has four members. Three are read; newton:mimicEnabled does not appear in plugin/usd_decoder/newton_tokens.h at all, and is not referenced anywhere under plugin/ or src/.

eq->active is instead derived from a different attribute entirely (usd_decoder.cc:2094-2097):

void ParseJointEnabled(mjsEquality* eq, const pxr::UsdPhysicsJoint& joint) {
  bool jointEnabled = true;
  joint.GetJointEnabledAttr().Get(&jointEnabled);
  eq->active = jointEnabled ? 1 : 0;
}

These control different things:

  • physics:jointEnabled (UsdPhysics) — whether the joint is enabled.
  • newton:mimicEnabled — whether the mimic constraint is active. Per the schema: "When disabled, the follower joint moves independently, as though the mimic constraint was not applied."

So the natural authoring of "an ordinary, enabled joint whose mimic coupling is switched off" — physics:jointEnabled = true with newton:mimicEnabled = false — yields an active equality constraint in MuJoCo, silently coupling two joints the author explicitly decoupled. There is no diagnostic, since the attribute is never inspected.

This currently goes unnoticed for mujoco-usd-converter output only because that producer happens to author both attributes from the same source flag; any producer writing NewtonMimicAPI alone hits it.


Secondary: inconsistent mjc: vs newton: precedence

Where both spellings exist, the two code paths disagree about which wins:

  • ParseMjcPhysicsJointAPI (usd_decoder.cc:1812-1849) — deprecated mjc: wins, newton: is the fallback.
  • The mimic path (usd_decoder.cc:2166-2178) — newton: wins, deprecated mjc: is the fallback.

Whichever is intended, having both makes migration behaviour hard to reason about: for joint gains a producer must drop mjc: to get the new path, and for mimic coefficients it must drop newton: to avoid it.

Environment

Observed by reading gdm/main at 4929f2cd; 39e44588 is not in a tagged release. Cross-checked against mujoco-usd-converter 0.5.0 (pinned mujoco>=3.11.0,<3.12) and newton-usd-schemas v0.4.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions