Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
2a5f45a
Fix fragment writers to reach nested rigid-body and mass prims
vidurv-nvidia Jul 20, 2026
b082790
Add trailing recursive token to prim path expressions
vidurv-nvidia Jul 20, 2026
f49ea9c
Route rigid-body fragment writer through prim path expressions
vidurv-nvidia Jul 21, 2026
234eb08
Create rigid body explicitly in mesh converter
vidurv-nvidia Jul 21, 2026
0cae9d1
Route mass fragment writer through prim path expressions
vidurv-nvidia Jul 21, 2026
a1158e0
Route articulation-root fragment writer through prim path expressions
vidurv-nvidia Jul 21, 2026
6bd2b1b
Route joint-drive fragment writer through prim path expressions
vidurv-nvidia Jul 21, 2026
2589fdc
Merge branch 'vidurv/frag-artic' into vidurv/schema-frag-regex-targeting
vidurv-nvidia Jul 21, 2026
33bc9a8
Merge branch 'vidurv/frag-jointdrive' into vidurv/schema-frag-regex-t…
vidurv-nvidia Jul 21, 2026
9380020
Route collision fragment writer through prim path expressions
vidurv-nvidia Jul 21, 2026
573be92
Route tendon fragment writers through prim path expressions
vidurv-nvidia Jul 21, 2026
9d6b260
Merge branch 'vidurv/frag-collision' into vidurv/schema-frag-regex-ta…
vidurv-nvidia Jul 21, 2026
7fa44ce
Merge branch 'vidurv/frag-tendon' into vidurv/schema-frag-regex-targe…
vidurv-nvidia Jul 21, 2026
fae8290
Drop traversal helper superseded by expression matching
vidurv-nvidia Jul 21, 2026
e7c0e9c
Add per-family target patterns to spawner configs
vidurv-nvidia Jul 21, 2026
56e3004
Add changelog for expression-driven fragment writers
vidurv-nvidia Jul 21, 2026
70069d7
Share the spawner target-pattern join helper
vidurv-nvidia Jul 21, 2026
983165b
Rename creation candidates for clarity in fragment writers
vidurv-nvidia Jul 21, 2026
cffb317
Clarify single-candidate mass creation comment
vidurv-nvidia Jul 21, 2026
1c1371a
Create mass on every matched prim without a body gate
vidurv-nvidia Jul 21, 2026
c1e172a
Tighten mass writer docstrings
vidurv-nvidia Jul 21, 2026
aa9252b
Trust the expression in fragment writer creation
vidurv-nvidia Jul 21, 2026
f69a3d4
Align recursive matching and joint-drive skip reporting
vidurv-nvidia Jul 21, 2026
189c2c4
Key fragment spawner configs by target pattern
vidurv-nvidia Jul 22, 2026
a15edb5
Pin ungated creation coverage and consolidate changelog
vidurv-nvidia Jul 22, 2026
a935eaa
Document schema fragment targeting
vidurv-nvidia Jul 22, 2026
de878d2
Merge branch 'vidurv/frag-docs' into vidurv/schema-frag-regex-targeting
vidurv-nvidia Jul 22, 2026
590d9ee
Merge remote-tracking branch 'origin/develop' into vidurv/schema-frag…
vidurv-nvidia Aug 14, 2026
042dcdb
Replace the recursive token with plain regex targeting
vidurv-nvidia Aug 14, 2026
2509ba0
Mark backend root API relocation gap as expected failure
vidurv-nvidia Aug 14, 2026
c51848c
Point writer docstrings at the shared matcher grammar
vidurv-nvidia Aug 17, 2026
7bd1ac6
Accept collision fragment mappings on deformable meshes
vidurv-nvidia Aug 17, 2026
f325324
Merge branch 'develop' into vidurv/schema-frag-regex-targeting
ooctipus Aug 17, 2026
198639d
Document descendants-only as the whole-subtree idiom
vidurv-nvidia Aug 17, 2026
52e2c29
Merge remote-tracking branch 'vidur/vidurv/schema-frag-regex-targetin…
vidurv-nvidia Aug 17, 2026
aff9ab9
Accept a bare fragment as a spawner field shorthand
vidurv-nvidia Aug 19, 2026
b3a704f
Use the shorthand form in fragment documentation examples
vidurv-nvidia Aug 19, 2026
bcc4b5c
Read the normalized mapping when flattening fragment values
vidurv-nvidia Aug 20, 2026
29caa26
Carry backend root schemas through articulation relocation
vidurv-nvidia Aug 20, 2026
beffe52
Treat an empty fragment sequence as no mapping entries
vidurv-nvidia Aug 24, 2026
03eb6e0
Keep the bare fragment form reaching nested schema carriers
vidurv-nvidia Aug 25, 2026
9e394c2
Keep schema-free assets a single body on the bare-fragment form
vidurv-nvidia Aug 26, 2026
0fbe420
Re-trigger CI
vidurv-nvidia Aug 27, 2026
01d86ae
Merge branch 'develop' into vidurv/schema-frag-regex-targeting
kellyguo11 Aug 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions docs/source/api/lab/isaaclab.sim.schemas.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,47 @@ isaaclab.sim.schemas
BoundingCubePropertiesCfg
BoundingSpherePropertiesCfg

