Schema Configuration Classes#

Isaac Lab’s spawners author USD physics attributes onto prims via a layered set of configuration classes. The layering separates universal-physics parameters from backend-specific parameters, so the same asset cfg can be authored once and target any backend that supports it.

This page explains the class hierarchy, when to use each tier, and how parameters route to the underlying USD attributes.

Migrating from 2.x? See Schema Configuration Class Refactor in the 3.0 migration guide.

Quick example#

Add MuJoCo (MJC) gravity compensation to an articulated asset:

import isaaclab.sim as sim_utils
from isaaclab_newton.sim.schemas import (
    MujocoRigidBodyPropertiesCfg,
    MujocoJointDrivePropertiesCfg,
)

spawn = sim_utils.UsdFileCfg(
    usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/Franka/franka_instanceable.usd",
    rigid_props=MujocoRigidBodyPropertiesCfg(gravcomp=1.0),
    joint_drive_props=MujocoJointDrivePropertiesCfg(actuatorgravcomp=True),
)

The Mujoco-specific fields land under mjc:* on the prim; any RigidBodyBaseCfg / JointDriveBaseCfg fields you set on the same instance land under physics:*. See Mixed-namespace authoring on a single instance for the full routing rules.

Class hierarchy#

For each property group (rigid body, joint drive, collision, articulation root, material, mesh collision), Isaac Lab defines a single base class in core isaaclab.sim.schemas and one subclass per backend in the corresponding extension package:

isaaclab.sim.schemas
├── RigidBodyBaseCfg
│   ├── isaaclab_physx.sim.schemas.PhysxRigidBodyPropertiesCfg
│   └── isaaclab_newton.sim.schemas.NewtonRigidBodyPropertiesCfg
│       └── isaaclab_newton.sim.schemas.MujocoRigidBodyPropertiesCfg
│
├── JointDriveBaseCfg
│   ├── isaaclab_physx.sim.schemas.PhysxJointDrivePropertiesCfg
│   └── isaaclab_newton.sim.schemas.NewtonJointDrivePropertiesCfg
│       └── isaaclab_newton.sim.schemas.MujocoJointDrivePropertiesCfg
│
├── CollisionBaseCfg
│   ├── isaaclab_physx.sim.schemas.PhysxCollisionPropertiesCfg
│   └── isaaclab_newton.sim.schemas.NewtonCollisionPropertiesCfg
│
├── ArticulationRootBaseCfg
│   ├── isaaclab_physx.sim.schemas.PhysxArticulationRootPropertiesCfg
│   └── isaaclab_newton.sim.schemas.NewtonArticulationRootPropertiesCfg
│
├── MeshCollisionBaseCfg
│   ├── isaaclab_physx.sim.schemas.{PhysxConvexHull, PhysxConvexDecomposition,
│   │                                PhysxTriangleMesh, PhysxSDFMesh, ...}PropertiesCfg
│   └── isaaclab_newton.sim.schemas.NewtonMeshCollisionPropertiesCfg
│       (also inherits NewtonCollisionPropertiesCfg — multi-namespace)
│
└── isaaclab.sim.spawners.materials.RigidBodyMaterialBaseCfg
    ├── isaaclab_physx.sim.spawners.materials.PhysxRigidBodyMaterialCfg
    └── isaaclab_newton.sim.schemas.NewtonMaterialPropertiesCfg

NewtonMeshCollisionPropertiesCfg uses multiple inheritance: it extends both NewtonCollisionPropertiesCfg (for contact_margin / contact_gap) and MeshCollisionBaseCfg (for mesh_approximation_name). This is the textbook case for the per-declaring- class MRO routing described under Mixed-namespace authoring on a single instance — each inherited field is written under the namespace of the class that declared it.

The hierarchy is single-rooted per spawner slot: every spawner has a single field for each property group (rigid_props, joint_drive_props, collision_props, etc.), and Python’s polymorphism allows any subclass to be passed where the base type is expected.

When to use which class#

The choice depends on which backends you target and which fields you need.

Use a base class (RigidBodyBaseCfg, JointDriveBaseCfg, etc.)

when you only need universal-physics fields and you want your asset cfg to be backend-portable. Importing the base class does not pull in isaaclab_physx or isaaclab_newton.

Use a PhysX subclass (PhysxRigidBodyPropertiesCfg, etc.)

when your asset uses PhysX-specific knobs (per-body damping, TGS solver iterations, sleep / stabilization thresholds, torsional patch friction, compliant-contact materials, etc.) and you target the PhysX backend. Inherits all base-class fields, so you can set both universal and PhysX fields on the same instance.

Use a Newton subclass (NewtonRigidBodyPropertiesCfg, etc.)

when you target Newton and need Newton-native attributes (newton:contactMargin, newton:torsionalFriction, newton:selfCollisionEnabled, etc.). The empty Newton base classes (NewtonRigidBodyPropertiesCfg, NewtonJointDrivePropertiesCfg) reserve the newton:* namespace for future native fields and act as the parent for solver-specific subclasses.

