# Conflicts: # .github/labeler.yaml # .github/workflows/auto_pr_review.yaml # .github/workflows/docs.yaml # .github/workflows/release.yaml # .github/workflows/repo-maintenance.yaml # .github/workflows/tests.yaml # .github/workflows/ui_preview.yaml # README.md # SConstruct # conftest.py # docs/CARS.md # msgq_repo # opendbc_repo # openpilot/cereal/messaging/tests/validate_sp_cereal_upstream.py # openpilot/common/api.py # openpilot/common/hardware/hw.py # openpilot/common/version.py # openpilot/selfdrive/assets/fonts/Audiowide-Regular.ttf # openpilot/selfdrive/assets/sounds/prompt_single_high.wav # openpilot/selfdrive/assets/sounds/prompt_single_low.wav # openpilot/selfdrive/car/card.py # openpilot/selfdrive/car/helpers.py # openpilot/selfdrive/car/tests/test_car_interfaces.py # openpilot/selfdrive/car/tests/test_cruise_speed.py # openpilot/selfdrive/controls/lib/desire_helper.py # openpilot/selfdrive/controls/lib/longcontrol.py # openpilot/selfdrive/controls/plannerd.py # openpilot/selfdrive/controls/radard.py # openpilot/selfdrive/controls/tests/test_longcontrol.py # openpilot/selfdrive/modeld/compile_warp.py # openpilot/selfdrive/modeld/modeld.py # openpilot/selfdrive/monitoring/policy.py # openpilot/selfdrive/monitoring/test_monitoring.py # openpilot/selfdrive/selfdrived/events.py # openpilot/selfdrive/selfdrived/selfdrived.py # openpilot/selfdrive/ui/layouts/onboarding.py # openpilot/selfdrive/ui/mici/layouts/onboarding.py # openpilot/selfdrive/ui/soundd.py # openpilot/selfdrive/ui/tests/diff/replay.py # openpilot/selfdrive/ui/translations/app.pot # openpilot/system/athena/athenad.py # openpilot/system/athena/manage_athenad.py # openpilot/system/hardware/hardwared.py # openpilot/system/loggerd/config.py # openpilot/system/manager/github_runner.sh # openpilot/system/manager/manager.py # openpilot/system/updated/updated.py # panda # pyproject.toml # scripts/lint/lint.sh # system/manager/process_config.py # system/statsd.py # tinygrad_repo # tools/release/build_release.sh # tools/release/build_stripped.sh # uv.lock
Replay
replay allows you to simulate a driving session by replaying all messages logged during the use of openpilot. This provides a way to analyze and visualize system behavior as if it were live.
Setup
Before starting a replay, you need to authenticate with your comma account using auth.py. This will allow you to access your routes from the server.
# Authenticate to access routes from your comma account:
python3 openpilot/tools/lib/auth.py
Replay a Remote Route
You can replay a route from your comma account by specifying the route name.
# Start a replay with a specific route:
openpilot/tools/replay/replay <route-name>
# Example:
openpilot/tools/replay/replay '5beb9b58bd12b691/0000010a--a51155e496'
# Replay the default demo route:
openpilot/tools/replay/replay --demo
Replay a Local Route
To replay a route stored locally on your machine, specify the route name and provide the path to the directory where the route files are stored.
# Replay a local route
openpilot/tools/replay/replay <route-name> --data_dir="/path_to/route"
# Example:
# If you have a local route stored at /path_to_routes with segments like:
# 5beb9b58bd12b691/0000010a--a51155e496--0
# 5beb9b58bd12b691/0000010a--a51155e496--1
# You can replay it like this:
openpilot/tools/replay/replay "5beb9b58bd12b691/0000010a--a51155e496" --data_dir="/path_to_routes"
Send Messages via ZMQ
By default, replay sends messages via MSGQ. To switch to ZMQ, set the ZMQ environment variable.
# Start replay and send messages via ZMQ:
ZMQ=1 openpilot/tools/replay/replay <route-name>
Usage
For more information on available options and arguments, use the help command:
$ openpilot/tools/replay/replay -h
Usage: openpilot/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 the best available source (no video):
internal, openpilotci, comma_api, car_segments, testing_closet
--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 do output all messages including uiDebug, userBookmark.
this may causes issues when used along with UI
Arguments:
route the drive to replay. find your drives at
connect.comma.ai
Visualize the Replay in the openpilot UI
To visualize the replay within the openpilot UI, run the following commands:
openpilot/tools/replay/replay <route-name>
cd openpilot/selfdrive/ui && ./ui.py
Work with plotjuggler
If you want to use replay with plotjuggler, you can stream messages by running:
openpilot/tools/replay/replay <route-name>
openpilot/tools/plotjuggler/juggle.py --stream
watch3
watch all three cameras simultaneously from your comma three routes with watch3
simply replay a route using the --dcam and --ecam flags:
# start a replay
cd openpilot/tools/replay && ./replay --demo --dcam --ecam
# then start watch3
cd openpilot/selfdrive/ui && ./watch3.py
Stream CAN messages to your device
Replay CAN messages as they were recorded using a panda jungle. The jungle has 6x OBD-C ports for connecting all your comma devices. Check out the jungle repo for more info.
In order to run your device as if it was in a car:
- connect a panda jungle to your PC
- connect a comma device or panda to the jungle via OBD-C
- run
can_replay.py
batman:replay$ ./can_replay.py -h
usage: can_replay.py [-h] [route_or_segment_name]
Replay CAN messages from a route to all connected pandas and jungles
in a loop.
positional arguments:
route_or_segment_name
The route or segment name to replay. If not
specified, a default public route will be
used. (default: None)
optional arguments:
-h, --help show this help message and exit
