From 91bdd35a603d53efdd1f86e96d0d5c3d2980e80f Mon Sep 17 00:00:00 2001 From: openminddev <147775420+openminddev@users.noreply.github.com> Date: Wed, 22 Jul 2026 00:16:00 +0000 Subject: [PATCH] sync: replace isaac_sim from OM1-ros2-sdk@867e903238c37fcb9de5525e3b78c81da3c6df06 --- isaac_sim/README.md | 9 ++ isaac_sim/configs/environments/warehouse.yaml | 15 ++- isaac_sim/environments.py | 109 ++++++++++++++++++ isaac_sim/run.py | 9 ++ isaac_sim/sim_config.py | 2 + 5 files changed, 143 insertions(+), 1 deletion(-) diff --git a/isaac_sim/README.md b/isaac_sim/README.md index d79d22c..2b613a6 100644 --- a/isaac_sim/README.md +++ b/isaac_sim/README.md @@ -55,3 +55,12 @@ source env_isaacsim/bin/activate python3 run.py --robot_type g1 # using default policy python3 run.py --robot_type g1 --policy_dir YOUR_POLICY_DIR # using your own policy ``` + +### Optional Scene Elements + +Some environment features are disabled by default and must be opted into with a flag: + +```bash +python3 run.py --vehicles # enable scripted waypoint vehicles (forklifts/carts) +python3 run.py --platforms # enable elevated platforms/ramps (e.g. the warehouse mezzanine) +``` diff --git a/isaac_sim/configs/environments/warehouse.yaml b/isaac_sim/configs/environments/warehouse.yaml index 49e7aab..35eee93 100644 --- a/isaac_sim/configs/environments/warehouse.yaml +++ b/isaac_sim/configs/environments/warehouse.yaml @@ -221,6 +221,19 @@ props: - [4.41, 23.70, 0.20] - [4.41, 24.50, 0.20] +# Mezzanine for elevated-nav testing +platforms: + - name: Mezzanine + center: [2.9, -20.9] + top_z: 1.0 + size_xy: [4.0, 4.0] + thickness: 0.1 + color: [0.85, 0.65, 0.13] + ramp: + direction: "-x" + run: 5.7 # slope = atan(top_z / run), ~10 deg; 14 deg made Go2 slip + width: 1.6 + remove_prims: - region: [-4.6, -1.2, 8.5, 15.0] @@ -232,7 +245,7 @@ agents: turn_rate: 0.8 pause: 2.0 loop: true - waypoints: [[3.0, 6.0], [3.0, -18.0], [-22.0, -18.0], [-22.0, 6.0]] + waypoints: [[3.0, 6.0], [3.0, -16.0], [-22.0, -16.0], [-22.0, 6.0]] - name: Forklift2 usd_isaac_relative: /Isaac/Props/Forklift/forklift.usd diff --git a/isaac_sim/environments.py b/isaac_sim/environments.py index 976f227..a3b383a 100644 --- a/isaac_sim/environments.py +++ b/isaac_sim/environments.py @@ -19,6 +19,7 @@ def add_environment(env_cfg) -> None: else: _add_warehouse(env_cfg) _add_props(env_cfg) + _add_platforms(env_cfg) _scale_scene_prims(env_cfg) _remove_scene_prims(env_cfg) @@ -63,6 +64,114 @@ def _add_props(env_cfg) -> None: ) +def _add_platforms(env_cfg) -> None: + """Spawn walkable slabs with optional access ramps (``platforms`` in the env config). + + Each entry is a horizontal slab whose walking surface sits at ``top_z``; + an optional ``ramp`` block adds an incline whose top edge is flush with + the slab edge and whose bottom edge meets the ground, so only the height + and horizontal ``run`` need to be given (slope = atan(top_z / run)). + """ + specs = getattr(env_cfg, "platforms", None) + if not specs: + return + + import math + + import omni.usd + from pxr import Gf, Sdf, UsdGeom, UsdPhysics, UsdShade + + stage = omni.usd.get_context().get_stage() + + material = UsdShade.Material.Define(stage, "/World/PlatformPhysicsMaterial") + phys_mat = UsdPhysics.MaterialAPI.Apply(material.GetPrim()) + phys_mat.CreateStaticFrictionAttr(1.2) + phys_mat.CreateDynamicFrictionAttr(1.0) + material.GetPrim().CreateAttribute( + "physxMaterial:frictionCombineMode", Sdf.ValueTypeNames.Token + ).Set("max") + + def _render_material(parent_path, color): + """Lit surface material (same pattern as the AprilTag dock body).""" + mat = UsdShade.Material.Define(stage, f"{parent_path}/RenderMaterial") + shader = UsdShade.Shader.Define(stage, f"{parent_path}/RenderMaterial/Shader") + shader.CreateIdAttr("UsdPreviewSurface") + shader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Color3f).Set( + Gf.Vec3f(*color) + ) + shader.CreateInput("roughness", Sdf.ValueTypeNames.Float).Set(0.6) + shader.CreateInput("metallic", Sdf.ValueTypeNames.Float).Set(0.1) + shader.CreateOutput("surface", Sdf.ValueTypeNames.Token) + mat.CreateSurfaceOutput().ConnectToSource(shader.ConnectableAPI(), "surface") + return mat + + def _make_box(path, color, render_mat): + cube = UsdGeom.Cube.Define(stage, path) + cube.CreateSizeAttr(1.0) + cube.CreateDisplayColorAttr([Gf.Vec3f(*color)]) + UsdPhysics.CollisionAPI.Apply(cube.GetPrim()) + binding = UsdShade.MaterialBindingAPI.Apply(cube.GetPrim()) + binding.Bind(material, materialPurpose="physics") + binding.Bind(render_mat) + return cube + + directions = { + "+x": (1.0, 0.0), + "-x": (-1.0, 0.0), + "+y": (0.0, 1.0), + "-y": (0.0, -1.0), + } + + for spec in specs: + name = spec.get("name", "Platform") + cx, cy = (float(v) for v in spec["center"]) + top_z = float(spec["top_z"]) + sx, sy = (float(v) for v in spec.get("size_xy", (4.0, 4.0))) + thickness = float(spec.get("thickness", 0.1)) + color = tuple(spec.get("color", (0.45, 0.45, 0.5))) + + stage.DefinePrim(f"/World/{name}", "Xform") + render_mat = _render_material(f"/World/{name}", color) + slab = _make_box(f"/World/{name}/Slab", color, render_mat) + xf = UsdGeom.Xformable(slab.GetPrim()) + xf.AddTranslateOp().Set(Gf.Vec3d(cx, cy, top_z - thickness / 2.0)) + xf.AddScaleOp().Set(Gf.Vec3f(sx, sy, thickness)) + + ramp = spec.get("ramp") + if not ramp: + logger.info("Platform %s: slab top z=%.2f (no ramp)", name, top_z) + continue + + dx, dy = directions[ramp.get("direction", "+x")] + run = float(ramp["run"]) + width = float(ramp.get("width", 1.6)) + theta = math.atan2(top_z, run) + length = math.hypot(run, top_z) + + # Centre the box on the incline midpoint, pushed half a thickness + # down the tilted surface normal so the top face runs slab-edge-to-ground. + half = sx / 2.0 if dx else sy / 2.0 + offset = half + run / 2.0 + sin_t, cos_t = math.sin(theta), math.cos(theta) + mx = cx + dx * (offset - sin_t * thickness / 2.0) + my = cy + dy * (offset - sin_t * thickness / 2.0) + mz = top_z / 2.0 - cos_t * thickness / 2.0 + + ramp_box = _make_box(f"/World/{name}/Ramp", color, render_mat) + xf = UsdGeom.Xformable(ramp_box.GetPrim()) + xf.AddTranslateOp().Set(Gf.Vec3d(mx, my, mz)) + xf.AddRotateZOp().Set(math.degrees(math.atan2(dy, dx))) + xf.AddRotateYOp().Set(math.degrees(theta)) + xf.AddScaleOp().Set(Gf.Vec3f(length, width, thickness)) + logger.info( + "Platform %s: slab top z=%.2f, ramp %.1f deg over %.1f m run", + name, + top_z, + math.degrees(theta), + run, + ) + + def _scale_scene_prims(env_cfg) -> None: """Enlarge baked scene prims listed under ``scale_prims`` in the env config.""" specs = getattr(env_cfg, "scale_prims", None) diff --git a/isaac_sim/run.py b/isaac_sim/run.py index fdaf2ed..59bd3cc 100644 --- a/isaac_sim/run.py +++ b/isaac_sim/run.py @@ -727,6 +727,13 @@ def main(): choices=sim_config.available_environment_types(), help="Scene to load (one per configs/environments/*.yaml)", ) + parser.add_argument( + "--platforms", + action="store_true", + default=False, + help="Enable elevated platforms/ramps (e.g. the warehouse mezzanine) " + "from the environment config. Disabled by default.", + ) args, _ = parser.parse_known_args() robot_cfg = sim_config.load_robot_config(args.robot_type) @@ -744,6 +751,8 @@ def main(): args.scan_source, "enabled" if robot_cfg.enable_2d_lidar else "disabled", ) + if not args.platforms: + env_config.platforms = None logger.info("Running %s robot simulation", args.robot_type.upper()) diff --git a/isaac_sim/sim_config.py b/isaac_sim/sim_config.py index 64362af..2f73c25 100644 --- a/isaac_sim/sim_config.py +++ b/isaac_sim/sim_config.py @@ -127,6 +127,7 @@ class EnvironmentConfig: scale_prims: Optional[list] = None apriltag_dock: Optional[dict] = None remove_prims: Optional[list] = None + platforms: Optional[list] = None @property def usd_local_abs(self) -> Optional[str]: @@ -206,6 +207,7 @@ def load_environment_config(env_type: str) -> EnvironmentConfig: scale_prims=data.get("scale_prims"), apriltag_dock=data.get("apriltag_dock"), remove_prims=data.get("remove_prims"), + platforms=data.get("platforms"), )