.. rubric:: Schema fragments

A fragment mirrors exactly one USD applied schema and writes into a single attribute
namespace. The family writers below dispatch lists of fragments to the prims matched by
a target expression. See :ref:`schema-fragments` for the concept and the spawner-level
usage. Backend fragments live in :mod:`isaaclab_physx.sim.schemas` and
:mod:`isaaclab_newton.sim.schemas`.

.. autosummary::

SchemaFragment
RigidBodyFragment
CollisionFragment
MassFragment
ArticulationRootFragment
JointDriveFragment
MeshCollisionFragment
FixedTendonFragment
SpatialTendonFragment
UsdPhysicsRigidBodyCfg
UsdPhysicsCollisionCfg
UsdPhysicsDriveCfg
UsdPhysicsMeshCollisionCfg
MassCfg

.. rubric:: Fragment writers

.. autosummary::

apply_rigid_body_properties
apply_collision_properties
apply_mass_properties
apply_articulation_root_properties
apply_joint_drive_properties
apply_mesh_collision_properties
apply_fixed_tendon_properties
apply_spatial_tendon_properties
apply_namespaced
apply_drive
apply_mesh_collision

.. rubric:: Functions

.. autosummary::
Expand All @@ -51,6 +92,90 @@ isaaclab.sim.schemas
define_deformable_curve_properties
modify_deformable_body_properties

Schema Fragments
----------------

.. autoclass:: SchemaFragment
:members:
:exclude-members: __init__

.. autoclass:: RigidBodyFragment
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: CollisionFragment
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: MassFragment
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: ArticulationRootFragment
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: JointDriveFragment
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: MeshCollisionFragment
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: FixedTendonFragment
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: SpatialTendonFragment
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: UsdPhysicsRigidBodyCfg
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: UsdPhysicsCollisionCfg
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: UsdPhysicsDriveCfg
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: UsdPhysicsMeshCollisionCfg
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: MassCfg
:members:
:show-inheritance:
:exclude-members: __init__

.. autofunction:: apply_rigid_body_properties
.. autofunction:: apply_collision_properties
.. autofunction:: apply_mass_properties
.. autofunction:: apply_articulation_root_properties
.. autofunction:: apply_joint_drive_properties
.. autofunction:: apply_mesh_collision_properties
.. autofunction:: apply_fixed_tendon_properties
.. autofunction:: apply_spatial_tendon_properties
.. autofunction:: apply_namespaced
.. autofunction:: apply_drive
.. autofunction:: apply_mesh_collision

Articulation Root
-----------------

Expand Down
1 change: 1 addition & 0 deletions docs/source/overview/core-concepts/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This section we introduce core concepts in Isaac Lab.
multi_backend_architecture
physical-backends/index
schema_cfgs
schema_fragments
task_workflows
sensors/index.rst
renderers
Expand Down
1 change: 1 addition & 0 deletions docs/source/overview/core-concepts/schema_cfgs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ Both aliases are scheduled for removal in 4.0.
See also
--------

* :ref:`schema-fragments` — single-namespace fragments and expression-driven targeting
* :doc:`/source/migration/migrating_to_isaaclab_3-0` — migration guide
* :doc:`/source/api/lab/isaaclab.sim.schemas` — solver-common base class API
* :doc:`/source/api/lab_physx/isaaclab_physx.sim.schemas` — PhysX subclass API
Expand Down
193 changes: 193 additions & 0 deletions docs/source/overview/core-concepts/schema_fragments.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
.. _schema-fragments:

Schema Fragments
================

Isaac Lab authors physics properties onto USD prims through *schema fragments*: small
configuration classes that each mirror exactly one USD applied schema and write into a
single attribute namespace. Because fragments compose in lists, one asset configuration
can carry OpenUSD physics (``physics:*``), PhysX (``physx*:*``), and Newton
(``newton:*`` / ``mjc:*``) attributes side by side and run on any backend.

This page explains the fragment model, the prim-path expressions that target fragments
at prims, and the spawner-level configuration surface. For the solver-common vs.
backend-specific class tiers, see :ref:`schema-cfgs`. For the full class and function
reference, see :doc:`/source/api/lab/isaaclab.sim.schemas`.

The fragment model
------------------

Every fragment subclasses :class:`~isaaclab.sim.schemas.SchemaFragment` and declares
which USD namespace its fields write to and which applied schema, if any, it owns. A
fragment's :attr:`~isaaclab.sim.schemas.SchemaFragment.func` names the callable that
applies it to a prim; the default applier
(:func:`~isaaclab.sim.schemas.apply_namespaced`) writes each non-``None`` field as
``<namespace>:<camelCase(field)>`` and leaves ``None`` fields untouched (partial
update). Irregular APIs override ``func`` — for example
:class:`~isaaclab.sim.schemas.UsdPhysicsDriveCfg` dispatches through
:func:`~isaaclab.sim.schemas.apply_drive` to handle the multi-instance
``UsdPhysics.DriveAPI``.

Fragments are grouped into *families*, one per spawner slot. Each family has a writer
that resolves target prims from an expression and dispatches every fragment via its
``func``. Backend fragments carry backend-specific appliers, so the core package never
imports a backend:

.. list-table::
:header-rows: 1
:widths: 25 40 35

* - Spawner field
- Family writer
- Valid targets
* - ``rigid_props``
- :func:`~isaaclab.sim.schemas.apply_rigid_body_properties`
- prims with ``UsdPhysics.RigidBodyAPI``
* - ``collision_props``
- :func:`~isaaclab.sim.schemas.apply_collision_properties`
- prims with ``UsdPhysics.CollisionAPI``
* - ``mass_props``
- :func:`~isaaclab.sim.schemas.apply_mass_properties`
- prims with ``UsdPhysics.MassAPI``
* - ``articulation_props``
- :func:`~isaaclab.sim.schemas.apply_articulation_root_properties`
- prims with ``UsdPhysics.ArticulationRootAPI``
* - ``joint_drive_props``
- :func:`~isaaclab.sim.schemas.apply_joint_drive_properties`
- revolute / prismatic joint prims
* - ``fixed_tendons_props``
- :func:`~isaaclab.sim.schemas.apply_fixed_tendon_properties`
- tendon-bearing prims (existing tendon instances)
* - ``spatial_tendons_props``
- :func:`~isaaclab.sim.schemas.apply_spatial_tendon_properties`
- tendon attachment root / leaf prims

The tendon families are *tune-not-apply*: the tendon topology is authored in the source
asset, so their writers only tune existing instances and never create them.

Targeting expressions
---------------------

Target prims are resolved with :func:`~isaaclab.sim.utils.queries.find_matching_prims`.
The expression is a plain Python regular expression matched against the *whole* prim
path. Standard regex semantics apply: ``.`` matches any character including ``/``, so
``/World/Robot/.*`` selects every descendant at any depth, while ``[^/]+`` confines a
wildcard to a single path segment and ``/World/Robot(/.*)?`` selects the prim together
with its descendants. The traversal includes inactive and undefined prims as well as
instance proxies.

The matched set is then filtered to valid family targets (see the table above): API
carriers for the rigid-body, collision, mass, and articulation families; revolute and
prismatic joint prims for the joint-drive family; tendon-bearing prims for the tendon
families. Non-joint matches of a joint-drive expression are ignored silently, since a
subtree expression legitimately sweeps whole subtrees.

Edge cases behave as follows:

* **Instanced matches** cannot be authored on (prototypes are read-only) and are
skipped with a warning.
* **Zero targets** emit a warning and the writer returns ``False`` without authoring
anything.
* **An empty fragment list** is an authoring no-op and returns ``True``.

Configuring fragments on spawners
---------------------------------

Spawner configurations (:class:`~isaaclab.sim.spawners.from_files.UsdFileCfg`,
:class:`~isaaclab.sim.spawners.shapes.CuboidCfg`, ...) expose one field per family.
Each field accepts either a mapping from target pattern to a list of fragments, a bare
fragment or list of fragments (see the shorthand below), a
single legacy dataclass cfg (e.g.
:class:`~isaaclab.sim.schemas.RigidBodyBaseCfg` or a backend ``*PropertiesCfg``, routed
to the legacy writers), or ``None``.

