Docs Run the car Workspace repo
Docs menu

Map a course and race

The whole path from a course nobody has mapped to a race on its saved line: the three routes, what each step produces, and the run folder that ties them together.

Racing a course takes three steps. The car first drives laps on its own with gap_follow while slam_toolbox builds a map. The map, a racing line and the car’s start pose are then saved to a run folder. To race, the particle filter localizes the car on that map and pure_pursuit follows the line. Every route on this page has been tested in the simulator only, not yet on the cars.

Mapping, saving and racing a course Three steps from left to right. Map: gap_follow drives laps while slam_toolbox builds the map. Save: the map, the racing line and the start pose are written to a run folder. Race: the particle filter localizes the car on the saved map and pure_pursuit follows the racing line. 1. MAP gap_follow drives slam_toolbox maps 2. SAVE map.yaml raceline_profiled.csv 3. RACE particle_filter pure_pursuit map_course ~/.ros/racerbot_auto/<run>/ race_launch.py run_dir:=…
How to read it: the three boxes are the three steps, left to right. The text in each box names the nodes or files involved, and the text under each box is the command or folder for that step. Steps 1 and 2 are one command. Step 3 is a second command, run from the same spot.

The pipeline

Step What happens Produces Details
1. Map gap_follow drives laps while slam_toolbox builds an occupancy grid. Laps are counted from the car’s turning and checked for quality. map.yaml, map.pgm, SLAM’s pose graph Map a course, SLAM
2. Build the line The last clean lap is recorded as points, given a speed at each, and optionally reshaped to the least-curved line. A line the car could not steer is refused. raceline_raw.csv, raceline_profiled.csv, raceline_optimized.csv Racing line and speed profile
3. Save the start The pose where the car stopped is saved start_pose.yaml, commands.txt Map a course
4. Localize The particle filter starts on the map, seeded at the saved start pose The car’s pose on /pf/viz/inferred_pose Race a saved map, The particle filter
5. Race pure_pursuit_node follows the line at its profiled speeds, under the safety net /drive Pure pursuit, Safety net

Steps 1 to 3 are one command, map_course. Steps 4 and 5 are a second, race_launch.py.

Three routes

Route Commands Use it when
Map, stop, then race map_course, then race_launch.py The standard route. The map can be raced again on another day.
Map and race in one launch auto_map_race_launch.py Racing straight after mapping, with no restart
Map by hand slam_launch.py beside teleop, then map_saver_cli Driving the mapping laps manually

The first and third are on Map a course and Race a saved map. The second is below.

Map and race in one launch

auto_map_race_launch.py maps the course and hands control straight to pure_pursuit once the racing lap passes its quality check, with no restart. It starts bringup itself, so run it on its own.

ros2 launch racerbot_launch auto_map_race_launch.py

During this launch gap_follow and pure_pursuit both run, but neither publishes on /drive. The supervisor, auto_map_race_node, forwards gap_follow’s commands while mapping and pure_pursuit’s after the handover. See System architecture.

It maps for two laps by default (mapping_laps in auto_map_race.yamlGitHub), and records up to three if a lap fails the quality check. The terminal shows lap messages, a handover summary, then Transition complete: pure pursuit now has drive control. A lap on the club’s 126 m hallway loop takes about 136 s, so a run takes several minutes. The progress line shows how far round the car is, for example ~34% round, ~83m to go.

During the race, SLAM keeps running and keeps localizing the car, so this route needs no particle filter. The controller reads the rear-axle pose on /slam_pose instead of the particle filter’s LiDAR pose.

The run folder

map_course and auto_map_race_launch.py write everything to one folder per run, named by date and time.

File Contents
map.yaml, map.pgm The occupancy grid: each cell free, occupied or unknown
Pose graph files SLAM’s pose graph, so the map can be reloaded and extended
raceline_raw.csv The recorded racing lap, as x, y points
raceline_profiled.csv The same points with a target speed at each
raceline_optimized.csv The minimum-curvature line, when the optimizer ran
start_pose.yaml Where the car stopped, which seeds the race’s localization
commands.txt The race commands for this run, as printed at the end
Source Folder
The car ~/racerbot-ws/data/<id>/racerbot_auto/<YYYYMMDD-HHMMSS>/
The simulator ~/racerbot-ws/data/<id>/racerbot_sim/auto/<YYYYMMDD-HHMMSS>/

To find the newest runs and print one run’s commands again:

ls -t ~/racerbot-ws/data/<id>/racerbot_auto | head -3
cat ~/racerbot-ws/data/<id>/racerbot_auto/<run>/commands.txt

Troubleshooting for each half is on Map a course and Race a saved map.

Checked against car 1 commit 0265263 and car 2 commit b81b291, before the two workspaces merged.