Verification level

Visible native Isaac. The native window remains available while FastSim pauses, single-steps, resumes, and resets the world.

Prerequisites

  • FastSim 0.1.0a6, UniRoboSim Core 0.10.0, and unirobosim-isaaclab==0.10.1 in the same Python 3.12 environment.
  • Isaac Lab 3.0 / Isaac Sim 6.0, an NVIDIA GPU, and a working display.

Configuration

run.yaml uses the same small two-joint robot as example 02. The 60 Hz physics and control clocks have an exact 1:1 ratio, so one single_step() is one physics tick and one control boundary.

The important configuration lines are:

yaml
backend: isaaclab       # Select the Isaac Lab provider.
runtime:
  launch_profile: visible # Keep the native application window visible.
  physics_hz: 60        # Physics ticks per simulated second.
  control_hz: 60        # Control boundaries per simulated second.
  seed: 13              # Reproducible generation seed.
scenario:
  scene:
    robots:
      arm:
        use: robot://fastsim/demo-two-joint-arm

The remaining pose and initial_state lines explicitly place the robot at the world origin with zero joint positions.

Python, in order

  • show(...) reads only immutable ApplicationSnapshot fields and prints a compact lifecycle trace.
  • start() prepares the world and enters continuous running state.
  • pause() waits for a safe boundary, then preserves the world in paused state.
  • single_step() advances one physics tick while returning to paused state.
  • resume() re-enters continuous physics.
  • The second pause() makes the following reset transition easy to see.
  • reset() starts a new generation from the configured initial state and seed policy.
  • Leaving async with closes all owned runtime/backend resources.

pause() is not stop(): stopping is terminal for this application instance, while pausing keeps the scene available.

Run it

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

The printed states should follow running → paused → paused → running → paused → paused. The single-step tick must be greater than the preceding paused tick. Reset increments the generation, resets the tick to zero, restores the configured initial state, and preserves the caller's paused lifecycle state.

Common errors

  • Calling single_step() while running: pause first so the requested tick has an unambiguous boundary.
  • Using stop() when you want to inspect later: use pause(); stop() tears down the live Run.
  • Assuming reset continues the old generation: subscriptions and control chunks must treat the new generation as new world authority.

Next

Continue with 04 — Blocking joint path.