Summary
Validating a robot with a coupled parallel gripper (one motor, two opposed racks, so the two finger joints are rigidly 1:1) surfaces three separate problems in physics_driven_joints. The first is a crash, the second makes the requirement unsatisfiable for linear joints, and the third asks for an asset configuration that PhysX does not currently honour.
All three are reproducible with small standalone scripts; none need the original robot.
Environment: simready-foundation @ main, simready-validate 2026.4.9, omniverse-asset-validator 1.18.0, Isaac Sim 6.1 (PhysX 110.1.13), Linux aarch64.
1. DJ.001 crashes on any joint carrying PhysxMimicJointAPI
nv_core/sr_specs/docs/capabilities/physics_bodies/physics_driven_joints/validation.py:
255 for drive, joint_state in zip(drives, joint_states):
256 stiffness = drive.GetStiffnessAttr().Get() # -> float
257 damping = drive.GetDampingAttr().Get() # -> float
258 if (stiffness and stiffness.Get() != 0.0) or (damping and damping.Get() != 0.0):
^^^^^^^^^^^^^^^ float has no .Get()
Lines 256–257 already resolve the attributes to floats; line 258 calls .Get() on the float. Reported as:
Uncaught error: 'float' object has no attribute 'Get'
FET022_DRIVEN_JOINTS_NEUTRAL: failing requirements: ['DJ.001']
The branch is only reachable when a joint has PhysxMimicJointAPI and non-zero drive gains, which is presumably why it has gone unnoticed — it needs a coupled mechanism (parallel gripper, differential, belt drive) to trigger.
The same expression appears twice, at line 258 (neutral) and line 535 (PhysX variant). Line 621 uses stiffness.Get() correctly, because there stiffness is the attribute.
Suggested fix:
if (stiffness and stiffness != 0.0) or (damping and damping != 0.0):
With that one-line change applied locally, our asset goes from [FAILED] to [PASSED] on Robot-Body-Neutral.
Minimal reproducer (builds a 2-joint stage from scratch)
from pxr import PhysxSchema, Usd, UsdGeom, UsdPhysics
stage = Usd.Stage.CreateNew("/tmp/mimic.usda")
root = UsdGeom.Xform.Define(stage, "/Robot")
stage.SetDefaultPrim(root.GetPrim())
UsdPhysics.ArticulationRootAPI.Apply(root.GetPrim())
base = UsdGeom.Cube.Define(stage, "/Robot/base")
UsdPhysics.RigidBodyAPI.Apply(base.GetPrim())
for name in ("left", "right"):
link = UsdGeom.Cube.Define(stage, f"/Robot/{name}")
UsdPhysics.RigidBodyAPI.Apply(link.GetPrim())
joint = UsdPhysics.PrismaticJoint.Define(stage, f"/Robot/joint_{name}")
joint.CreateBody0Rel().SetTargets([base.GetPath()])
joint.CreateBody1Rel().SetTargets([link.GetPath()])
joint.CreateAxisAttr().Set("Z")
drive = UsdPhysics.DriveAPI.Apply(joint.GetPrim(), "linear")
drive.CreateStiffnessAttr().Set(5000.0) # non-zero: reaches line 258
drive.CreateDampingAttr().Set(41.28)
drive.CreateMaxForceAttr().Set(1904.0)
PhysxSchema.JointStateAPI.Apply(joint.GetPrim(), "linear")
follower = stage.GetPrimAtPath("/Robot/joint_right")
mimic = PhysxSchema.PhysxMimicJointAPI.Apply(follower, "Z")
mimic.CreateReferenceJointRel().SetTargets([stage.GetPrimAtPath("/Robot/joint_left").GetPath()])
mimic.CreateGearingAttr().Set(-1.0)
stage.GetRootLayer().Save()
# now: simready-validate /tmp/mimic.usda --profile Robot-Body-Neutral --version 1.0.0
Result: mimic absent -> rule passes, mimic present -> AttributeError: 'float' object has no attribute 'Get'.
2. DJ.007 cannot be satisfied by a prismatic mimic joint
Lines 664–676 match the mimic axis against rotational tokens only:
match axis:
case "rotX": ...
case "rotY": ...
case "rotZ": ...
case _:
self._AddFailedCheck(
requirement=DrivenJointsCapReq.DJ_007,
message=f"Joint {prim.GetPath()} has unknown mimic axis: {axis}, aborting checks",
A linear coupled DOF — which is what a parallel gripper is — authors transX/transY/transZ (or the X/Y/Z short form). UsdPhysics.Tokens defines transX, transY, transZ, PhysxSchema.PhysxMimicJointAPI.Apply() accepts them, and PhysX's own Newton migration checker explicitly documents mimic support for PhysicsPrismaticJoint:
NewtonMimicAPI is single-apply per joint and supports single-DOF followers and leaders only (PhysicsRevoluteJoint / PhysicsPrismaticJoint).
So today no parallel-jaw gripper can pass FET022_DRIVEN_JOINTS_PHYSX/_ISAAC, regardless of how it is authored. Adding transX/transY/transZ (and the short X/Y/Z spelling) to the match would close it.
3. DJ.004 asks for zero gains, but PhysX does not enforce a prismatic mimic
DJ.004 fails a joint that has both a mimic API and non-zero drive gains:
Joint .../joint_right has both drive and mimic API
For a revolute follower that is the correct model — one motor, one drive, the constraint carries the other DOF. We applied it, then measured the result in Isaac Sim 6.1:
| follower drive |
finger deviation |
left/right asymmetry |
0 / 0 (DJ.004 compliant) |
51.50 mm |
51.50 mm |
5000 / 41.28 |
0.006 mm |
0.012 mm |
500 / 4.13 |
0.092 mm |
0.097 mm |
A follow-up A/B shows why: on a prismatic joint, PhysX does not enforce PhysxMimicJointAPI at all. Removing the API entirely produces numbers identical to four decimal places:
| case |
mimic |
slew deviation |
asymmetry |
leader → 40 mm |
follower |
| mimic + follower drive |
True |
0.0064 mm |
0.0123 mm |
40.000 |
20.000 |
| no mimic + follower drive |
False |
0.0064 mm |
0.0123 mm |
40.000 |
20.000 |
| mimic + zero gains |
True |
51.5009 mm |
51.4996 mm |
40.000 |
0.941 |
| no mimic + zero gains |
False |
51.5009 mm |
51.4996 mm |
40.000 |
0.941 |
The same probe on a revolute pair does show the constraint acting. So DJ.004 is right in general and wrong for linear DOFs on PhysX: complying makes the gripper physically worse than the bug it was authored to fix.
Newton (NewtonMimicAPI) and MuJoCo (<equality joint>) both honour the coupling, so an asset that must work across all three ends up keeping the constraint and the drive — which DJ.004 rejects.
Suggestion: scope DJ.004 to DOF types where the runtime actually enforces the constraint, or downgrade it to a warning when the follower is prismatic.
Why this came up
We are bringing Seeed-Projects/reBot-Isaacsim into SimReady conformance. The arm's gripper is a single RobStride motor driving two opposed racks through one pinion, so the two finger joints are rigidly coupled — modelling them as independent DOFs let the jaws drift 2.3 mm under arm motion and sag 7.4 mm under gravity.
With items 1–3 addressed, Robot-Body-Neutral passes. Happy to test any proposed fix against the asset and against the standalone reproducers.
Separately, and possibly worth its own issue: the validate venv installs usd-exchange, whose pxr build does not ship PhysxSchema. Every rule that touches PhysxSchema.JointStateAPI / PhysxMimicJointAPI then reports "PhysxSchema is not available in this environment" as a FAILURE rather than skipping or erroring loudly — on this asset that was 161 messages, and DJ.001/DJ.002/DJ.003 all reported as failing requirements when the asset satisfied two of them. Running the same validator against a pxr that does provide PhysxSchema cleared DJ.002 and DJ.003 immediately.
Summary
Validating a robot with a coupled parallel gripper (one motor, two opposed racks, so the two finger joints are rigidly 1:1) surfaces three separate problems in
physics_driven_joints. The first is a crash, the second makes the requirement unsatisfiable for linear joints, and the third asks for an asset configuration that PhysX does not currently honour.All three are reproducible with small standalone scripts; none need the original robot.
Environment:
simready-foundation@main,simready-validate2026.4.9,omniverse-asset-validator1.18.0, Isaac Sim 6.1 (PhysX 110.1.13), Linux aarch64.1. DJ.001 crashes on any joint carrying
PhysxMimicJointAPInv_core/sr_specs/docs/capabilities/physics_bodies/physics_driven_joints/validation.py:Lines 256–257 already resolve the attributes to floats; line 258 calls
.Get()on the float. Reported as:The branch is only reachable when a joint has
PhysxMimicJointAPIand non-zero drive gains, which is presumably why it has gone unnoticed — it needs a coupled mechanism (parallel gripper, differential, belt drive) to trigger.The same expression appears twice, at line 258 (neutral) and line 535 (PhysX variant). Line 621 uses
stiffness.Get()correctly, because therestiffnessis the attribute.Suggested fix:
With that one-line change applied locally, our asset goes from
[FAILED]to[PASSED]onRobot-Body-Neutral.Minimal reproducer (builds a 2-joint stage from scratch)
Result:
mimic absent -> rule passes,mimic present -> AttributeError: 'float' object has no attribute 'Get'.2. DJ.007 cannot be satisfied by a prismatic mimic joint
Lines 664–676 match the mimic axis against rotational tokens only:
A linear coupled DOF — which is what a parallel gripper is — authors
transX/transY/transZ(or theX/Y/Zshort form).UsdPhysics.TokensdefinestransX,transY,transZ,PhysxSchema.PhysxMimicJointAPI.Apply()accepts them, and PhysX's own Newton migration checker explicitly documents mimic support forPhysicsPrismaticJoint:So today no parallel-jaw gripper can pass
FET022_DRIVEN_JOINTS_PHYSX/_ISAAC, regardless of how it is authored. AddingtransX/transY/transZ(and the shortX/Y/Zspelling) to the match would close it.3. DJ.004 asks for zero gains, but PhysX does not enforce a prismatic mimic
DJ.004 fails a joint that has both a mimic API and non-zero drive gains:
For a revolute follower that is the correct model — one motor, one drive, the constraint carries the other DOF. We applied it, then measured the result in Isaac Sim 6.1:
0 / 0(DJ.004 compliant)5000 / 41.28500 / 4.13A follow-up A/B shows why: on a prismatic joint, PhysX does not enforce
PhysxMimicJointAPIat all. Removing the API entirely produces numbers identical to four decimal places:The same probe on a revolute pair does show the constraint acting. So DJ.004 is right in general and wrong for linear DOFs on PhysX: complying makes the gripper physically worse than the bug it was authored to fix.
Newton (
NewtonMimicAPI) and MuJoCo (<equality joint>) both honour the coupling, so an asset that must work across all three ends up keeping the constraint and the drive — which DJ.004 rejects.Suggestion: scope DJ.004 to DOF types where the runtime actually enforces the constraint, or downgrade it to a warning when the follower is prismatic.
Why this came up
We are bringing
Seeed-Projects/reBot-Isaacsiminto SimReady conformance. The arm's gripper is a single RobStride motor driving two opposed racks through one pinion, so the two finger joints are rigidly coupled — modelling them as independent DOFs let the jaws drift 2.3 mm under arm motion and sag 7.4 mm under gravity.With items 1–3 addressed,
Robot-Body-Neutralpasses. Happy to test any proposed fix against the asset and against the standalone reproducers.Separately, and possibly worth its own issue: the validate venv installs
usd-exchange, whosepxrbuild does not shipPhysxSchema. Every rule that touchesPhysxSchema.JointStateAPI/PhysxMimicJointAPIthen reports"PhysxSchema is not available in this environment"as a FAILURE rather than skipping or erroring loudly — on this asset that was 161 messages, and DJ.001/DJ.002/DJ.003 all reported as failing requirements when the asset satisfied two of them. Running the same validator against apxrthat does providePhysxSchemacleared DJ.002 and DJ.003 immediately.