# Start the Reachy simulation on MuJoCo

## In this learning path

- [Introduction](https://learn.arm.com/learning-paths/cross-platform/build-a-reachy-robot-app-on-pi/)
- [Learn about Reachy and the Reachy Gladiator application](https://learn.arm.com/learning-paths/cross-platform/build-a-reachy-robot-app-on-pi/reachy-app/)
- [Start the Reachy simulation on MuJoCo](https://learn.arm.com/learning-paths/cross-platform/build-a-reachy-robot-app-on-pi/start-simulation/)
- [Set up the Raspberry Pi and run the edge AI app](https://learn.arm.com/learning-paths/cross-platform/build-a-reachy-robot-app-on-pi/run-pi-app/)
- [Use the Reachy Gladiator application](https://learn.arm.com/learning-paths/cross-platform/build-a-reachy-robot-app-on-pi/use-the-app/)
- [Understand the Reachy Gladiator application code](https://learn.arm.com/learning-paths/cross-platform/build-a-reachy-robot-app-on-pi/understand-code/)
- [(Optional) Extend the project](https://learn.arm.com/learning-paths/cross-platform/build-a-reachy-robot-app-on-pi/extend/)
- [Next Steps](https://learn.arm.com/learning-paths/cross-platform/build-a-reachy-robot-app-on-pi/_next-steps/)

## What is MuJoCo?
MuJoCo is an open-source physics engine from Google DeepMind, used for simulating articulated bodies such as robots. It can model joints, contacts, gravity, and rigid-body dynamics. This makes MuJoCo useful for robotics prototyping, control development, reinforcement learning, and safety testing before hardware is available.

In this project, you’ll use MuJoCo to see Reachy Mini move without owning a physical Reachy. It’s not a perfect replacement for hardware: real cameras, lighting, network latency, calibration, mechanical tolerances, and safety constraints still matter. MuJoCo is best treated as a fast development and validation tool before moving to physical testing.

## Create or activate a simulation environment
The simulation host doesn’t need the full `reachy_gladiator_lp` project. It needs only the Reachy Mini SDK with MuJoCo support and the `start_sim.sh` launcher script.

### Create a simulation environment
Python 3.12 is required for the simulation environment. Python 3.13 can cause dependency resolution failures because pre-built wheels for some SDK dependencies are not yet available for that version.

Check your Python version:
```bash
python3 --version
```

If Python 3.12 isn’t installed, install it by using one of the following commands. On macOS, install Python 3.12 with [Homebrew](https://brew.sh). On Ubuntu or WSL2, use `apt`:
```bash
brew install python@3.12
```
```bash
sudo apt install python3.12 python3.12-venv
```

After ensuring you have Python 3.12 installed, on the machine that will run the simulation, create a small workspace and a Python virtual environment:
```bash
mkdir -p ~/reachy_projects/reachy_sim/scripts
cd ~/reachy_projects/reachy_sim
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
```

Install the Reachy Mini SDK with the MuJoCo simulation dependencies:
```bash
python -m pip install --upgrade "reachy-mini[mujoco]"
```

The `mujoco` extra is required for `--sim`. If you install only `reachy-mini`, the daemon can start but simulation fails with `MuJoCo is not installed`.

### Activate an existing simulation environment
If you already have a working Reachy Mini simulation environment, you can activate that environment instead.

Download the simulation launcher script from the [reachy_gladiator_lp repository](https://github.com/matt-cossins/reachy_gladiator_lp):
```bash
curl -L https://raw.githubusercontent.com/matt-cossins/reachy_gladiator_lp/main/scripts/start_sim.sh -o scripts/start_sim.sh
chmod +x scripts/start_sim.sh
```
`curl` is available by default on macOS and is commonly available on Linux and WSL distributions. If your Linux environment doesn’t include it, install it with your package manager.

## Start the Reachy Mini simulation
Start the daemon and MuJoCo simulation from the simulation workspace:
```bash
cd ~/reachy_projects/reachy_sim
source .venv/bin/activate
REACHY_SIM_PORT=18000 ./scripts/start_sim.sh
```

The simulation can take several minutes to start up. When the simulation is ready, the output is similar to:
```
__output__ reachy_mini.daemon.daemon - INFO - Daemon started successfully.
__output__ uvicorn.error - INFO - Application startup complete.
__output__ uvicorn.error - INFO - Uvicorn running on http://0.0.0.0:18000 (Press CTRL+C to quit)
__output__ reachy_mini.utils.discovery - INFO - mDNS service registered: reachy_mini on port 18000
__output__ reachy_mini.media.media_server - INFO - Pipeline latency (live=True, min_latency=30000000, max_latency=1200000000)
```

Leave this terminal running after it completes and boots the simulation view.

![MuJoCo simulation window with Reachy Mini](https://learn.arm.com/learning-paths/cross-platform/build-a-reachy-robot-app-on-pi/mujoco.png "MuJoCo simulation window showing the Reachy Mini robot in a standing position, confirming the simulation started successfully")

The script starts the Reachy Mini daemon with simulation enabled, binds FastAPI to `0.0.0.0`, and disables localhost-only mode so the Raspberry Pi can connect. In this Learning Path, you’ll use port `18000`.

The daemon is the network boundary between the Pi app and the simulated robot. The Pi doesn’t run MuJoCo. It connects to this daemon and sends the same SDK motion commands that it would send to a physical Reachy daemon.

The script runs a command equivalent to:
```bash
mjpython -m reachy_mini.daemon.app.main \
  --sim \
  --fastapi-host 0.0.0.0 \
  --fastapi-port 18000 \
  --no-localhost-only
```

On macOS, `mjpython` is often needed because MuJoCo opens a native graphics window. On Linux, regular `python` is usually enough. The provided script picks an appropriate runtime when it can.

### Troubleshoot port and connection issues
If the script reports that address `0.0.0.0:18000` is already in use, another daemon or server is already using port `18000`.

Find the process:
```bash
lsof -nP -iTCP:18000 -sTCP:LISTEN
```

If the process is an old Reachy daemon, stop it with `Ctrl+C` in its terminal. If you need to terminate it from the command line, replace `<pid>` with the process ID from `lsof`:
```bash
kill <pid>
```

You can also run the simulation on a different port:
```bash
REACHY_SIM_PORT=18001 ./scripts/start_sim.sh
```

If you change the simulation port, use the same port when configuring the Pi app later:
```bash
REACHY_GLADIATOR_DAEMON_PORT=18001 ./scripts/run_pi_app.sh <simulation-host-ip>
```

## Find the simulation host IP address
Use the tab for your simulation host operating system.

**Note:** On macOS, `en0` is usually Wi-Fi. If you use Ethernet or another network interface, the device name might be different.

```bash
ipconfig getifaddr en0
```
```bash
hostname -I
```
```bash
hostname -I
```

**Note:** If the Pi can’t connect later, check that the simulation machine and Raspberry Pi are on the same network and that the local firewall allows inbound connections to port `18000`.

## What you’ve accomplished and what’s next
You’ve now created a simulation environment, started the Reachy Mini MuJoCo daemon on a network-accessible port, and found the host IP address the Raspberry Pi needs when it connects to the simulated robot. You should now see a simulated Reachy robot in MuJoCo.

Next, you’ll prepare the Raspberry Pi.
