Skip to content

[Newton] Fix kit-less mode and Newton v0.2.2 compatibility#5124

Open
Kripner wants to merge 3 commits intoisaac-sim:dev/newtonfrom
Kripner:pr/newton-kitless-fixes
Open

[Newton] Fix kit-less mode and Newton v0.2.2 compatibility#5124
Kripner wants to merge 3 commits intoisaac-sim:dev/newtonfrom
Kripner:pr/newton-kitless-fixes

Conversation

@Kripner
Copy link
Copy Markdown

@Kripner Kripner commented Mar 29, 2026

The dev/newton branch supports running Isaac Lab without Omniverse (kit-less mode using the Newton physics backend), but several issues prevent it from working outside of Isaac Sim's bundled Python environment. Two fixes:

  • Guard unconditional import omni statements that crash at import time when Omniverse is not installed. Add HTTPS fallback for downloading S3-hosted USD assets without omni.client. Remove omniverseclient from setup.py (never imported). Fix stale warp-lang dev pins.
  • Pin Newton to v0.2.2 (the pinned commit 51ce35e8 lacks body_label used by newton_replicate.py). Fix API mismatches: articulation_data.py tensor indexing, direct_rl_env_warp.py kwarg name (mask -> env_mask), add has_rtx_sensors() stub.

All changes are backwards-compatible - when Omniverse is available, behavior is unchanged.

Context

The Newton kit-less mode is a key feature of Isaac Lab 3.0 Beta, but the dev/newton branch currently crashes on import without Omniverse installed. These fixes enable headless RL training on HPC clusters using only CUDA (no Omniverse/Isaac Sim).

Tested environments (training + Newton OpenGL visualization):

  • Isaac-Cartpole-Direct-Warp-v0 (direct workflow)
  • Isaac-Reach-Franka-Warp-v0 (manager-based warp workflow)
  • Isaac-Open-Drawer-Franka-v0 (manager-based standard workflow)

Kripner added 2 commits March 29, 2026 21:19
…llback

The dev/newton branch supports running Isaac Lab without Omniverse
(kit-less mode using the Newton physics backend), but several
unconditional imports prevent it from working:

- `isaaclab/utils/assets.py` unconditionally imports `omni.client` and
  `pxr.Sdf` at module level. Wrap in try/except and add HTTPS fallback
  using `urllib` for downloading S3-hosted USD assets without
  `omni.client`.

- Multiple files in `isaaclab/envs/` and `isaaclab_experimental/envs/`
  eagerly import from `isaaclab.ui.widgets` and `isaaclab.envs.ui`,
  which depend on `omni.ui`. Guard each with try/except, falling back
  to None. These classes are only used as default values in config
  dataclasses and for Omniverse viewport control.

- `isaaclab/setup.py` lists `omniverseclient` as a dependency. This
  package only exists inside Isaac Sim's bundled Python and is never
  imported anywhere in the source. Remove it.

