# Isaac Sim 4.5.0 -> 5.0.0 Migration Guide ## Background - GPU: NVIDIA RTX PRO 6000 Blackwell (SM_120, compute capability 12.0) - IS 4.5.0 = Kit 106.5.0, DLSS Ray Reconstruction not supported on Blackwell (needs Kit >= 106.5.3), rendering has noise - IS 5.0.0 = Kit 107.x, fixes Blackwell rendering noise - IS 5.1.0 headless camera rendering completely broken (known bug GitHub #3250), abandoned ## Issues & Solutions ### 1. SimulationApp import path changed **Error:** `ModuleNotFoundError: No module named 'omni.isaac.kit'` **Cause:** IS 5.x changed the import path. **Fix** (`nimbus_extension/components/load/env_loader.py`): ```python try: from isaacsim import SimulationApp # IS 5.x except ImportError: from omni.isaac.kit import SimulationApp # IS 4.x ``` ### 2. USD metersPerUnit / upAxis not auto-compensated **Error:** RigidObject Z coordinate flying to 109.75+ after `world.reset()`, curobo `plan_single()` fails with "Plan did not converge" (goal_pos Z = 25261 meters). **Cause:** IS 4.5.0 auto-added `Rotate:unitsResolve` (X=90) and `Scale:unitsResolve` (0.01, 0.01, 0.01) xformOps to compensate for USD files with `metersPerUnit=0.01, upAxis=Y`. IS 5.0.0 no longer does this, causing PhysX to misinterpret RigidObject positions. GeometryObjects (no physics) were unaffected — only RigidObjects with PhysX simulation had the issue. **Fix:** Change USD metadata directly using pxr scripting. Run `fix_usd_metadata.py`: ```python from pxr import Usd, UsdGeom stage = Usd.Stage.Open(usd_path) UsdGeom.SetStageMetersPerUnit(stage, 1.0) # was 0.01 UsdGeom.SetStageUpAxis(stage, UsdGeom.Tokens.z) # was Y stage.GetRootLayer().Save() ``` All 14 `Aligned_obj.usd` files under `workflows/simbox/example_assets` have been batch-fixed. Backups saved as `.bak`. **Verification:** After fix, pick_object_right Z went from 109.75 to 0.7968 (normal). ### 3. scipy `scalar_first` parameter not supported **Error:** `Rotation.as_quat() takes no keyword arguments` **Cause:** IS 5.0.0 ships scipy < 1.11 which doesn't support `scalar_first` parameter in `Rotation.from_quat()` / `Rotation.as_quat()`. Dozens of files use this parameter. **Fix** (`launcher.py`): Monkey-patch via subclass at startup: ```python try: from scipy.spatial.transform import Rotation as _R _R.from_quat([1, 0, 0, 0], scalar_first=True) except TypeError: # Install Rotation subclass that handles scalar_first # See launcher.py for full implementation pass ``` ### 4. `arena_file_path` is None on second reset **Error:** `arena_file_path` becomes None after first episode. **Cause:** `self.task_cfg.pop("arena_file", None)` on line 107 of `simbox_dual_workflow.py` deletes the key after first use. **Fix** (`workflows/simbox_dual_workflow.py`): Cache the value: ```python self._arena_file_path = None # in __init__ # in reset(): arena_file_path = self.task_cfg.get("arena_file", None) or self._arena_file_path if arena_file_path: self._arena_file_path = arena_file_path ``` ### 5. "Task name should be unique in the world" **Error:** `AssertionError` when calling `world.add_task()` on second episode. **Cause:** World retains tasks from previous episode. **Fix** (`workflows/simbox_dual_workflow.py`): ```python self.world._current_tasks.clear() self.world.add_task(self.task) ``` ### 6. "A prim already exists at prim path" **Error:** Scene setup tries to re-create existing prims on repeated `world.reset()` calls. **Fix** (`workflows/simbox/core/tasks/banana.py`): Add `_scene_initialized` guard: ```python def set_up_scene(self, scene): if getattr(self, '_scene_initialized', False): self._task_objects = {} self._task_objects |= ( getattr(self, 'fixtures', {}) | getattr(self, 'objects', {}) | getattr(self, 'robots', {}) | getattr(self, 'cameras', {}) ) return self._scene_initialized = True super().set_up_scene(scene) ``` ### 7. Collision group prim already exists **Error:** Collision group prims persist across resets. **Fix** (`workflows/simbox/core/utils/collision_utils.py`): Remove existing collision prims before re-creating: ```python collision_prim = stage.GetPrimAtPath(collision_root_path) if collision_prim.IsValid(): stage.RemovePrim(collision_root_path) ``` ### 8. DomeLight environment map tilted **Error:** HDR environment map appears rotated/tilted in viewport and rendered output. **Cause:** DomeLight rotation was randomized on all 3 axes (X, Y, Z). Rotating X/Y tilts the environment. **Fix** (`workflows/simbox/core/tasks/banana.py`): Only rotate Z axis: ```python # Before: rotation = [random.uniform(r[0], r[1]) for _ in range(3)] # After: rotation = [0.0, 0.0, random.uniform(r[0], r[1])] ``` ## Files Modified | File | Change | |------|--------| | `nimbus_extension/components/load/env_loader.py` | SimulationApp import compatibility | | `launcher.py` | scipy Rotation monkey-patch | | `workflows/simbox_dual_workflow.py` | arena_file caching, task clearing, task reuse | | `workflows/simbox/core/tasks/banana.py` | Scene re-init guard, DomeLight rotation fix | | `workflows/simbox/core/utils/collision_utils.py` | Collision group cleanup | | `workflows/simbox/example_assets/**/Aligned_obj.usd` | metersPerUnit=1.0, upAxis=Z | | `fix_usd_metadata.py` | Batch USD metadata fix script | ## Tools Migration tools are located in the `migerate/` directory. ### scan_usd_metadata.py — Scan USD metadata Scan all USD files and report their `metersPerUnit` / `upAxis`: ```bash conda activate banana500 # Scan entire project python migerate/scan_usd_metadata.py --root . # Scan specific directory python migerate/scan_usd_metadata.py --root workflows/simbox/example_assets ``` Exit code: 0 = all OK, 1 = found files with non-standard metadata. 建议扫描后丢给大模型分析一下然后再做下一步 ### fix_usd_metadata.py — Batch fix USD metadata Fix `metersPerUnit` and `upAxis` in USD files, with backup/restore support: ```bash conda activate banana500 # Dry run — see what would be fixed, no changes made python migerate/fix_usd_metadata.py --root . --dry-run --skip curobo,robot # Fix example assets only (default) python migerate/fix_usd_metadata.py --root workflows/simbox/example_assets # Fix all USD in project, skip robot/curobo models python migerate/fix_usd_metadata.py --root . --skip curobo,robot # Fix only Aligned_obj.usd files python migerate/fix_usd_metadata.py --root . --pattern "Aligned_obj.usd" # Restore from backups (undo all fixes) python migerate/fix_usd_metadata.py --root workflows/simbox/example_assets --restore ``` **Important:** Do NOT fix robot USD (curobo, split_aloha) — their metersPerUnit/upAxis are intentionally set for their own coordinate systems. Use `--skip` to exclude them. ## Notes - `plan_single()` occasionally returns None for edge-case target poses (workspace boundary). This is normal and happens in IS 4.5.0 too. - Example HDR is only 1k resolution — production should use 4k/8k for better background quality. - Example `envmap_lib` only has 1 HDR file — add more for randomization diversity. - `non_recyclable_garbage/obj_0` does not exist in example assets (only obj_1~obj_11). Config changed to use `obj_1`.