You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
isaaclab_newton.sensors.JointWrenchSensor builds its ArticulationView with exclude_joint_types=[JointType.FREE, JointType.FIXED] (joint_wrench_sensor.py#L153); the docstring says both are excluded because "neither has a meaningful joint anchor". That holds for FREE, but I don't think it holds for FIXED, and the PhysX backend behaves differently, so the two backends disagree on which bodies the sensor reports.
What each backend does
PhysX: one entry per articulation link via get_link_incoming_joint_force(). Fixed joints inside the articulation are ordinary eFIX links and get a real wrench; _create_joint_frame_buffers() iterates every UsdPhysics.Joint prim, FixedJoint included. Only the root link is zero (PhysX docs: "The root link reports a zero spatial force").
Newton: one entry per joint that survives the filter, labelled by its child body. Anything welded on (tool flange, F/T-sensor mount, a foot fixed to a shin) is simply not in body_names, so find_bodies("tool") raises ValueError and a SceneEntityCfg("joint_wrench", body_names=[...]) that works on PhysX fails on Newton.
I checked this with a small fixed-base pendulum (base –revolute→ link –fixed→ tool): PhysX reports all three bodies with the tool entry equal to the tool's weight; Newton reports only link.
Why FIXED joints do have a meaningful anchor in Newton
The USD importer passes parent_xform / child_xform into ModelBuilder.add_joint_fixed() like for every other joint type, so joint_X_c is populated.
SolverMuJoCo turns an in-tree FIXED joint into a welded MuJoCo body; MuJoCo computes cfrc_int for every body, and convert_rigid_forces_from_mj_kernel writes it into body_parent_f for every mapped body. SolverFeatherstone fills body_parent_f per body from the RNEA backward pass.
Isaac Lab does not set collapse_fixed_joints, so these bodies survive import.
So body_parent_f[child_of_fixed_joint] is exactly what a 6-axis F/T sensor mounted at that joint would read, which is the usual way to model one (see #1725). The one case that arguably should stay excluded is the world→root fixed joint of a fixed-base robot, for parity with PhysX, but that is a joint_parent == -1 check rather than dropping the whole joint type.
Questions
Was excluding FIXED a deliberate choice?
Would you accept a PR that keeps in-tree FIXED joints (excluding only FREE and the world-attached root joint), with a test against the gravity load on a fixed-mounted body?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Summary
isaaclab_newton.sensors.JointWrenchSensorbuilds itsArticulationViewwithexclude_joint_types=[JointType.FREE, JointType.FIXED](joint_wrench_sensor.py#L153); the docstring says both are excluded because "neither has a meaningful joint anchor". That holds forFREE, but I don't think it holds forFIXED, and the PhysX backend behaves differently, so the two backends disagree on which bodies the sensor reports.What each backend does
get_link_incoming_joint_force(). Fixed joints inside the articulation are ordinaryeFIXlinks and get a real wrench;_create_joint_frame_buffers()iterates everyUsdPhysics.Jointprim,FixedJointincluded. Only the root link is zero (PhysX docs: "The root link reports a zero spatial force").body_names, sofind_bodies("tool")raisesValueErrorand aSceneEntityCfg("joint_wrench", body_names=[...])that works on PhysX fails on Newton.I checked this with a small fixed-base pendulum (
base–revolute→link–fixed→tool): PhysX reports all three bodies with the tool entry equal to the tool's weight; Newton reports onlylink.Why FIXED joints do have a meaningful anchor in Newton
parent_xform/child_xformintoModelBuilder.add_joint_fixed()like for every other joint type, sojoint_X_cis populated.SolverMuJoCoturns an in-tree FIXED joint into a welded MuJoCo body; MuJoCo computescfrc_intfor every body, andconvert_rigid_forces_from_mj_kernelwrites it intobody_parent_ffor every mapped body.SolverFeatherstonefillsbody_parent_fper body from the RNEA backward pass.collapse_fixed_joints, so these bodies survive import.So
body_parent_f[child_of_fixed_joint]is exactly what a 6-axis F/T sensor mounted at that joint would read, which is the usual way to model one (see #1725). The one case that arguably should stay excluded is the world→root fixed joint of a fixed-base robot, for parity with PhysX, but that is ajoint_parent == -1check rather than dropping the whole joint type.Questions
FIXEDa deliberate choice?FREEand the world-attached root joint), with a test against the gravity load on a fixed-mounted body?All reactions