Skip to content

Accelerate and strengthen asset tests [8/13] - #8147

Closed
AntoineRichard wants to merge 10 commits into
isaac-sim:developfrom
AntoineRichard:antoiner/asset-tests-p14-physx-rigid-object
Closed

AntoineRichard wants to merge 10 commits into
isaac-sim:developfrom
AntoineRichard:antoiner/asset-tests-p14-physx-rigid-object

Conversation

@AntoineRichard

@AntoineRichard AntoineRichard commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Part 8/13 of the asset-test series (tracker: #7282). Scope: PhysX rigid object and rigid object collection. Depends on #8131; this branch contains its commits until it merges.

What changed

test_rigid_object.py and test_rigid_object_collection.py each run on one module-scoped scene of locally authored 1 kg cubes instead of a Nucleus DexCube scene per test. Both scenes run on cpu and cuda:0 and use two environments, so partial writes target one environment and prove the other is preserved in the real PhysX state.

Rigid object (two environments of gravity-free dynamic cubes, two of kinematic cubes), four nodes:

  • Initialization: refcount and shapes; kinematic cubes hold their default pose under gravity.
  • Inertial properties: full and int64 partial mass, COM and inertia writes, read back from the PhysX view; mass survives a step.
  • Root state: partial pose and velocity writes on environment 1, read back from the PhysX view (the velocity against the COM velocity computed from the written link velocity). Every root writer is checked with a COM offset, including the cross-frame consistency; the node steps between the default-selector and explicit-selector passes, so the second pass has to write again. Spinning about the COM leaves the COM in place while the link frame orbits it.
  • Wrenches and reset: the node sets 1 kg masses and a centered COM itself. A body-frame force on a rotated cube acts only on environment 1; world-frame forces, and forces at a position, match their body-frame counterparts. The partial and full composer reset assertions are kept verbatim.

The invalid-body failure, the gravity vector (with and without gravity) and physics warmup keep their own scenes and run before the composite scene, which a new simulation context would otherwise replace.

Rigid object collection (two environments of three gravity-free cubes, plus a single-cube kinematic collection). PhysX stores collection bodies body-major, so writes select non-sorted environment and body subsets and read the view back. Four nodes:

  • Initialization: includes the 1×1 collection; kinematic cubes hold their pose under gravity.
  • State writes: non-sorted partial pose and velocity writes. Every body writer is checked with a COM offset, including the cross-frame consistency, plus the spin kinematics about the COM. The node steps between the default-selector and explicit-selector passes and reads the link-velocity write back from the PhysX view as a COM velocity.
  • Masses: non-sorted partial mass writes, read back from the body-major view.
  • Wrenches and reset: local and global forces, and forces at a position, on every other body; unselected bodies stay at rest. A permanent force persists: a second step doubles the velocity. The partial and full composer reset assertions follow, verbatim.

Both collection regressions, test_subset_write_reaches_selected_view_entry (develop) and #8131's test_inertial_property_subset_writes_reach_selected_view_entries, are kept verbatim in their own scenes. The inertial one runs on a buffer that has never been read; reverting any of the three #8131 changes turns it red (the COM float view, the COM cache freshness, and the inertia 3-D reshape).

Disposition

"Mutation" means a one-line production change that turns the keeper red; each was checked red on the keeper and reverted.

Removed develop test Keeper Proof
test_rigid_object.py::test_initialization (1 and 2 cubes) rigid-object initialization; one instance via test_warmup_loads_physics_once assertions carried
test_rigid_object.py::test_initialization_with_kinematic_enabled rigid-object initialization assertions carried
test_rigid_object.py::test_initialization_with_no_rigid_body test_initialization_rejects_invalid_rigid_body[none] same assertion, local collider
test_initialization_with_articulation_root test_initialization_rejects_invalid_rigid_body[articulation_root] strict xfail that only accepts the missing rejection (raises=pytest.fail.Exception); see "Product bugs"
test_set_rigid_object_state root state mutation: partial root pose kernel writes row i
test_reset_rigid_object rigid-object wrenches and reset verbatim assertions
test_rigid_body_no_friction, test_rigid_body_with_static_friction, test_rigid_body_with_restitution none needed these tested PhysX contact physics through the raw material API; the Lab calls they made are covered (partial root pose kernel, frame flag, and torque delivery mutations; permanent-wrench persistence by isaaclab/test/utils/test_wrench_composer_integration.py on develop, red when write_data_to_sim resets the permanent composer)
test_rigid_body_set_mass inertial properties mutation: set_masses skipped
test_body_root_state_properties root state (spin) mutation: COM→link velocity lever sign flipped
test_write_root_state root state mutation: COM→link pose offset sign flipped
test_rigid_object_collection.py::test_initialization (1×1, 2×3) collection initialization assertions carried
test_rigid_object_collection.py::test_initialization_with_kinematic_enabled collection initialization assertions carried
test_external_force_on_single_body, test_external_force_on_single_body_at_position collection wrenches and reset mutation: is_global negated; torques zeroed; write_data_to_sim resets the permanent composer instead of the instantaneous one
test_set_object_state state writes mutation: partial body pose kernel writes cell (i, j)
test_object_state_properties state writes (spin) mutation: COM→link velocity lever sign flipped
test_write_object_state state writes mutation: COM→link pose offset sign flipped
test_reset_object_collection collection wrenches and reset verbatim assertions
test_gravity_vec_w (both files), test_rigid_object_collection.py::test_initialization_with_no_rigid_body same tests kept, local cubes
test_warmup_loads_physics_once same test assertions verbatim, local cube

Both files' root and link velocity writers are also read back through raw get_velocities(): making set_velocities a no-op in the link-velocity writer turns each state node red.

Devices and CI selection

  • Every test runs on every available device (cpu and cuda:0), including the invalid-body and gravity tests.
  • Every rigid-object test carries @pytest.mark.isaacsim_ci, as on develop. The collection file carried no mark on develop and carries none now.

Timing

Warm Warp cache, repository orchestrator (pytest tools), one process per file, second of two runs, RTX 5090. develop is 09b1d54; this branch is 516c378.

Times are the per-file process wall times the orchestrator reports, including interpreter and Kit startup.

File develop This branch
test_rigid_object.py 15.7 s (44 tests) 6.3 s (16 tests + 2 xfailed)
test_rigid_object_collection.py 12.6 s (38 tests) 5.6 s (18 tests)
Total 28.3 s 11.9 s

With #8131 (a8300a3), the develop collection file takes 13.1 s (40 tests).

Product bugs

  • Pinned (strict xfail): the PhysX RigidObject no longer rejects an enabled articulation root. The check (Adds check that no articulation root API is applied on rigid bodies #1358) was dropped in skip usd cloning in pure newton path #5743. The develop test still passes only because its Nucleus fixture resolves no rigid body at all ("Expected 1 prims … found 0"). The local case authors an enabled articulation root (physxArticulation:articulationEnabled = True) on the rigid body itself. Re-inserting the removed check turns it into XPASS(strict) on both devices.
  • Found, not pinned: a full RigidObjectCollection.reset() still leaves the wrench composers active. reset() passes _ALL_ENV_INDICES to WrenchComposer.reset, which takes the partial-reset path. [Tests] Prune PhysX tests with the test-audit skill #8009 reported this. The reset assertions are kept from develop and do not check active.

Type of change

  • Test-suite redesign (no production change)

Release backport

  • Backport this pull request to the active release branch after it merges into develop

Checklist

Docker and GPU tests run on demand. Push the commits you want tested, then
comment run-ci on the pull request.

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with uv run isaaclab --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have validated the changed behavior with focused coverage and applied the test-audit criteria to any test changes
  • I have added a changelog fragment under source/<pkg>/changelog.d/ for every touched package (do not edit CHANGELOG.rst or bump package versions — CI handles that)
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

RigidObjectCollection.set_coms_index passed wp.transformf data to the
PhysX tensor API, which raises a KeyError. It also marked the lazily
filled body_com_pose_b cache as fresh after a partial write, so the
unselected entries read back as zeros when the cache had not been read
before. set_inertias_index flattened the (num_instances, num_bodies, 9)
inertias with the 2D reshape, which the backend rejects.

Pass the COM poses as float32, let the next read refresh the COM cache
from the view as RigidObject does, and reshape the inertias with the 3D
helper. A new test writes both properties to a non-sorted subset of
(env, body) cells and checks the PhysX view and the data buffers.
Share one module-scoped scene of locally authored cubes instead of a
Nucleus scene per test. Partial state, inertial, and wrench writes
select environment 1 and read the PhysX view back; a center-of-mass
offset checks every root-frame writer and the spin kinematics. Failure
modes, the gravity vector, and physics warmup keep their own scenes.

The articulation-root rejection is kept as a strict xfail: the check was
removed from the PhysX rigid object, and the previous Nucleus fixture
only failed because it resolved no rigid body.
Share one module-scoped scene of locally authored cubes instead of a
Nucleus scene per test. Partial state, mass, and wrench writes select
non-sorted body-major subsets and read the PhysX view back; a
center-of-mass offset checks every body-frame writer and the spin
kinematics. Failure modes, the gravity vector, and the subset-write
regressions keep their own scenes.
@AntoineRichard
AntoineRichard requested a review from a team September 29, 2026 12:48
@github-actions github-actions Bot added the isaac-lab Related to Isaac Lab team label Sep 29, 2026
@greptile-apps

greptile-apps Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

[Medium risk] Refactors physics simulation test suite for rigid objects.

The PR should not merge until the new composite tests run in the short CI suite.

Findings

  1. P1 Composite tests skipped in short CI ▶
  2. P2 PhysX contact coverage removed ▶
  3. P2 CPU gravity checks removed ▶

Summary

The PR replaces per-test Nucleus rigid-object scenes with locally authored cubes and a shared PhysX scene, while retaining separate contexts for invalid-body, gravity, and warmup checks.

  • Adds batched checks for inertial writes, root-frame state, wrench delivery, and resets.
  • The new shared tests are not selected by the short CI marker run, and the rewrite drops PhysX contact-response and CPU gravity-vector coverage.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Separate invalid-body, gravity, and warmup tests] --> B[Module-scoped PhysX scene]
  B --> C[Dynamic cubes in two environments]
  B --> D[Kinematic cubes in two environments]
  C --> E[Initialization and inertial tests]
  C --> F[Root-state and wrench tests]
  D --> E
Loading

Reviews (1) · Last reviewed commit: "Run PhysX rigid-object tests on one comp..."

cube_object.update(sim.cfg.dt)

env_ids = None if i % 2 == 0 else env_idx
def test_rigid_object_initialization(rigid_object_scene: _RigidObjectScene):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Composite tests skipped in short CI When ISAACSIM_CI_SHORT=true, the test runner selects this file because earlier tests are marked, then runs pytest with -m isaacsim_ci. This test and the other three new composite tests lack that marker, so all four are deselected. Short CI consequently misses the replacement coverage for initialization, inertial properties, root state, and wrenches.

cube_object.update(sim.cfg.dt)

env_ids = None if i % 2 == 0 else env_idx
def test_rigid_object_initialization(rigid_object_scene: _RigidObjectScene):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 PhysX contact coverage removed The rewrite removes the three tests that set rigid-object material properties and check friction or restitution during contact. The replacement tests use airborne cubes, and the similarly named tests in isaaclab_ov exercise a different view. A regression in the PhysX material or contact path can now pass this package’s asset tests; please retain a focused contact case or replace that coverage elsewhere.

Knowledge Base Used: PhysX backend

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


@pytest.mark.parametrize("num_cubes", [2])
@pytest.mark.parametrize("device", test_devices())
@pytest.mark.parametrize("device", test_devices(DeviceScope.CUDA))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 CPU gravity checks removed Restricting this test to CUDA removes the CPU checks of the gravity vector and body acceleration with gravity both enabled and disabled. The remaining CPU warmup test only checks that a cube falls, so it cannot catch an incorrect CPU gravity vector or acceleration when gravity is disabled. Please keep the CPU case unless an equivalent PhysX test covers it.

@AntoineRichard
AntoineRichard marked this pull request as draft September 29, 2026 12:54
Import the mock and PhysX interfaces at module level, allocate repeated
rows directly, state the articulation-root xfail as the current contract,
and annotate the tests and the scene fixture.
Drop step-narrating comments from the gravity test and annotate the tests and fixtures.
The strict xfail now authors an enabled articulation root on the rigid
body itself and only accepts the missing-rejection failure, so it turns
red once the check is restored. Every test carries the Isaac Sim CI
marker, the invalid-body and gravity tests run on every device, the
writer passes step in between, the wrench node sets its own masses, and
the partial velocity write is read back from PhysX.
A second step must double the velocity from a permanent force, which
the deleted single-body force test covered. The writer passes step in
between, the link velocity write is read back from PhysX, and the
invalid-body and gravity tests run on every device again.
@AntoineRichard AntoineRichard changed the title Accelerate and strengthen asset tests [14/24] Accelerate and strengthen asset tests [8/13] Sep 29, 2026
@StafaH

StafaH commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator

Closing because the combined PR #7282 has merged. This split PR is superseded by #7282 and is no longer needed.

@StafaH StafaH closed this Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

isaac-lab Related to Isaac Lab team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants