Simulator¶
The Gazebo Jetty based simulation environment. The robot inside it
runs the same PhysiCar ROS stack; on top of that, the simulator serves
its own HTTP API under /sim/api/ for world, vehicle and evaluation control.
SIM only — a real robot has no /sim/api.
Every interface on this page is runnable from the PhysiCar panel's Tutorials → Robot APIs screen — each card carries a play button and a copyable command.
Status & time¶
| Method | Path | Description |
|---|---|---|
GET |
/sim/api/status |
Simulator runtime status |
GET |
/sim/api/clock |
Sim time / real time / RTF / paused |
Vehicle¶
| Method | Path | Description |
|---|---|---|
GET |
/sim/api/pose |
Vehicle pose (world absolute coordinates) |
POST |
/sim/api/pose |
Teleport the vehicle — {"x": 1.0, "y": 2.0, "yaw": 0.0}, omitted fields keep their current value. The pose is normalized upright at ground level, so this also rights a flipped car. The response returns after the pose is confirmed applied |
Teleport and odometry
Odometry (LiDAR + IMU) cannot observe a teleport, so /odom may keep an offset
afterwards. Use POST /sim/api/respawn when a clean odometry state is needed —
it restarts the odometry stack.
World & objects¶
| Method | Path | Description |
|---|---|---|
GET |
/sim/api/world |
One-call snapshot of the current world's definition: identity (world_id/rev/display name), track geometry, object catalog, and whether it has an evaluation |
GET |
/sim/api/route |
Track centerline waypoints, plus inner/outer boundary lines when available |
GET |
/sim/api/bounds |
Track bounds (bounding box) |
GET |
/sim/api/objects |
World models (name, type: object/wall/light, static, movable, origin/current pose, size) |
POST |
/sim/api/models/<name>/pose |
Move/rotate a world object — {"x", "y", "z", "yaw"}, omitted fields keep their value, rotation is yaw-only. Works for World Builder objects and traffic lights; walls and the track itself are rejected |
Traffic lights¶
| Method | Path | Description |
|---|---|---|
GET |
/sim/api/traffic_lights |
The world's traffic lights and their states. Default state is green; states survive a respawn of the same world |
POST |
/sim/api/traffic_lights/<name> |
{"state": "red"} or {"state": "green"} — green→red passes through 3 s of yellow, during which commands are rejected with 409 |
Traffic lights come from the world itself (placed in the Custom World Builder) — there is no runtime placement API.
Reset¶
| Method | Path | Description |
|---|---|---|
POST |
/sim/api/reset |
Every movable object, traffic light and the vehicle back at its start pose — instant, pose-only, no world reload. The go-to reset between training episodes |
POST |
/sim/api/respawn |
Reload the whole world (~6 s) — the heavyweight reset, for when the world misbehaves |
Display¶
| Method | Path | Description |
|---|---|---|
GET / POST |
/sim/api/brightness |
Scene brightness — {"value": 0.2..2.0}, 1.0 = default. Applied instantly at the display layer: the 3D viewer and the robot camera frames darken/brighten by the same factor. One shared server-side value (all viewers stay in sync); persists across world switches and restarts |
GET / POST |
/sim/api/overlay |
Status text on the /sim screen — {"text": "...", "ttl": 10, "size": 1}, text ≤300 chars, ttl 1–3600 s, size = text size multiplier 0.5–4; expires by itself (e.g. training progress) |
Monitoring¶
| Method | Path | Description |
|---|---|---|
GET |
/sim/api/state |
One-call snapshot of everything that changes in real time: world/running/switching, sim time/paused/rtf, vehicle pose, object poses, traffic lights, overlay, brightness, and the evaluation run state |
GET |
/sim/api/events |
SSE stream of named events — event: state (full status snapshot pushed on change), event: run (student-process output during an evaluation) and event: evaluation (the evaluation session: start, phase, record, script log line, end with the outcome). Subscribe with addEventListener and ignore unknown event names |
Evaluation¶
| Method | Path | Description |
|---|---|---|
GET |
/sim/api/evaluation |
The current world's evaluation document ({version, config, script}, published from the World Builder) — 404 when the world has none |
POST |
/sim/api/evaluation/start |
Start an evaluation session — {"command"?, "time_limit_s"?}: command starts the student's code (omitted = nothing is launched, the session only observes; the process is killed when the session ends), time_limit_s defaults to the world's evaluation config. The simulator runs the script and launches the student's code; output streams to event: run, progress to event: evaluation on /sim/api/events. Returns {ok, session}; 400 on invalid values, 404 when the world has no evaluation, 409 when the world isn't ready, a session is active or the student's code is already running |
POST |
/sim/api/evaluation/stop |
End the active session (outcome stopped) and the student's process — idempotent, anyone can stop it |
GET |
/sim/api/evaluation/session |
The active session ({active, session} — phase, current record, recent log lines), for a page that opens mid-run |
GET |
/sim/api/evaluation/record |
The last session's stored result record (?session=<id> for a specific one): outcome (finished / timeout / script_error / stopped / unsupported), record, reason, event log — 404 when there is none |
Normally driven by the ⚑ button on the /sim page — one session per simulator, shared by every viewer.
Worlds¶
| Method | Path | Description |
|---|---|---|
GET |
/sim/api/worlds |
World list (includes the current one): name, file, display (published name, or the official world's display name), world_id (32-hex publish id, null for built-ins), official, evaluation, deletable |
POST |
/sim/api/switch |
Switch world — {"world": "<name>.world"} or {"world_id": "<32-hex id>"}; the id form resolves an installed published world and returns 404 when it is not installed. Takes several seconds (full world load) |
GET |
/sim/api/worldpub |
Current world's publish coordinates (world_id/rev for an installed published world) plus the official-asset CDN revision and CDN base URL |
POST |
/sim/api/worlds/install |
Install a published world from the worlds CDN — {"world_id": "<32-hex id>"}. Server-side download, installed as custom_*; a same-rev reinstall returns "cached": true without downloading |
The /sim viewer does the same things
The web viewer supports direct manipulation: click an object to select, drag to move, drag the blue dot handle to rotate; clicking a traffic light opens its RED/GREEN panel. The vehicle can be moved the same way. Everything maps to the pose APIs above.
Learn more
- The robot's own interfaces → PhysiCar ROS
- Build and publish worlds → Your own world with Custom World