Skip to content

Fix backend asset state invalidation#6150

Draft
AntoineRichard wants to merge 3 commits into
isaac-sim:developfrom
AntoineRichard:antoiner/feat/cleaned-up_asset_invalidation_timestamps
Draft

Fix backend asset state invalidation#6150
AntoineRichard wants to merge 3 commits into
isaac-sim:developfrom
AntoineRichard:antoiner/feat/cleaned-up_asset_invalidation_timestamps

Conversation

@AntoineRichard

Copy link
Copy Markdown
Collaborator

Description

Fix stale cached pose and velocity state after backend asset state writers push data into simulation.

This updates the Newton, PhysX, and OV PhysX backend asset writers to invalidate the affected cached
data through shared data-class reset helpers, and adds regression coverage that checks the invalidation
paths across articulations, rigid objects, and rigid object collections.

Fixes # (issue): N/A

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Screenshots

N/A

Validation

  • ./isaaclab.sh -p -m pytest source/isaaclab/test/assets/test_backend_asset_invalidation.py
  • ./isaaclab.sh -f (all hooks passed except check-git-lfs-pointers, which failed because git-lfs is not installed locally)
  • SKIP=check-git-lfs-pointers ./isaaclab.sh -f

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with ./isaaclab.sh --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have added a changelog fragment under source/<pkg>/changelog.d/ for every touched package (do not edit CHANGELOG.rst or bump extension.toml — CI handles that)
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

Add cross-backend tests that verify asset writers invalidate cached pose and velocity data. Include changelog fragments and formatter cleanups for the touched backend files.
@github-actions github-actions Bot added the isaac-lab Related to Isaac Lab team label Jun 11, 2026
@AntoineRichard AntoineRichard marked this pull request as draft June 11, 2026 16:55
Address review feedback on the cache-invalidation cleanup:

- Add from_link/from_com flags to the Newton reset_pose/reset_velocity
  helpers so writing a com pose or link velocity no longer clobbers the
  freshly-written buffer, matching the PhysX and OVPhysX behavior.
- Delete a leftover invalidate_fk call in the Newton rigid object
  collection link-velocity writer that double-fired and ran even when
  skip_forward was set.
- Add the skip_forward parameter to the abstract base writers so the
  contract matches the concrete backend implementations.
- Reword the from_link/from_com docstrings across all backends to state
  what the flag actually gates, and add kinematic-chain rationale
  comments to the OVPhysX helpers.
@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes stale cached pose and velocity state after backend asset writers push data into simulation. It refactors all three backends (Newton, PhysX, OVPhysX) so that each data class owns a reset_pose/reset_velocity helper that stamps dependent buffers stale and calls SimulationManager.invalidate_fk; writers delegate to these helpers instead of scattering inline timestamp assignments.

  • A skip_forward: bool = False parameter is added to every write_*_to_sim_* method to support deferred/batched invalidation without redundant FK invalidation on intermediate writes.
  • A new AST-based regression test verifies that each writer transitively calls reset_pose and/or reset_velocity across all three backends and all three asset types.
  • Newton kernels are simplified by removing the partial state write-through superseded by the data-class invalidation approach.

Confidence Score: 3/5

Not safe to merge as-is — three P1 defects in the Newton backend mean the new skip_forward feature silently misbehaves for RigidObject and RigidObjectCollection callers.

The PhysX and OVPhysX backends are correctly implemented and the core data-class refactor is sound. However, the Newton backend has concrete bugs where skip_forward is accepted but not propagated, causing unconditional FK invalidation that defeats the feature's purpose. The regression test also has a coverage gap (only checks leaf index methods, not mask wrappers) so these bugs would not be caught automatically.

source/isaaclab_newton/isaaclab_newton/assets/rigid_object/rigid_object.py and source/isaaclab_newton/isaaclab_newton/assets/rigid_object_collection/rigid_object_collection.py require fixes before merge.

Important Files Changed

