Docs menu
Race a saved map
Localize the car on a mapped course from its saved start pose, then race the saved line with pure pursuit or another steering law.
Racing is the second half of racing a course. It needs a run folder from mapping, with a map, a racing line and the start pose, and the car back on that start pose. race_launch.py localizes the car on the map with the particle filter, then starts pure_pursuit_node to follow the line. Racing has been tested in the simulator only.
Race
Start with the car where mapping left it, or back on the marked spot facing the same way. Bringup must be running in terminal 1.
Terminal 2. Replace <id> with rb1 or rb2, and <run> with the folder printed at the end of mapping:
ros2 launch racerbot_launch race_launch.py run_dir:=$HOME/racerbot-ws/data/<id>/racerbot_auto/<run>The printout at the end of mapping contains this command with the folder filled in. To find it again:
ls -t ~/racerbot-ws/data/<id>/racerbot_auto | head -3
cat ~/racerbot-ws/data/<id>/racerbot_auto/<run>/commands.txtThe race is working when Particle filter is at the start pose; racing can begin. appears. pure_pursuit starts only after that line, then drives the line while LB is held.
To race with another steering law, add steering_law:=:
ros2 launch racerbot_launch race_launch.py run_dir:=$HOME/racerbot-ws/data/<id>/racerbot_auto/<run> steering_law:=stanleylqr and mpc work the same way. MPC also needs the osqp package.
What the launch does
race_launch.py does four things, in order.
- Checks the GPU ray caster. The particle filter’s settings are read first. The launch refuses to start if
range_libcwas built without CUDA, because the filter would crash on its first scan, or ifmax_particlesis above 4,297, the most the GPU buffer holds with 61 rays per particle. - Starts the particle filter on the run’s map.
- Seeds it.
seed_start_posereadsstart_pose.yamland publishes it on/initialpose, as RViz’s 2D Pose Estimate tool would. It repeats the seed a few times, in case the first message arrives while the filter is still loading its map, then waits until the filter reports a pose close to the seed, and exits. - Starts
pure_pursuit_node, only after the seeder has exited successfully.
The order matters. Before it is seeded, the filter publishes its own unseeded guess, and in the simulator that guess jumped 6 m. A controller already driving on it steered into a wall, which is why the controller waits for the seeder.
The start pose
The filter spreads its first particles 0.5 m and 0.4 rad (about 23°) around the seed. A car within a few tens of centimetres and degrees of the saved pose is therefore found at once; a car a metre away or facing the wrong way may never be. start_pose.yaml is the pose SLAM measured where the car stopped, on the racing line it had recorded.
The saved pose describes the rear axle, and the filter estimates the LiDAR’s pose, 0.26 m further forward, so the seeder moves the seed forward by that much before sending it.
Check it
ros2 topic hz /pf/viz/inferred_pose # one pose per scan when the filter keeps up
ros2 topic hz /drive # 40 Hz once pure_pursuit runs
ros2 param get /pure_pursuit_node steering_lawpure_pursuit_node’s decision line names the steering law as its state while it races. A stop names its reason; see One tick, in order.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| The filter never reaches the start pose | The car is not where mapping left it, or the run folder is wrong | Move the car to the marked spot and run the race command again. Nothing drives in the meantime. |
The launch refuses to start, naming range_libc or CUDA |
The GPU ray caster was built without CUDA | Rebuild it: Set up the workspace, step 4. |
The launch refuses to start, naming max_particles |
More particles than the GPU buffer holds | Lower max_particles to 4,297 or fewer. |
ModuleNotFoundError: No module named 'range_libc' |
The GPU ray caster was never built | Set up the workspace, step 4. |
steering_law:=mpc fails to start |
osqp is not installed |
Set up the workspace, step 5. |
| The car drives confidently the wrong way | Localization started from a wrong pose | Stop. Put the car on the start spot and race again. |
Checked against
car 1 commit 0265263
and
car 2 commit b81b291, before the two workspaces merged.