isaaclab_ov.physics#

OvPhysX physics manager implementation.

Classes

OvPhysxManager

Manages an ovphysx-backed physics simulation lifecycle.

OvPhysxCfg

Configuration for the ovphysx physics manager.

Physics Manager#

class isaaclab_ov.physics.OvPhysxManager[source]#

Bases: PhysicsManager

Manages an ovphysx-backed physics simulation lifecycle.

Unlike PhysxManager, this manager does not depend on a host Kit or Carbonite runtime, or on the Omniverse timeline. It drives the simulation through the OVPhysX Python wheel and its packaged runtime.

Lifecycle: initialize() -> reset() -> step() (repeated) -> close()

Methods:

get_dt()

Get the physics timestep.

require_full_stage()

Load every authored environment during the next stage warmup.

fix_articulation_root(articulation_prim[, stage])

Fix and normalize an articulation root for the OVPhysX parser.

register_clone(source, targets[, ...])

Queue clones at the given world positions with identity rotations.

initialize(sim_context)

Initialize the physics manager with simulation context.

reset([soft])

Reset physics simulation.

forward()

No-op -- ovphysx does not have a fabric/rendering pipeline.

step()

Step the simulation by one physics timestep.

close()

Release ovphysx resources and clean up.

get_physx_instance()

Return the underlying ovphysx.PhysX instance (or None if not yet created).

get_gravity()

Return the world-frame gravity vector [m/s^2] from the active simulation cfg.

get_scene_data_backend()

Return the SceneDataBackend for the central SceneDataProvider.

after_visualizers_render()

Hook after visualizers have stepped during render().

clear_callbacks()

Remove all registered callbacks.

deregister_callback(callback_id)

Remove a registered callback.

dispatch_event(event[, payload])

Dispatch an event to all registered callbacks.

get_backend()

Get the tensor backend being used ("numpy" or "torch").

get_device()

Get the physics simulation device.

get_physics_dt()

Get the physics timestep in seconds.

get_physics_sim_view()

Get the physics simulation view.

get_simulation_time()

Get the current simulation time in seconds.

handles_decimation()

True when step() executes the full decimation loop internally.

pause()

Pause physics simulation.

play()

Start or resume physics simulation.

pre_render()

Sync deferred physics state to the rendering backend.

register_callback(callback, event[, order, ...])

Register a callback for a physics event.

safe_callback_invoke(fn, *args[, ...])

Invoke a callback, catching exceptions that would be swallowed by external event buses.

set_decimation(decimation)

Inform the physics backend how many substeps the environment runs per policy step.

stop()

Stop physics simulation.

video_capture_backend()

Return the video capture backend identifier for this physics manager.

wait_for_playing()

Block until the timeline is playing.

classmethod get_dt() float[source]#

Get the physics timestep. Alias for get_physics_dt().

classmethod require_full_stage() None[source]#

Load every authored environment during the next stage warmup.

classmethod fix_articulation_root(articulation_prim: Any, stage: Any = None) Any[source]#

Fix and normalize an articulation root for the OVPhysX parser.

classmethod register_clone(source: str, targets: list[str], parent_positions: list[tuple[float, float, float]] | None = None) None[source]#

Queue clones at the given world positions with identity rotations.

Parameters:
  • source – Source prim path (env_0 articulation root).

  • targets – Target prim paths for env_1..N.

  • parent_positions – Final world positions (x, y, z) [m] for whole-environment target roots. Each position uses an identity rotation.

classmethod initialize(sim_context: SimulationContext) None[source]#

Initialize the physics manager with simulation context.

This stores the config and device but does not load the USD stage yet – the stage may not be fully populated at this point. The actual load happens lazily in reset().

cls._physx is intentionally not cleared here: if the current SimulationContext already constructed it and has not been closed, the manager reuses that instance. cls._locked_device carries IsaacLab’s conservative first-device policy for this process.

classmethod reset(soft: bool = False) None[source]#

Reset physics simulation.

On the first (non-soft) reset the method: - Serializes the current USD stage in memory - Creates the ovphysx.PhysX instance - Populates and attaches an OVStage - Warms up GPU buffers (if on CUDA) - Dispatches PHYSICS_READY

