Model-Based Adaptive Cruise Control & Autonomous Steering
A Simulink-based vehicle control system for the NXP S32K144.
Project Overview
This project involved the design and implementation of a sophisticated Adaptive Cruise Control (ACC) and autonomous steering system for a simulated vehicle. Using MATLAB/Simulink for model-based design, the system was deployed on an NXP S32K144 microcontroller.
The core of the project was to create a multi-mode control system that could maintain a set speed, adapt to traffic by maintaining a safe following distance, and autonomously steer the vehicle along a predefined course. The system integrated hardware I/O, CAN bus communication for vehicle-to-vehicle data, and a haptic steering wheel for realistic force feedback.

Key Features
Multi-Mode Control
Stateflow logic switches between manual, speed control, and position control modes.
CAN Bus Integration
Processes data from up to six other vehicles to identify the lead car for adaptive control.
Autonomous Steering
A tuned PD controller provides stable lane-keeping at speeds up to 30 m/s with haptic feedback.
Technical Implementation
Simulink Modeling & Vehicle Dynamics
The vehicle's motion was modeled using a bicycle model, with differential equations implemented in a Simulink S-Function to describe the longitudinal and lateral dynamics. The model took throttle inputs and steering angle to calculate the vehicle's position (x, y) and heading (ψ) in a global coordinate system.
Lead Vehicle Detection
A critical component of the ACC system is the "Pick Lead Logic." I developed a C-based S-Function that takes an array of s-coordinates (distance along the road) for all vehicles on the CAN bus. The function iterates through these vehicles, compares their position to our own, and identifies the closest vehicle that is geometrically ahead. This logic outputs the lead vehicle's s-coordinate and speed, which is fed into the ACC's state machine.
PD Controller for Autonomous Steering
The automatic steering was achieved using a Proportional-Derivative (PD) controller. The error signal for the controller was the vehicle's lateral deviation ('n' coordinate) from the center of the road. The PD controller was tuned to provide stable lane-keeping with minimal overshoot and steady-state error, even at high speeds, and actuated the haptic wheel to provide realistic steering feedback to the user.
Code Snippet
Below is a C code snippet from the "pick_lead" S-Function, which is responsible for identifying the lead vehicle from the CAN bus data.
/* S-Function: pick_lead_outputs_wrapper */
void pick_lead_Outputs_wrapper(const real32_T *car_dist,
real32_T *distance,
int32_T *index,
boolean_T *no_lead)
{
float min_dist_ahead = 1e9; // Initialize with a very large number
int lead_idx = -1; // -1 indicates no lead vehicle found
// car_dist[0] is our own car's s-coordinate
float my_s = car_dist[0];
// Iterate through the other 6 cars
for (int i = 1; i <= 6; i++) {
float other_s = car_dist[i];
// Check if the other car is ahead of us
if (other_s > my_s) {
float dist_ahead = other_s - my_s;
// If this car is closer than the current lead, update
if (dist_ahead < min_dist_ahead) {
min_dist_ahead = dist_ahead;
lead_idx = i;
}
}
}
if (lead_idx != -1) {
// A lead vehicle was found
*distance = car_dist[lead_idx]; // Output the s-coordinate of the lead car
*index = lead_idx; // Output the index of the lead car
*no_lead = 0; // Set no_lead flag to false
} else {
// No lead vehicle found
*distance = my_s; // Output our own distance as a fallback
*index = 0; // Output our own index
*no_lead = 1; // Set no_lead flag to true
}
}