- `isaaclab_experimental/setup.py` and `isaaclab_tasks_experimental/
  setup.py` pin `warp-lang>=1.9.0.dev20250825`, a dev build that has
  been removed from PyPI. Pin to `==1.11.1` (matching isaaclab's pin).

- `isaaclab/sim/__init__.py` imports from `.views` which does not exist
  as a module. Guard with try/except.

None of these changes affect behavior when Omniverse IS available --
all guards fall back gracefully.
The dev/newton branch pins Newton to commit 51ce35e8, but the code
(newton_replicate.py) uses `builder.body_label` which was only added
in Newton v0.2.2. The pinned commit is 107 commits before v0.2.2.
Pin to v0.2.2 which is compatible with warp-lang 1.11.1 and
mujoco-warp 3.5.0.

Additional fixes for API mismatches between the dev/newton code and
Newton v0.2.2:

- articulation_data.py: handle variable ndim from
  get_root_transforms() and get_root_velocities() instead of
  hardcoding [:, 0, 0] indexing.

- direct_rl_env_warp.py: use env_mask= instead of mask= when calling
  InteractiveScene.reset() (parameter was renamed).

- simulation_context.py: add has_rtx_sensors() stub that returns False
  in kit-less mode (method was removed during SimulationContext refactor
  but direct_rl_env_warp.py still references it).
@github-actions github-actions bot added bug Something isn't working isaac-lab Related to Isaac Lab team labels Mar 29, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 29, 2026

Greptile Summary

This PR fixes two classes of issues blocking kit-less (Newton) mode on the dev/newton branch: unconditional import omni / import omni.ui calls that crash at import time without Omniverse, and Newton v0.2.2 API mismatches introduced since the previously-pinned commit SHA. All changes are guarded so existing Omniverse behaviour is unchanged.

Key changes:

  • All omni.client, omni.ui, and pxr imports are now wrapped in try/except ModuleNotFoundError with None or boolean flag fallbacks across six env/sim files.
  • assets.py gains an HTTPS fallback path using urllib.request for check_file_path, retrieve_file_path, and read_file when omni.client is unavailable; _find_usd_references is short-circuited when pxr is absent.
  • simulation_context.py (Newton variant) adds the missing has_rtx_sensors() stub returning False.
  • direct_rl_env_warp.py fixes the maskenv_mask kwarg rename in scene.reset().
  • articulation_data.py replaces brittle hard-coded [:, 0, 0] / [:, 0] indexing with ndim-aware expressions for fixed-base vs. free articulations, and avoids a None-assignment bug for _sim_bind_root_com_vel_w.
  • omniverseclient removed from setup.py; warp-lang dev pin replaced with ==1.11.1; Newton pinned to v0.2.2 tag.
  • Four debug print() statements remain in articulation_data.py (lines 2292–2297) and should be removed before merge.

Confidence Score: 5/5

Safe to merge — all remaining findings are P2 style issues that do not affect correctness or runtime behaviour.

All P1-or-higher issues are resolved by this PR (import crashes, API mismatches, wrong kwarg). The only open findings are two P2 items: debug print statements in articulation_data.py and a legacy urlretrieve call in assets.py. Neither affects correctness or causes runtime failures.

source/isaaclab_newton/isaaclab_newton/assets/articulation/articulation_data.py — four debug print() calls should be cleaned up before merge.

Important Files Changed

Filename Overview
source/isaaclab_newton/isaaclab_newton/assets/articulation/articulation_data.py Fixes tensor indexing for fixed-base vs. free articulations using dynamic ndim checks; four debug print() statements remain and should be removed before merge.
source/isaaclab/isaaclab/utils/assets.py Adds HTTPS fallback for omni.client, guarding all three public API calls (check, retrieve, read); uses legacy urlretrieve in one branch while the other two branches already use urlopen.
source/isaaclab/isaaclab/sim/simulation_context.py Adds has_rtx_sensors() stub returning False, satisfying callers in direct_rl_env_warp.py without requiring the Omniverse renderer interface.
source/isaaclab_experimental/isaaclab_experimental/envs/direct_rl_env_warp.py Fixes kwarg rename mask → env_mask in scene.reset() call, aligning with the updated InteractiveScene API.
source/isaaclab/isaaclab/envs/manager_based_env.py Guards both ManagerLiveVisualizer and ViewportCameraController imports; both are only used inside "kit" visualizer guard blocks.
source/isaaclab_newton/setup.py Pins Newton to the v0.2.2 tag instead of a specific commit SHA that lacked the body_label attribute needed by newton_replicate.py.
source/isaaclab_experimental/setup.py Replaces stale pre-release warp-lang dev pin with the stable 1.11.1 release pin.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Python import / env init] --> B{omni.client available?}
    B -- Yes --> C[Use omni.client for Nucleus / asset ops]
    B -- No --> D{path is http/https?}
    D -- Yes --> E[Use urllib.request HEAD / urlopen / urlretrieve]
    D -- No --> F[Return 0 / raise RuntimeError]

    A --> G{omni.ui / pxr available?}
    G -- Yes --> H[ViewportCameraController / BaseEnvWindow / ManagerLiveVisualizer]
    G -- No --> I[Fallback = None - only used inside kit visualizer guard]

    A --> J{Newton scene.reset call}
    J --> K[env_mask= kwarg fixed in direct_rl_env_warp.py]

    A --> L{articulation_data _create_simulation_bindings}
    L --> M{is_fixed_base?}
    M -- Yes --> N[root_transforms with ndim-1 zero indices]
    M -- No --> O[root_transforms at index 0 if ndim gt 1 else root_transforms]
Loading

Comments Outside Diff (1)

  1. source/isaaclab_newton/isaaclab_newton/assets/articulation/articulation_data.py, line 2292-2297 (link)

    P2 Debug print() statements left in production code

    Four debug print statements were left in _create_simulation_bindings — these will spam stdout on every environment reset/init in any downstream training run:

    print("joint pos shape:", self._root_view.get_dof_positions(NewtonManager.get_state_0()).shape)
    print("joint vel shape:", self._root_view.get_dof_velocities(NewtonManager.get_state_0()).shape)
    # ... and two more on lines 2296-2297

    These should be removed before merge (or converted to logger.debug(...) if the shape information is genuinely useful for diagnostics).

Reviews (1): Last reviewed commit: "[Newton] Fix Newton v0.2.2 compatibility" | Re-trigger Greptile

import urllib.request

try:
urllib.request.urlretrieve(cur_url, target_path)
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 urlretrieve is a legacy API

urllib.request.urlretrieve is considered a legacy/deprecated helper (Python docs mark it as a "legacy interface"). It also has no streaming capability, so large USD files will be buffered entirely in memory before being written.

The preferred replacement is urllib.request.urlopen in a context manager with an explicit write loop:

