Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/commaai/openpilot/llms.txt

Use this file to discover all available pages before exploring further.

The replay tool lets you relive a recorded drive without any hardware. It reads a route from your comma account or from a local directory and re-publishes every logged openpilot message exactly as it was originally sent — camera frames, sensor data, CAN packets, and control outputs — so you can run openpilot code against real data and watch how it behaves. Combined with the openpilot UI or PlotJuggler, replay is the standard way to debug, reproduce issues, and test code changes without being in a car.

Authentication

Before replaying routes from your comma account, authenticate once with:
python3 tools/lib/auth.py

Replay modes

1

Demo route (no account needed)

Run replay immediately against a built-in public route to verify your environment is working:
tools/replay/replay --demo
2

Remote route from comma connect

Replay any route from your comma account. Find route identifiers at connect.comma.ai.
tools/replay/replay '5beb9b58bd12b691/0000010a--a51155e496'
3

Local route from disk

Replay segments stored locally. The directory should contain segment folders named with the route ID.
tools/replay/replay "5beb9b58bd12b691/0000010a--a51155e496" \
  --data_dir="/path_to/routes"
4

CAN replay to a physical device

Replay CAN messages through a panda jungle to a connected comma device, making the device behave as if it is in a real car.
cd tools/replay
./can_replay.py '5beb9b58bd12b691/0000010a--a51155e496'
This requires a panda jungle connected to your PC and a comma device or panda connected to the jungle via OBD-C.

Full options reference

$ tools/replay/replay -h
Usage: tools/replay/replay [options] route
Mock openpilot components by publishing logged messages.

Options:
  -h, --help             Displays this help.
  -a, --allow <allow>    whitelist of services to send (comma-separated)
  -b, --block <block>    blacklist of services to send (comma-separated)
  -c, --cache <n>        cache <n> segments in memory. default is 5
  -s, --start <seconds>  start from <seconds>
  -x <speed>             playback <speed>. between 0.2 - 3
  --demo                 use a demo route instead of providing your own
  --auto                 Auto load the route from best available source (no video)
  --data_dir <data_dir>  local directory with routes
  --prefix <prefix>      set OPENPILOT_PREFIX
  --dcam                 load driver camera
  --ecam                 load wide road camera
  --no-loop              stop at the end of the route
  --no-cache             turn off local cache
  --qcam                 load qcamera
  --no-hw-decoder        disable HW video decoding
  --no-vipc              do not output video
  --all                  output all messages including uiDebug, userBookmark
  --benchmark            run in benchmark mode (process all events then exit with stats)

Visualizing replay in the openpilot UI

Replay publishes all openpilot service messages onto the local message bus. You can connect the openpilot UI or any other openpilot process to the running replay just as it would connect to a live device.
# Terminal 1: start the replay
tools/replay/replay '5beb9b58bd12b691/0000010a--a51155e496'

# Terminal 2: start the UI
selfdrive/ui/ui

Watching all three cameras with watch3

Use the --dcam and --ecam flags to include the driver-facing and wide road cameras, then launch watch3 to view all three camera streams simultaneously:
# Terminal 1: start replay with all cameras
tools/replay/replay --demo --dcam --ecam

# Terminal 2: launch watch3
selfdrive/ui/watch3.py

Using replay with PlotJuggler

Stream replay messages into PlotJuggler to plot any signal from the route:
# Terminal 1: start the replay
tools/replay/replay '5beb9b58bd12b691/0000010a--a51155e496'

# Terminal 2: start PlotJuggler in streaming mode
tools/plotjuggler/juggle.py --stream

Sending messages via ZMQ

By default, replay sends messages over MSGQ. To use ZMQ instead (for example, when connecting to tools running on another host), set the ZMQ environment variable:
ZMQ=1 tools/replay/replay '5beb9b58bd12b691/0000010a--a51155e496'

Common development workflows

Testing a code change against real data: make a change to an openpilot process (for example, controlsd), start replay with the route that exercises the bug, and run the modified process alongside it. The modified process receives the same inputs as the original recording. Reproducing a reported issue: grab the route identifier from a user report on connect.comma.ai and replay it locally with the UI running to see exactly what the car saw. Filtering services: use --allow and --block to control which services replay publishes. This is useful when you want to run a single openpilot process live while keeping all other services mocked from the recording.
# Only publish camera and sensor data; let controlsd run live
tools/replay/replay <route> --block controlsState,carState
Route replay requires no hardware — only a comma account and an internet connection to download the route. CAN replay (using can_replay.py) requires a panda jungle connected to your PC and a comma device or panda connected to the jungle via OBD-C.

Build docs developers (and LLMs) love