A forced re-warm dispatches STOP before replacing the attached stage so listeners discard stale bindings.

classmethod forward() None[source]#

No-op – ovphysx does not have a fabric/rendering pipeline.

classmethod step() None[source]#

Step the simulation by one physics timestep.

classmethod close() None[source]#

Release ovphysx resources and clean up.

classmethod get_physx_instance() Any[source]#

Return the underlying ovphysx.PhysX instance (or None if not yet created).

classmethod get_gravity() tuple[float, float, float][source]#

Return the world-frame gravity vector [m/s^2] from the active simulation cfg.

Mirrors PhysX’s SimulationView.get_gravity() so backend-agnostic sensor code can read gravity through one classmethod.

Raises:

RuntimeError – If no simulation is active. Call initialize() first.

classmethod get_scene_data_backend() SceneDataBackend[source]#

Return the SceneDataBackend for the central SceneDataProvider.

Constructed eagerly in initialize() so SimulationContext captures a real instance (not None) when wiring up the central SceneDataProvider. Bindings are empty until _warmup_and_load() calls OvPhysxSceneDataBackend.setup() against the live ovphysx PhysX and USD stage; reads against an unsetup backend return empty data rather than raising.

classmethod after_visualizers_render() None#

Hook after visualizers have stepped during render().

Use for physics-backend sync (e.g. fabric) if needed. Default is a no-op.

classmethod clear_callbacks() None#

Remove all registered callbacks.

Do NOT reset _callback_id — handle IDs must remain monotonically unique across the lifetime of the process. Resetting the counter would let a future register_callback() hand out an ID that an old, still-alive CallbackHandle (e.g. on a sensor that has not been garbage-collected yet) holds, so when the old object eventually finalizes its __del__ would deregister the new callback. This bit ovphysx’s kitless multi-context tests where two InteractiveScene``s are created in sequence: the first scene's sensor would post-GC deregister the second scene's ``_initialize_callback by ID collision, leaving the second sensor forever uninitialized.

classmethod deregister_callback(callback_id: int | CallbackHandle) None#

Remove a registered callback.

Parameters:

callback_id – The ID or CallbackHandle returned by register_callback().

classmethod dispatch_event(event: PhysicsEvent, payload: Any = None) None#

Dispatch an event to all registered callbacks.

This is the default implementation using simple callback lists. Subclasses may override or extend with platform-specific dispatch.

Parameters:
  • event – The event to dispatch.

  • payload – Optional data to pass to callbacks.

classmethod get_backend() str#

Get the tensor backend being used (“numpy” or “torch”).

classmethod get_device() str#

Get the physics simulation device.

classmethod get_physics_dt() float#

Get the physics timestep in seconds.

classmethod get_physics_sim_view() Any#

Get the physics simulation view. Override in subclasses.

classmethod get_simulation_time() float#

Get the current simulation time in seconds.

classmethod handles_decimation() bool#

True when step() executes the full decimation loop internally.

When this returns True the environment should call step() once per policy step instead of looping decimation times.

classmethod pause() None#

Pause physics simulation. Default is no-op.

classmethod play() None#

Start or resume physics simulation. Default is no-op.

classmethod pre_render() None#

Sync deferred physics state to the rendering backend.

Called by render() before cameras and visualizers read scene data. The default implementation is a no-op. Backends that defer transform writes (e.g. Newton’s dirty-flag pattern) should override this to flush pending updates.

classmethod register_callback(callback: Callable[[Any], None], event: PhysicsEvent, order: int = 0, name: str | None = None, wrap_weak_ref: bool = True) CallbackHandle#

Register a callback for a physics event.

Parameters:
  • callback – The callback function. Receives event payload as argument.

  • event – The event to listen for.

  • order – Priority order (lower = earlier). Default 0.

  • name – Optional name for debugging.

  • wrap_weak_ref – If True, wrap bound methods with weak references to prevent preventing garbage collection. Default True.

Returns:

CallbackHandle that can be used to deregister the callback.

Example