import urllib.request

try:
    with urllib.request.urlopen(cur_url) as response, open(target_path, "wb") as out_file:
        out_file.write(response.read())
except Exception as e:
    raise RuntimeError(f"Unable to download file: '{cur_url}'. Error: {e}")

This is consistent with the pattern already used in read_file (line 193) and check_file_path (line 77).

Copy link
Copy Markdown

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

Choose a reason for hiding this comment

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

🤖 Isaac Lab Review Bot — PR #5124

Summary

This PR fixes two categories of issues on the dev/newton branch that prevent kit-less (Omniverse-free) operation:

  1. Import guards — Wraps unconditional import omni.* / from pxr / from .views / from .ui statements in try/except ModuleNotFoundError across 10 files, falling back to None or pass. Adds HTTPS fallback for S3 asset downloads using urllib. Removes the unused omniverseclient pip dependency.
  2. Newton v0.2.2 compatibility — Pins Newton to v0.2.2 (from a stale commit 107 revisions behind). Fixes articulation_data.py tensor indexing to handle variable ndim from Newton's API. Renames mask=env_mask= in InteractiveScene.reset() call. Adds has_rtx_sensors() stub. Fixes stale warp-lang dev pins.

Design Assessment

Approach: ✅ Correct. The fundamental strategy of guarding imports at the boundary and providing fallback behavior is the right pattern for optional-dependency support. The alternative (a full abstraction layer / backend interface) would be over-engineering at this stage.

Key design decisions verified:

  • All None fallbacks for UI classes (BaseEnvWindow, ViewportCameraController, ManagerLiveVisualizer) are safe because their call sites are already guarded by "kit" in available_visualizers or self.sim.has_gui checks.
  • The has_rtx_sensors() → False stub is correct: it's a plain method (not @property), matching callers like self.sim.has_rtx_sensors() in direct_rl_env_warp.py.
  • The _find_usd_references → set() short-circuit means recursive USD dependency downloading is disabled without pxr. This is acceptable — Newton handles mesh loading independently.
  • The articulation_data.py dynamic-ndim indexing preserves exact behavior when Newton returns the original tensor shapes, while gracefully handling v0.2.2's potentially different dimensionality.

Architecture Impact

Low risk. All changes are additive guards with no behavioral change when Omniverse IS available. The import-guard pattern is already used elsewhere in Isaac Lab. Dependency pins (warp-lang==1.11.1, newton@v0.2.2) align with the main isaaclab package.

Implementation Verdict

✅ Ship it. Clean, minimal, backwards-compatible. Two minor items below worth addressing.

Test Coverage

The author tested 3 environments (Cartpole-Direct-Warp, Reach-Franka-Warp, Open-Drawer-Franka) with training + Newton OpenGL visualization. No automated tests are added, but these are infrastructure-level import guards — testing requires an actual kit-less environment, which CI likely doesn't have.

CI Status

labeler — pass. No other CI checks ran (likely because dev/newton does not have the full CI pipeline configured yet).


Findings

🟡 Warning: urllib.request.urlretrieve is deprecated (assets.py:148)

urllib.request.urlretrieve has been informally deprecated since Python 3. While it still works, using urllib.request.urlopen with manual file writing (as you already do in read_file) would be more consistent and avoids the deprecation concern.

🔵 Improvement: Consider logging when falling back to kit-less paths (assets.py)

When _OMNI_AVAILABLE is False and the HTTPS fallback is used, there's no log message. A single logger.debug("omni.client not available, using HTTPS fallback for asset download") at import time (or on first use) would help debugging when users hit asset-download issues in kit-less mode.

🔵 Improvement: _find_usd_references returns empty set silently (assets.py:215)

When _PXR_AVAILABLE is False, _find_usd_references silently returns set(). If a user's USD references textures hosted on S3, they'll silently get missing assets. Consider logging a warning on the first call:

if not _PXR_AVAILABLE:
    logger.warning("pxr not available — USD reference resolution disabled; referenced assets will not be downloaded")
    return set()

Overall: Well-scoped fix that correctly enables the kit-less code path. The import guard pattern is appropriate and all fallback values are safe at their call sites.

@ooctipus
Copy link
Copy Markdown
Collaborator

dev/newton is not actively developed anymore.

develop branch should support kit-less path very well!

@diegoferigo-rai
Copy link
Copy Markdown

develop branch should support kit-less path very well!

Note: as I outlined in #5084 (comment), omniverseclient is still needed in the kit-less setup also in the develop branch, and I'm not sure if this in intended.

@ooctipus
Copy link
Copy Markdown
Collaborator

ooctipus commented Apr 3, 2026

omniverseclient should be pip installable publicly , so It should be kit-less compatible. Ahh I see your concern in the comment, let me discuss this with team

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working isaac-lab Related to Isaac Lab team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants