Skip to content

[Backport release/3.0.0] Newton startup, cloner, and rendering fixes - #7299

Merged
ooctipus merged 5 commits into
isaac-sim:release/3.0.0from
ooctipus:codex/backport-prs-7285-7292-release-3.0.0
Aug 22, 2026
Merged

[Backport release/3.0.0] Newton startup, cloner, and rendering fixes#7299
ooctipus merged 5 commits into
isaac-sim:release/3.0.0from
ooctipus:codex/backport-prs-7285-7292-release-3.0.0

Conversation

@ooctipus

@ooctipus ooctipus commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

Backports the following merged changes to release/3.0.0 as separate provenance-preserving cherry-picks:

Each source squash commit was cherry-picked with -x and applied without conflicts.

Validation

  • Stable patch IDs match all five source squash commits exactly.
  • File-by-file manifests match each source squash commit.
  • git diff --check upstream/release/3.0.0..HEAD
  • uv run --frozen python tools/changelog/cli.py check backport-7285-7292-base
  • SKIP=check-changelog-fragments uv run --frozen isaaclab -f
  • Cloner/Newton focused tests: 98 passed
  • Scene global-ownership tests: 2 passed
  • Simulator clone-plan tests: 4 passed
  • Video recording regression test: 1 passed
  • Newton BVH lifecycle tests: 2 passed
  • Newton contact-selector tests: 7 passed
  • Newton raycast BVH test: 4 passed
  • Non-finite depth display tests: 4 passed
  • [Newton] Avoid repeated model startup work #7295 physics lifecycle, cloner, manager, and coupling tests: 248 passed
  • [Newton] Avoid repeated model startup work #7295 Newton joint-wrench sensor tests: 11 passed
  • [Newton] Avoid repeated model startup work #7295 PhysX joint-wrench sensor tests: 16 passed

PR #7121 remains open and is intentionally excluded; it will be backported from its final merge commit after merging.

ooctipus and others added 2 commits August 22, 2026 03:40
# Description

Newton replication currently calls `ModelBuilder.add_usd()` from the
stage root and relies on ignore paths for replicated environments. This
change moves global ownership to the scene composition root and carries
it in `ClonePlan.global_paths`.

- `InteractiveScene` returns env-scoped clone configs and an ordered
`tuple[str, ...]` of shared prim roots.
- `ClonePlan` carries that tuple without representing globals as clone
rows.
- Hand-built scenes pass non-empty globals explicitly; the ordinary
no-global case defaults to `()`.
- The replication pipeline passes the plan declaration directly to
backend contexts.
- Newton imports only the physics scene and each declared global root
with `root_path=...`.
- Terrain-heightfield discovery scans those same roots.

There is no stage-root guessing, global-path registry, or full-stage
fallback in clone-plan replication.

## Data flow

The scene owns classification:

```python
clone_cfgs, global_paths = self._collect_asset_cfgs()
with ReplicateSession(clone_cfgs, ..., global_paths=global_paths, stage=stage):
    self._add_entities_from_cfg()
```

The plan carries the declaration:

```python
ctx = BackendContext(stage, global_paths=plan.global_paths)
```

Newton performs narrow imports. For a plan declaring ground and light:

```python
builder.add_usd(stage, root_path="/physicsScene")
builder.add_usd(stage, root_path="/World/Ground")
builder.add_usd(stage, root_path="/World/Light")
```

The physics-scene result remains the returned stage metadata;
global-import result dictionaries are not merged. Globals stay outside
`sources`, `destinations`, `clone_mask`, and `cfg_rows`, so they create
no clone work or per-environment solver/sensor structures.

PhysX collision filtering remains a separate post-clone concern based on
`collision_group == -1`; global import ownership does not change that
policy.

## Direct scenes

Only scenes with shared roots need an explicit argument:

```python
global_paths = ("/World/ground",)
plan = clone_plan_from_env_0(src, dest, num_envs, device, positions, global_paths)
```

Scenes without shared roots keep the compact default:

```python
plan = clone_plan_from_env_0(src, dest, num_envs, device, positions)
```

## Startup benchmark

RTX 5090, 4,096 environments, seed 42, Newton MJWarp, three post-warm-up
runs per commit in alternating order. The baseline is `bc8b7bdf005`,
immediately before scoped global import. Values are medians; positive
deltas mean the PR is faster.

