> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cyberwave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Simulation

> Iterate at the speed of code: run any environment in the browser, in MuJoCo, or (soon) Isaac Sim with zero extra setup

Cyberwave turns every [environment](/overview/features/environment) into a runnable simulation. Hit **Simulate** in the editor, or flip the SDK into sim mode: same scene, same twins, same code:

```python theme={null}
from cyberwave import Cyberwave

cw = Cyberwave()
robot = cw.twin("the-robot-studio/so101")   # create the twin first: it selects the environment
cw.affect("playground")                     # free; "simulation" starts a billable MuJoCo run

robot.joints.set("shoulder_pan", 45, degrees=True)   # runs against the virtual twin
```

When you're done, `cw.affect("live")` points the same code at the real robot. No rewrites, no second SDK, no second environment.

***

## Why simulate?

<CardGroup cols={2}>
  <Card title="Develop at code speed" icon="bolt">
    Tweak a policy, re-run, see the result in the viewport: no robot, no lab, no waiting on hardware.
  </Card>

  <Card title="CI for robotics" icon="circle-check">
    Run the same scene headlessly in CI. Catch regressions in motion planners, perception, and controllers before they ship.
  </Card>

  <Card title="Train models" icon="brain">
    Use simulation rollouts to train and evaluate [VLAs and RL policies](/feature-reference/ml-models/index) on the same twins you'll deploy on.
  </Card>

  <Card title="Synthetic data" icon="database">
    Render camera streams, depth, and joint states from any environment to bootstrap datasets when real-world data is scarce.
  </Card>
</CardGroup>

***

## Simulation engine agnostic

Set up your environment **once**. Cyberwave handles the export to each backend so you can pick the right tool for the job without re-modeling anything.

<CardGroup cols={3}>
  <Card title="Playground" icon="browser">
    Browser-based, runs on your machine's compute. Best for fast iteration.
  </Card>

  <Card title="MuJoCo" icon="atom">
    High-fidelity, contact-rich physics. Best for RL, evaluation, and reproducible sim sweeps.
  </Card>

  <Card title="Isaac Sim" icon="sparkles">
    GPU-accelerated photoreal simulation. **Coming soon.**
  </Card>
</CardGroup>

Each twin advertises which backends it supports; see [Simulator compatibility](/feature-reference/catalog/simulation-support) to control which simulators an asset or twin can participate in.

***

## Powered by the twin catalog

There's no separate "simulation setup" step. Physics, kinematics, sensors, and collision geometry are read straight from the [digital twins](/overview/features/digital-twin) you dropped into the environment; every twin in the [catalog](/feature-reference/catalog) ships with a URDF and inertial data ready to simulate.

Add a twin → it's instantly simulatable. Swap a SO-101 for a UR7e → the physics update on the next run.

***

## The two simulators today

Open any environment in the editor and click **Simulate** in the top bar.

### Playground: instant browser physics

