What it was
Firmware for a small RC-style self-driving car platform — the lowest tier of the autonomy stack. Sample sensors via ADC, drive motors via PWM, and run a simple PID loop closing position error to motor command. Done alongside the SDC nanodegree as a hardware companion to the simulator-only projects.
What I’d do differently with hindsight
- Rust embedded. The Rust ecosystem on Cortex-M (RTIC, embassy) is mature now and offers safety guarantees C/C++ can’t. For new embedded work I wouldn’t pick C++.
- Test on the bench, not in the car. Most of the debugging time on this project was “drive the car around, see what went wrong.” A bench harness with simulated wheel encoders + scope captures would have collapsed the iteration loop.
What it taught me
Even toy autonomy reveals where the complexity lives. The high-level SDC nanodegree projects (lane finding, EKF, etc.) all assume “I will be handed a velocity setpoint and the car will track it.” This project showed how much engineering hides inside that assumption — calibration, deadzones, PWM linearity, sensor noise. Most autonomy that fails in the field fails here, not in the planner.