Prerequisites

Install FastSim and the Isaac Lab provider in the same environment. The Run starts Isaac Lab 3.0 / Isaac Sim 6.0 in visible mode.

Configuration, key by key

yaml
schema: fastsim/2               # FastSim vNext Run schema.
name: demo-planning-geometry    # Stable Run name.
backend: isaaclab               # Select the wedge's Isaac Lab USD variant.

runtime:
  launch_profile: visible       # Open the native simulator window.
  physics_hz: 60                # Physics integration frequency.
  control_hz: 60                # Control admission frequency.
  seed: 43                      # Reproducible reset seed.

scenario:
  scene:
    objects:
      wedge:                    # Alias; canonical entity ID is objects.wedge.
        use: object://fastsim/demo-mesh-wedge
        pose:
          xyz_m: [0.0, 0.0, 0.2] # Root position in world metres.
          quat_xyzw: [0.0, 0.0, 0.0, 1.0]

The component points to ../../_shared/assets/mesh_wedge.usda. Its collision shape is an authored UsdGeom.Mesh with triangle-mesh approximation, so the provider must publish resource-backed mesh geometry rather than an inline box or sphere.

Python, line by line

  1. The docstring states the exact goal: resolve resource-backed collision geometry.
  2. asyncio runs the application API; hashlib verifies content; math rejects non-finite transforms; Path finds the adjacent Run; fastsim is the public facade.
  3. RUN_FILE and VISIBLE_HOLD_SECONDS define the input and short visual hold.
  4. main() defines the asynchronous flow.
  5. fastsim.app(..., planning_reads=True) is essential: planning publication is disabled by default so applications that do not use it pay no ongoing cost.
  6. async with owns the application and all provider resources.
  7. start() builds the real Isaac Lab world; pause() fixes a coherent geometry transform boundary.
  8. geometry.capabilities() declares supported representations, storage modes, size limits, and delta features. Consumers should inspect this instead of assuming.
  9. geometry.catalog() returns path-free structural collision facts and immutable resource identities; it does not copy mesh buffers into WorldState.
  10. geometry.transforms() returns the current lightweight world transforms in a separate committed snapshot.
  11. The selection requires exactly one resource-backed geometry owned by objects.wedge, verifies triangle_mesh, and confirms the provider advertised that representation. Any mismatch exits non-zero.
  12. geometry.resolve(id, representation) opens a provider-owned, read-only lease for exactly the catalog entry requested.
  13. async with resource guarantees prompt lease release, including on failure.
  14. resource.descriptor() returns portable metadata and must declare a positive byte count. It never returns a filesystem path or native handle.
  15. resource.read(0, descriptor.byte_size) performs one bounded read. Large users should advance through descriptor.read_span(...) in chunks.
  16. The byte-count check and hashlib.sha256(payload) independently verify complete, immutable content; a mismatch fails instead of feeding corrupt geometry to a planner.
  17. The transform lookup pairs the geometry ID with its lightweight world_pose and rejects a non-finite position.
  18. The print statements report catalog size, provider representations, resolved identity, resource byte count/digest, and world position.
  19. The final sleep keeps the paused wedge visible for three seconds.
  20. asyncio.run(main()) executes the program when launched directly.

Acceptance gates

  • Exactly one wedge entry must be resource-backed triangle_mesh, and that representation must appear in provider capabilities.
  • Descriptor size must be positive; returned bytes must match both exact size and SHA-256 digest; world position must be finite.
  • The visible Isaac Lab acceptance run on 2026-08-25 resolved 168 bytes with digest 7b05a6d7d6dc6542cfed8dda2f8011120be4f406948f96d0862e016be2972d7d, measured world position (0, 0, 0.200000003) m, and exited with code 0.

Run it

From this case directory:

bash
cd demo/fundamentals/10_planning_geometry
fastsim config validate run.yaml --json
python main.py

Expected output contains a mesh representation (triangle_mesh), a non-zero resource size, a 64-character SHA-256 digest, and the wedge's finite world position. Digest verification must complete without raising RuntimeError.

Verification level

REAL VISIBLE ISAAC PASS. The native run resolved and independently verified the 168-byte triangle mesh, exited normally, and left no Isaac worker process behind.

What a planner should cache

Cache immutable mesh bytes by the catalog entry's resolution identity. Refresh the small transform snapshot as the world moves. Do not request the same unchanged mesh every control tick, and do not put mesh buffers into ordinary observations.

Common errors

  • SERVICE_ACCESS_DENIED: keep planning_reads=True.
  • No resource-backed entry: the collider was reduced to an inline primitive, or the asset did not publish a supported mesh collision representation.
  • RESOURCE_LEASE_REVOKED: a reset or close invalidated a retained lease; resolve it again against the new generation's catalog.
  • PLANNING_SCENE_INCOMPLETE: the active provider cannot publish a complete collision scene for one of the selected assets. Do not silently plan against a partial world.