[Newton] Fix kit-less mode and Newton v0.2.2 compatibility#5124
[Newton] Fix kit-less mode and Newton v0.2.2 compatibility#5124Kripner wants to merge 3 commits intoisaac-sim:dev/newtonfrom
Conversation
…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).
Greptile SummaryThis PR fixes two classes of issues blocking kit-less (Newton) mode on the Key changes:
Confidence Score: 5/5Safe 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
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]
|
| import urllib.request | ||
|
|
||
| try: | ||
| urllib.request.urlretrieve(cur_url, target_path) |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
🤖 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:
- Import guards — Wraps unconditional
import omni.*/from pxr/from .views/from .uistatements intry/except ModuleNotFoundErroracross 10 files, falling back toNoneorpass. Adds HTTPS fallback for S3 asset downloads usingurllib. Removes the unusedomniverseclientpip dependency. - Newton v0.2.2 compatibility — Pins Newton to
v0.2.2(from a stale commit 107 revisions behind). Fixesarticulation_data.pytensor indexing to handle variablendimfrom Newton's API. Renamesmask=→env_mask=inInteractiveScene.reset()call. Addshas_rtx_sensors()stub. Fixes stalewarp-langdev 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
Nonefallbacks for UI classes (BaseEnvWindow,ViewportCameraController,ManagerLiveVisualizer) are safe because their call sites are already guarded by"kit" in available_visualizersorself.sim.has_guichecks. - The
has_rtx_sensors() → Falsestub is correct: it's a plain method (not@property), matching callers likeself.sim.has_rtx_sensors()indirect_rl_env_warp.py. - The
_find_usd_references → set()short-circuit means recursive USD dependency downloading is disabled withoutpxr. This is acceptable — Newton handles mesh loading independently. - The
articulation_data.pydynamic-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.
|
dev/newton is not actively developed anymore. develop branch should support kit-less path very well! |
Note: as I outlined in #5084 (comment), |
|
|
The
dev/newtonbranch 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:import omnistatements that crash at import time when Omniverse is not installed. Add HTTPS fallback for downloading S3-hosted USD assets withoutomni.client. Removeomniverseclientfromsetup.py(never imported). Fix stalewarp-langdev pins.51ce35e8lacksbody_labelused bynewton_replicate.py). Fix API mismatches:articulation_data.pytensor indexing,direct_rl_env_warp.pykwarg name (mask->env_mask), addhas_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/newtonbranch 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)