Use a MuJoCo subclass (MujocoRigidBodyPropertiesCfg, MujocoJointDrivePropertiesCfg)

when you specifically use Newton’s MuJoCo solver and need MuJoCo-only knobs (gravity compensation via mjc:gravcomp / mjc:actuatorgravcomp). Inherits from the Newton base, so isinstance(cfg, NewtonRigidBodyPropertiesCfg) is True.

What parameters live where#

Note

The tables below summarize which fields live on which cfg classes. The canonical source is the auto-generated API reference — see isaaclab.sim.schemas, isaaclab_physx.sim.schemas, and isaaclab_newton.sim.schemas, which render the cfg class docstrings directly. Treat these tables as a navigation aid; if they drift from the source, the API docs win.

Universal physics (declared on the base class)#

Lives on the base class. Most fields write to physics:* (the standard UsdPhysics.*API namespace), but a small set of “exception” fields are declared on the base for backend-portability yet route to a non-physics:* namespace because that is the only USD path honored today (e.g., disable_gravity writes physxRigidBody:disableGravity because both PhysX and Newton’s importer consume the PhysX attribute). The “USD attribute” column below is the actual emitted attribute, not the namespace family.

Base class

Field

USD attribute

RigidBodyBaseCfg

rigid_body_enabled, kinematic_enabled

physics:rigidBodyEnabled, physics:kinematicEnabled

RigidBodyBaseCfg

disable_gravity

physxRigidBody:disableGravity (per-body on PhysX; scene-level partial honor on Newton)

CollisionBaseCfg

collision_enabled

physics:collisionEnabled

CollisionBaseCfg

contact_offset, rest_offset

physxCollision:contactOffset, physxCollision:restOffset (Newton consumes via PhysX bridge)

ArticulationRootBaseCfg

articulation_enabled

physxArticulation:articulationEnabled

ArticulationRootBaseCfg

fix_root_link

synthesizes UsdPhysics.FixedJoint (writer-side, not a USD attribute)

JointDriveBaseCfg

drive_type, max_force, stiffness, damping

drive:<axis>:physics:type/maxForce/stiffness/damping

JointDriveBaseCfg

max_joint_velocity

physxJoint:maxJointVelocity (sole USD path; Newton consumes via PhysX bridge today)

JointDriveBaseCfg

ensure_drives_exist

writer-side only — when True, ensures any drive with stiffness=0 and damping=0 gets a minimal stiffness=1e-3 so backends like Newton recognize the joint as actively driven; not a USD attribute on its own

MassPropertiesCfg

mass, density

physics:mass, physics:density

RigidBodyMaterialBaseCfg

static_friction, dynamic_friction, restitution

physics:staticFriction, physics:dynamicFriction, physics:restitution

MeshCollisionBaseCfg

mesh_approximation_name

physics:approximation

PhysX-specific (physx*:* namespace, Physx*API schemas)#

Lives on the PhysX subclass. Only authored when the user opts in by setting the field on a PhysX cfg.

PhysX subclass

Fields (selection)

USD namespace / schema

PhysxRigidBodyPropertiesCfg

linear_damping, angular_damping, max_linear_velocity, max_angular_velocity, solver_position_iteration_count, sleep_threshold, enable_gyroscopic_forces, …

physxRigidBody:* / PhysxRigidBodyAPI

PhysxJointDrivePropertiesCfg

(currently empty; reserved for future PhysX-only drive knobs)

physxJoint:* / PhysxJointAPI

PhysxCollisionPropertiesCfg

torsional_patch_radius, min_torsional_patch_radius

physxCollision:* / PhysxCollisionAPI

PhysxArticulationRootPropertiesCfg

enabled_self_collisions, solver_position_iteration_count, sleep_threshold, stabilization_threshold

physxArticulation:* / PhysxArticulationAPI

PhysxRigidBodyMaterialCfg

compliant_contact_stiffness, compliant_contact_damping, friction_combine_mode, restitution_combine_mode

physxMaterial:* / PhysxMaterialAPI

PhysxConvexHullPropertiesCfg (and other mesh-cooking subclasses)

hull_vertex_limit, min_thickness, …

physxConvexHullCollision:* / PhysxConvexHullCollisionAPI

Newton-targeted (newton:* namespace, Newton*API schemas)#

Lives on the Newton subclass. Authored only when the user opts in.

Newton subclass

Fields

USD namespace / schema

NewtonRigidBodyPropertiesCfg

(empty — reserved for future Newton-native rigid-body fields)

newton:*

NewtonJointDrivePropertiesCfg

(empty — reserved for future Newton-native joint-drive fields)

newton:*

NewtonCollisionPropertiesCfg

contact_margin, contact_gap

newton:* / NewtonCollisionAPI

