[OVPHYSX] Articulation rewrite (data class + asset class + kernels)#10
Draft
AntoineRichard wants to merge 1 commit intoantoiner/feat/ovphysx_rigidobjectfrom
Draft
[OVPHYSX] Articulation rewrite (data class + asset class + kernels)#10AntoineRichard wants to merge 1 commit intoantoiner/feat/ovphysx_rigidobjectfrom
AntoineRichard wants to merge 1 commit intoantoiner/feat/ovphysx_rigidobjectfrom
Conversation
394ade8 to
f72c5f4
Compare
2b8cc8d to
26a442b
Compare
Add Articulation and ArticulationData for the OVPhysX backend, mirroring the PhysX/Newton public API. Resolves PR isaac-sim#5459. Articulation ^^^^^^^^^^^^ * index/mask split for every state writer, simulation-parameter writer, setter, and tendon setter; OVPhysX exposes both _index and _mask as first-class paths and intentionally drops the PhysX-specific ``full_data`` kwarg. * Dedicated dynamic + viscous friction setters (write_joint_{dynamic,viscous}_friction_coefficient_to_sim_{index,mask}) that touch only their slot of the combined (N, J, 3) DOF_FRICTION_PROPERTIES buffer. The combined write_joint_friction_coefficient_to_sim_index/_mask still accepts all three components as kwargs (Coulomb static + dynamic + optional viscous) for source-compatible PhysX call sites. * Deprecated non-indexed shorthand shims for friction (x3) and root / joint state (x4), forwarding to the index variants with a DeprecationWarning, matching PhysX's deprecated section. * Wrench-composer return types tightened to non-None (instantaneous_wrench_composer / permanent_wrench_composer); composers are always set in _create_buffers, mirroring PhysX/Newton. * Section organisation matches PhysX exactly: Properties -> Operations -> Operations - Finders -> Operations - State Writers -> Operations - Simulation Parameters Writers -> Operations - Setters -> Operations - Tendons -> Internal helper -> Internal simulation callbacks -> Internal helpers -- Actuators -> Internal helpers -- Debugging -> Deprecated methods. Section delimiters use bare """Section.""" docstring blocks (Newton/PhysX convention). ArticulationData ^^^^^^^^^^^^^^^^ * Pull-on-demand timestamped buffers; CPU-only bindings route through pinned-host staging (PR isaac-sim#5329 pattern). * Property names match PhysX exactly: joint_friction_coeff, joint_dynamic_friction_coeff, joint_viscous_friction_coeff (no *_static / *_dynamic / *_viscous renames). * SI units annotated on every public property docstring ([m or rad, depending on joint type], [m/s or rad/s, ...], [N*m], [kg], etc.) per AGENTS.md. * binding_getter parameter on __init__ typed as Callable[[int], Any] | None. * Section organisation matches PhysX (Defaults -> Joint commands -> Joint properties -> Fixed tendon -> Spatial tendon -> Root state -> Body state -> Joint state -> Derived -> Sliced -> Internal helpers -> Deprecated properties). Kernels ^^^^^^^ * Articulation-specific kernels in isaaclab_ovphysx/assets/articulation/kernels.py (soft-limit clamp, friction-data writer, finite-difference joint-acc helper, body-CoM pose composer); shared kernels promoted to isaaclab_ovphysx/assets/kernels.py. * Per-kernel docstrings document purpose, shape/dtype/SI units, and divergence notes where the OVPhysX implementation differs (e.g. _fd_joint_acc takes inv_dt rather than dt to avoid per-element division). Tests ^^^^^ * Real-backend test_articulation.py mirrors isaaclab_physx 1-to-1 under run_ovphysx.sh; 99 tests pass on each of CPU + CUDA. * test_articulation_helpers.py covers the kitless-only helpers (tendon scoping, mock binding shapes). * Cross-backend test_articulation_iface.py runs the OVPhysX path: 544 tests pass, 16 skipped, 0 failed on each of CPU + CUDA. Brings the iface helper up to the actual ArticulationData constructor signature and broadcasts scalar inputs across joint / fixed-tendon / spatial-tendon mask setters that previously rejected them. OVPhysX-only surface dropped ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * Articulation: set_external_force_and_torque_{index,mask} (use instantaneous_wrench_composer.add_forces_and_torques_*), set_spatial_tendon_limit_{index,mask}, and set_spatial_tendon_rest_length_{index,mask} (NotImplementedError stubs PhysX never had). * ArticulationData: body_pose_w / body_lin_vel_w / body_ang_vel_w / body_acc_w / body_link_acc_w (base class provides matching defaults), body_inv_mass / body_inv_inertia, fixed_tendon_limit (PhysX exposes only fixed_tendon_pos_limits), spatial_tendon_limit / spatial_tendon_rest_length (no PhysX equivalent).
f72c5f4 to
7a12614
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
Drastic rewrite of OVPhysX
ArticulationandArticulationDataso they follow the same shape as the post-refactor OVPhysXRigidObject(PR isaac-sim#5426 on isaac-sim/IsaacLab), with the API surface mirroringNewton Articulationand behavior parity withPhysX Articulation. Single-PR atomic rewrite, clean break (no deprecation aliases for OVPhysX-introduced renames; framework-inherited deprecated shims kept).The OVPhysX articulation diverged significantly from the rest of the framework conventions. This PR brings it back in line: same docstring template, same section ordering, same naming, same internal patterns, same lifecycle.
This PR is stacked on the rigid-object refactor (
antoiner/feat/ovphysx_rigidobject, isaac-sim PR isaac-sim#5426). Once isaac-sim#5426 merges todevelop, the upstream PR for this work will be retargeted todevelop.Status: draft. Implementation is complete (all writers, setters, properties, lifecycle, actuator pipeline); the verbatim PhysX test mirror that already lives in tree (
test_articulation.py, ~210 parametrizations) currently shows 104 failures from a single root-cause bug —_binding_read(TT.BODY_COM_POSE, ...)during_initialize_implis not routing through pinned-host staging despite the type being in_CPU_ONLY_TYPES. Iterating on that bug + remaining triage in a fresh-context follow-up session.Fixes # (none — internal refactor; no associated issue)
Design references
docs/superpowers/specs/2026-04-30-ovphysx-articulation-rewrite-design.md(gitignored, local).docs/superpowers/plans/2026-04-30-ovphysx-articulation-rewrite-plan.md(gitignored, local).source/isaaclab_ovphysx/test/assets/test_articulation.pyis a verbatim 1-to-1 mirror ofisaaclab_physx.test.assets.test_articulation(~210 parametrizations) — landed in the rigid-object PR [OVPHYSX] RigidObject + RigidObjectData asset isaac-sim/IsaacLab#5426. The_ovphysx_session_patchesand_ovphysx_skip_other_deviceautouse fixtures bridge the kitless invocation gap (see the rigid-object test header).Architectural changes
OVPhysX RigidObject is the design template. It has navigated the hybrid OVPhysX surface — Newton-style mask+index dual API + PhysX-style CPU-only bindings via pinned-host staging à la isaac-sim#5329 + pull-to-refresh
binding.read(target):TimestampedBufferWarpallocation in_create_buffers(single source of truth — no_invalidate_caches/_ensure_*_buffers/_ensure_root_buffersmachinery)._binding_read/_binding_write/_stage_to_pinned_cpuhelpers route CPU-only types through pinned-host memory.ProxyArray(warp + torch dual view); rawwp.arrayfor one-shot config buffers.num_instances,num_bodies,num_joints,body_names,joint_names, ...) demoted from@propertyto plain instance attributes.*_indexaccepts partial data;*_maskaccepts full data with awp.boolmask).write_*/set_*parameters are kwarg-only after*,. No positional. Nofull_dataflag anywhere._write_body_stateplumbing layer is removed; deprecated state-writer shims (write_root_state_to_sim, etc.) call the publicwrite_*_to_sim_indexmethods directly, mirroring RigidObject.Articulation-specific surface mirrors Newton 1-to-1: joint-state writers, joint-property writers (CPU-only), body-property setters (multi-body shape), joint-command target setters, external-wrench setters via
WrenchComposer, fixed/spatial tendon setters, deprecated state-writer shims, full actuator pipeline (compute,_apply_actuator_model,_process_actuators_cfg).Files changed
source/isaaclab_ovphysx/isaaclab_ovphysx/assets/articulation/articulation.py— full rewrite (~3863 lines, matches Newton).source/isaaclab_ovphysx/isaaclab_ovphysx/assets/articulation/articulation_data.py— full rewrite (~2504 lines).source/isaaclab_ovphysx/isaaclab_ovphysx/assets/kernels.py— gained 6 articulation kernels migrated from the stop-gapkernels_old.py(now deleted):_compose_root_com_pose,_compute_heading,_copy_first_body,_projected_gravity,_world_vel_to_body_ang,_world_vel_to_body_lin. Plus 2 new joint-property kernels (write_joint_position_limit_to_buffer_index/maskfor trailing-dim-2 limits,write_joint_friction_to_buffer_index/maskfor the broadcast-coefficient pattern).source/isaaclab_ovphysx/isaaclab_ovphysx/assets/kernels_old.py— deleted.Type of change
0.2.x, clean break is acceptable per semver-on-0.x; no deprecation aliases for OVPhysX-introduced renames).Validation
Verifications happen in three layers (Tasks 16-19 of the implementation plan, deferred to fresh-context follow-up):
Real-backend port —
test_articulation.py(already in tree, verbatim PhysX mirror). Run on GPU and CPU separately via./scripts/run_ovphysx.sh -m pytest <path> -k 'cuda:0'and... -k 'cpu'(the wheel's process-global device-mode lock makes a single invocation lock to one device). Expected end state: each pass shows<X> passed, <Y> xfailed, 0 failed.Yis bounded by the wheel-gaps spec; everyxfailcarries areasonpointing at the spec entry.Cross-backend interface —
source/isaaclab/test/assets/test_articulation_iface.pywill gain anovphysxbackend, mirroring the rigid-object iface treatment from [OVPHYSX] RigidObject + RigidObjectData asset isaac-sim/IsaacLab#5426 (commitb340a551f6c). Run on both devices.API consistency audit — per-method side-by-side checklist comparing Newton, RigidObject (post-refactor), and the rewritten Articulation; verifies method name, kwarg-only signature, parameter order, return type, docstring template (one-liner →
.. note::→.. tip::→Args:), section-header placement.Outstanding
_binding_read(TT.BODY_COM_POSE, ...)during_initialize_impldoes not route through pinned-host staging despiteBODY_COM_POSEbeing inTT._CPU_ONLY_TYPES. Likely a single bug in the read path; fix unblocks ~80% of failures.0.2.x→0.3.0.Type of change
Checklist
pre-commitchecks with./isaaclab.sh --formatconfig/extension.tomlfile (Task 20)CONTRIBUTORS.mdor my name already exists there