| Workload | Metric | Baseline | PR | PR delta |
|---|---|---:|---:|---:|
| `Isaac-Velocity-Rough-AnymalD`, kitless | Scene creation | 4.932 s |
4.934 s | -0.05% |
|  | Environment creation | 13.511 s | 13.569 s | -0.43% |
|  | Total startup | 15.420 s | 15.520 s | -0.65% |
| `Isaac-Lift-KukaAllegro`, kitless | Scene creation | 14.248 s | 14.202
s | +0.32% |
|  | Environment creation | 26.222 s | 26.184 s | +0.15% |
|  | Total startup | 28.875 s | 28.830 s | +0.16% |
| `Isaac-Lift-KukaAllegro-Camera`, OVRTX RGB64 | Scene creation | 8.312
s | 8.232 s | +0.96% |
|  | Environment creation | 35.743 s | 35.782 s | -0.11% |
|  | Total startup | 39.936 s | 39.976 s | -0.10% |

All differences are below 1%, so these workloads show no measurable
gain. That is expected for the two kitless tasks because their USD
stages do not contain materialized replicated environment trees. The
warmed OVRTX workload also does not reproduce the earlier single-run
estimate.

A full Kit-stage comparison could not be run because Isaac Sim/Kit is
not installed on the benchmark machine. That is the case where avoiding
traversal of a materialized replicated USD tree should matter, and it
remains unmeasured here.

## Testing

- Clone-plan, replication-session, and Newton global-world coverage: `90
passed` on the final API.
- Newton contact-sensor module after moving its ground into the scene
declaration: `85 passed, 8 xpassed`.
- Earlier full focused suite: `151 passed`.
- Finalized-model coverage verifies the declared ground collider has
Newton `shape_world == -1`; the declared light correctly creates no
Newton physics entity.
- 16-env Cartpole, Anymal-D, and Newton + OVRTX camera
startup/reset/first-step checks passed.
- Three 4,096-environment benchmark runs per workload and commit passed.
- Repository formatting and pre-commit checks passed.

The contact suite exposed the ownership boundary correctly: its ground
had previously been spawned by `build_simulation_context()` outside the
scene config and therefore was absent from the clone plan. The fix
declares the ground in `ContactSensorTestSceneCfg`; the single
intentionally groundless test sets `terrain = None`. No discovery
fallback was added.

## Type of change

- Performance/architecture improvement
- Documentation update

## Checklist

- [x] I have run the pre-commit checks.
- [x] I have made corresponding changes to the documentation.
- [x] My changes generate no new warnings.
- [x] I have added tests that prove the feature works.
- [x] I have added changelog fragments for changed packages.

(cherry picked from commit 909cc5d)
# Description

> [!IMPORTANT]
> Confirm the pull request base before submitting. Target `develop` for
all
> contributions. The `release/3.0.0-beta2` branch is a frozen stable
landing
> snapshot and is not used for ongoing maintenance.

<!--
Thank you for your interest in sending a pull request. Please make sure
to check the contribution guidelines.

Link:
https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html

💡 Please try to keep PRs small and focused. Large PRs are harder to
review and merge.
-->

To reduce flakiness in motion check in the video recording unit test
- Add initial horizontal velocity to cart, instead of relying mostly on
gravity affecting the pole to create motion
- Extend the duration of the capture to allow for more motion

<!-- As a practice, it is recommended to open an issue to have
discussions on the proposed pull request.
This makes it easier for the community to keep track of what is being
developed or added, and if a given feature
is demanded by more than one party. -->

## Type of change

<!-- As you go through the list, delete the ones that are not
applicable. -->

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

## Screenshots

Please attach before and after screenshots of the change if applicable.

<!--
Example:

| Before | After |
| ------ | ----- |
| _gif/png before_ | _gif/png after_ |

To upload images to a PR -- simply drag and drop an image while in edit
mode and it should upload the image directly. You can then paste that
source into the above before/after sections.
-->

## Checklist

