Agent Skills › isaac-sim/IsaacSim › spatial-reasoning

spatial-reasoning

GitHub

提供USD场景的3D空间推理能力,包括坐标变换、包围盒分析、布局规划和路径辅助。用于正确放置、缩放和排列场景资产,处理单位转换及变换矩阵顺序等核心数学问题。

.claude/skills/spatial-reasoning/SKILL.md isaac-sim/IsaacSim

触发场景

在USD场景中放置或排列3D资产 计算物体包围盒或碰撞检测 处理不同资产的米制单位转换 执行基于坐标系的旋转和平移操作

安装

npx skills add isaac-sim/IsaacSim --skill spatial-reasoning -g -y
更多选项

非标准路径

npx skills add https://github.com/isaac-sim/IsaacSim/tree/develop/.claude/skills/spatial-reasoning -g -y

不安装直接使用

npx skills use isaac-sim/IsaacSim@spatial-reasoning

指定 Agent (Claude Code)

npx skills add isaac-sim/IsaacSim --skill spatial-reasoning -a claude-code -g -y

安装 repo 全部 skill

npx skills add isaac-sim/IsaacSim --all -g -y

预览 repo 内 skill

npx skills add isaac-sim/IsaacSim --list

SKILL.md

Frontmatter
{
    "name": "spatial-reasoning",
    "license": "Apache-2.0",
    "metadata": {
        "author": "Renato Gasoto <info@nvidia.com>"
    },
    "description": "USD spatial math: transforms, bbox, layouts, and planning helpers. Use when placing, scaling, or arranging scene assets."
}

3D Spatial Reasoning

Purpose

Apply coordinate math, bounding-box analysis, collision-free layouts, look-at placement, and lightweight path/grid helpers when composing USD scenes.

Prerequisites

  • Built Isaac Sim ($ISAAC_SIM_DIR or _build/linux-x86_64/release).
  • NVIDIA GPU with a current driver (nvidia-smi).
  • Shell env contract from isaac-sim-orchestrator: $ISAAC_SIM_DIR, $ISAAC_LAB_DIR, $WORKSPACE_DIR.

Limitations

  • Targets Isaac Sim 6 / Kit 110 unless a section states otherwise.
  • Does not replace official NVIDIA documentation for unsupported edge cases.

Troubleshooting

Error / symptom Cause Solution
Extension or import not found Wrong $ISAAC_SIM_DIR or stale build Point env vars at _build/linux-x86_64/release or rebuild
Black or empty frames Missing lights or non-RTX render mode Add dome/key light; confirm RTX / PathTracing settings
Hang on stage load or first render MDL compile or oversized stage Follow isolation steps in isaac-sim-troubleshooting

Core spatial math for placing objects correctly in OpenUSD scenes.

Available Scripts

Script Purpose Arguments
scripts/spatial.py Spatial see script --help

Running scripts

From agent runtimes that expose skill execution helpers, invoke helpers with run_script():

run_script("scripts/spatial.py", args=["--help"])

From a built Isaac Sim tree, run the same file with ./python.sh (Linux) or python.bat (Windows) from _build/*/release, or execute shell helpers directly when they do not require the simulator.

Coordinate System

  • Stage: Z-up, metersPerUnit=1.0 (meters)
  • All placement coordinates are in meters
  • Rotations: always AddRotateXYZOp() — never individual axis ops

metersPerUnit Conversion (CRITICAL)

Assets have their own metersPerUnit. Common values:

  • 1.0 = meters (robots, environments)
  • 0.01 = centimeters (most KION lightspeed assets, SimModelAnimation, compositions)

Rule: Before referencing any asset, read its metersPerUnit:

asset_stage = Usd.Stage.Open(asset_path)  # Must use Usd.Stage, NOT Sdf.Layer
mpu = UsdGeom.GetStageMetersPerUnit(asset_stage)

Sdf.Layer.FindOrOpen() FAILS SILENTLY on binary .usd crate files — always returns None. Never use it for mpu detection.

Getting real-world size of an asset:

bbox_cache = UsdGeom.BBoxCache(Usd.TimeCode.Default(), [UsdGeom.Tokens.default_])
raw_range = bbox_cache.ComputeWorldBound(default_prim).ComputeAlignedRange()
raw_size = raw_range.GetMax() - raw_range.GetMin()
real_size_meters = [raw_size[i] * mpu for i in range(3)]

Transform Matrix Order (CRITICAL)

When placing an asset with scale + rotation + translation:

# CORRECT: Translate * Rotate * Scale
# Scale shrinks asset to meters, Rotate orients it, Translate positions it
scale_mat = Gf.Matrix4d().SetScale(Gf.Vec3d(mpu, mpu, mpu))
rot_mat = Gf.Matrix4d().SetRotate(Gf.Rotation(Gf.Vec3d(0,0,1), heading_deg))
trans_mat = Gf.Matrix4d().SetTranslate(Gf.Vec3d(x, y, z))
xf.MakeMatrixXform().Set(trans_mat * rot_mat * scale_mat)

WRONG: scale * translate scales the translation vector too — a 3m offset becomes 0.03m for mpu=0.01.

Placement Helper

def place(stage, prim_path, asset_path, x, y, z=0, rot_z=0, mpu=0.01):
    """Place an asset with correct metersPerUnit scaling."""
    prim = stage.DefinePrim(prim_path, "Xform")
    prim.GetReferences().AddReference(asset_path)
    xf = UsdGeom.Xformable(prim)
    S = Gf.Matrix4d().SetScale(Gf.Vec3d(mpu, mpu, mpu))
    R = Gf.Matrix4d().SetRotate(Gf.Rotation(Gf.Vec3d(0,0,1), rot_z))
    T = Gf.Matrix4d().SetTranslate(Gf.Vec3d(x, y, z))
    xf.MakeMatrixXform().Set(T * R * S)
    return prim

Look-At Camera Math

def look_at_rotation(cam_pos, target_pos):
    """Compute XYZ Euler rotation for camera to look at target. Z-up stage."""
    dx = target_pos[0] - cam_pos[0]
    dy = target_pos[1] - cam_pos[1]
    dz = target_pos[2] - cam_pos[2]
    horiz = math.sqrt(dx*dx + dy*dy)
    pitch = math.degrees(math.atan2(horiz, -dz))
    yaw = math.degrees(math.atan2(dx, -dy))
    return Gf.Vec3f(pitch, 0, yaw)

Grid Layout

def grid_positions(n_items, spacing, origin=(0,0)):
    """Generate grid positions for n items with given spacing."""
    cols = min(8, math.ceil(math.sqrt(n_items * 1.5)))
    positions = []
    for i in range(n_items):
        row, col = divmod(i, cols)
        x = origin[0] + col * spacing
        y = origin[1] + row * spacing
        positions.append((x, y))
    return positions, cols

Baked Waypoint Animation

See bake_waypoints() in scripts/spatial.py (28 lines).

Zone Boundary Check

def in_zone(x, y, zone):
    """Check if (x,y) is within a zone dict with 'x':[min,max], 'y':[min,max]."""
    return zone['x'][0] <= x <= zone['x'][1] and zone['y'][0] <= y <= zone['y'][1]

Shell vs Interior Coordinate Alignment (CRITICAL)

The KION mega warehouse shell at mpu=0.01 is ~170×100m in stage meters. When placing interior cubes/assets at specific zone coordinates (e.g., racks at X=30-60), the camera must be positioned WITHIN the layout zone, not at the building origin.

Hero camera rule: Place camera at (zone_start_x + 3, zone_center_y, 2.5) looking INTO the zone — never at (0, y, z) which will be inside the shell wall geometry.

Top-down camera rule: Place at (layout_center_x, layout_center_y, max(W,D)*0.9) with focal 12mm. This is the money shot for layout validation — always render this first.

Camera-to-layout match: Before rendering, verify camera pos is inside the bounding box of your placed content, not just inside the shell.

Render File Size Validation

Size Meaning
~82KB Blank grey — nothing rendered
~275KB Viewport grid only — stage loaded but camera sees nothing
1-2MB Partial scene — some geometry visible
2-5MB Full scene with detail
Same size across all views Camera switching FAILED — all captures from same view

If all renders within a stage have identical byte counts, the camera path switch didn't take effect. Fix: create a fresh camera prim for each shot (remove + redefine), not just change the path.

KION Asset Scale Map (CRITICAL — 2026-03-14)

The KION asset tree has MIXED units. ALWAYS validate with Usd.Stage.Open() + UsdGeom.BBoxCache:

Asset Category Example Raw BBox True Units Scale Factor
Shell (sm_warehouse_mega) 18586×14200 raw Centimeters 0.01
GSRC module 58.3×82.8×8.4 raw Meters 1.0
Conveyors 0.9×6.7×1.7 raw Meters 1.0
PackStation 2.9×2.6×2.9 raw Meters 1.0
Depalletizer 2.8×1.2×3.3 raw Meters 1.0
PutAway Rack 0.8×5.3×2.0 raw Meters 1.0
Trolly 0.7×1.6×1.3 raw Meters 1.0
SimReady racks 2.5×1.3×3.7 Meters 1.0
SimReady barriers 6.1×0.5×1.7 Meters 1.0
claw_lighting.usd ~17000 raw Centimeters 0.01

Rule: ONLY Shell + Lighting need 0.01. ALL other KION assembly assets are in meters.

Placing meter-scale assets at mpu=0.01 makes them 100× too small (invisible). This bug silently breaks scenes — assets "exist" in USD but render as sub-centimeter specs.

Validation command:

stage = Usd.Stage.Open(asset_path)
bbox = UsdGeom.BBoxCache(0, [UsdGeom.Tokens.default_]).ComputeWorldBound(stage.GetPseudoRoot()).ComputeAlignedRange()
size = bbox.GetMax() - bbox.GetMin()
# If any dimension > 1000 → centimeters (use 0.01)
# If all dimensions < 100 → meters (use 1.0)

Common Gotchas

0a. Shell interior bounds ≠ shell bbox — sm_warehouse_mega bbox is (-13.2,-5.2)→(172.6,136.8) but Corner module starts at X=0.6 and Center (floor) at X=11.6. Actual usable interior: X=3-170, Y=0-134. Always check module children bboxes, not just root. 0b. UsdGeom.Cube extent is [-1,1]³ (size 2) — scale by w/2, d/2, h/2 NOT w, d, h. Using full dimensions makes every block 2× its intended size. This caused 14,570 phantom clashes in uber warehouse v2. 0b. SetTranslateOnly() WIPES scale from Gf.Matrix4d — if you set mat[0][0]=0.01 then call mat.SetTranslateOnly(...), the scale reverts to identity. Build the matrix with explicit 16 floats: Gf.Matrix4d(sx,0,0,0, 0,sy,0,0, 0,0,sz,0, tx,ty,tz,1). This caused a 100× shell scaling bug. 0c. World delta != child local delta — to move a child by a world vector while keeping its authored local rotation/scale, map the vector through the parent's inverse rotation/scale, then write only the translation row. Adding a world delta straight to the local translation applies the parent's rotation/scale to it (wrong motion whenever the parent isn't identity/translation-only).

  1. Sdf.Layer.FindOrOpen fails on binary .usd crate files — use Usd.Stage.Open
  2. Matrix order: T * R * S not S * R * T
  3. Cameras default look along -Z in camera space = straight down in Z-up stage (no rotation needed for top-down)
  4. xformOp:translate already exists in xformOpOrder → use MakeMatrixXform() instead of AddTranslateOp()
  5. DHGen humans already have xformOps defined — must use MakeMatrixXform() which clears and replaces
  6. Shell is ~170×100m — layout area is usually a subset. Camera must be inside the layout area, not at origin.
  7. Isaac Sim vp.camera_path sometimes silently fails between rapid renders — always create fresh camera prim with stage.RemovePrim() + UsdGeom.Camera.Define() for each shot
  8. RT2 needs 200+ settle frames for convergence. Less = noisy/incomplete renders.

Lessons Learned — GSRC Integration (2026-03-12)

Scaling Awareness

  • When placing large equipment (50m+ footprint), the facility MUST grow proportionally
  • A 58×83m module in a 120×80m warehouse = impossible overlap
  • Always calculate: equipment_area / facility_area — if > 30%, facility needs to grow

Collision Prevention

  • Before placing a new zone, check all existing zone bounding boxes
  • Zone overlaps are the #1 failure mode when scaling up quickly (V7/V8 had overlaps)
  • Use coordinate-based collision detection: if new_x_range overlaps existing_x_range AND new_y_range overlaps existing_y_range → collision

Variation Workflow

  • Build ONE variation at a time — render — show — get feedback — iterate
  • Don't batch multiple variations without showing intermediate results
  • Each variation should have a distinct spatial philosophy, not just moved zones

Occupancy Map as Validation

  • Generate occupancy map after each variation as a spatial sanity check
  • If free_space% < 40%, the layout is too dense for robot navigation
  • If free_space% > 80%, the layout has too much wasted space
  • Sweet spot for warehouses: 55-70% free space

Advanced Topics

See advanced.md for details.

版本历史

  • 2469084 当前 2026-09-22 15:46

同 Skill 集合

.claude/skills/action-and-event-data-generation/SKILL.md
.claude/skills/actor-sdg-generate-lighting-variations/SKILL.md
.claude/skills/actor-sdg-sweep-config/SKILL.md
.claude/skills/behavior-tree-generation/SKILL.md
.claude/skills/calibrate-metropolis-camera/SKILL.md
.claude/skills/data-collection-sim/SKILL.md
.claude/skills/generate-incident-config/SKILL.md
.claude/skills/isaac-camera/SKILL.md
.claude/skills/isaac-sim-assets/SKILL.md
.claude/skills/isaac-sim-headless-deployment/SKILL.md
.claude/skills/isaac-sim-installation/SKILL.md
.claude/skills/isaac-sim-migration/SKILL.md
.claude/skills/isaac-sim-orchestrator/SKILL.md
.claude/skills/isaac-sim-remote/SKILL.md
.claude/skills/isaac-sim-rendering/SKILL.md
.claude/skills/isaac-sim-robot-navigation/SKILL.md
.claude/skills/isaac-sim-ros-workspaces/SKILL.md
.claude/skills/isaac-sim-ros2-bridge/SKILL.md
.claude/skills/isaac-sim-sensor/SKILL.md
.claude/skills/isaac-sim-troubleshooting/SKILL.md
.claude/skills/isaac-sim-validator/SKILL.md
.claude/skills/isaac-sim-workflow/SKILL.md
.claude/skills/manipulation-ik/SKILL.md
.claude/skills/meta-skills/SKILL.md
.claude/skills/mobility-gen/SKILL.md
.claude/skills/motion-generation/SKILL.md
.claude/skills/navigation-primitives/SKILL.md
.claude/skills/object-bin-packing/SKILL.md
.claude/skills/occupancy-map/SKILL.md
.claude/skills/physics-simulation/SKILL.md
.claude/skills/place-camera-aim-at/SKILL.md
.claude/skills/place-camera-max-coverage/SKILL.md
.claude/skills/profile-isaac-sim/SKILL.md
.claude/skills/run-incident-events/SKILL.md
.claude/skills/skill-distillation/SKILL.md
.claude/skills/skills-eval-triage/SKILL.md
.claude/skills/urdf-mjcf-to-usd-conversion/SKILL.md
.claude/skills/usd-articulation/SKILL.md
.claude/skills/usd-composition-architecture/SKILL.md
.claude/skills/usd-pipeline/SKILL.md
.claude/skills/validation-diff-gifs/SKILL.md
.claude/skills/vlm-scene-captioning/SKILL.md
skills/action-and-event-data-generation/SKILL.md
skills/actor-sdg-generate-lighting-variations/SKILL.md
skills/actor-sdg-sweep-config/SKILL.md
skills/behavior-tree-generation/SKILL.md
skills/calibrate-metropolis-camera/SKILL.md
skills/data-collection-sim/SKILL.md
skills/generate-incident-config/SKILL.md

元信息

文件数
0
版本
2469084
Hash
62115a42
收录时间
2026-09-22 15:46

首页 - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-09-25 13:13
浙ICP备14020137号-1