Skip to content

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.

import requests

BASE = "http://localhost/sim/api"
requests.get(f"{BASE}/status").json()

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

AI