Docs menu
Autonomy
The driving algorithms that run on the car, what each one needs, and the mathematics behind it.
Every algorithm here runs as a control layer on top of bringup, publishes on /drive, and drives only while LB is held. They fall into two groups. gap_follow is reactive: it decides from the scan in front of it and needs no map. The race stack follows a saved racing line on a mapped course, and can steer with any of four steering laws.
| Page | Needs a map | Runs in | Use it for |
|---|---|---|---|
| Follow the gap | No | gap_follow_node |
A new course, mapping laps, and any run without a saved map |
| Racing line and speed profile | Yes | Offline tools | Building the line the race stack follows |
| Pure pursuit | Yes | pure_pursuit_node |
Racing a saved line; the default steering law |
| Stanley | Yes | pure_pursuit_node |
Alternative steering law, error at the front axle |
| LQR | Yes | pure_pursuit_node |
Alternative steering law, computed feedback gains |
| MPC | Yes | pure_pursuit_node |
Alternative steering law, plans one second ahead |
| Safety net and overtaking | Yes | pure_pursuit_node |
The checks that override every steering law, and passing another car |
| Neural racer | Optional | neural_racer_node |
Experimental learned policy, in shadow mode |
Each algorithm page lists the node’s topics, explains each step with its mathematics derived from the start, and shows the code that implements it.
Racing on a map
gap_follow sees only the current scan, so it cannot brake early for a corner it has not reached or hold a chosen line through a bend. On a mapped course, pure_pursuit_node races instead. It knows the whole course as a racing line with a target speed at every point, and it knows where the car is on that line, so it starts braking before a corner and drives the same line every lap. The cost is a dependence on the map and on localization, which is why a reactive LiDAR safety net, built on the same idea as gap_follow, runs underneath it.
| Step | What happens | Tool | When |
|---|---|---|---|
| 1. Map | slam_toolbox builds an occupancy grid of the course |
map_course or slam_launch.py |
Once per course |
| 2. Record a lap | The car’s positions along one lap are saved as x, y points |
auto_map_race_node, or waypoint_recorder_node by hand |
Once per course |
| 3. Profile | A target speed is computed for every point | generate_velocity_profile |
After each recording |
| 4. Optimize (optional) | The line is reshaped to the least-curved path that fits the track | optimize_raceline |
After each recording |
| 5. Race | The particle filter localizes the car, and pure_pursuit_node follows the line |
race_launch.py |
Every run |
map_course and auto_map_race_launch.py run steps 1 to 4 automatically. Running a step by hand is useful for re-profiling a saved lap with different limits, or for a line recorded while driving manually. The commands are on Map a course and race.
Lecture 10 (notes) of the course covers pure pursuit, and Lecture 7 (notes), Lecture 8 (notes) and Lecture 9 (notes) cover the localization it depends on.
Choose a steering law
A steering law answers one question each tick: how far to turn the wheels to stay on the racing line. pure_pursuit_node has four, chosen at launch with steering_law:=:
ros2 launch racerbot_launch race_launch.py run_dir:=$HOME/racerbot-ws/data/<id>/racerbot_auto/<run> steering_law:=stanleyOnly the steering changes. The LB check, the watchdogs, the safety net, overtaking and every speed limit are shared, so a poorly tuned law can track the line worse or lap slower but cannot switch off a safety layer, and no law can raise the speed. The law and its parameters are read at launch and cannot be changed while the node runs.
| Law | Looks at | Strength | Weakness |
|---|---|---|---|
| Pure pursuit | A point a speed-dependent distance ahead | Smooth, hides delay and noise | Turns early, cutting corners at entry |
| Stanley | The front axle’s errors now | No lookahead to tune | Sensitive to delay and pose noise |
| LQR | The rear axle’s errors now, with feedforward | Gains computed from a model | Same sensitivity as Stanley |
| MPC | The next second of the line | Sees bends coming; respects the rate limit exactly | Must finish a solve in 8 ms |
Each law was tuned on one set of simulator seeds and judged once on a separate set: three circuits (Spielberg, Silverstone, Brands Hatch) and five seeds each. A law is promoted only if it is safe on every run, strictly better than pure pursuit on cross-track error or lap time, and at most 5% worse on the other.
| Law | Runs passed | Mean cross-track | Mean lap | Verdict |
|---|---|---|---|---|
| Pure pursuit | 15/15 | 0.0690 m | 147.6 s | Baseline |
| Stanley | 15/15 | 0.0679 m (−1.6%) | 151.7 s (+2.8%) | Promote |
| LQR | 15/15 | 0.0714 m (+3.5%) | 145.2 s (−1.6%) | Promote |
| MPC | 15/15 | 0.0694 m (+0.6%) | 145.3 s (−1.5%) | Promote |
Results from October 19, 2026. No run of any law touched a wall. Promotion means a law may be selected on the car, not that it becomes the default. Every margin is under 5% and was measured only in the simulator; Stanley, LQR and MPC have not been driven on a car. The full procedure is in docs/steering-laws.mdGitHub.
- Follow the gapReactive driving with no map: gap_follow aims into the best-scoring opening in each LiDAR scan and caps its speed so the car can always stop within the free distance ahead.
- Racing line and speed profileHow the racing line is recorded, how every point gets a target speed from the car's grip and braking limits, and how the line can be reshaped to the least-curved path the track allows.
- Pure pursuitThe default race controller: each tick it picks a point a speed-dependent distance ahead on the racing line and steers along the circle that reaches it.
- StanleySteering from the front axle's errors: turn the wheels parallel to the racing line, then toward it by an angle that grows with the sideways error.
- LQRFeedforward for the bend plus feedback on the sideways and heading errors, with gains computed from a model of the car rather than tuned by hand.
- MPCEvery tick, MPC plans 20 steering moves over the next second within the servo's angle and rate limits, applies the first, and plans again.
- Safety net and overtakingThe independent checks that can stop or steer pure_pursuit, and how it detects another car with the LiDAR, tracks it along the track and passes it.
- Neural racerAn experimental learned racing policy: a small network trained in simulation, run in shadow mode beside gap_follow, inside a deterministic safety wrapper that can only make its commands safer.
Checked against
car 1 commit 0265263
and
car 2 commit b81b291, before the two workspaces merged.