Skip to content

Commit 6486b76

Browse files
Documents JointDrivePropertiesCfg.ensure_drives_exist (#5723)
# Description Documents the `JointDrivePropertiesCfg.ensure_drives_exist` flag introduced in #5251. Adds a troubleshooting entry and a how-to section so users hitting *"my joints actuate in PhysX but do nothing in Newton with `ImplicitActuatorCfg`"* can find the fix without having to read the schemas source. ## Background Newton's USD importer only materialises a solver actuator for a joint when the authored `PhysicsDriveAPI` reports a non-zero stiffness or damping. Many existing assets ship with both at `0`, expecting an `ImplicitActuatorCfg` (or `IdealPDActuatorCfg`) to supply the gains at runtime. PhysX creates the actuator regardless and lets the runtime writes take effect; Newton drops the joint from the actuator set before the runtime writes can attach. `ensure_drives_exist=True` on the spawn config writes a minimal placeholder stiffness (`1e-3`) to any drive whose authored stiffness *and* damping are both zero, so Newton creates the actuator. The actual gains still come from the actuator model at runtime. ## Changes - `docs/source/refs/troubleshooting.rst` — new "Joints actuate in PhysX but not in a Newton-based backend" section, slotted with the other physics-stability entries. Includes symptom, cause, and a working code snippet. - `docs/source/how-to/import_new_asset.rst` — new "Ensuring joint drives exist on every joint" section with the labelled anchor `import-new-asset-ensure-drives-exist` so other pages can cross-reference the full explanation. Sits between the MJCF importer and Mesh importer sections since it applies to URDF- and MJCF-imported assets but not to mesh assets. - `docs/source/how-to/write_articulation_cfg.rst` — short cross-reference admonition next to the `ImplicitActuatorCfg` example, pointing readers to the anchor above. - `source/isaaclab/changelog.d/antoiner-docs-ensure-drives-exist.skip` — docs-only, no version bump. ## Type of change - Documentation update ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the `pre-commit` checks with `./isaaclab.sh --format` - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works (docs-only) - [x] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file (`.skip` fragment, docs-only) - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there
1 parent d2304a7 commit 6486b76

4 files changed

Lines changed: 116 additions & 0 deletions

File tree

docs/source/how-to/import_new_asset.rst

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,61 @@ Executing the above script will create the USD file inside the
343343
:alt: result of convert_mjcf.py
344344

345345

346+
.. _import-new-asset-ensure-drives-exist:
347+
348+
Ensuring joint drives exist on every joint
349+
------------------------------------------
350+
351+
A common pitfall when porting a freshly-imported asset across physics backends
352+
is that joints which actuate fine in PhysX silently do nothing in a
353+
Newton-based backend (MuJoCo Warp, XPBD, Featherstone, Semi-implicit).
354+
355+
The URDF and MJCF importers both write a ``PhysicsDriveAPI`` to every
356+
articulated joint, but the stiffness and damping on that drive are often left
357+
at ``0`` — the assumption being that the actuator gains are authored at runtime
358+
by an :class:`~isaaclab.actuators.ImplicitActuatorCfg` or
359+
:class:`~isaaclab.actuators.IdealPDActuatorCfg`. This is the recommended way to
360+
keep gains tunable per task without re-importing the USD.
361+
362+
PhysX creates a solver actuator for every joint regardless of the authored
363+
gains, so the runtime writes from ``ImplicitActuatorCfg.stiffness`` /
364+
``damping`` always take effect. Newton's USD importer, by contrast, only
365+
materialises a solver actuator when the authored drive reports a non-zero
366+
stiffness or damping — a joint whose authored gains are both zero is treated
367+
as passive and is dropped from the actuator set, so subsequent runtime writes
368+
have nothing to attach to.
369+
370+
The recommended fix is to opt the spawn config into the cross-backend bridge by
371+
setting :attr:`~isaaclab.sim.schemas.JointDrivePropertiesCfg.ensure_drives_exist`
372+
to ``True``:
373+
374+
.. code:: python
375+
376+
spawn=sim_utils.UsdFileCfg(
377+
usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/Agility/Cassie/cassie.usd",
378+
joint_drive_props=sim_utils.JointDrivePropertiesCfg(ensure_drives_exist=True),
379+
...
380+
)
381+
382+
When ``ensure_drives_exist=True``, every drive whose authored stiffness *and*
383+
damping are both zero is updated with a minimal placeholder stiffness
384+
(``1e-3``) before the simulation starts. This is enough for Newton's importer
385+
to create the actuator; the actual gains are then overwritten by the actuator
386+
model at runtime, so the placeholder has no effect on the simulated dynamics.
387+
Drives whose authored gains are non-zero are left untouched.
388+
389+
This is how ``isaaclab_assets.CASSIE_CFG`` keeps Cassie working across both
390+
PhysX and Newton — the asset ships with zero-gain drives because it relies on
391+
``ImplicitActuatorCfg`` for the legs, and the spawn config enables
392+
:attr:`~isaaclab.sim.schemas.JointDrivePropertiesCfg.ensure_drives_exist` so
393+
that both backends see the same actuator set.
394+
395+
You can leave the flag at its default ``False`` for assets that author non-zero
396+
drive gains in the USD itself, or for assets driven by an
397+
:class:`~isaaclab.actuators.IdealPDActuatorCfg` that explicitly zeroes the
398+
solver drive and applies torque externally.
399+
400+
346401
Using Mesh Importer
347402
-------------------
348403

docs/source/how-to/write_articulation_cfg.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,15 @@ to combine them into a single actuator model.
116116
),
117117
},
118118
119+
.. note::
120+
If your asset's USD authored drives ship with zero stiffness *and* zero damping
121+
— a common pattern for assets that expect ``ImplicitActuatorCfg`` to supply the
122+
gains at runtime — the joints will actuate under PhysX but appear unactuated
123+
under Newton-based backends (MuJoCo Warp, XPBD, Featherstone, Semi-implicit).
124+
Set :attr:`~isaaclab.sim.schemas.JointDrivePropertiesCfg.ensure_drives_exist`
125+
to ``True`` on the spawn config to keep both backends in sync. See
126+
:ref:`import-new-asset-ensure-drives-exist` for the full explanation.
127+
119128