- [ ] I have read and understood the [contribution
guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html)
- [ ] I have run the [`pre-commit` checks](https://pre-commit.com/) 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

<!--
As you go through the checklist above, you can mark something as done by
putting an x character in it

For example,
- [x] I have done this task
- [ ] I have not done this task
-->

(cherry picked from commit 86cf666)
@ooctipus
ooctipus requested a review from a team August 22, 2026 10:51
@github-actions github-actions Bot added documentation Improvements or additions to documentation isaac-lab Related to Isaac Lab team infrastructure labels Aug 22, 2026

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

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.

Isaac Lab Review Bot

The explicit global_paths ownership model is coherent and consistently threaded through clone plans and backend contexts, but the backport narrows two public extension contracts without migration guidance and drops metadata from Newton global-root imports.

  • Design and architecture: Separating shared assets from replication rows appropriately scopes Newton imports. However, the per-root Newton import loop retains only the physics-scene import result, discarding metadata produced for declared global roots; the results should be combined before returning stage_info.
  • API: make_clone_plan no longer tolerates global or spawn-less cfgs as its prior documented behavior did, instead failing with incidental attribute errors. Replication contexts must also now accept global_paths and define replicate_priority, breaking custom classes supplied through AssetBaseCfg.cloning_contexts. These narrowed contracts need descriptive validation and explicit migration guidance.
  • Implementation: Backend dispatch and migrated direct-scene callers consistently propagate global_paths, and the Newton test verifies global colliders remain in world -1. The remaining implementation defect is that stage_info = import_results[0] excludes metadata from all subsequently imported global roots.

Minor fixes needed. Posted 3 actionable findings inline.

Automated review; human maintainers own approval decisions.

prim_path = cfg.prim_path
if (matched := match(prim_path, env_template)) is None:
continue
matched = match(cfg.prim_path, env_template)

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.

🟡 Warning · Api — make_clone_plan crashes on previously skipped cfgs

The guard that skipped cfgs without prim_path/spawn or outside the env root was removed. A global cfg now yields matched=None and line 281 raises a bare AttributeError; a spawn-less cfg fails on cfg.spawn. make_clone_plan/ReplicateSession are documented for scenes assembled outside InteractiveScene, where such cfgs were previously tolerated. Raise a descriptive error naming the offending path and record the narrowed input contract with migration guidance in the changelog fragment.

backend_ctxs: dict[type, Any] = {}
for BackendCtxCls, row_set in backend_rows.items():
ctx = BackendCtxCls(stage)
ctx = BackendCtxCls(stage, global_paths=plan.global_paths)

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.

🟡 Warning · Api — Replication-context protocol tightened without migration note

Contexts are now constructed as BackendCtxCls(stage, global_paths=...), ctx.replicate_priority is read without the previous default, and cfg.spawn is dereferenced directly. Both PhysX and OvPhysX contexts needed replicate_priority = 0 added here, confirming the old fallbacks were load-bearing. Classes supplied through the public AssetBaseCfg.cloning_contexts extension point that follow the prior protocol now fail with TypeError/AttributeError; document this protocol change and migration guidance.

builder, stage, import_result["path_shape_map"], load_visual_shapes
)
import_results.append(import_result)
stage_info = import_results[0]

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.

🔵 Suggestion · Design Architecture — Global-root import metadata dropped from stage_info

stage_info = import_results[0] keeps only the physics-scene import, so path_shape_map and other metadata for every declared global_paths root are discarded. Previously one add_usd covered all non-env prims, so the metadata returned by NewtonReplicateContext.replicate and newton_physics_replicate silently narrows for shared assets such as the ground plane. Merge the per-root import results before returning.

@greptile-apps

greptile-apps Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR makes shared scene roots explicit in clone plans so Newton imports only declared global assets, propagates the new metadata through scene and backend replication, and updates direct environments and documentation accordingly. It also stabilizes the video regression test by recording a longer clip with deterministic nonzero camera-environment actions.

  • Adds ClonePlan.global_paths and forwards it through replication contexts.
  • Separates env-scoped clone configurations from shared global roots in InteractiveScene.
  • Scopes Newton USD and terrain-heightfield imports to the physics scene and declared global assets.
  • Updates direct task, tutorial, demo, template, and regression-test clone plans.
  • Stabilizes the sensor/PhysX video recording test.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete correctness or security defects identified in the changed paths.

The explicit global-root metadata is consistently propagated through plan construction, scene composition, built-in backend contexts, direct-environment callers, and focused tests, while the video-test adjustment remains isolated to test stabilization.

Important Files Changed