[Playground](/feature-reference/environment-editor/index#simulate-tab-playground-physics) is a lightweight rigid-body simulator that runs entirely in your browser, using your machine's compute. There's nothing to install and nothing to wait for; it's running the moment the page loads.

* **Fastest feedback loop**: change a joint target in code, see the twin move in the viewport.
* **Great for sanity checks**: verify motion plans, joint limits, and basic collisions before going live.
* **Works offline from cloud compute**: every browser is its own simulator.

```python theme={null}
from cyberwave import Cyberwave

cw = Cyberwave()
arm = cw.twin("the-robot-studio/so101")
cw.affect("playground")          # subsequent commands run in the free Playground
arm.joints.set("shoulder_pan", 30, degrees=True)
arm.joints.set("elbow_flex",   -45, degrees=True)
```

**Locomotion previews in Playground too.** Locomotion and flight commands drive
the twin in the browser viewport exactly like the keyboard teleop overlay does,
so you can sanity-check a driving/flying script before pointing it at hardware:

```python theme={null}
dog = cw.twin("unitree/go2")
dog.move_forward()               # the GO2 walks forward in the viewport
dog.turn_left()

drone = cw.twin("dji/tello")
drone.commands.takeoff()         # rises to its hover altitude
drone.move_forward()
drone.commands.land()
```

**Camera previews, including depth.** Each camera on a twin gets its own tile in
the right sidebar, previewing what that camera sees as you move things around. A
depth camera previews as the same grayscale ramp it produces in MuJoCo — near
surfaces dark, far ones bright, scaled to the sensor's own range, with anything
past its reach left white. Playground previews are for framing and reach; to pull
frames into code or a workflow, run the environment in MuJoCo.

### MuJoCo: contact-rich physics, your way

Need real grasps, friction, and reproducible RL sweeps? Cyberwave one-click-exports any environment to MuJoCo, two ways:

<CardGroup cols={2}>
  <Card title="Export and run anywhere" icon="download">
    Download a self-contained MuJoCo scene (XML + meshes) and run it on your laptop, your cluster, or your CI runner. Backed by the [environment MuJoCo export API](/api-reference/rest/DefaultApi).
  </Card>

  <Card title="Run in the Cyberwave cloud" icon="cloud">
    Kick off a MuJoCo simulation from the editor and stream results straight back into the browser viewport, no local install required.
  </Card>
</CardGroup>

All twins in the environment must be marked MuJoCo-compatible before a remote run starts; [see how the compatibility gate works](/feature-reference/catalog/simulation-support).

### Camera playback statistics

Simulation camera panels show **video fps**. Hover or focus this value for its
meaning: it counts received or decoded video frames, which can repeat an older
image. It does not measure fresh camera observations or prove real-time control.

### One simulation per environment

An environment runs one cloud simulation at a time. Starting a new one stops
whatever was still running first, so pressing **Simulate** again always gives you
a clean run rather than two robots fighting over the same twin.

If a second start arrives while one is already in flight — a second browser tab,
a teammate, or an SDK call racing the editor — the API returns `409` naming the
simulation that already holds the environment.

***

## Speaker and microphone audio in MuJoCo

Speaker and microphone twins work in MuJoCo simulations too. Upload a WAV file
as a speaker twin's audio source in the editor (optionally looping it), start
the simulation, and any microphone twin in the same environment hears it —
useful for testing audio-based perception (wake words, sound classification)
without a physical room.

A speaker that's actively playing shows a small wave animation expanding
forward from it in the 3D viewport, so you can tell it's emitting audio at a
glance without opening any panel.

The audio format — sample rate, channels, and bit depth — is set per sensor
under **Sensor Parameters** in the asset editor, for microphones and speakers
alike. Leave a field blank and it falls back to 48000 Hz, 16-bit, with the
channel count taken from the sensor type: `audio_stereo` is 2 channels and every
other microphone type is 1. A speaker falls back to 2, so set channels to `1`
for a mono source such as a single warning speaker.

***

## Mapping and autonomous navigation in simulation

Mobile twins can build an occupancy map during a MuJoCo run, exactly as they do
on hardware. Start the simulation, press **Start Mapping**, drive the robot
around the environment, then press **Stop Mapping**: the map streams into the
viewport while you drive and is saved to the twin when you stop.

Once a map is saved, the twin localizes against it and follows waypoints on its
own — the same **Move Twin** and waypoint workflows you use on a real robot, and
the same navigation stack running behind them. Send a goal and the robot plans a
path, avoids what its lidar sees, and reports progress back to the workflow.

On a real Go2, a printed AprilTag recorded during mapping lets the robot find
itself on the saved map after a restart. See
[AprilTag relocalization](/robots/go2-apriltag-relocalization).

Supported today: **Unitree Go2** and **MiR250** (including the Coesia variant).
The MiR250 fuses its front and rear lidars into a single 360° scan, so a single
pass down an aisle maps both sides.

***

## Runtime profiles, cost, and what each serves

`cw.affect(...)` picks the runtime and, for MuJoCo, **starts the simulation for you**:

* `cw.affect("simulation")` / `"sim"` / `"mujoco"` — starts (or reuses) a **MuJoCo** run. A MuJoCo simulation is a billable cloud instance (**\~0.6 credits/hour**); selecting it logs the cost. Pass `environment_id=` / `duration=` to `affect()`, or set `CYBERWAVE_ENVIRONMENT_ID`.
* `cw.affect("playground")` — lightweight kinematic runtime, no MuJoCo instance, no cost.
* `cw.affect("live")` — real hardware.

Stop a run with `sim.stop()` (it also stops at its `duration`):

```python theme={null}
cw = Cyberwave(environment_id="acme/envs/floor")
camera = cw.twin("cyberwave/standard-cam")
cw.affect("simulation")               # starts MuJoCo, logs ~0.6 credits/hour
frame = camera.get_frame()            # reads from the running sim
...
cw.environments.simulations.get_active(robot.environment_id).stop()
```

What each runtime serves:

* **Any sim runtime**: `pose`, `joints`.
* **MuJoCo only**: camera frames, `get_video()`, depth, point clouds, LiDAR — otherwise `SimulationNotRunningError` / `SimulationLevelError`.
* **Any sim runtime**: locomotion and flight control surfaces — `twin.commands.*`, `twin.locomotion.*`, `twin.flight.*` and their twin shortcuts (`twin.move_forward()`, `twin.takeoff()`, `twin.land()`, …). In MuJoCo a drone flies under thrust, so it obeys gravity and contacts
* **Not in simulation**: the `imu` and `gps` sensors — raise `NotSimulatedError` (live/driver-only). A twin positioned from GPS renders from its saved position in Simulate; see [Geo reference](/feature-reference/environment-editor/geo-reference).
* **Not available yet**: the `compass` sensor isn't implemented in any runtime.

***

## See simulation in action

<CardGroup cols={2}>
  <Card title="Autonomous rover inspection" icon="route" href="/tutorials/rover-ai-mission">
    Build and run an AI-driven inspection mission in a fully simulated environment.
  </Card>

  <Card title="Train a VLA with SO-101" icon="brain" href="/tutorials/train-vla-cyberwave">
    Collect data, train a vision-language-action model, and validate in sim before touching hardware.
  </Card>

  <Card title="Go2: digital to physical" icon="dog" href="/tutorials/go2-digital-to-physical">
    Configure a Unitree Go2 in simulation, then flip the same code onto the real robot.
  </Card>

  <Card title="Sandwich-making robot (SmolVLA)" icon="bread-slice" href="/tutorials/sandwich-robot-smolvla">
    Train, evaluate, and iterate a manipulation policy with simulation in the loop.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.