Filename Overview
source/isaaclab/test/assets/test_backend_asset_invalidation.py New AST regression test verifying reset_pose/reset_velocity reachability from each writer; does not cover wrapper mask methods so misses the skip_forward propagation bugs.
source/isaaclab_newton/isaaclab_newton/assets/rigid_object/rigid_object.py Adds skip_forward to all writers; write_root_pose_to_sim_mask accepts the param but silently drops it (never passed to delegate).
source/isaaclab_newton/isaaclab_newton/assets/rigid_object_collection/rigid_object_collection.py Adds skip_forward + reset_pose/reset_velocity delegation; write_body_link_velocity_to_sim_index has an orphaned unconditional SimulationManager.invalidate_fk(); all mask variants fail to propagate skip_forward to their index delegates.
source/isaaclab_newton/isaaclab_newton/assets/articulation/articulation_data.py Adds reset_pose/reset_velocity helpers with correct FK invalidation; adds _ensure_fk_fresh() calls on body_com_pose_w and body_com_vel_w properties.
source/isaaclab_newton/isaaclab_newton/assets/kernels.py Removes stale-state write-through from kernels; all invalidation now goes through the data-class helpers.
source/isaaclab_physx/isaaclab_physx/assets/articulation/articulation_data.py Adds _fk_timestamp tracking, _ensure_fk_fresh(), reset_pose/reset_velocity with proper FK sync; correctly implemented.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant Writer as write_*_to_sim_*(skip_forward)
    participant DataClass as ArticulationData / RigidObjectData
    participant SimMgr as SimulationManager

    Caller->>Writer: "write_*_to_sim_index(data, skip_forward=False)"
    Writer->>Writer: kernel launch (writes sim buffers)
    alt skip_forward is False
        Writer->>DataClass: reset_pose(env_ids) or reset_velocity(env_ids)
        DataClass->>DataClass: "stamp dependent buffers timestamp = -1.0"
        DataClass->>DataClass: "_fk_timestamp = -1.0"
        DataClass->>SimMgr: invalidate_fk(env_ids, articulation_ids)
    end

    Caller->>DataClass: read body_link_pose_w (lazy access)
    DataClass->>DataClass: _ensure_fk_fresh()
    alt "_fk_timestamp < _sim_timestamp"
        DataClass->>SimMgr: forward() / update_articulations_kinematic()
        DataClass->>DataClass: "_fk_timestamp = _sim_timestamp"
    end
    DataClass-->>Caller: fresh pose data
Loading

Reviews (1): Last reviewed commit: "Refine asset cache invalidation helpers ..." | Re-trigger Greptile

env_mask: Environment mask. If None, then all the instances are updated. Shape is (num_instances,).
skip_forward: Whether to skip the forward pass. Defaults to False.
"""
self.write_root_link_pose_to_sim_mask(root_pose=root_pose, env_mask=env_mask)

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 skip_forward is accepted by this method but silently dropped — it is never forwarded to write_root_link_pose_to_sim_mask. Any caller that passes skip_forward=True expecting to defer cache invalidation will have the invalidation run anyway, because the delegate uses its own default of False.

Suggested change
self.write_root_link_pose_to_sim_mask(root_pose=root_pose, env_mask=env_mask)
self.write_root_link_pose_to_sim_mask(root_pose=root_pose, env_mask=env_mask, skip_forward=skip_forward)

SimulationManager.invalidate_fk(env_ids=env_ids, articulation_ids=self._root_view.articulation_ids)
# Invalidate dependent timestamps. The link velocities were just written, so they must not be
# invalidated. ``reset_velocity`` already triggers the simulation-side FK invalidation.
if not skip_forward:

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 Orphaned SimulationManager.invalidate_fk() call that was not removed when timestamp invalidation was refactored into reset_velocity. reset_velocity already calls SimulationManager.invalidate_fk internally, so this produces a redundant double-call when skip_forward=False, and — more critically — still fires when skip_forward=True, defeating the entire purpose of the flag for this method. All other pose/velocity writers in this file had the corresponding call removed or moved inside reset_pose/reset_velocity; this one was missed.

Comment on lines 473 to +477
self.write_body_link_pose_to_sim_index(
body_poses=body_poses, env_ids=env_ids, body_ids=body_ids, full_data=True
)
if not skip_forward:
self.data.reset_pose(env_ids=env_ids)

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 skip_forward is not propagated to write_body_link_pose_to_sim_index, so the index method always runs with skip_forward=False and calls reset_pose unconditionally. The outer if not skip_forward: self.data.reset_pose(...) then calls it a second time when skip_forward=False, and is a no-op when skip_forward=True since the inner call already fired. The same pattern exists in write_body_com_pose_to_sim_mask, write_body_com_velocity_to_sim_mask, and write_body_link_velocity_to_sim_mask.

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.

1 participant