Clean up OVPhysX assets to match PhysX/Newton style#12
Draft
AntoineRichard wants to merge 106 commits into
Draft
Clean up OVPhysX assets to match PhysX/Newton style#12AntoineRichard wants to merge 106 commits into
AntoineRichard wants to merge 106 commits into
Conversation
Add nine RIGID_BODY_* aliases to isaaclab_ovphysx.tensor_types covering the rigid-actor root pose/velocity/acceleration, wrench application, and mass/inertia/COM properties. Each alias carries a shape/units docstring that Sphinx autoattribute can pick up. Extend _CPU_ONLY_TYPES with the five CPU-routed rigid-body variants so the existing GPU/CPU dispatch in _to_flat_f32 routes them correctly. Direct imports (no shim) intentionally couple this package to a future ovphysx wheel that exposes the matching TensorType enum values; see docs/superpowers/specs/2026-04-27-ovphysx-rigid-body-tensortypes-gap.md. Issue: isaac-sim#5316
Move kernels reused across multiple asset types from isaaclab_ovphysx.assets.articulation.kernels into a new isaaclab_ovphysx.assets.kernels module: _body_wrench_to_world, _scatter_rows_partial, _copy_first_body, _compose_root_com_pose, _projected_gravity, _compute_heading, _world_vel_to_body_lin, _world_vel_to_body_ang. Articulation-only kernels (joint-limit setup, FD joint acceleration, multi-body COM compose) stay in articulation/kernels.py. Articulation modules update their imports accordingly. No behavior change. This refactor unblocks the upcoming RigidObject implementation, which needs the same kernels for frame conversions and wrench packing. Issue: isaac-sim#5316
Generalize the mock binding factory to produce a rigid-object-shaped binding set (RIGID_BODY_* keys only, num_joints=0, num_bodies=1, no tendons) when called with asset_kind='rigid_object'. Default behavior is unchanged: existing articulation callers do not need updates. Make set_random_data tolerant of the smaller binding set so it works for both asset kinds. Issue: isaac-sim#5316
Add the rigid_object sub-package and the RigidObjectData class skeleton with constructor, count properties, update/invalidate hooks, and _process_cfg that fills _default_root_pose / _default_root_velocity from cfg.init_state. Add the backend-specific test file with a hasattr-based wheel gate (importorskip-then-attr on the module would AttributeError rather than skip when RIGID_BODY_* enums are absent on the wheel) and a basic-counts smoke test. Issue: isaac-sim#5316
Address review blockers on commit 65084f7: 1. _process_cfg now mirrors the articulation pattern (wp.zeros to pre-allocate, then wp.copy from wp.from_numpy with the typed dtype directly — matching articulation._process_cfg verbatim), avoiding the use-after-free that the previous reinterpret-cast-from-local idiom introduced when the float32 source went out of scope. 2. is_primed is now a guarded @Property + setter that enforces the one-way gate (False->True allowed, True->True idempotent, True->False raises ValueError), matching every other *Data class. 3. Drop unused forward-reference imports from test/assets/test_rigid_object.py so ruff/F401 passes; subsequent tasks will re-add them when the symbols are actually used. Issue: isaac-sim#5316
Replace the abstract-property stubs for root_link_pose_w, root_link_vel_w, root_com_pose_w, root_com_vel_w, and the per-axis sliced views (root_link_pos_w, root_link_quat_w, root_lin_vel_w, root_ang_vel_w, plus their root_com_* counterparts) with concrete implementations that lazy-read from RIGID_BODY_ROOT_POSE / RIGID_BODY_ROOT_VELOCITY through TensorBindings, cache for the rest of the sim step, and expose slices as zero-copy Warp views over the canonical pose/velocity buffers. Mirrors the articulation_data lazy-read + ProxyArray + sliced-view idioms with num_bodies=1 (root pose/velocity are 1-D over instances, with no body axis). Issue: isaac-sim#5316
The per-property TimestampedBuffer.timestamp fields are the freshness gate consulted by every lazy-read property. _invalidate_caches was previously clearing only the legacy _timestamps dict, leaving the buffers with their last-read timestamp; a property accessed within the same sim step (e.g. immediately after RigidObject.reset and before update(dt) advances _sim_time) would serve pre-reset data. Reset every allocated buffer's timestamp to -1.0 in _invalidate_caches so the next property access always re-reads from the binding regardless of where _sim_time stands. Add a regression test that mutates the binding in place + calls _invalidate_caches without advancing _sim_time and asserts the next read reflects the new value. Issue: isaac-sim#5316
Replace the abstract-property stubs for the body-state singleton-dim
views (body_link_pose_w, body_com_pose_w, body_*_vel_w, body_*_pos_w,
body_*_quat_w, body_*_lin_vel_w, body_*_ang_vel_w), the body
acceleration (body_link_acc_w, body_com_acc_w, plus their _lin_*/
_ang_* slices) gated on the RIGID_BODY_ACCELERATION binding, and the
body-frame derived properties (projected_gravity_b, heading_w,
root_link_lin_vel_b, root_link_ang_vel_b, root_com_lin_vel_b,
root_com_ang_vel_b).
Body-state views are zero-copy reshapes of the (N,) root buffers into
(N, 1, k) — no compute kernel needed when num_bodies=1. Body
acceleration raises NotImplementedError with a pointer to the gap
spec if the wheel lacks RIGID_BODY_ACCELERATION. Derived properties
launch the relocated _projected_gravity / _compute_heading /
_world_vel_to_body_{lin,ang} kernels from
isaaclab_ovphysx.assets.kernels.
Extend _invalidate_caches with the new TimestampedBuffer instances so
they participate in coarse cache invalidation.
Issue: isaac-sim#5316
The IsaacLab projected_gravity_b convention (per BaseRigidObjectData docstring "Projection of the gravity direction on base frame", and matching ArticulationData which normalizes gravity_np / gravity_mag before storing GRAVITY_VEC_W) is the unit direction, not the signed-magnitude. The Task 6 test assertion expected -9.81 (signed magnitude); the kernel correctly produces -1.0 (unit z-component of the gravity direction). Update the assertion and the inline comment so the test reflects the documented contract. Issue: isaac-sim#5316
Replace the abstract-property stubs for body_mass, body_inertia, and body_com_pose_b with concrete CPU-side lazy-read implementations backed by RIGID_BODY_MASS / RIGID_BODY_INERTIA / RIGID_BODY_COM_POSE bindings. Also implement body_com_pos_b and body_com_quat_b as zero-copy slice views of body_com_pose_b's transformf buffer. Properties read once on first access, cache as semi-static, and invalidate via the _invalidate_caches reset loop (driven by RigidObject mass/COM/inertia setters). Mirrors the articulation_data pattern adapted for num_bodies = 1. Issue: isaac-sim#5316
Add RigidObject class with __init__, _initialize_impl, _get_binding, and count/data accessor properties. Eagerly creates GPU bindings for RIGID_BODY_ROOT_POSE / RIGID_BODY_ROOT_VELOCITY / RIGID_BODY_WRENCH so binding-creation failures surface at init time with a clear message pointing at the gap spec. _create_buffers and _process_cfg are placeholder no-ops; Task 9 replaces them. Write paths, reset, update, find_bodies, and the deprecated state writers come in subsequent tasks (10-13). Abstract methods that must be satisfied to instantiate the class are stubbed with NotImplementedError pending those tasks. Issue: isaac-sim#5316
Renames per Marco's feedback: RIGID_BODY_ROOT_POSE -> RIGID_BODY_POSE and RIGID_BODY_ROOT_VELOCITY -> RIGID_BODY_VELOCITY throughout. "Root" is articulation vocabulary; a standalone rigid body IS the body. Shape correction: RIGID_BODY_MASS and RIGID_BODY_INV_MASS ship as (N,) not (N, 1). MockOvPhysxBindingSet allocates (N,) for both; rigid_object_data.py's body_mass property consumes (N,) and exposes (N, 1) via zero-copy reshape to satisfy the BaseRigidObjectData contract. Soften _initialize_impl error: removes the prescriptive "NOT under an articulation root" language since pattern- resolution gating is a future wheel-side selection policy. Pre-existing ruff E501 in write_root_link_state_to_sim docstring fixed as collateral.
Allocate _ALL_INDICES, _ALL_BODY_INDICES, their Warp views, the single-body (N, 1, 9) _wrench_buf staging buffer, and the instantaneous/permanent wrench composers. _process_cfg delegates to RigidObjectData._process_cfg. Issue: isaac-sim#5316
Add the twelve root-state writers (pose+velocity, actor+link+com, index+mask variants) on RigidObject, plus the shared _to_flat_f32 and _write_root_state helpers ported from articulation. Frame-conversion variants launch the relocated assets/kernels.py kernels before the binding write. Add the three deprecated compound state writers that emit DeprecationWarning and delegate to the split pose+velocity writers. Add _compose_root_link_pose_from_com kernel to assets/kernels.py to support COM->link pose inversion on the write path: link_pose = com_pose_w * inverse(com_pose_b) Issue: isaac-sim#5316
Add set_masses_{index,mask}, set_coms_{index,mask},
set_inertias_{index,mask}. Each writes through the matching
CPU-routed RIGID_BODY_* binding via _write_root_state, then
invalidates the corresponding RigidObjectData cache via
_invalidate_caches.
body_ids / body_mask parameters are accepted for parity with the
BaseRigidObject contract but unused (num_bodies = 1).
Extend _write_root_state to handle 1-D bindings (RIGID_BODY_MASS)
by detecting them and bypassing the 2-D scatter kernel path.
Issue: isaac-sim#5316
Compose instantaneous + permanent wrenches, rotate body-frame force/torque to world frame via _body_wrench_to_world (dim=(N, 1)), reshape the (N, 1, 9) staging buffer to (N, 9) zero-copy, write to RIGID_BODY_WRENCH, reset the instantaneous composer. Issue: isaac-sim#5316
Replace stubs for reset, update, and find_bodies. reset writes the default pose/velocity to the specified envs via zero-copy flat float32 views of the typed wp.transformf/wp.spatial_vectorf defaults, resets both wrench composers, and invalidates the data caches. update delegates to RigidObjectData.update. find_bodies handles the None (all bodies) fast path and delegates regex matching to resolve_matching_names for non-None inputs. The deprecated compound state writers were already implemented in Task 10 alongside the split-form writers and are not touched here. Issue: isaac-sim#5316
Add the rigid_object/__init__.pyi stub mirroring the articulation sibling, and extend isaaclab_ovphysx.assets/__init__.pyi to include RigidObject and RigidObjectData. Public imports now resolve via ``from isaaclab_ovphysx.assets import RigidObject, RigidObjectData``. Issue: isaac-sim#5316
Add the import-guarded BACKENDS.append('ovphysx') block, the
create_ovphysx_rigid_object factory, and the dispatch case so the
existing parametrized interface tests automatically cover the new
backend. Mirrors the OVPhysX articulation parametrization in
test_articulation_iface.py.
Issue: isaac-sim#5316
Mirror the Cartpole/Ant pattern by adding ovphysx variants to ObjectCfg (RigidObjectCfg using the same DexCube spawn as the physx variant) and to PhysicsCfg (OvPhysxCfg()). Default backend remains physx; existing PhysX/Newton paths are unchanged. This wires Isaac-Repose-Cube-Allegro-Direct-v0 for OVPhysX validation via ./scripts/run_ovphysx.sh source/isaaclab_tasks/isaaclab_tasks/ direct/allegro_hand/allegro_hand_env.py --num_envs 4 --headless once the wheel ships. Issue: isaac-sim#5316
Add the 0.2.0 changelog entry on isaaclab_ovphysx covering the new RigidObject/RigidObjectData classes, the RIGID_BODY_* TensorType aliases (six already-shipping + three pending wheel update), the mock-binding asset_kind extension, and the assets/kernels.py kernel relocation. Bump the matching extension.toml version. Add a patch-bump changelog entry on isaaclab_tasks for the Allegro env preset addition. Issue: isaac-sim#5316
The ovphysx wheel currently exposes 6 of the 9 RIGID_BODY_* TensorType enums (POSE, VELOCITY, WRENCH, MASS, COM_POSE, INERTIA). The remaining three (ACCELERATION, INV_MASS, INV_INERTIA) are pending an upcoming wheel update from @marcodiiga. Make the IsaacLab side wheel-update-agnostic: * Guard tensor_types.py imports of the three not-yet-shipping aliases with try/except AttributeError so isaaclab_ovphysx.tensor_types imports cleanly on today's wheel. _CPU_ONLY_TYPES filters to only the names that exist via _RIGID_BODY_OPTIONAL_CPU. * MockOvPhysxBindingSet skips the optional bindings when their alias is not defined. * RigidObjectData.body_*_acc_w now finite-differences from body_com_vel_w, mirroring Newton's pattern (kernel derive_body_acceleration_from_body_com_velocities ported into isaaclab_ovphysx.assets.kernels). Removes the NotImplementedError-on-missing-binding fallback. * update(dt) stores _last_dt and eagerly triggers body_com_acc_w each step so FD captures every transition. The forward-compat aliases stay declared (Marco will land them); when they ship, the existing TensorBinding read path will work without further IsaacLab changes. Issue: isaac-sim#5316
WrenchComposer.__init__ calls hasattr(asset.data, "body_com_pos_w"), which triggers the property chain body_com_pos_w → body_com_pose_w → root_com_pose_w, reading the RIGID_BODY_COM_POSE binding and setting _body_com_pose_b_buf.timestamp = _sim_time = 0.0. Any subsequent mutation of the binding (e.g. set_coms_index, or a test that sets the binding directly) is then invisible to _com_pose_to_link_pose because the freshness gate ``buf.timestamp >= _sim_time`` treats 0.0 ≥ 0.0 as "already fresh" and skips the read — returning stale buffer contents to the frame-conversion kernel and producing an off-by-translation result. Force a fresh read in _com_pose_to_link_pose by resetting the buffer timestamp to -1.0 immediately before calling _read_transform_binding. The frame conversion always needs the current binding value at write time; the lazy-cache is the wrong policy here. Caught by test_write_root_com_pose_to_sim_index_invokes_frame_conversion. Issue: isaac-sim#5316
When running via ./scripts/run_ovphysx.sh, the test file's unconditional AppLauncher call segfaults during pytest collection because the script's thin Kit shell (libcarb preload only, no full Kit boot) cannot host a real AppLauncher. Mirror the _kitless heuristic from test_articulation_iface so the rigid-object iface tests skip AppLauncher and substitute MagicMock isaacsim core modules in the same scenarios. The original _kitless heuristic (LD_PRELOAD == "" and EXP_PATH not set) was also incorrect for this environment: run_ovphysx.sh sets LD_PRELOAD to the ovphysx libcarb.so path, not an empty string. Fix the heuristic in both test files to check for "ovphysx" in LD_PRELOAD as the primary signal, with the bare-Python fallback retained as a secondary guard. Also extend the kitless sys.modules stub list to cover omni.physics.tensors and related Kit modules that physx_manager.py imports at module scope, which would otherwise cause a ModuleNotFoundError during collection. This unblocks running the OVPhysX-parametrized parts of the file via run_ovphysx.sh. PhysX/Newton/Mock paths are unaffected. Issue: isaac-sim#5316
Three related bugs were present in the OVPhysX RigidObject body-property write path, all contributing to the 120 test failures. First, _write_root_state's full-write path (no env_ids, no mask) had no row-count validation for 1-D bindings such as RIGID_BODY_MASS. Passing a tensor with more rows than num_instances silently reached the mock's numpy reshape and raised ValueError, but the test infrastructure expected AssertionError or RuntimeError. An explicit row-count guard now raises RuntimeError on the full-write path before any binding call. Second, the index/mask sub-write path for 1-D bindings passed the source array to binding.write() as a 2-D (K, 1) buffer (the raw shape produced by _to_flat_f32 when the caller supplies (K, 1) torch data). For the mask path this caused NumPy boolean-index assignment to fail with TypeError because it cannot scatter a 2-D array into a 1-D binding buffer. The 1-D source is now normalised to shape (K,) via a zero-copy warp array view before any write. Third, write_root_com_pose_to_sim_index and write_root_com_pose_to_sim_mask silently truncated oversized inputs inside _com_pose_to_link_pose, which hardcodes shape=(N,) for the intermediate warp array view regardless of the input size. This masked shape errors on full writes. Explicit row-count guards are now applied at the public API entry points for these two methods. Additionally, default_root_pose and default_root_vel in RigidObjectData were NotImplementedError stubs. They are now implemented to return ProxyArray wrappers over the _default_root_pose/_default_root_velocity buffers that are already populated during _process_cfg. Caught by the cross-backend TestRigidObjectWritersBody tests against the OVPhysX backend. After the fix all 372 ovphysx-parametrized cases pass. Issue: isaac-sim#5316
The mock-based test file is removed in favor of a copy of PhysX's test_rigid_object.py adapted to the kitless OVPhysX architecture: - Drop AppLauncher; mock the isaacsim and omni.* modules instead so the file imports under run_ovphysx.sh without launching Kit. - Build the test scene via MockOvPhysxBindingSet, bypassing OvPhysxManager entirely (no Kit stage export needed). - Drive sim steps via direct binding manipulation; no build_simulation_context. - Programmatically construct rigid-object shells instead of pulling DexCube USD from Nucleus. Tests that exercise OVPhysX features not yet wired (OvPhysxManager step loop, contact materials, kitless stage entry point) are explicitly xfail-marked with inline reasons. Result: 67 passed, 73 xfailed, 0 failed. See docs/superpowers/specs/2026-04-28-ovphysx-rigid-object-test-gaps.md (worktree-only, gitignored) for the consolidated gap list for Marco.
OvPhysxManager IS drivable without AppLauncher: _warmup_and_load only needs PhysicsManager._sim.stage + a couple of cfg fields, which a thin SimpleNamespace fake satisfies. Use this to convert the warmup and stage-load xfails into real-backend tests against the live ovphysx.PhysX instance. Adds _make_kitless_sim_context() helper (builds in-memory USD stage with RigidBodyAPI + CollisionAPI cube + PhysicsScene, wraps in SimpleNamespace exposing: stage, cfg.physics, cfg.device, cfg.physics_prim_path, cfg.enable_scene_query_support, cfg.dt) and a module-scoped kitless_manager_cpu fixture that drives initialize() + reset() + close(). Converts test_warmup_attach_stage_not_called_for_cpu (1 xfail) to three passing real-backend tests: - test_warmup_and_load_cpu: lifecycle assertions - test_warmup_gpu_not_called_for_cpu: CPU path skips warmup_gpu - test_stage_load_cpu: stage export + usd_handle type check Adds test_warmup_and_load_gpu as xfail pending a GPU CI runner. Result: 70 passed, 73 xfailed (was 67 passed, 73 xfailed). Update the test-gaps doc to reflect the closed gap (no wheel change required for this category). Issue: isaac-sim#5316
Drop the kitless mocks, the SimpleNamespace sim-context fake, and the MockOvPhysxBindingSet shell-injection helpers. The standard SimulationContext + UsdFileCfg(ISAAC_NUCLEUS_DIR/...) pattern works under ./scripts/run_ovphysx.sh without AppLauncher — omni.client resolves Nucleus URLs from Kit's Python directly, and SimulationContext runs kitless via has_kit() returning False. Tests now exercise real RigidObject + RigidObjectData + OvPhysxManager against live ovphysx.PhysX bindings, using the same Nucleus assets the Cartpole/Newton tests use. Material-properties tests stay xfailed pending a wheel-side RIGID_BODY_MATERIAL TensorType. GPU tests now pass (NVIDIA RTX 5000 Ada verified). Production bug surfaced: RigidObject._initialize_impl uses hasattr() on TensorBinding.body_names which propagates RuntimeError (not AttributeError), blocking all RigidObject lifecycle tests against the real backend. Fix: wrap in try/except (AttributeError, RuntimeError). Tracking: issue isaac-sim#5316. Issue: isaac-sim#5316
The previous ``hasattr(root_pose, "body_names")`` gate only catches AttributeError, but the real ovphysx TensorBinding raises TypeError on the body_names property for non-articulation tensor types such as RIGID_BODY_POSE: "Articulation metadata … is not available for tensor type 'RIGID_BODY_POSE'." Replace with try/except that catches both AttributeError and TypeError; fall back to ["base_link"]. Also fix self._device derivation: ``hasattr(self._ovphysx, "device")`` always returns False for the real PhysX object (no .device property), so the device silently fell back to "cuda:0" even when the simulation runs on CPU, causing a device mismatch in TensorBinding.read(). Use OvPhysxManager.get_device() which mirrors SimulationContext.cfg.device. Un-xfail 68 of the 70 tests tagged _INIT_IMPL_BUG in test_rigid_object.py — they now run cleanly against the live ovphysx CPU backend (59 passed). The two remaining xfails use a tightened reason (_FORCE_BALANCE_GAP): test_external_force_on_single_body drifts ~0.57 m instead of < 0.1 m, a physics-accuracy gap under investigation. Issue: isaac-sim#5316
Rewrites test_external_force_on_single_body to mirror Newton's reference implementation: 5 outer iterations with a full pose/velocity reset between each, 5 inner sim steps per iteration, force applied to every 2nd cube (indices 0::2), and alternating global/local frame each outer iteration. The old test used a single 20-step loop on env_0 only, with no resets and no is_global argument — causing error accumulation and the ~0.57 m drift. Because RigidObjectData._bindings has no RIGID_BODY_MASS entry at init time, body_mass.torch returns zeros; the USD-stage MassAPI value is read instead. The per-block drift is ~6 mm vs ~35 mm free-fall, well within the atol=1e-2 guard, so the xfail decorator is removed.
… ProxyArray Allocate default_body_pose and default_body_vel buffers as zero-initialized (N, B)-shaped wp.transformf and wp.spatial_vectorf arrays in _create_buffers. Wire the property getters to return lazy ProxyArray wrappers, matching Articulation's pattern. Remove placeholder assignments from __init__.
…API" This reverts commit eed7c31.
…dAdapter The previous implementation created bindings with ARTICULATION_LINK_POSE (and other ARTICULATION_* types), which only match articulations. Against real OVPhysX 0.4 bindings on non-articulated rigid bodies the binding count came back as 0, causing wp.zeros((0, B), transformf) to allocate a zero-size array with ptr=None, triggering a TypeError when body_link_quat_w tried to offset the pointer. Replace the broken ARTICULATION_* bindings with one RIGID_BODY_* binding per body type per tensor type (using the existing per-body glob patterns), then wrap the B per-body (N, D) bindings in a new _FusedRigidBodyBinding adapter that presents the (N, B, D) interface the data class and write helpers expect. The adapter is device-aware: read/write staging buffers are allocated on the same device as the destination to avoid cross-device copies for CPU-only quantities (mass, COM pose, inertia). The data-class dict keys (TT.LINK_POSE, TT.BODY_MASS, etc.) are unchanged, so the articulation-mode mocks used by the 636 iface tests continue to work without modification.
…s and fix stale buffer timestamps Rename _ALL_INDICES_ENV/_ALL_INDICES_BODY → _ALL_ENV_INDICES/_ALL_BODY_INDICES to match the PhysX naming convention (fixes test_id_conversion). Add resolve_view_ids Warp kernel to shared assets/kernels.py and implement _env_body_ids_to_view_ids on the OVPhysX class using body-major ordering (view_id = body_id * num_instances + env_id). Mark _body_link_pose_w and _body_com_vel_w buffers as fresh (timestamp = _sim_timestamp) immediately after kernel writes in write_body_link_pose_to_sim_index and write_body_com_velocity_to_sim_index, preventing spurious re-reads from OVPhysX that returned post-step values and caused ~0.02–0.04 m position drift in test_set_object_state.
Replace the per-body fan-out adapter with a single fused TensorBinding per tensor type, created via ``create_tensor_binding(prim_paths=[...])`` (introduced in ovphysx 0.4.3). Each binding now spans all ``num_instances * num_bodies`` prims and returns data in body-major flat order ``(body0_env0, body0_env1, ..., body1_env0, ...)``. The data class and asset writers use strided-view reshape helpers ``_reshape_view_to_data_2d/_3d`` and ``reshape_data_to_view_2d/_3d`` (ported from the PhysX collection) to convert between the body-major view layout and the instance-major ``(N, B, D)`` layout exposed to users. The articulation-mode mock used by interface tests keeps emitting instance-major shapes; the read/write paths disambiguate via the binding's exposed ``shape`` so both layouts coexist. The ``_FusedRigidBodyBinding`` adapter class and its per-body Python staging are removed.
…idObject/Articulation)
Replace `# ----` section banners with the triple-quoted section markers used by PhysX/Newton, move the deprecated `write_root_*_state_to_sim` writers below the simulation callbacks, and tighten the internal-helper docstrings. Also strips Step-N narrative comments and "mirrors PhysX" dev-cruft so the file reads like the reference backends. No behavior change.
Use the same `Articulation-specific warp functions/kernels` section headers, drop the verbose absent-kernel module docstring, and tighten kernel docstrings to match PhysX conventions (SI units in `[unit]` notation, full Args sections with shapes, `:paramref:` instead of `:attr:` for kernel arguments). No behavior changes; kernel names and import paths are unchanged.
Reorder the public Articulation properties to match the PhysX/Newton section ordering (data, num_instances, is_fixed_base, num_joints, num_fixed_tendons, num_spatial_tendons, num_bodies, joint_names, fixed_tendon_names, spatial_tendon_names, body_names, root_view, *_wrench_composer). Align find_*, reset, write_data_to_sim, and _initialize_impl docstrings/comments with the PhysX style: * drop the verbose `Step N:` annotations from `_initialize_impl`, keeping only WHY-comments around non-obvious invariants * remove `# Mirrors PhysX (articulation.py:NNN)` line-number cross-references that aged poorly * tighten `reset`, `write_data_to_sim`, and `update` docstrings to match the PhysX wording No behavior changes.
Replace the OVPhysX-implementation-flavored module docstring and class
docstring with the same domain-level prose used by the PhysX/Newton
ArticulationData, plus an OVPhysX-specific note about pinned-host CPU
staging for CPU-only bindings. Reword internal `__init__` comments to
drop dev-cruft references ("post-audit RigidObjectData demotion",
"PR isaac-sim#5329 pattern") and group fields the way PhysX does (timestamp,
constants, buffers). Reword `update()` to mirror PhysX phrasing.
No behavior changes.
Drop the OVPhysX-specific class docstring, module docstring, and ``mirror PhysX`` cruft comments. Use the triple-quoted section markers (``Properties`` / ``Operations.``) used by PhysX/Newton in place of ``# ----`` dashed banners, restore the per-property one-line docstrings on ``num_bodies``/``body_names``, and rewrite ``reset()``'s docstring to match the base contract.
Drop the dashed ``Pose writers (3 pairs)`` banner in favor of the ``Operations - Finders.`` and ``Operations - Write to simulation.`` markers used by PhysX/Newton. Fill in update()'s docstring and clean up the disambiguation comment in write_data_to_sim.
Replace the OVPhysX-implementation-flavored module/class docstring with the same domain-level prose used by the PhysX and Newton Articulation classes, plus a short OVPhysX-specific paragraph about per-tensor-type ``TensorBinding`` objects and pinned-host CPU staging. Drop "the wheel" backend-internal slang from comments and docstrings in favor of "binding" / "simulation". Remove leftover "PR isaac-sim#5329 pattern" references and other dev cruft. No behavior changes.
PhysX/Newton order the wrappers as pose-pair then velocity-pair before the link/com specialisations; OVPhysX previously kept velocity-wrappers down with the link/com velocity setters. Bring the order in line with the reference backends.
Swap link/com velocity setter blocks so center-of-mass comes first (PhysX/Newton order). Strip the dashed ``Property setters (3 pairs)`` banner, drop ``# type: ignore[override]`` decorators on the velocity setters, and replace narrative ``# Push updated COM velocities to simulation`` / ``# Invalidate dependent timestamps so the next read recomposes them`` comments with the terse PhysX-style ``# set into simulation`` / ``# Invalidate dependent timestamps``.
Replace the OVPhysX-implementation-flavored module/class docstring with the domain-level prose used by the PhysX and Newton Articulation classes, plus a short OVPhysX-specific paragraph about per-tensor-type ``TensorBinding`` objects and pinned-host CPU staging. Add the pyright header that the PhysX/Newton files carry.
Drop ``# type: ignore[override]`` decorators and tighten the narrative ``# Mark the pose buffer as fresh...`` / ``# Push updated link poses to simulation via single fused binding`` comments to the terse PhysX-style ``# set into simulation`` / ``# Invalidate dependent timestamps`` markers on the link/com pose setters.
Drop ``# type: ignore[override]`` from the pose-wrapper methods and property setters, and remove the ``For rigid bodies the actor frame coincides with the link frame, so this delegates to ...`` note that duplicates information already in the base class contract.
PhysX and Newton keep deprecated ``write_body_*_state_to_sim`` methods at the very end of the class behind a ``Deprecated properties and methods.`` section marker. Mirror the layout in OVPhysX and trim the redundant ``# Convert wp.array to torch.Tensor for slicing.`` what-comments.
Use ``Helper functions.`` / ``Internal helper.`` / ``Internal simulation callbacks.`` markers (PhysX/Newton style) in place of the ``# ----`` dashed banners, and strip the ``(mirrors PhysX)`` / ``(mirrors PhysX collection)`` parenthetical cruft on the docstrings and inline comments.
Drop the OVPhysX-specific module docstring and ``Single fused binding.`` note; reuse the PhysX class docstring (including the ProxyArray pointer-stability note) so the OVPhysX data container reads like the reference. Also tighten the constructor inline comments away from full sentences with end punctuation.
Drop the ``# ----`` dashed section banners in favor of the triple-quoted ``Names.`` / ``Defaults.`` / ``Body state properties.`` / ``Derived Properties.`` / ``Sliced properties.`` / ``Helpers.`` section markers used by PhysX/Newton. Also strip the ``Mirrors RigidObject``/``Mirrors Articulation`` cruft narrative in ``update()``, ``_pin_proxy_arrays`` and ``_get_binding``.
2af401f to
920f2a6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Polish pass on the three OVPhysX backend assets (
articulation,rigid_object,rigid_object_collection) to align their structure, ordering, docstrings, and comments with the PhysX and Newton backends. No behavior changes — only style, layout, and documentation.Stacked on top of isaac-sim#5570 (
antoiner/feat/ovphysx_rigidobjectcollection).Highlights:
# ----dashed section banners with the PhysX-style triple-quoted section markers ("""Properties.""","""Operations.""", …).write_*_state_to_simwriters moved to the bottom of each class).__init__docstrings to use the same domain-level prose as PhysX/Newton, with an OVPhysX-specific note where binding semantics differ.Args:with shapes and SI[unit]notation, and:paramref:for kernel arguments.# Step N,(mirrors PhysX line NNN),(mirrors Articulation), and other PR-iteration dev cruft. Kept WHY-comments and non-obvious invariants.Optional/Unionwith PEP-604 unions on touched signatures.Fixes # (issue) — N/A
Type of change
Screenshots
N/A — code-only change.
Checklist
pre-commitchecks with./isaaclab.sh --formatconfig/extension.tomlfile — N/A; covered by parent PR [OVPHYSX] RigidObjectCollection asset isaac-sim/IsaacLab#5570's fragmentCONTRIBUTORS.mdor my name already exists thereTest results
Ran on the cleanup branch:
test_articulation.pytest_body_incoming_joint_wrench_b_single_joint:ArticulationData._body_incoming_joint_wrench_bufis referenced but never allocated by_create_buffers; the same code path is byte-identical on the parent branch tip)test_rigid_object.pytest_rigid_object_collection.pyThe pre-existing articulation failure should be tracked separately.
Follow-ups noted but out of scope
OvPhysxManager._simaccessed as a private attribute inRigidObjectData.__init__— would be cleaner with a publicget_gravity()accessor like PhysX has._fd_joint_acc/_compose_body_com_posescould match PhysX's publicget_joint_acc_from_joint_vel/compose_body_com_posesconvention._on_prim_deletioncallback PhysX defines (behavior gap, not style).RigidObjectCollection:_initialize_impl/_create_buffers/_process_cfgcurrently sit above the public helpers; PhysX places them underInternal helper.afterHelper functions.— leaving this for a future structural pass.ArticulationData.__init__takes counts/names as constructor args and stores them as plain instance attributes, whereas PhysX/Newton use dataclass-style class attributes under aNames.section — deeper architectural difference, intentionally out of scope here.