You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Implement RigidObject and RigidObjectData for the OVPhysX backend, satisfying the BaseRigidObject and BaseRigidObjectData contracts. Mirrors PhysX RigidObject, substituting tensor views with ovphysx TensorBindings.
Reuse Warp kernels from Articulation (frame conversions, gravity projection)
Extend MockOvPhysxBindingSet for rigid body tensor types
Copy PhysX tests with config swap + add OVPhysX to interface tests
OVPhysX API Requirements
Needs RIGID_BODY_* TensorType variants (ROOT_POSE, ROOT_VELOCITY, MASS, COM_POSE, INERTIA) and a force/torque application API. If these don't exist yet in ovphysx, @marcodiiga needs to add them.
Implement RigidObject and RigidObjectData for the OVPhysX backend, satisfying the BaseRigidObject and BaseRigidObjectData contracts. The implementation mirrors the PhysX RigidObject, substituting PhysX tensor views with ovphysx TensorBindings. The existing OVPhysX Articulation (PR #4852) establishes all patterns to follow.
Validation environment:Isaac-Repose-Cube-Allegro-Direct-v0 — uses an Articulation (Allegro hand, already supported) and a RigidObject (DexCube). Getting this environment running end-to-end validates the RigidObject implementation.
Guiding Principles
Mirror PhysX structure. File layout, method signatures, and data flow should match the PhysX RigidObject as closely as possible.
Reuse Articulation patterns. The OVPhysX Articulation already implements lazy TensorBinding creation, DLPack zero-copy, CPU-only type routing, timestamped caching, and Warp kernel launches. Reuse these patterns identically.
Do not modify contracts.BaseRigidObject and BaseRigidObjectData must not be changed. If ovphysx lacks a needed API, flag it as a blocker for @marcodiiga.
Tests copied, only setup changes. PhysX tests are copied with config/backend swaps. Interface tests gain OVPhysX parametrization.
COM properties compose root link pose with body COM offset
OVPhysX API Requirements
The implementation needs these TensorType bindings from ovphysx:
TensorType
Shape
Device
Purpose
RIGID_BODY_ROOT_POSE
(N, 7)
GPU
Read/write root transforms
RIGID_BODY_ROOT_VELOCITY
(N, 6)
GPU
Read/write root velocities
RIGID_BODY_MASS
(N, 1)
CPU
Read/write masses
RIGID_BODY_COM_POSE
(N, 7)
CPU
Read/write center-of-mass poses
RIGID_BODY_INERTIA
(N, 9)
CPU
Read/write inertia tensors
Plus a force/torque application API:
add_forces_and_torques_index(forces, torques, indices) — or the ovphysx equivalent
Blocker for @marcodiiga: If RIGID_BODY_* TensorType variants don't exist yet in the ovphysx wheel, they need to be added. The Articulation uses ARTICULATION_* types. Check whether ovphysx already exposes rigid body bindings or whether this is new work.
Warp Kernels
Reuse existing kernels from the Articulation module where possible:
Kernel
Source
Purpose
set_root_link_pose_to_sim
assets/kernels.py
Convert link pose for sim write
set_root_com_pose_to_sim
assets/kernels.py
Convert COM pose for sim write
set_root_com_velocity_to_sim
assets/kernels.py
Convert COM velocity for sim write
get_root_link_vel_from_root_com_vel
assets/kernels.py
Frame velocity conversion
get_root_com_pose_from_root_link_pose
assets/kernels.py
Frame pose conversion
quat_apply_inverse_1D_kernel
assets/kernels.py
World-to-body frame rotation
root_heading_w
assets/kernels.py
Heading computation
If these kernels already exist in the Articulation's kernels.py, extract them to a shared assets/kernels.py (matching the PhysX pattern where both Articulation and RigidObject use the same assets/kernels.py).
Mock Infrastructure
Extend MockOvPhysxBindingSet in isaaclab_ovphysx/test/mock_interfaces/views/mock_ovphysx_bindings.py:
Add rigid body tensor types to the mock
Create MockRigidBodyBindingSet factory method that produces bindings with num_bodies=1, no joints
Summary
Implement
RigidObjectandRigidObjectDatafor the OVPhysX backend, satisfying theBaseRigidObjectandBaseRigidObjectDatacontracts. Mirrors PhysX RigidObject, substituting tensor views with ovphysx TensorBindings.Validation environment:
Isaac-Repose-Cube-Allegro-Direct-v0— Allegro hand (Articulation, already supported) + DexCube (RigidObject).Scope
rigid_object.py(~800 lines),rigid_object_data.py(~600 lines)MockOvPhysxBindingSetfor rigid body tensor typesOVPhysX API Requirements
Needs
RIGID_BODY_*TensorType variants (ROOT_POSE, ROOT_VELOCITY, MASS, COM_POSE, INERTIA) and a force/torque application API. If these don't exist yet in ovphysx, @marcodiiga needs to add them.Dependencies
Spec
Full design spec: `docs/superpowers/specs/2026-04-20-ovphysx-rigid-object-design.md`
Parent issue: #5315
📋 Full Design Spec (click to expand)
OVPhysX RigidObject + RigidObjectData — Design Spec
Issue: #5316 — [OVPHYSX] RigidObject asset
Date: 2026-04-20
Status: Draft
Summary
Implement
RigidObjectandRigidObjectDatafor the OVPhysX backend, satisfying theBaseRigidObjectandBaseRigidObjectDatacontracts. The implementation mirrors the PhysX RigidObject, substituting PhysX tensor views with ovphysx TensorBindings. The existing OVPhysX Articulation (PR #4852) establishes all patterns to follow.Validation environment:
Isaac-Repose-Cube-Allegro-Direct-v0— uses an Articulation (Allegro hand, already supported) and a RigidObject (DexCube). Getting this environment running end-to-end validates the RigidObject implementation.Guiding Principles
BaseRigidObjectandBaseRigidObjectDatamust not be changed. If ovphysx lacks a needed API, flag it as a blocker for @marcodiiga.Contract to Satisfy
BaseRigidObject (source/isaaclab/isaaclab/assets/rigid_object/base_rigid_object.py)
Abstract properties (7):
dataRigidObjectDatanum_instancesintnum_bodiesintbody_nameslist[str]root_viewinstantaneous_wrench_composerWrenchComposerpermanent_wrench_composerWrenchComposerAbstract methods — core (4):
reset(env_ids, env_mask) -> Nonewrite_data_to_sim() -> Noneupdate(dt: float) -> Nonefind_bodies(name_keys, preserve_order) -> (list[int], list[str])Abstract methods — root pose writers (6):
write_root_pose_to_sim_index(root_pose, env_ids) -> Nonewrite_root_pose_to_sim_mask(root_pose, env_mask) -> Nonewrite_root_com_pose_to_sim_index(root_pose, env_ids) -> Nonewrite_root_com_pose_to_sim_mask(root_pose, env_mask) -> Nonewrite_root_link_pose_to_sim_index(root_pose, env_ids) -> Nonewrite_root_link_pose_to_sim_mask(root_pose, env_mask) -> NoneAbstract methods — root velocity writers (6):
write_root_velocity_to_sim_index(root_velocity, env_ids) -> Nonewrite_root_velocity_to_sim_mask(root_velocity, env_mask) -> Nonewrite_root_com_velocity_to_sim_index(root_velocity, env_ids) -> Nonewrite_root_com_velocity_to_sim_mask(root_velocity, env_mask) -> Nonewrite_root_link_velocity_to_sim_index(root_velocity, env_ids) -> Nonewrite_root_link_velocity_to_sim_mask(root_velocity, env_mask) -> NoneAbstract methods — body property setters (6):
set_masses_index(masses, body_ids, env_ids) -> Noneset_masses_mask(masses, body_mask, env_mask) -> Noneset_coms_index(coms, body_ids, env_ids) -> Noneset_coms_mask(coms, body_mask, env_mask) -> Noneset_inertias_index(inertias, body_ids, env_ids) -> Noneset_inertias_mask(inertias, body_mask, env_mask) -> NoneAbstract methods — deprecated state writers (3):
write_root_state_to_sim(root_state, env_ids) -> Nonewrite_root_com_state_to_sim(root_state, env_ids) -> Nonewrite_root_link_state_to_sim(root_state, env_ids) -> NoneInternal hooks (3):
_initialize_impl_create_buffers_process_cfgBaseRigidObjectData (source/isaaclab/isaaclab/assets/rigid_object/base_rigid_object_data.py)
Abstract properties (~40): Root state (pose, velocity in link/com/actor frames), body state (pose, velocity, acceleration), body properties (mass, inertia, com), derived quantities (projected_gravity, heading, body-frame velocities), sliced components (pos, quat, lin_vel, ang_vel extracted from compound types).
Abstract method (1):
update(dt: float) -> NoneAll properties use warp types:
wp.transformf,wp.spatial_vectorf,wp.vec3f,wp.quatf,wp.float32.Architecture
File Layout
No separate
kernels.py— reuse kernels from the articulation module or from a sharedassets/kernels.py(same as PhysX pattern).Implementation Pattern
Follow the existing Articulation exactly:
rigid_object.py:
_initialize_impl():RigidObjectDatawith lazy binding getter (_get_binding)_create_buffers(),_process_cfg(),update(0.0)data.is_primed = True_get_binding(tensor_type):TensorType_bindingsdictRoot state writers (index variants):
_to_flat_f32()write_root_pose_to_sim_index: write viaRIGID_BODY_ROOT_POSEbindingwrite_root_link_pose_to_sim_index: compose with COM offset, then writewrite_root_com_pose_to_sim_index: decompose to link frame, then writeRoot state writers (mask variants):
write_data_to_sim():reset():rigid_object_data.py:
RIGID_BODY_ROOT_POSEandRIGID_BODY_ROOT_VELOCITYbindingsprojected_gravity_b:quat_apply_inverse(quat, gravity_vec)heading_w:atan2(forward_x, forward_y)from root orientationroot_link_lin_vel_b:quat_apply_inverse(quat, lin_vel_w)root_link_ang_vel_b:quat_apply_inverse(quat, ang_vel_w)OVPhysX API Requirements
The implementation needs these TensorType bindings from ovphysx:
RIGID_BODY_ROOT_POSE(N, 7)RIGID_BODY_ROOT_VELOCITY(N, 6)RIGID_BODY_MASS(N, 1)RIGID_BODY_COM_POSE(N, 7)RIGID_BODY_INERTIA(N, 9)Plus a force/torque application API:
add_forces_and_torques_index(forces, torques, indices)— or the ovphysx equivalentBlocker for @marcodiiga: If
RIGID_BODY_*TensorType variants don't exist yet in the ovphysx wheel, they need to be added. The Articulation usesARTICULATION_*types. Check whether ovphysx already exposes rigid body bindings or whether this is new work.Warp Kernels
Reuse existing kernels from the Articulation module where possible:
set_root_link_pose_to_simassets/kernels.pyset_root_com_pose_to_simassets/kernels.pyset_root_com_velocity_to_simassets/kernels.pyget_root_link_vel_from_root_com_velassets/kernels.pyget_root_com_pose_from_root_link_poseassets/kernels.pyquat_apply_inverse_1D_kernelassets/kernels.pyroot_heading_wassets/kernels.pyIf these kernels already exist in the Articulation's
kernels.py, extract them to a sharedassets/kernels.py(matching the PhysX pattern where both Articulation and RigidObject use the sameassets/kernels.py).Mock Infrastructure
Extend
MockOvPhysxBindingSetinisaaclab_ovphysx/test/mock_interfaces/views/mock_ovphysx_bindings.py:MockRigidBodyBindingSetfactory method that produces bindings withnum_bodies=1, no jointsTests
Backend-specific tests (copy from PhysX)
Source:
source/isaaclab_physx/test/assets/test_rigid_object.pyTarget:
source/isaaclab_ovphysx/test/assets/test_rigid_object.pyChanges from PhysX version:
PhysxCfgwithOvPhysxCfgin simulation configInterface tests (add OVPhysX parametrization)
File:
source/isaaclab/test/assets/test_rigid_object_iface.pyAdd OVPhysX as a parametrized backend alongside PhysX and Newton:
"ovphysx"to the backend parametrize listtest_articulation_iface.pywhich already has OVPhysXValidation
Target environment
Isaac-Repose-Cube-Allegro-Direct-v0This environment uses:
Validation steps:
Test commands
Dependencies
Estimated Scope
rigid_object.py: ~800 lines (PhysX is ~1000, OVPhysX Articulation patterns reduce boilerplate)rigid_object_data.py: ~600 lines (PhysX is ~800)kernels.pychanges: extract shared kernels if not already shared