Support Demo Scripts With Multiple Backends#5771
Conversation
Signed-off-by: Yize Wang <yizew@nvidia.com>
There was a problem hiding this comment.
Follow-up Review (a427283): New commits address several concerns and add new features.
✅ Issues Resolved
-
has_no_alive_visualizer_windowinfinite loop — FIXED 🎉- Old:
bool(sim.visualizers and not any(v.is_running() and not v.is_closed for v in sim.visualizers)) - New:
visualizers = sim.visualizers or ()+return not any(...) - Empty/None visualizers now correctly return
True("no alive windows"), allowing the loop to exit. This was the most critical issue from the previous review.
- Old:
-
PhysX + Newton visualizer combination — NOW SUPPORTED
- Previous TODO ("Not supported yet. Investigation needed.") has been implemented
- Comment clarifies: "PhysX still launches Isaac Sim Kit headless because it depends on Kit extensions"
- The
if viz_type == "kit" or args.physics == "physx"condition correctly handles this case
-
Code simplification
dtfolded directly intoSimulationCfg(dt=0.005, ...)— cleaner- Articulation instantiation simplified:
Articulation(CFG.replace(...))instead of intermediate_cfgvariables - Loop condition cleaner:
while not has_no_alive_visualizer_window(sim):instead of break-inside-while-True
🆕 New Additions
-
get_usage_examples()helper function — Extracts bash examples from docstrings for argparse epilog. Nice UX improvement for--helpoutput. -
Expanded docstring examples — More usage combinations documented (physx+kit, physx+newton, newton_mjwarp+kit, etc.)
-
Stricter visualizer validation —
if not isinstance(args.visualizer, list) or len(args.visualizer) != 1: raise ValueError(...)— Explicit error instead of silent fallback
⚠️ Remaining Concerns (from original review)
-
Relative import
from demo_helper import ...— Still assumes working directory isscripts/demos/. This may break if invoked from a different directory. -
args.visualizer = [viz_type]mutation — Still present inresolve_backend_and_visualizer(L65). The helper mutates the args namespace before passing to AppLauncher. -
conflict_handler="resolve"removal — Good: this was removed. Butparser.set_defaults(visualizer=["kit"])now sets a default that may conflict with AppLauncher's--visualizerhandling. Worth verifying this doesn't cause issues. -
No tests added — PR still lacks unit tests for the new helper functions.
📋 Summary
| Previous Issues | Status |
|---|---|
Infinite loop in has_no_alive_visualizer_window |
✅ Fixed |
| PhysX + Newton visualizer unsupported | ✅ Fixed |
| Relative import fragility | ⏳ Not addressed |
| Args mutation side-effect | ⏳ Not addressed |
| No tests | ⏳ Not addressed |
Verdict: The critical infinite loop bug is fixed 🎉. The remaining concerns are minor/stylistic. This looks much better than before.
🤖 Follow-up review by Isaac Lab Review Bot
Update (b20cdab): New commits add two documentation comments to scripts/demos/quadrupeds.py:
- Comment explaining why Kit visualizer is the default
- Comment before
main()call
These are purely cosmetic changes — no functional code modified. Previous concerns remain unchanged (see summary table above). No new issues.
Update (5e57982): Added physx_cfg parameter to resolve_backend_and_visualizer(), allowing callers to pass custom PhysX configuration instead of always using default PhysxCfg(). Clean enhancement with backward compatibility (parameter is optional). No new issues.
Greptile SummaryThis PR extracts a
Confidence Score: 5/5Safe to merge — the changes are additive, the loop-exit predicate is consistent with existing scripts, and the context manager correctly defers Kit launch without leaking resources. The refactoring is narrowly scoped to the demo layer. No files require special attention. Important Files Changed
Reviews (2): Last reviewed commit: "Recover 2 Comments" | Re-trigger Greptile |
| if needs_kit: | ||
| from isaaclab.app import AppLauncher | ||
|
|
||
| args.visualizer = [viz_type] | ||
| close_fn = AppLauncher(args).app.close |
There was a problem hiding this comment.
Mutable side-effect on caller's
args namespace
args.visualizer is mutated in-place from a str (as parsed by the script's own --visualizer argument) to a list before AppLauncher is constructed. This leaks into the caller's namespace after the context manager exits and makes resolve_backend_and_visualizer non-reentrant. Using a shallow copy of the namespace would contain the mutation to the helper.
| if needs_kit: | |
| from isaaclab.app import AppLauncher | |
| args.visualizer = [viz_type] | |
| close_fn = AppLauncher(args).app.close | |
| if needs_kit: | |
| from isaaclab.app import AppLauncher | |
| import copy | |
| kit_args = copy.copy(args) | |
| kit_args.visualizer = [viz_type] | |
| close_fn = AppLauncher(kit_args).app.close |
Signed-off-by: Yize Wang <yizew@nvidia.com>
hujc7
left a comment
There was a problem hiding this comment.
Maybe need to add some smoke test generally for demos?
| return scene_entities, origins | ||
|
|
||
|
|
||
| def run_simulator(sim: sim_utils.SimulationContext, entities: dict[str, Articulation], origins: torch.Tensor): |
There was a problem hiding this comment.
Any reason to remove the type hint here?
There was a problem hiding this comment.
Same reason as my last comment: https://github.com/isaac-sim/IsaacLab/pull/5771/changes#r3310474409. These types are not defined yet (these packages not imported). Let me know if my understanding in the previous comment is wrong.
There was a problem hiding this comment.
I think we can use from __future__ import annotations and type checking for this. shouldn't be necessary to remove the type hints
Signed-off-by: Yize Wang <yizew@nvidia.com>
Signed-off-by: Yize Wang <yizew@nvidia.com>
| ./isaaclab.sh -p scripts/demos/quadrupeds.py --physics newton_mjwarp --visualizer newton | ||
|
|
||
| # Usage with the PhysX backend without Kit (launches Newton visualizer). | ||
| # TODO(yizew@nvidia.com): Not supported yet. Investigation needed. |
There was a problem hiding this comment.
Is physx + newton expected to work by design? physx seems dependent on IsaacSim. I need to properly resolve this dependency if we want this pair to work.
There was a problem hiding this comment.
Was it just the kit launch? or there are other issues?
There was a problem hiding this comment.
nit: ideally this help message should also show up when run with -h/--help
There was a problem hiding this comment.
Added help messages in the "Append Usage Examples to Help Menu" commit.
Signed-off-by: Yize Wang <yizew@nvidia.com>
Signed-off-by: Yize Wang <yizew@nvidia.com>
Signed-off-by: Yize Wang <yizew@nvidia.com>
| ./isaaclab.sh -p scripts/demos/quadrupeds.py --physics newton_mjwarp --visualizer newton | ||
|
|
||
| # Usage with the PhysX backend without Kit (launches Newton visualizer). | ||
| # TODO(yizew@nvidia.com): Not supported yet. Investigation needed. |
There was a problem hiding this comment.
Was it just the kit launch? or there are other issues?
Signed-off-by: Yize Wang <yizew@nvidia.com>
Signed-off-by: Yize Wang <yizew@nvidia.com>
Signed-off-by: Yize Wang <yizew@nvidia.com>
|
|
||
|
|
||
| @contextmanager | ||
| def resolve_backend_and_visualizer(args, newton_cfg=None): |
There was a problem hiding this comment.
The option is limited inside ["kit", "newton"], to avoid dealing with rerun or vizer and to minimize the branches in demo_helper.py. Please let me know if these 2 visualizers are also supposed to be supported.
There was a problem hiding this comment.
I think it'd be nice to also support rerun and viser so that we can be consistent across all the scripts
|
@greptileai review |
| # Resolve visualizer cfg | ||
| if not isinstance(args.visualizer, list) or len(args.visualizer) != 1: | ||
| raise ValueError("Demos support exactly one --visualizer value: kit or newton.") | ||
| viz_type = args.visualizer[0] |
There was a problem hiding this comment.
why do we only parse the first element? is there a limitation to supporting multiple visualizers like the training scripts?
| elif args.physics == "newton_mjwarp": | ||
| from isaaclab_newton.physics import MJWarpSolverCfg, NewtonCfg | ||
|
|
||
| DEFAULT_NEWTON_CFG = NewtonCfg( |
There was a problem hiding this comment.
how generalizable is this cfg? do we expect this to work for most scripts? if not, it may be better to just keep this as a default MjWarpSolverCfg() object.
|
|
||
|
|
||
| @contextmanager | ||
| def resolve_backend_and_visualizer(args, newton_cfg=None): |
There was a problem hiding this comment.
I think it'd be nice to also support rerun and viser so that we can be consistent across all the scripts
| # Simulate physics | ||
| while simulation_app.is_running(): | ||
| # Exit when every visualizer window has been closed (works for kit and newton) | ||
| while not has_no_alive_visualizer_window(sim): |
There was a problem hiding this comment.
the double negative can be a bit confusing. would it make sense to make the utility has_alive_visualizer_window instead?
| return scene_entities, origins | ||
|
|
||
|
|
||
| def run_simulator(sim: sim_utils.SimulationContext, entities: dict[str, Articulation], origins: torch.Tensor): |
There was a problem hiding this comment.
I think we can use from __future__ import annotations and type checking for this. shouldn't be necessary to remove the type hints
| # Usage with the default PhysX backend (launches Isaac Sim Kit by default). | ||
| ./isaaclab.sh -p scripts/demos/quadrupeds.py | ||
| ./isaaclab.sh -p scripts/demos/quadrupeds.py --visualizer kit | ||
| ./isaaclab.sh -p scripts/demos/quadrupeds.py --physics physx | ||
| ./isaaclab.sh -p scripts/demos/quadrupeds.py --physics physx --visualizer kit | ||
|
|
||
| # Usage with the kit-less Newton (MJWarp) backend (launches Isaac Sim Kit by default). | ||
| ./isaaclab.sh -p scripts/demos/quadrupeds.py --physics newton_mjwarp | ||
| ./isaaclab.sh -p scripts/demos/quadrupeds.py --physics newton_mjwarp --visualizer kit | ||
|
|
||
| # Usage with the Newton (MJWarp) backend without Kit (launches Newton visualizer). | ||
| ./isaaclab.sh -p scripts/demos/quadrupeds.py --physics newton_mjwarp --visualizer newton | ||
|
|
||
| # Usage with the PhysX backend and Newton visualizer. | ||
| # PhysX still launches Isaac Sim Kit headless because it depends on Kit extensions. | ||
| ./isaaclab.sh -p scripts/demos/quadrupeds.py --physics physx --visualizer newton |
There was a problem hiding this comment.
this could be simplified a bit to avoid duplicates
Signed-off-by: Yize Wang <yizew@nvidia.com>
Description
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context.
List any dependencies that are required for this change.
Fixes # (issue)
Type of change
Screenshots
Please attach before and after screenshots of the change if applicable.
Checklist
pre-commitchecks with./isaaclab.sh --formatconfig/extension.tomlfileCONTRIBUTORS.mdor my name already exists there