PhysX Backend (Isaac Sim)
The PhysX backend runs NVIDIA PhysX inside Isaac Sim, on the Omniverse Kit
runtime. Its integration lives in the isaaclab_physx package. This page
explains how that package starts Kit, owns the simulation lifecycle, configures
the PhysX scene, and exposes native PhysX data to Isaac Lab assets and sensors.
For solver selection and tuning, see PhysX and
Tune the PhysX Solver. For the kit-less PhysX path, see
OvPhysX Backend.
Selecting the backend
Configure the backend with ~isaaclab_physx.physics.PhysxCfg on
isaaclab.sim.SimulationCfg.physics, or select it from the command line
with physics=isaacsim_physx when the task exposes that preset:
The physx selector is automatic. It selects a
~isaaclab.physics.PhysxAutoCfg that holds a PhysxCfg and, when
the task supports it, an ~isaaclab_ov.physics.OvPhysxCfg. When the
simulation is launched, the auto configuration resolves to Isaac Sim PhysX if
the run needs Kit, and otherwise to OvPhysX when one is configured. Use
isaacsim_physx to require the Isaac Sim path.
Runtime: Isaac Sim and Kit
Launch
PhysxCfg names its launcher through the launcher_type class attribute,
which is isaaclab_physx.app:KitLauncher.
~isaaclab.app.launch_simulation scans the resolved configuration,
collects the launchers that the physics and renderer configurations name, and
starts them. Kit starts first. Scripts do not construct the launcher
themselves.
~isaaclab_physx.app.KitLauncher creates the Isaac Sim
SimulationApp. Unless --experience is passed, it selects an Isaac Lab
experience file from the repository apps/ directory based on the headless,
camera-rendering, livestream, and XR settings, for example
isaaclab.python.headless.kit or isaaclab.python.rendering.kit. After
startup it publishes Isaac Lab settings such as /isaaclab/has_gui that the
simulation context and renderers read. The launcher’s environment variables
and arguments are documented in isaaclab_physx.app.
Stage
Isaac Lab owns the USD stage. Kit extensions, including PhysX, its tensor
views, and the viewport, read the stage from Kit’s USD context instead. When
Kit is running, ~isaaclab.sim.SimulationContext registers a
~isaaclab_physx.app.KitStageBackendCfg, and
~isaaclab_physx.app.KitStageBackend attaches the simulation stage to
omni.usd’s context. Closing that backend closes the Kit stage before the
simulation clears its stage cache.
Interaction with Isaac Sim’s simulation manager
~isaaclab_physx.physics.PhysxManager is the single owner of the
simulation lifecycle. Isaac Sim’s own
isaacsim.core.simulation_manager.SimulationManager registers default
timeline and stage callbacks. Its stop callback invalidates the shared
omni.physics.tensors simulation view, which would also invalidate the views
that Isaac Lab assets hold. KitLauncher asks Isaac Sim to skip these
callbacks at startup through the
/exts/isaacsim.core.simulation_manager/enable_default_callbacks setting.
Newer Isaac Sim versions honor it, and Isaac Lab then leaves the manager
untouched. On older versions, PhysxManager.initialize() disables those
callbacks and redirects the module’s SimulationManager to
PhysxManager. PhysxManager re-applies this patch if the Isaac Sim
extension is enabled later.
Simulation lifecycle
PhysxManager implements the shared ~isaaclab.physics.PhysicsManager
contract on top of the omni.physx, omni.physics.tensors, and
omni.timeline interfaces:
Initialization
Applies Kit physics settings such as the CUDA device and GPU readback
suppression, authors the PhysX scene attributes described in
Scene configuration_, binds a default physics material, and loads or
unloads the PhysX Fabric extension.
First reset
Attaches the stage to PhysX (on CPU, PhysX instead loads the scene
directly from USD), runs one warm-start update, and dispatches the
warm-up event. It then registers a
~isaaclab_physx.physics.PhysxBackendCfg with the simulation
context. The resulting PhysxBackend owns the
omni.physics.tensors simulation view, created with the Warp frontend for
the current stage. Finally, the manager dispatches
PHYSICS_READY, and assets and
sensors create their typed views from the simulation view.
Step
Advances PhysX through the omni.physx simulation interface with
simulate(dt) followed by fetch_results(). Physics stepping does not
pump the Kit application. Rendering is driven separately by the simulation
context. forward() refreshes articulation kinematics through the tensor
view only when pose writes have marked them dirty.
Timeline and teardown
play(), pause(), and stop() drive omni.timeline and pump
one Kit update so timeline callbacks run synchronously. Stopping the
timeline invalidates every tensor view. The next play or reset warms up
PhysX and creates the views again. close() detaches PhysX from the
stage before views are invalidated and prims are deleted.
Lifecycle events
Backend-agnostic code registers callbacks with
~isaaclab.physics.PhysicsEvent. PhysxManager maps those events to
its PhysX-specific ~isaaclab_physx.physics.IsaacEvents, which remain
available for backward compatibility:
IsaacEvents also exposes PRE_PHYSICS_STEP and POST_PHYSICS_STEP
through the omni.physx step subscription, and PRIM_DELETION during
teardown. New code should prefer PhysicsEvent.
Scene configuration
PhysxCfg fields are written to the physics scene prim at
isaaclab.sim.SimulationCfg.physics_prim_path. The manager applies
PhysxSceneAPI and sets each remaining field as a physxScene:
attribute in camel case, for example gpu_max_rigid_contact_count becomes
physxScene:gpuMaxRigidContactCount. Some fields are translated instead of
copied:
solver_typebecomesphysxScene:solverType("TGS"or"PGS").bounce_threshold_velocitybecomesphysxScene:bounceThreshold.- The timestep becomes
physxScene:timeStepsPerSecond. - GPU simulation enables GPU dynamics and the GPU broadphase. CPU simulation uses the MBP broadphase.
enable_ccdtakes effect only on CPU. CCD is disabled with a warning when GPU dynamics is enabled.- The backend-agnostic
deterministicrequest enablesenable_enhanced_determinism. - Scene query support follows
SimulationCfg.enable_scene_query_supportand is forced on when Kit runs with a GUI.
Per-prim physics properties are not part of PhysxCfg. They are authored
through the USD schema configurations described in
/source/concepts/schema_cfgs. PhysX-only schema configurations, such as
~isaaclab_physx.sim.schemas.PhysxRigidBodyPropertiesCfg, live in
isaaclab_physx.sim.schemas.
Fabric
When isaaclab.sim.SimulationCfg.use_fabric is True, the default,
the manager enables the omni.physx.fabric extension. It also turns off
PhysX write-back to USD (/physics/updateToUsd and related settings), so
simulated transforms reach the renderer through Fabric instead of USD. With
use_fabric=False, PhysX writes simulation results back to USD, which is
slower for large scenes.
Tensor views and native access
The PhysX Tensor API provides typed views for data paths and capabilities that require engine-native access.
Every PhysX asset and sensor in isaaclab_physx, except SurfaceGripper,
is built on typed views created from the shared omni.physics.tensors
simulation view:
Assets expose their view through root_view. The contact sensor exposes its
rigid-contact view through contact_view. Use
~isaaclab_physx.physics.PhysxManager.get_physics_sim_view to reach the
simulation view itself after the first reset.
Environment cloning uses
~isaaclab_physx.cloner.PhysxReplicateContext, which applies the
clone plan through the omni.physx replicator interface.
Mental model
The API starts from a SimulationView and creates typed views over selected
physics objects. Access is entirely method-based: a getter pulls data from the
view, and an independent setter publishes data back. Returned buffers are not
live pointers, so editing a getter result does not update the simulation. Raw
views select objects with PhysX Tensor API wildcard patterns.
Lifecycle prerequisite
~isaaclab_physx.physics.PhysxManager creates its
SimulationView with the Warp frontend. Low-level
code must run only after physics initialization and simulation reset, when the
PhysX Tensor API view has been created:
Reuse Isaac Lab-owned access
When an Isaac Lab asset already has the desired selection, reuse its
isaaclab_physx.assets.Articulation.root_view rather than creating a
second view:
isaaclab_physx.assets.Articulation.root_view is backend-specific and
typed. An articulation, rigid object, rigid-object collection, or deformable
can expose a different native PhysX view type, so choose methods that match the
returned view rather than assuming one common interface.
Create raw access
Create a view directly only when no Isaac Lab-owned selection matches the
needed objects or capability. In this Tensor API pattern, * selects the
matching object below every cloned environment:
Read/write semantics
Each getter and setter is a separate operation. Clone a returned Warp buffer before editing it locally, then call the matching setter to publish the result:
Cloning makes ownership explicit. Callers can modify the clone with Warp before
the setter, but edits to a local buffer do not publish themselves. The
indices array selects the complete view and matches the setter’s required
int32 dtype and device; the setter performs the write. For active Tensor API
contracts that require link transforms to be refreshed after joint-state writes, call
update_articulations_kinematic().
Not every setter requires that refresh; follow the method-level behavior in the
upstream reference.
Access the contact view
The PhysX contact sensor exposes its native RigidContactView through
isaaclab_physx.sensors.ContactSensor.contact_view. Use it when the
public sensor data does not expose the required contact details:
Other Isaac Lab sensors may use ordinary rigid-body or articulation views internally, but those views are not sensor-specific low-level interfaces.
Ownership, synchronization, and invalidation
Preserve a view’s expected selection ordering, device, dtype, and tensor shape when supplying values to a setter. Check and reacquire views after a hard reset, object removal, stage reload, or manager teardown. Prefer public Isaac Lab sensor data when direct native contact or motion data is not required.
Authoritative references
PhysX-specific and shared components
Kit-hosted rendering, such as the
~isaaclab_physx.renderers.IsaacRtxRendererCfg renderer, also ships in
isaaclab_physx because it requires Kit. Renderer selection is
configured separately from the physics backend, but the kit-less OVRTX renderer
cannot share a process with Isaac Sim PhysX. See Backend architecture for the
factory and registry design that all backends share.