Docs menu

Record a run

Where recordings come from, how to start one by hand, and what each file in the run folder answers.

race_diagnostics records a run so it can be diagnosed afterwards. Its probe, race_diag_node, watches the whole chain from /scan to /drive at once, because a node’s own log cannot explain why the node before it went silent. The package is src/race_diagnostics/GitHub. It only subscribes and reads the ROS graph, so it is safe beside anything.

Each run gets its own timestamped folder, <ts>, under the car’s own data folder, ~/racerbot-ws/data/<id>/racerbot_runs/<ts>/, where <id> is rb1 on car 1 and rb2 on car 2.

Record

Bringup records every run of an algorithm by itself. Its auto_record node watches the ROS graph, starts record_run.py into a new run folder when a node starts publishing /drive (or another trigger topic in config/auto_record.yaml), and stops it when that node goes. It never records beside another recorder, and record:=false on the bringup launch leaves it out. An automatic recording also gets auto_record.yaml (what started and stopped it), metadata/processes.txt (the command line of every ROS process) and recorder.log.

To record by hand instead, start the recorder before the driving stack so nothing is missed.

Terminal 1:

ros2 launch race_diagnostics record_run.py

It prints the run folder it created and a tee command for the next terminal.

Terminal 2, the driving stack, with its output copied into the run folder:

ros2 launch racerbot_launch auto_map_race_launch.py 2>&1 | tee ~/racerbot-ws/data/<id>/racerbot_runs/<ts>/launch.log

The tee is optional: if launch.log is missing, summarize_run rebuilds it from the per-node log files ROS 2 writes under ~/.ros/log/. To watch only the important lines live, in a third terminal:

ros2 run race_diagnostics filter_log ~/racerbot-ws/data/<id>/racerbot_runs/<ts>/launch.log

map_course and auto_map_race_launch.py start the recorder by themselves (diagnostics:=true), with a bag by default (record_bag:=false skips it). record_run.py takes system_log:=false to skip the resource log described below.

What a run folder contains

File Written by Answers
launch.log Your tee What every node decided: one line per second and every state change
events.jsonl race_diag_node Pipeline state, pose lag and watchdog stops, as JSON lines
probe.log race_diag_node The same, readable
bag/ ros2 bag record Every message, replayable: /scan, /odom, /odom/imu, both IMUs, /drive, /joy, /ackermann_cmd, /tf, SLAM’s pose and pose graph, /parameter_events, /rosout
system/proc.jsonl system_log, once a second CPU use, memory and thread count of each named ROS node’s process. 100% CPU is one full core.
system/tegrastats.log The Jetson’s tegrastats, once a second CPU use per core, GPU use, memory and temperatures
metadata/git/ record_run.py The commit, branch, git status and uncommitted diff of racerbot-ws
metadata/files/ record_run.py Copies of the car’s IMU calibration files, which no ROS parameter holds
metadata/car.yaml record_run.py The car that ran (car_id), and the path and SHA-256 hash of each calibration and tuning overlay it loaded
metadata/packages.txt record_run.py The installed version of every ros-jazzy-* apt package, slam_toolbox first
metadata/submodules.txt record_run.py Each submodule’s checked-out commit, the commit the workspace records for it, and whether it has local changes
metadata/params/ snapshot_params, from 15 s in Every node’s parameters, one YAML per node, usable as --params-file
map.pgm, map.yaml, raceline_*.csv The mapping run The map and racing lines that run produced
analysis/ The analysis tools Reports and cached arrays. See Analyze a run.

Run folders recorded on car 2 before the two workspaces merged on November 1, 2026 have no system/ folder and no packages.txt or submodules.txt. If the car could not be identified, metadata/car.yaml holds car_id: null and the reason is in metadata/car_id.txt; check it before treating a run as evidence about one car’s settings.

Which code, settings and versions ran

The metadata answers “which code and settings ran” weeks later, and each file covers something the others cannot.

  • Packages. slam_toolbox is installed from apt, not built from this repository, so Git cannot say which version ran. packages.txt holds the version of every ROS package, which is how to tell whether an apt upgrade changed SLAM between two runs.
  • Submodules. submodules.txt ends with a MOVED: <path> line for every submodule whose checked-out commit differs from the one the workspace records. That usually means someone advanced a submodule, such as team A’s src/racerbot_a, without committing the change in the workspace.
  • Parameters. On car 1, snapshot_params waits 15 s, then checks the graph every 2 s for the whole run. A node that starts late gets its file when it appears, and a restarted node gets <name>.<n>.yaml. Namespaced nodes are written as ns__name.yaml. Later changes to a running node are in the bag’s /parameter_events. On car 2 it keeps watching for 120 s after those first 15 s and then stops, so a node that starts more than 135 s into the run has no file. snapshot_params only calls each node’s parameter services, so it cannot change anything.

system_log matches processes to ROS nodes by the __node name on their command line. It answers whether a node was starved of CPU, which a node’s own log cannot show. If tegrastats is not installed, as on a laptop running the simulator, the recorder prints a warning and records everything else.

Pose lag

Pose lag is the age of the pose a controller is steering from, read from the message’s header stamp. It is the most useful single number in a recording, because a stale pose is invisible in a topic’s rate: auto_map_race_node republishes SLAM’s transform at a fixed 40 Hz whatever its age, so a frozen pose arrives as punctually as a live one. On July 27, 2026, pure_pursuit steered for a full second from a position the car had already left, while its watchdog, which measured message arrival, saw nothing wrong. The probe reports the lag directly.

Summarize

ros2 run race_diagnostics summarize_run ~/racerbot-ws/data/<id>/racerbot_runs/<ts>

The summary lists the pipeline’s health, the pose lag, every watchdog stop and the lap closures, with the quality verdict of each mapping lap. For the full analysis with the cause of each stop, and the SLAM report, see Analyze a run.

Ask for help with a run

The workspace’s docs/run-diagnostics.mdGitHub includes a template for handing a recorded run to a person or an AI agent: the context, what was run, what was expected, what happened, and the run folder. A request that includes the run folder can be answered from evidence instead of guesswork.

Checked against car 1 commit 8a88dcc and car 2 commit 80da6f5, before the two workspaces merged.