>>> def on_physics_ready(payload):
...     print("Physics is ready!")
>>> handle = PhysxManager.register_callback(on_physics_ready, PhysicsEvent.PHYSICS_READY)
>>> # Later, to remove:
>>> handle.deregister()
static safe_callback_invoke(fn: Callable, *args, physics_manager: type[PhysicsManager] | None = None) None#

Invoke a callback, catching exceptions that would be swallowed by external event buses.

Ignores ReferenceError (from garbage-collected weakref proxies). All other exceptions are forwarded to physics_manager.``store_callback_exception`` when available (see note below), or re-raised immediately otherwise.

Note (Octi):

The carb event bus used by PhysX/Omniverse silently swallows exceptions raised inside callbacks. PhysxManager works around this by storing the exception and re-raising it after event dispatch completes (in reset() / step()). Backends that dispatch events directly (e.g. Newton) don’t need this — exceptions propagate normally — so store_callback_exception is not called for them. This is a known wart; a cleaner solution is actively being explored.

classmethod set_decimation(decimation: int) None#

Inform the physics backend how many substeps the environment runs per policy step.

Backends that can fold the full decimation loop into a single step() call (e.g. Newton with all-graphable actuators) use this to size their internal loop / CUDA graph. The default implementation is a no-op.

Parameters:

decimation – Number of physics steps per environment step.

classmethod stop() None#

Stop physics simulation. Default is no-op.

classmethod video_capture_backend() str | None#

Return the video capture backend identifier for this physics manager.

Used by VideoRecorder to select how perspective video frames are captured when no visualizer is active.

Returns:

"kit" for backends that use Kit/Replicator (e.g. PhysxManager), "newton_gl" for backends that use a headless Newton GL viewer (e.g. NewtonManager), or None if the backend does not support perspective video capture.

classmethod wait_for_playing() None#

Block until the timeline is playing. Default is no-op.

Physics Configuration#

class isaaclab_ov.physics.OvPhysxCfg[source]#

Bases: PhysicsCfg

Configuration for the ovphysx physics manager.

PhysX scene-level parameters (solver iterations, GPU buffer sizes, etc.) are read from the USD PhysicsScene prim. Only ovphysx-specific settings that are not captured in USD live here.

Attributes:

class_type

The physics manager class to use.

enable_enhanced_determinism

Enable/disable improved determinism at the expense of performance.

enable_external_forces_every_iteration

Enable/disable external forces every position iteration in the TGS solver.

gpu_max_rigid_contact_count

Size of the GPU rigid-body contact buffer.

gpu_max_rigid_patch_count

Size of the GPU rigid-body patch buffer.

gpu_found_lost_pairs_capacity

Capacity for GPU found/lost broadphase pairs.

gpu_found_lost_aggregate_pairs_capacity

Capacity for GPU found/lost aggregate broadphase pairs.

gpu_total_aggregate_pairs_capacity

Capacity for total GPU aggregate broadphase pairs.

gpu_collision_stack_size

GPU collision stack size in bytes.

class_type: type[PhysicsManager] | Any#

The physics manager class to use. Must be set by subclasses.

enable_enhanced_determinism: bool#

Enable/disable improved determinism at the expense of performance. Defaults to False.

For more information on PhysX determinism, please check here.

enable_external_forces_every_iteration: bool#

Enable/disable external forces every position iteration in the TGS solver. Default is False.

This can help improve the accuracy of velocity updates. Consider enabling this flag if the velocities generated by the simulation are noisy.

gpu_max_rigid_contact_count: int#

Size of the GPU rigid-body contact buffer.

gpu_max_rigid_patch_count: int#

Size of the GPU rigid-body patch buffer.

gpu_found_lost_pairs_capacity: int#

Capacity for GPU found/lost broadphase pairs.

gpu_found_lost_aggregate_pairs_capacity: int#

Capacity for GPU found/lost aggregate broadphase pairs.

gpu_total_aggregate_pairs_capacity: int#

Capacity for total GPU aggregate broadphase pairs.

gpu_collision_stack_size: int#

GPU collision stack size in bytes.