# Quickstart: simulated cell

> Build the real-time core, start a simulated Rosie cell with dev-stack.sh, and jog a joint from the offline programming app, with no hardware.

URL: https://advancedmetalresearch.com/docs/get-started/quickstart
Section: RosieOS docs / Get started
Last updated: 2026-10-10

This page takes you from a fresh clone to a simulated robot moving. It takes two steps. First you start the simulated real-time core and its control API, and check them from the command line. Then you start the offline programming (OLP) app, and home, arm and jog the simulated robot from your browser.

Everything here runs on your own machine. The simulator (`rosie-rt-core-sim`) runs the same state machine as the real core over a simulated bus, and no drive is involved.

You need Linux or WSL2 with the toolchain from [Install the toolchain](https://advancedmetalresearch.com/docs/get-started/installation). The simulator also needs at least two CPUs that the process is allowed to use.

## 1. Clone and build the core

```bash
git clone https://github.com/advanced-metal-research/RosieOS.git
cd RosieOS
make -C rt-core control sim
```

`make control sim` builds five programs into `rt-core/build/`:

- `rt-control`, the public control API
- `rtctl`, the operator CLI
- `benchdrive`
- `rt-natspublisher`
- `rosie-rt-core-sim`, the simulated core

## 2. Start the simulated core

Run everything from the repository root. Keep the UI on loopback, and turn off the launcher's firewall helper, which otherwise tries to add a `ufw` rule for remote access:

```bash
export DEV_STACK_UI_HOST=127.0.0.1 DEV_STACK_FIREWALL=0
./dev-stack.sh start rt-sim rt-control
./dev-stack.sh status rt-sim rt-control
```

`start` compiles a simulation machine config, starts the simulator and `rt-control`, and waits until both are healthy. Status then lists the sockets and reports both services as `healthy`. It looks like this, with your own paths and pids:

```text
  backend: rt_core
  rt-core sockets: native=/run/user/1000/rosie-dev-rt-1000/ipc.sock control=/run/user/1000/rosie-dev-rt-1000/control.sock jog=/run/user/1000/rosie-dev-rt-1000/jog.sock
  rt-sim     pid 41210    healthy  /run/user/1000/rosie-dev-rt-1000/ipc.sock
  rt-control pid 41288    healthy  /run/user/1000/rosie-dev-rt-1000/control.sock (jog /run/user/1000/rosie-dev-rt-1000/jog.sock)
  olp target: rt_core control=/run/user/1000/rosie-dev-rt-1000/control.sock
  app:    http://127.0.0.1:5189/offline-programming/v1/ui/  (ui mode: dev, live reload)
  remote: off (UI bound to 127.0.0.1; unset DEV_STACK_UI_HOST or set it to 0.0.0.0)
```

The directory comes from `$XDG_RUNTIME_DIR`, or from `$TMPDIR` if that is unset, so your paths will differ. The pids differ too. On WSL, the sockets must live on a Linux filesystem such as `/run/user/…` or `/dev/shm`, not under `/mnt/c`.

## 3. Ask the core what it is

`rtctl` talks to `rt-control` over its Unix socket. Point it at the control socket from the status output:

```bash
sock="${XDG_RUNTIME_DIR:-${TMPDIR:-/tmp}}/rosie-dev-rt-$UID/control.sock"
rt-core/build/rtctl describe --socket "$sock" | head -20
rt-core/build/rtctl status --socket "$sock" --json | head -c 400; echo
```

`describe` returns:

- the backend, `simulation`
- the configuration, machine and deployment digests
- the cycle time, 1,000,000 ns
- the lease and jog-age ceilings, `max_grant_lease_ns` and `max_jog_input_age_ns`
- the nine simulated axes J1 to J9, with their limits in radians

None of these calls needs control of the robot. The stack binds its clients to the pair `local-dev`, revision 1.

## 4. Start the offline programming app

The OLP app needs three more things. Install each once:

- the Tesseract collision environment, which the OLP launcher requires
- the OLP UI's npm packages
- the Cartesian motion server, which the launcher builds itself if it is missing

```bash
(cd tesseract/v1 && pixi install --locked)
(cd offline-programming/v1/ui && npm ci)
./dev-stack.sh start olp ui
```

The `olp` service runs `offline-programming/v1/start-offline-programming.sh`. The first start builds the OLP server and the motion server, so it takes a few minutes. Follow its log with `./dev-stack.sh logs olp`. When it is ready, the log shows the lines below, and status reports `olp` and `ui` as healthy.

```text
olp-start: rails: seam worker UNAVAILABLE -- provision the weld planner environment: cd weld_planner/v1 && pixi install -e default. 'Define welds from edges' will fail until then.
olp-start: motion: http://127.0.0.1:8796
```

`rails: … UNAVAILABLE` is expected until you install the weld planner. You do not need the planner to jog.

Open the app at **http://127.0.0.1:5189/offline-programming/v1/ui/**. Use port 5189 (the UI), not 8794 (the API).

## 5. Home, arm and jog

> [!WARNING] This step moves only the simulated robot. The same controls drive a real cell when a real one is selected. Before you ever do that, read the [safety model](https://advancedmetalresearch.com/docs/get-started/safety-model).

The Machine panel walks you through five steps: Choose, Connect, Home, Arm, Drive.

1. **Choose a machine:** select **Local simulation**. This is the simulated core you started in step 2.
2. **Connect:** OLP describes the machine and checks its identity. This does not take control.
3. **Home:** press **Home**. The dev-stack simulation requires Home on every axis, just like a real cell.
4. **Arm:** press **ARM**, then **Confirm: energise motors**. OLP acquires the lease, enables the axes and arms them.
5. **Drive:** in the joint table, hold **+** or **−** under **Hold to jog** for J1. The position column and the 3D view follow the simulated joint. Let go and the joint stops.

Press **STOP** or **DISARM** when you are done. STOP inhibits outputs at once and releases the lease.

## 6. Stop the stack

```bash
./dev-stack.sh stop
```

`stop` shuts down only what `start` launched, in reverse order. Logs and pid files stay in the stack directory, `${XDG_RUNTIME_DIR:-$TMPDIR}/rosie-stack-$UID`.

## If something is off

| Symptom | Cause and fix |
|---|---|
| `local simulation requires two allowed CPUs` | The simulator pins its cycle thread. Give the VM or container two or more CPUs. |
| `olp requires healthy rt-control` | Start `rt-sim rt-control` first, or start all of them in one command in that order. |
| `Tesseract pixi env missing` | Install pixi, then run `cd tesseract/v1 && pixi install --locked`. |
| `nats: … is missing; skipping` | Harmless. NATS is optional for this quickstart. |
| `catalog: … is missing; skipping` | Harmless. The program catalog service is not part of this repository. |
| Programs you saved are gone | The project store lives in the browser, per origin. `127.0.0.1` and `localhost` are separate stores. Always use the same address. |

## Next steps

- [Your first motion](https://advancedmetalresearch.com/docs/get-started/first-motion) moves a joint from your own Go program.
- [Run everything in simulation](https://advancedmetalresearch.com/docs/guides/run-in-simulation) covers every dev-stack service, including the weld planner and the virtual pendant.
- [Architecture](https://advancedmetalresearch.com/docs/concepts/architecture) explains what you just started.

## Sources

Written from these files in the RosieOS repository (https://github.com/advanced-metal-research/RosieOS):

- `dev-stack.sh:12-80,172-183,248-257,284-297,332-395,442-470,500-552,555-613`
- `motion-server/v1/local-rt-core.sh:6-12,14-66,67-92,93-130`
- `rt-core/Makefile:31-50,295-301`
- `rt-core/tools/rtctl/control.go:22-26,48-110`
- `offline-programming/v1/start-offline-programming.sh:16-18,70-110,285-310,490-515,620-668`
- `offline-programming/v1/ui/vite.config.ts:3-14`
- `offline-programming/v1/ui/package.json:6-11`
- `offline-programming/v1/ui/src/execution/densePanel.ts:495-534`
- `offline-programming/v1/ui/src/execution/jointJog.ts:526-600`