Filename Overview
source/isaaclab/isaaclab/cloner/clone_plan.py Adds explicit shared-root metadata to clone plans and both plan construction entry points.
source/isaaclab/isaaclab/cloner/replicate_session.py Propagates declared global roots to backend contexts and formalizes their replication interface.
source/isaaclab/isaaclab/scene/interactive_scene.py Separates cloneable env-scoped configs from global scene roots before creating the replication session.
source/isaaclab_newton/isaaclab_newton/cloner/replicate.py Replaces broad stage traversal with scoped imports of the physics scene and explicitly declared global roots.
source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py Supports root-scoped terrain heightfield discovery for the new Newton import flow.
source/isaaclab_tasks/test/core/test_video_recording.py Uses longer clips and deterministic nonzero actions to make motion validation less timing-sensitive.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    Scene[InteractiveScene or direct environment] --> Plan[ClonePlan]
    Scene -->|env-scoped configs| Plan
    Scene -->|declared shared roots| Globals[global_paths]
    Globals --> Plan
    Plan --> Dispatch[replicate]
    Dispatch --> USD[USD context]
    Dispatch --> PhysX[PhysX or OvPhysX context]
    Dispatch --> Newton[Newton context]
    Newton --> PhysicsScene[Import physics scene]
    Newton --> Shared[Import declared global roots once]
    Newton --> Worlds[Replicate env-scoped sources into worlds]
Loading

Reviews (1): Last reviewed commit: "Fix flakey video recording test (#7285)" | Re-trigger Greptile

## Summary

This PR is now the contact/raycast part of the Newton startup work:

- compile contact-sensor full-path expressions once and match them
directly, without regex-to-glob conversion or stage globbing;
- use Newton's current contact-sensing API names;
- declare raycast collision-shape requirements before model
finalization, so the model builds one correctly configured BVH instead
of rebuilding it during sensor initialization.

The contact-selector and sensing-API commits retain Chris's (`camevor`)
original authorship. The BVH lifecycle change incorporates the review
from isaac-sim#7296 while keeping this as Chris's PR.

The related ownership work is intentionally split by component: isaac-sim#7292
handles explicit global ownership, and isaac-sim#7295 handles model/articulation
startup. This PR contains no inactive-solver registration or
articulation-view changes and supersedes isaac-sim#7296.

Production code is `+29/-56` (net `-27`) against `909cc5decc5`.

## Startup benchmark

RTX 5090, CUDA device 1, 4096 environments, three fresh processes per
revision/task. Values are median end-to-end startup wall time. Base:
`909cc5decc5`. PR: `5d0e1b1595e`.

| Task | Base | PR | Change |
|---|---:|---:|---:|
| `Isaac-Cartpole` | 8.316 s | 8.410 s | +1.1% |
| `Isaac-Velocity-Rough-UnitreeGo2` | 16.363 s | 15.682 s | -4.2% |
| `Isaac-Lift-KukaAllegro-Camera` | 39.473 s | 37.605 s | -4.7% |

Cartpole has no contact/raycast workload here and is neutral within
process-startup noise. The sensor-heavy tasks show the intended gain:

| Median phase | Go2 base | Go2 PR | Kuka base | Kuka PR |
|---|---:|---:|---:|---:|
| `newton_contact_sensor` | 0.10 s | 0.04 s | 1.32 s | 0.24 s |
| `simulation_start` | 6.36 s | 5.91 s | 11.48 s | 10.39 s |

Raw end-to-end totals:

- Cartpole base: 9.368, 8.316, 8.195 s; PR: 8.410, 8.370, 8.476 s.
- Go2 rough base: 19.900, 16.363, 16.091 s; PR: 15.669, 15.682, 15.984
s.
- Kuka camera base: 41.328, 38.625, 39.473 s; PR: 37.580, 37.605, 38.785
s.

## Test plan

- `261 passed, 8 xpassed` across the Newton manager abstraction,
contact-sensor, and raycast-sensor suites.
- Repository formatting and pre-commit checks pass.
- Architecture checks reject the removed regex-to-glob path, deprecated
sensing names, duplicate BVH state, and late BVH fallback.
- The three 4096-environment benchmark tasks also provide end-to-end
Newton MJWarp startup coverage.

## Type of change

- Performance improvement
- Bug fix

---------