NewtonMeshCollisionPropertiesCfg

max_hull_vertices

newton:* / NewtonMeshCollisionAPI

NewtonMaterialPropertiesCfg

torsional_friction, rolling_friction

newton:* / NewtonMaterialAPI

NewtonArticulationRootPropertiesCfg

self_collision_enabled

newton:* / NewtonArticulationRootAPI

MuJoCo-solver-specific (mjc:* namespace)#

Lives on a MuJoCo subclass that extends a Newton subclass. Only consumed when running Newton’s MuJoCo solver.

MuJoCo subclass

Field

USD attribute / schema

MujocoRigidBodyPropertiesCfg

gravcomp

mjc:gravcomp (raw attribute, no applied schema)

MujocoJointDrivePropertiesCfg

actuatorgravcomp

mjc:actuatorgravcomp via MjcJointAPI

Note

The two MuJoCo rows differ in their USD applied-schema requirement: mjc:actuatorgravcomp is part of the registered MjcJointAPI applied schema (so the writer calls prim.AddAppliedSchema("MjcJointAPI") when the field is non-None). mjc:gravcomp has no registered Mjc applied schema for body-level gravity compensation, so the writer authors it as a raw USD attribute. Newton’s MuJoCo solver consumes both via the same resolver path; the schema-application difference is purely a USD-side detail.

Mixed-namespace authoring on a single instance#

Because each cfg field is routed to its declaring class’s namespace (not the instance’s class), a subclass instance can author attributes across multiple namespaces on the same prim. For example:

from isaaclab_newton.sim.schemas import MujocoRigidBodyPropertiesCfg

cfg = MujocoRigidBodyPropertiesCfg(
    rigid_body_enabled=True,        # declared on RigidBodyBaseCfg → physics:rigidBodyEnabled
    disable_gravity=True,            # declared on RigidBodyBaseCfg (exception) → physxRigidBody:disableGravity
    gravcomp=1.0,                    # declared on MujocoRigidBodyPropertiesCfg → mjc:gravcomp
)

The writer applies each field to the namespace of the class where the field is declared. The applied schemas (PhysxRigidBodyAPI for disable_gravity, none for the Mjc raw attribute) are added only when the corresponding fields are non-None.

Spawner usage#

Spawners (UsdFileCfg, MeshCuboidCfg, MeshSphereCfg, …) accept the base class type for each slot and use polymorphism to dispatch to the correct subclass at write time:

import isaaclab.sim as sim_utils
from isaaclab_physx.sim.schemas import PhysxRigidBodyPropertiesCfg
from isaaclab_newton.sim.schemas import MujocoJointDrivePropertiesCfg

spawn = sim_utils.UsdFileCfg(
    usd_path="...",
    rigid_props=PhysxRigidBodyPropertiesCfg(disable_gravity=True, linear_damping=0.1),
    joint_drive_props=MujocoJointDrivePropertiesCfg(
        drive_type="acceleration",
        stiffness=10.0,
        damping=0.1,
        actuatorgravcomp=True,
    ),
)

Gravity compensation (MuJoCo solver)#

Gravity compensation has two halves and you typically need both:

  • Body-level: gravcomp on each rigid body (writes mjc:gravcomp). This is what computes the compensation force.

  • Joint-level: actuatorgravcomp on each joint (writes mjc:actuatorgravcomp). This routes the compensation force through the actuator channel (qfrc_actuator) so it counts against actuatorfrcrange; otherwise it goes to qfrc_passive.

actuatorgravcomp=True alone is a no-op — without body-level gravcomp there are no forces to route. To prevent this footgun, the spawner auto-enables MujocoRigidBodyPropertiesCfg(gravcomp=1.0) whenever joint_drive_props is a Mujoco cfg with actuatorgravcomp=True and rigid_props is not already a Mujoco cfg. If you want a different gravcomp value (or want to disable the auto-enable), pass an explicit MujocoRigidBodyPropertiesCfg in rigid_props.

Naming convention#

Cfg field names use snake_case; the writer converts them to camelCase USD attribute names (contact_marginnewton:contactMargin). For single-token fields (gravcomp, actuatorgravcomp), the conversion is identity, which matches MuJoCo’s lowercase convention.

Field renames preserve backward compatibility via deprecation aliases. Two such aliases live on JointDriveBaseCfg today:

  • max_velocitymax_joint_velocity (USD attribute is physxJoint:maxJointVelocity)

  • max_effortmax_force (USD attribute is drive:<axis>:physics:maxForce)

The old names remain as real dataclass fields (so dataclasses.fields() sees them), defaulting to None. __post_init__ runs _deprecate_field_alias which, when the old field is set: emits a DeprecationWarning, copies the value into the canonical field if the canonical is None, then nulls the old field. Setting both in the same constructor is silent — the canonical wins; the old name’s value is discarded. Both aliases are scheduled for removal in 4.0.

See also#