You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add scene_prep utilities and update Isaac Sim launch scripts (#324)
* Add scene_prep utilities and update Isaac Sim launch scripts
Add simulation/isaac-sim/utils/scene_prep.py with four helpers:
- scale_stage_prim: apply uniform XYZ scale to a stage prim
- add_colliders: recursively apply CollisionAPI to all mesh prims
- add_dome_light: add/update a dome light (intensity=3500, exposure=-3)
- save_scene_as_contained_usd: collect Nucleus assets into a local directory
Update example_one and example_two launch scripts to use scene_prep
for environment scaling, collision setup, and lighting instead of
inline UsdLux calls. Fix two_drone_scene_import.
Update write-isaac-sim-scene SKILL.md to reference scene_prep utilities
and ignore prepare_scene.py in .gitignore.
* updated docs
Four reusable helpers that cover the most common environment setup tasks. Import them as shown in Step 3.
520
+
521
+
| Function | When to use |
522
+
|----------|-------------|
523
+
|`scale_stage_prim(stage, prim_path, scale)`| Nucleus assets authored in centimetres need `STAGE_SCALE=0.01`; assets already in metres use `1.0`. |
524
+
|`add_colliders(stage_prim)`|**Must** be called for physics to interact with environment meshes. Without it drones fall through the floor. Call after scaling. |
525
+
|`add_dome_light(stage, **kwargs)`| Adds uniform hemisphere lighting. Defaults: `intensity=3500`, `exposure=-3`. Pass kwargs to override, e.g. `add_dome_light(stage, intensity=5000)`. |
526
+
|`save_scene_as_contained_usd(src_url, output_dir)`| Copies a Nucleus-hosted stage (and all its textures/MDLs) to a local directory using `omni.kit.usd.collect.Collector`. Useful for archiving or offline replay. |
527
+
528
+
**Two-step save pattern** used internally by `save_scene_as_contained_usd`:
529
+
1.`export_as_stage_async` — writes a flat `.usd` of the live stage
530
+
2.`Collector` — resolves and copies all referenced Nucleus assets locally
531
+
532
+
Set `SAVE_SCENE_TO = None` in your script to skip saving entirely.
533
+
534
+
---
535
+
501
536
### Multi-Robot Scenarios
502
537
503
538
For multiple robots, spawn additional vehicles with unique IDs and ports:
`scene_prep.py` provides helpers that are shared across all example launch scripts:
58
+
59
+
| Function | Purpose |
60
+
|----------|---------|
61
+
|`scale_stage_prim(stage, prim_path, scale_factor)`| Applies a uniform XYZ scale transform to the prim at `prim_path`, clearing any existing xform ops first. Use `0.01` for Nucleus assets authored in centimetres; use `1.0` for assets already in metres. |
62
+
|`add_colliders(stage_prim)`| Recursively walks every child of `stage_prim` and applies `UsdPhysics.CollisionAPI` to each `UsdGeom.Mesh`. **Must be called or drones fall through the floor.** Skips prims that already have the API. |
63
+
|`add_dome_light(stage, intensity=3500, exposure=-3)`| Adds a hemisphere light at `/World/DomeLight` (or updates it if it already exists). Pass `intensity` / `exposure` keyword arguments to override the defaults. |
64
+
|`save_scene_as_contained_usd(source_usd_url, output_dir)`| Copies the stage and all its dependencies (textures, MDL materials) from a Nucleus `omniverse://` URL into a local directory via `omni.kit.usd.collect.Collector`. Set `SAVE_SCENE_TO = None` in your script to skip this step. |
65
+
|`get_stage_meters_per_unit(stage)`| Returns `(meters_per_unit, scene_scale_factor)`. Multiply metric coordinates by `scene_scale_factor` to convert them into stage-space units. Useful for computing drone spawn heights when `STAGE_SCALE != 1.0`. |
66
+
67
+
#### Loading `scene_prep`
68
+
69
+
`scene_prep.py` lives in `utils/`, which is not on `sys.path` by default. The example scripts add it at runtime before importing:
| Drone falls through the floor immediately |`add_colliders` was not called | Call `add_colliders(stage_prim)` after loading the environment |
107
+
| Colliders applied to wrong-scale geometry |`add_colliders` called before `scale_stage_prim`| Always call `scale_stage_prim` first, then `add_colliders`|
108
+
| Physics behaves erratically after colliders added | Update frames not pumped after `add_colliders`| Pump at least 10 `omni.kit.app.get_app().update()` calls after `add_colliders`|
109
+
|`ImportError: No module named 'omni'` at script top |`omni` imported before `SimulationApp()`| Move all `omni.*` imports to after the `SimulationApp(...)` line |
110
+
|`scene_prep` not found / `ModuleNotFoundError`|`utils/` not on `sys.path` in Isaac Sim's Python | Use `sys.path.insert` to add the `utils/` directory before importing `scene_prep`|
111
+
| Drone spawns at wrong height in cm-scale scene | Spawn coordinates not converted to stage space | Multiply metric `init_pos` values by `scene_scale` from `get_stage_meters_per_unit`|
69
112
70
-
5. Update your environment variables:
71
-
- Set the ISAAC_SIM_GUI variable to point to your newly saved .usd file (make sure to put the path within the docker container or in the omniverse server)
72
-
- Set ISAAC_SIM_USE_STANDALONE to "false" to load this saved environment directly next time.
73
113
74
114
## Known bugs and workarounds for Scripted Scene Generation
75
115
@@ -94,4 +134,6 @@ Occasionally, the right camera in a stereo camera pair may fail to initialize.
94
134
The drone not arming/taking off can be a symptom of the PX4Multirotor Node not being recognized in omnigraph. This may be due the `pegasus.simulator` extension not being loaded.
95
135
96
136
- To fix, launch the simulator with `airstack up isaac-sim`, in the toolbar, click Window -> Extensions -> Third Party, serach for "pegasus", select the "PEGASUS SIMULATOR" and enable "AUTOLOAD"
97
-
- Restart your docker container by running `airstack down isaac-sim && airstack up isaac-sim` and the extension should load every time now.
137
+
- Restart your docker container by running `airstack down isaac-sim && airstack up isaac-sim` and the extension should load every time now.
0 commit comments