120129
ActuatorCfg velocity/effort limits considerations
121130
-------------------------------------------------

docs/source/refs/troubleshooting.rst

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,57 @@ To enable OmniPVD capture in Isaac Lab, add the relevant kit arguments to the co
107107
./isaaclab.sh -p scripts/demos/bipeds.py --kit_args "--/persistent/physics/omniPvdOvdRecordingDirectory=/tmp/ --/physics/omniPvdOutputEnabled=true" --headless
108108
109109
110+
Joints actuate in PhysX but not in a Newton-based backend
111+
---------------------------------------------------------
112+
113+
If your robot's joints move under PhysX but appear unactuated under one of the
114+
Newton-based backends (MuJoCo Warp, XPBD, Featherstone, Semi-implicit) — even
115+
though you have authored an :class:`~isaaclab.actuators.ImplicitActuatorCfg`
116+
with non-zero ``stiffness`` and ``damping`` — the cause is almost always that
117+
the USD asset ships with zero authored drive gains.
118+
119+
Newton's USD importer only materialises a solver actuator when the authored
120+
``PhysicsDriveAPI`` reports a non-zero stiffness *or* damping. Many existing
121+
assets leave both at ``0`` on purpose, expecting the actuator gains to come from
122+
an :class:`~isaaclab.actuators.ImplicitActuatorCfg` at runtime. PhysX creates
123+
the actuator regardless and lets the runtime gain writes take effect, so the
124+
asset works there; Newton drops the actuator before the runtime writes can
125+
attach to it.
126+
127+
The fix is to set
128+
:attr:`~isaaclab.sim.schemas.JointDrivePropertiesCfg.ensure_drives_exist` to
129+
``True`` on the spawn config. This writes a minimal placeholder stiffness
130+
(``1e-3``) to any drive whose authored stiffness *and* damping are both zero,
131+
which is enough for Newton's importer to create the actuator. The actual gains
132+
are then overwritten by the actuator model at runtime, so the placeholder has
133+
no effect on the simulated dynamics.
134+
135+
.. code:: python
136+
137+
from isaaclab.actuators import ImplicitActuatorCfg
138+
from isaaclab.assets import ArticulationCfg
139+
import isaaclab.sim as sim_utils
140+
141+
ROBOT_CFG = ArticulationCfg(
142+
spawn=sim_utils.UsdFileCfg(
143+
usd_path="...",
144+
joint_drive_props=sim_utils.JointDrivePropertiesCfg(ensure_drives_exist=True),
145+
),
146+
actuators={
147+
"legs": ImplicitActuatorCfg(
148+
joint_names_expr=[".*HAA", ".*HFE", ".*KFE"],
149+
effort_limit_sim=120.0,
150+
velocity_limit_sim=7.5,
151+
stiffness={".*": 40.0},
152+
damping={".*": 5.0},
153+
),
154+
},
155+
)
156+
157+
See :ref:`import-new-asset-ensure-drives-exist` for the underlying USD-import
158+
details and the equivalent fix when authoring a new asset.
159+
160+
110161
Checking the internal logs from the simulator
111162
---------------------------------------------
112163

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Docs-only: add FAQ and how-to coverage for the ensure_drives_exist flag.

0 commit comments

Comments
 (0)