F1TENTH Final Project · Validated on three physical tracks
Racing Blind — Autonomous Explore-to-Race Pipeline
A car that maps a track it has never seen, computes a raceline from its own map, and then races it — no prior map, no human initialization. Validated at 3.0–4.0 m/s on Levine, Skirkanich and Towne.
Period
Jan – May 2026
Stack
ROS 2 · SLAM · RTAB-Map · EKF · OSQP · Pure Pursuit
Highlights
- 01Fully autonomous explore-to-race pipeline needing no prior map and no human initialization
- 02Wall-following PID drives the exploratory lap while RTAB-Map builds a loop-closure-aware occupancy grid
- 03EKF fusing D435i IMU and wheel odometry for drift-corrected pose during exploration
- 04State machine extracts a centerline by distance-transform skeletonization, then optimizes a raceline with OSQP
- 05Pure Pursuit with an adaptive cross-track-error speed controller that finds and locks the maximum sustainable speed on its own
- 063.0–4.0 m/s achieved across all three physical tracks
Demo video
Levine — full explore-to-race run
Skirkanich — full explore-to-race run
Towne — full explore-to-race run
Write-up
Every racing stack assumes someone hands it a map and a raceline. Racing Blind removes that assumption: you put the car down on a track it has never seen, and it works out the rest by itself — explore, map, plan a raceline, then race it, with no prior map and nobody initializing anything.
The exploratory lap is deliberately dumb and reliable. A wall-following PID drives it, because the only requirement at that stage is getting all the way around without hitting anything. While it drives, RTAB-Map builds a loop-closure-aware occupancy grid, fed by an EKF that fuses D435i IMU with wheel odometry — without that fusion the pose drifts far enough over a lap that the loop never closes cleanly and the map is unusable.
Then a state machine takes over. It extracts a centerline from the occupancy grid by distance-transform skeletonization — the skeleton of the free space is, by construction, the set of points furthest from the walls — and hands that to an OSQP raceline optimization that trades curvature against path length. Control switches to Pure Pursuit for the racing laps.
The last piece is knowing how fast the car can actually go, which is track-dependent and not something you can look up. An adaptive speed controller ramps up while watching cross-track error, and locks in the highest speed it can sustain before tracking starts to degrade. Across Levine, Skirkanich and Towne it settled between 3.0 and 4.0 m/s — the three runs below are the full laps, unedited.