CédricHollande

Robotics

F1TENTH / RoboRacer Autonomous Racing

ICRA 2026 RoboRacer Finalist in Vienna — placed 2nd in time trials and 5th in head-to-head racing among ~30 teams (150+ entrants), competing as 1 of 2 engineers against ~5-person teams from CMU, ETH Zurich, TU Munich, a…

ICRA 2026 RoboRacer Finalist in Vienna — placed 2nd in time trials and 5th in head-to-head racing among ~30 teams (150+ entrants), competing as 1 of 2 engineers against ~5-person teams from CMU, ETH Zurich, TU Munich, and others. Full real-time autonomy stack on a 1:10-scale car with Penn xLab (support from Penn Robotics and Autonomous Systems): LiDAR particle-filter localization, optimized racelines, opponent prediction, and a JAX/GPU MPPI planner on a Jetson Orin Nano.

Time trial run at ICRA 2026 RoboRacer (2nd place)

At ICRA 2026 — Vienna

A week at TU Wien for the RoboRacer competition: trophy day for the time-trial finish, race-arena bringup between heats, and the rest of the ICRA program in between.

Holding the 2nd-place ICRA RoboRacer time-trial trophy
2nd place in time trials at the ICRA 2026 RoboRacer competition (Vienna)
ICRA 2026 RoboRacer group photo
Group photo with the ICRA 2026 RoboRacer teams in Vienna
Working on the F1TENTH car before a race run
Bringup and fixes between race runs at ICRA
With teammate Dhyey at ICRA RoboRacer
With teammate Dhyey at the RoboRacer arena
At TU Wien for ICRA 2026
At TU Wien for the ICRA 2026 RoboRacer competition
ICRA 2026 venue interior
ICRA 2026 venue interior

What I built

I led the full autonomy stack: JAX MPPI controller, opponent-aware cost design, integration with CUDA particle-filter localization, a C++ opponent-prediction node, ROS 2 systems integration, real-time debugging, and a web-based raceline editor for race-day tuning.

  • JAX/GPU MPPI planner: 1.3M trajectories/s (10M steps/s) at 40 Hz on a Jetson Orin, RK4-integrating a 7-state model
  • CUDA-accelerated LiDAR particle-filter localization: 8,000 particles at 50 Hz on isolated cores alongside MPPI
  • C++ opponent-prediction node: LiDAR clustering + raceline-arclength Kalman filtering on (s, v) for predictive overtaking
  • Opponent-aware MPPI cost for dynamic avoidance and overtaking
  • Raceline Studio: web UI to edit waypoints + speed profiles and hot-swap into the running MPPI node via a ROS 2 service
  • Real-time ROS 2 debugging: BEST_EFFORT QoS on debug topics, rate-gated visualization, pose-driven controller callbacks

Repos: https://github.com/cedrichld/opp_aware_mppi_f1tenth and https://github.com/cedrichld/raceline_UI_f1tenth

Race-Day Hardware Deployment

Deployed on a Jetson Orin Nano with CPU pinning: particle filter on cores 0-2, MPPI on 3-5, opponent predictor sharing core 5 with spillover. RELIABLE QoS for /drive to the VESC; BEST_EFFORT + subscriber-count gating for debug topics to avoid race-day Foxglove backpressure stalls.

Race-day overtaking on the Houston track

MPPI avoiding multiple opponents (race-day, Houston)

MPPI Pipeline and Cost Stack

Sampling-based predictive control in JAX on the Jetson Orin Nano's GPU. The planner samples 1.3M trajectories per second (~10M dynamics steps/s) at every control step, RK4-integrating a 7-state vehicle model over an 8-step horizon (~0.8 s lookahead) at a 40 Hz control rate. Softmax temperature lambda = 0.05 weights low-cost rollouts; unified memory preallocation (XLA_PYTHON_CLIENT_PREALLOCATE) avoids JAX fragmentation under continuous control. The cost stack combines raceline tracking, speed-profile tracking, signed-distance-field wall avoidance, and opponent-aware penalties driven by the predictor.

MPPI rollouts in the F1TENTH simulator
MPPI rollouts and chosen trajectory in the F1TENTH simulator
Opponent-aware MPPI overtaking a static obstacle in sim
Opponent-aware MPPI passing a static opponent in simulation

Opponent Prediction

C++ ROS 2 node that clusters LiDAR returns into candidate opponents, projects each onto the raceline's arclength axis, and runs a Kalman filter on (s, v) to predict where the opponent will be a horizon into the future. The MPPI cost function consumes those predictions for opponent-aware rollout scoring.

MPPI following and avoiding a moving opponent in simulation
MPPI following and avoiding a moving opponent in simulation
Opponent-aware MPPI executing a close overtake
Opponent-aware MPPI executing a close overtake in simulation

Raceline Studio — live raceline editing

Practical race-day tooling: a Flask + rclpy web app to drag waypoints, adjust speed profiles, optimize racelines, and push updates live to the running MPPI node through a ROS 2 service. No file reloads, no controller restart. Speeds up race-day tuning loops from minutes to seconds. Also includes a CLI raceline optimizer for batch profiling.

Raceline Studio web UI
Raceline Studio: web UI to edit waypoints and speed profiles, pushed live to the MPPI node via ROS 2 service

Simulation and Foxglove visualizations

Hardware brings extra failure modes; the simulator stays the fastest iteration loop for the controller and cost design. Below: an obstacle-avoidance run on the real car at Levine (UPenn) and a dynamic-obstacle clip from a Houston run that exercises the opponent predictor closing the loop.

Static-obstacle avoidance at the Levine track (UPenn)

Dynamic-obstacle avoidance on the Houston track (raceline-arclength Kalman prediction)

Prior Coursework — Pure Pursuit, RRT*, Follow-the-Gap

Earlier passes on the same hardware platform covering classical racing controllers: pure pursuit on optimized racelines, RRT* for obstacle-aware planning, and follow-the-gap as the reactive baseline. The overlay below shows the planned line vs the car's actual track during pure pursuit tuning.

Pure pursuit raceline editor
Pure pursuit raceline editor (prior coursework)
Pure pursuit raceline with speed overlay
Pure pursuit raceline with speed profile overlay (prior coursework)

Pure pursuit on the real car (prior coursework)

Pure pursuit, second pass (prior coursework)

RRT* in simulation with static obstacles (prior coursework)

RRT* overtaking a dynamic obstacle (prior coursework)

Follow-the-gap obstacle map (prior coursework)

Pure pursuit after iterative tuning (prior coursework)