Mapping keys are regular-expression suffixes appended to *the prim the spawner authors
that family on*: the spawn prim for USD, URDF, and MJCF assets; for shape and mesh
spawners, the geometry prim for the collision family and the container prim for the
rigid-body and mass families. A key therefore carries its own leading ``/`` when it
targets descendants: ``""`` selects the anchor prim itself, ``"/[^/]+"`` its direct
children, and ``"/.*"`` everything beneath it. Prefer ``"/.*"`` for a whole-subtree
rule: the anchor is usually a plain ``Xform`` that carries no family API, so including
it changes nothing — except under ``create_if_missing``, where ``"(/.*)?"`` would also
apply the API to the anchor itself. Reach for ``"(/.*)?"`` only when the anchor is
genuinely a target too. Entries apply in insertion order, so when two patterns match the
same prim, fragments from later entries override attributes authored by earlier ones.

The bare fragment (or list of fragments) shorthand skips the mapping when a rule needs no
targeting of its own. On the shape and mesh spawners it targets the anchor prim, the only
prim those spawners author. On the file spawners it targets the spawn prim together with
its descendants, so it reaches the schema carriers wherever the asset puts them; and when
the subtree carries no prim with the family's defining API at all — the usual shape of an
art asset shipped without physics schemas — the file spawners apply that API to the spawn
prim and author there, turning the asset into a single body.

A robot spawned from USD, with a broad rule and a narrowing override:

.. code-block:: python

import isaaclab.sim as sim_utils
from isaaclab.sim.schemas import UsdPhysicsDriveCfg, UsdPhysicsRigidBodyCfg
from isaaclab_newton.sim.schemas import MujocoRigidBodyCfg
from isaaclab_physx.sim.schemas import PhysxRigidBodyCfg
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR

spawn = sim_utils.UsdFileCfg(
usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/Franka/franka_instanceable.usd",
rigid_props={
# every rigid body: universal + PhysX + MuJoCo attributes side by side
"/.*": [
UsdPhysicsRigidBodyCfg(rigid_body_enabled=True),
PhysxRigidBodyCfg(max_depenetration_velocity=5.0),
MujocoRigidBodyCfg(gravcomp=1.0),
],
# hand links (and their subtrees) get a tighter depenetration limit
"/.*_hand/.*": [PhysxRigidBodyCfg(max_depenetration_velocity=1.0)],
},
joint_drive_props={
"/.*": [UsdPhysicsDriveCfg(drive_type="force", stiffness=40.0, damping=4.0)],
},
)

A primitive shape, where every family targets the anchor prim, so the mapping can be
dropped entirely:

.. code-block:: python

import isaaclab.sim as sim_utils
from isaaclab.sim.schemas import MassCfg, UsdPhysicsCollisionCfg, UsdPhysicsRigidBodyCfg
from isaaclab_newton.sim.schemas import NewtonCollisionCfg

cuboid = sim_utils.CuboidCfg(
size=(0.1, 0.1, 0.1),
rigid_props=UsdPhysicsRigidBodyCfg(),
mass_props=MassCfg(mass=0.5),
collision_props=[UsdPhysicsCollisionCfg(collision_enabled=True), NewtonCollisionCfg(contact_margin=0.001)],
)

Reach for the mapping when a rule must target something other than the anchor prim — the
usual situation for assets spawned from USD, URDF, or MJCF files, where the spawn prim is a
container and the schema carriers sit beneath it.

Creating missing APIs
---------------------

By default, the family writers only *modify* prims that already carry the family's
defining USD API. Three per-family spawner flags — ``mass_props_create_if_missing``,
``articulation_props_create_if_missing``, and ``joint_drive_props_create_if_missing`` —
additionally apply the defining API to matched prims that lack it before the fragments
are authored (for the joint-drive family, the axis-appropriate ``UsdPhysics.DriveAPI``
instance). Shape and mesh spawners always create the APIs on the bare prims they
author, since freshly created geometry carries no physics APIs yet.

The writers trust the expression as written: with creation enabled, every matched prim
receives the API, so a too-broad pattern can, for example, give every mesh in a subtree
its own mass. Which bodies participate in an articulation is still decided by the
asset's joints, not by the expression. Scope creation patterns deliberately.

See also
--------

* :ref:`schema-cfgs` — solver-common vs. backend-specific configuration tiers
* :doc:`/source/api/lab/isaaclab.sim.schemas` — fragment base classes and family writers
* :doc:`/source/api/lab_physx/isaaclab_physx.sim.schemas` — PhysX fragments
* :doc:`/source/api/lab_newton/isaaclab_newton.sim.schemas` — Newton / MuJoCo fragments
Loading
Loading