First Place Solution in Spring 2026 Simulation Racing Series
Written by Advay Bansal, a junior at Emerald High School.
Stanley Controller Solution: https://github.com/CodeWizard17/ROAR_stuff
Pure Pursuit Solution: https://github.com/advaybansal/roar_feb
Table of Contents
Introduction
Our goal was to build a faster autonomous racing agent by replacing the provided pure pursuit baseline with a more precise Stanley controller, a physics-based speed profile, and a minimum-curvature racing line optimizer. Despite running over 100 simulations and extensive tuning, none of these improvements outperformed the baseline, so we pivoted to improving pure pursuit directly, finishing with a best time of 320.4s.
Development
An autonomous racing agent needs to solve three problems simultaneously: where to steer, how fast to go, and which path to follow.
Lateral Controller
Responsible for steering the car along the intended path. We implemented a Stanley controller, which computes steering corrections based on both the car’s heading error and how far it has drifted from the path (cross-track error): δ = θ_e + arctan(K · e_cte / (v + σ)), with K=2.0 and σ=10. This is a well-established approach used in real autonomous vehicles, including Stanford’s entry in the DARPA Urban Challenge.
Speed Controller
Determines throttle and braking at each point on the track. Our controller computes a target speed from path curvature: v_target = √(μ·g / κ) — using friction coefficients (μ) tuned per track section. Manual braking overrides and post-braking recovery logic were calibrated at the most demanding corners.
Path Planning
The car follows 2,626 pre-computed waypoints per lap, with racing line offsets applied to select sections.
Stanley Controller
Pure Pursuit Baseline (321s)
The competition provided a pure pursuit implementation completing 3 laps in 321s (~107s/lap). Pure pursuit steers toward a lookahead point ahead on the path rather than the nearest point, which cuts the inside of corners and shortens the driven distance, much like an experienced driver would.
Stanley Controller (348.9s)
We replaced pure pursuit with Stanley, expecting its precise cross-track error correction to produce faster laps. After extensive tuning, our best result was 348.9s, 28 seconds slower. The reason was counterintuitive: by tracking the centerline so accurately, Stanley gave up the corner-cutting advantage that pure pursuit gets for free. All configurations using a local path tangent caused crashes in the S1 hairpin; only a far-lookahead (9–30 waypoints) hybrid remained stable.
Physics-Based Speed Profile (361s)
We built a speed controller grounded in vehicle dynamics, using a friction ellipse forward/backward pass — forward: v_next = √(v² + 2·√(a_lon² − a_lat²)·ds), backward: v_prev = √(v_next² + 2·√(a_brake² − a_lat²)·ds) – with a_lon_max = 10 m/s² and a_brake_max = 18 m/s². In theory this produces an optimal speed profile (~103s/lap estimated), but CARLA’s simplified tire model allowed the car to corner faster than the physics predicted, making our profile too conservative and costing time on every straight.
Racing Line Optimizer (crash)
We manually drove both walls to record boundary data (left: 20,537 pts, right: 24,743 pts) and ran a minimum-curvature optimizer, which estimated a lap time of 172.6s. In practice, the optimized path ran too close to the inside walls in several sections – in S6 (Lesmo), our centerline was already 0.9m from the inside wall, leaving no room for the theoretically correct line. Every configuration crashed.
Pure Pursuit
Rather than continuing to chase a Stanley-based solution, we focused on making the pure pursuit pipeline as fast as possible. Comparing our final submission against the original baseline, only two files were modified: ThrottleController.py and submission.py. The lateral controller and all path-following logic were left untouched.
Friction Coefficient Expansion (ThrottleController.py)
The original speed controller used a default friction coefficient of μ = 2.75 for most track sections, with overrides only for sections 2, 3, 4, 6, and 9. Our fork explicitly calibrated μ for three additional sections that had been left at the conservative default:
Section | Original μ | Our μ | |
|---|---|---|---|
S0 (S1 hairpin) | 2.75 (default) | 3.2 | New |
S1 | 2.75 (default) | 3.0 | New |
S2 | 3.35 | 3.4 | |
S4 | 2.85 | 3.05 | |
S8 | 2.75 (default) | 3.1 | New |
Since target speed follows v_target = √(μ·g·r), raising μ from 2.75 to 3.2 in S0 increases the target cornering speed by approximately 8% at a given radius – meaningful accumulated time over three laps.
Results
Configuration | 3-Lap Time | Notes |
|---|---|---|
Pure Pursuit (original baseline) | 321.0s | Provided implementation |
Stanley Hybrid (best attempt) | 348.9s | 0 collisions |
Stanley + Speed Profile | 361.0s | Too conservative |
Stanley + Racing Line | Crash | S6 wall constraint |
Pure Pursuit + our changes | 320.4s | Final submission |
Conclusion
Our most sophisticated approaches: a precise steering controller, an optimal speed profile, and a mathematically computed racing line, all underperformed the simpler baseline. The clearest lesson was that algorithms which work well in theory depend heavily on the accuracy of their underlying assumptions. When the simulator’s physics don’t match the model, theoretical optimality doesn’t translate to real performance.
Ultimately, our winning changes were targeted and empirical: expanding friction coefficient coverage to undertreated track sections, making the post-braking throttle recovery more aggressive, tuning three global speed parameters, and fixing a lap-boundary index bug. The lateral controller, pure pursuit ,was never touched. All the time gains came from the speed controller.
Future work should focus on acquiring accurate CARLA boundary data to safely apply the racing line optimizer across the full track, and re-tuning braking zones accordingly, which we estimate could yield a further 10–15s improvement.