Co-authored-by: Octi Zhang <zhengyuz@nvidia.com>
(cherry picked from commit 21bc111)
@ooctipus ooctipus changed the title [Backport release/3.0.0] Cloner global paths and video test stabilization [Backport release/3.0.0] Cloner, Newton sensor startup, and video test fixes Aug 22, 2026
# Description

`normalize_camera_output_for_display()` normalized depth images using
the raw tensor maximum. Depth camera outputs may contain `inf` for
no-hit pixels and can contain other non-finite values, so the maximum
became non-finite; dividing by it could produce `NaN` pixels and
suppress finite depth contrast.

This change zeroes non-finite depth values before computing the display
scale, preserving finite depth normalization while keeping no-hit pixels
black.

## Validation

Adds unit coverage for:
- mixed finite, `inf`, and `NaN` depth values across supported depth
display types;
- all-non-finite depth input.

## Type of change

- Bug fix

---------

Signed-off-by: Sylvester Kaczmarek <16242628+sylvesterkaczmarek@users.noreply.github.com>
Co-authored-by: Antoine RICHARD <antoiner@nvidia.com>
(cherry picked from commit 0a05bbd)
@ooctipus ooctipus changed the title [Backport release/3.0.0] Cloner, Newton sensor startup, and video test fixes [Backport release/3.0.0] Cloner, sensor startup, and rendering fixes Aug 22, 2026
## Summary

This is the model/articulation part of the scoped Newton startup work.
It keeps startup work with the component that owns it:

- each Newton manager declares only the custom builder schema used by
its active solver;
- articulation target modes are resolved for the prototype and copied to
its replicas;
- the base physics manager owns the articulation-view registry;
- articulations create and register their view, while joint-wrench
sensors reuse it or create it when used independently;
- root expressions remain regular expressions instead of taking a lossy
regex-to-glob round trip.

The active-solver and reusable-view findings originated in Chris's
isaac-sim#7269. This PR isolates those model/articulation changes so isaac-sim#7269 can
remain the contact/raycast change under Chris's PR.

This replaces the cloner's unconditional MuJoCo + Kamino registration
and the duplicate joint-wrench view. There is no view scan,
manager-specific cache API, compatibility fallback, or duplicate
registry.

The production diff against the current base is `+57/-60` (net `-3`).

The explicit-global-ownership part is isaac-sim#7292. The contact/raycast part
remains in isaac-sim#7269.

## Startup benchmark

RTX 5090, CUDA device 1, 4096 environments, three fresh processes per
revision/task. Values are median end-to-end startup wall time; raw runs
are included below. Base: `86cf66651bd`. PR: `947869af173`.

| Task | Base | PR | Change |
|---|---:|---:|---:|
| `Isaac-Cartpole` | 8.316 s | 7.655 s | -8.0% |
| `Isaac-Velocity-Rough-UnitreeGo2` | 17.525 s | 14.844 s | -15.3% |
| `Isaac-Lift-KukaAllegro-Camera` | 41.691 s | 36.832 s | -11.7% |

Raw totals:

- Cartpole base: 10.595, 8.190, 8.316 s; PR: 7.655, 7.674, 7.469 s.
- Go2 rough base: 17.568, 17.525, 16.426 s; PR: 14.852, 14.844, 14.724
s.
- Kuka camera base: 47.590, 41.691, 38.724 s; PR: 36.832, 36.666, 37.032
s.

The measured `env_creation` medians improve from 6.473 to 5.801 s for
Cartpole, 15.558 to 12.863 s for Go2 rough, and 37.481 to 32.578 s for
Kuka camera.

## Test plan

- `247 passed` across the physics-manager lifecycle, Newton cloner,
manager abstraction, coupled-manager, and joint-wrench reuse tests.
- `test_rename_builder_labels.py`: `17 passed` after removing obsolete
solver-registration mocks.
- Ruff check and format pass on all changed Python files.
- The three 4096-environment benchmark tasks provide end-to-end Newton
MJWarp startup coverage.

(cherry picked from commit c4a2759)
@ooctipus ooctipus changed the title [Backport release/3.0.0] Cloner, sensor startup, and rendering fixes [Backport release/3.0.0] Newton startup, cloner, and rendering fixes Aug 22, 2026
@ooctipus
ooctipus merged commit 6e0cbe2 into isaac-sim:release/3.0.0 Aug 22, 2026
46 of 47 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation infrastructure isaac-lab Related to Isaac Lab team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants