Verification level

Visible native Isaac camera. Acceptance requires both a visible native Isaac window and a 1280×720 PNG produced from sensors.overview. A desktop or viewport screenshot does not satisfy this level.

Prerequisites

  • Isaac Lab 3.0 and Isaac Sim 6.0 in their compatible Python 3.12 environment.
  • FastSim 0.1.0a6, unirobosim==0.10.0, and unirobosim-isaaclab==0.10.1 installed there.
  • Pillow (python -m pip install Pillow) only for encoding returned RGB bytes as PNG.
  • A working NVIDIA GPU and display. Run this acceptance with the native application visible; main.py itself never screenshots that window.

Configuration

The object uses a tiny red USD cube shipped in _shared/assets/. The sensor uses a procedural camera component, so no camera asset file is required.

yaml
backend: isaaclab                         # Select the Isaac Lab provider.
objects:
  red_cube:
    use: object://fastsim/demo-cube       # Registry selects its Isaac USD variant.
    pose:
      xyz_m: [0.0, 0.0, 0.3]             # Raise it above the provider ground.
      quat_xyzw: [0.0, 0.0, 1.0, 0.0]    # Valid half-turn around world Z.
sensors:
  overview:
    use: sensor://fastsim/demo-rgb-camera # 1280×720, RGB-only camera spec.
    pose:
      xyz_m: [1.4, -1.4, 1.0]            # Camera optical center in world metres.
      quat_xyzw: [0.5334021, 0.22094238, 0.31245971, 0.75434448]

Camera quaternions use XYZW and the OpenGL optical convention: local -Z points forward and local +Y points up. This quaternion looks toward the cube. Changing the world up axis in an asset is not a substitute for changing an instance pose; the demo USD explicitly declares upAxis = "Z" and metersPerUnit = 1.

Python, line by line

  1. fastsim.app(RUN_FILE) compiles the Run; planning reads remain disabled because a camera query does not need collision geometry publication.
  2. await simulation.start() creates the native world and starts physics/rendering.
  3. camera_rgb("sensors.overview") uses the canonical compiled sensor entity ID, waits at most 30 seconds, and returns immutable packed RGB bytes.
  4. Exiting async with closes the simulator before ordinary file encoding.
  5. The explicit size check rejects any frame that is not exactly 1280×720.
  6. Image.frombytes(...) interprets the exact rgb24 payload without changing camera resolution or color channels.
  7. OUTPUT_DIR.mkdir(...) creates the ignored case-local output/ directory when needed.
  8. image.save(...) writes output/overview-1280x720.png without resizing the frame.

Run it

bash
cd demo/fundamentals/06_camera_rgb_screenshot
fastsim config validate run.yaml --json
UNIROBOSIM_ISAACLAB_LAUNCH_PROFILE=visible \
  python main.py

Expected result: the native Isaac window opens and the terminal reports a saved 1280x720 frame. The output is output/overview-1280x720.png. Open it and verify that it shows the red cube and the Isaac provider's ground from the configured scene-camera viewpoint.

UNIROBOSIM_ISAACLAB_LAUNCH_PROFILE=visible asks this acceptance run to keep the native Isaac application visible. The PNG remains camera output, not a capture of that application window. The complete output/ directory and Python bytecode are ignored by Git.

Common errors

  • UNSUPPORTED sensor.camera.rgb@1: the selected provider lacks the required camera capability or the wrong provider version is installed.
  • NOT_FOUND sensors.overview: use the compiled entity ID, including sensors..
  • A blank or wrongly aimed frame: check the OpenGL optical convention and ensure the quaternion remains unit length.
  • No module named PIL: install Pillow in the same Isaac Python environment.
  • Running on PyBullet/MuJoCo by changing only backend: this specific shared camera acceptance is documented and validated for Isaac Lab; never assume rendering parity without a provider capability check and visual evidence.

Next

Continue with 07 — Inspect scene entities and live state.