A production-style Adaptive Cruise Control controller in C++17, covering three operating modes — free cruise, following, and emergency braking. Compiled as a shared library and validated through two layers: 15 GoogleTest unit tests for isolated behaviour, and a Python Software-in-the-Loop harness running four closed-loop driving scenarios against a vehicle dynamics model. The C ABI design keeps the controller fully decoupled from any test framework.
Demonstrates proficiency in production C++ for resource-constrained, real-time control systems — the same discipline required in batteryless IoT sensor firmware where every cycle and byte matters.
Used AI tooling throughout: formalising state transition logic, generating edge-case unit tests, and validating PD/PI gains against simulation traces. AI accelerated test coverage significantly.
Click any layer above to learn more about its role.
MinGW: statically linked libgcc/libstdc++ for zero runtime dependency
| From | To | Condition |
| FREE_CRUISE | FOLLOWING | vehicle_detected AND distance < 50 m |
| FOLLOWING | EMERGENCY | distance < 8 m |
| FOLLOWING | FREE_CRUISE | cleared OR distance > 60 m ← 10 m hysteresis |
| EMERGENCY | FOLLOWING | distance > 8 m AND ego_speed < 2 m/s |
Activated when distance < 8 m. No control computation — output is fully deterministic. This eliminates a class of safety-critical bugs where arithmetic could produce a partial brake under extreme sensor conditions.
Claude was used to enumerate edge cases from the state transition table, generating candidate test cases for hysteresis boundary conditions and integrator windup scenarios that manual review had missed. This reduced the time to achieve comprehensive coverage by approximately 60%.
Exposing the controller via extern "C" keeps Python, HIL bench, and integration harnesses all using the same binary. The same .so loads across all test environments without recompilation.
Unit tests run in <1 ms — CI-friendly. SIL catches emergent closed-loop behaviour (integrator windup, recovery under dynamics) that isolated unit tests cannot reveal.
d_safe = 2.0·v + 5.0 scales naturally with speed. A fixed threshold fails at low speeds (too tight) and high speeds (too close). Matches how production ACC defines following distance.
In EMERGENCY, no control computation occurs. Output is always brake=1, throttle=0. Eliminates a class of safety bugs where arithmetic could produce partial braking under extreme conditions.
Fixed-point arithmetic instead of float to avoid FPU dependency on Cortex-M0. DT computed from hardware timer counter, not passed as parameter. Integration gain Ki bounded to prevent windup on watchdog reset. State persistence across warm resets via retained RAM section. MISRA-C++ compliance sweep for safety certification.