The problem
An ADAS controller is designed as a model but ships as C code on an ECU, and each step can introduce errors: code generation, compiler, fixed-point effects, timing and communication. Industry checks each step with MIL, SIL, PIL and HIL tests. This project builds that chain at bench scale and measures where differences appear.
Objectives
- Design an ACC controller in Simulink with requirements linked to tests.
- Run back-to-back MIL and SIL tests with Simulink Test and Embedded Coder.
- Run PIL on the STM32 and measure execution time.
- Build a bench HIL loop over CAN with a real-time plant on the PC.
- Compare outputs and timing across MIL, SIL, PIL and HIL.
What you need
Tools and toolboxes
- Simulink and Stateflow — The ACC controller model and its mode logic.
- Automated Driving Toolbox — Lead-vehicle scenarios driving the plant model.
- Simulink Test — Test harnesses, test cases, back-to-back comparisons and the Test Manager.
- Embedded Coder — C code generation for SIL and PIL, with the STM32 support package for the target.
- Requirements Toolbox — Requirements linked to model elements and test cases.
- Vehicle Network Toolbox — CAN communication from the PC model to the board through a supported USB-CAN adapter.
- Simulink Desktop Real-Time — Pacing the PC plant model to real time for the HIL loop.
From the EV Embedded Development Kit
- STM32F103C8T6 microcontroller unit (Arm Cortex-M3)
- CAN bus interface with screw terminal
- Serial UART interface
- 16×2 LCD
- RGB LEDs and a buzzer
Software
- MATLAB, Simulink, Stateflow, Simulink Test, Embedded Coder and Requirements Toolbox
- Embedded Coder support package for STM32 processors
- STM32CubeIDE
Extra parts and data
- USB-CAN adapter supported by Vehicle Network Toolbox — Connects the PC plant model to the kit's CAN bus for the HIL loop.
- CAN cable with 120-ohm termination — A properly terminated two-node bus between the adapter and the kit.
Key concepts
- MIL, SIL, PIL and HIL
- Model-in-the-loop simulates the model; software-in-the-loop runs generated code on the PC; processor-in-the-loop runs it on the target processor; hardware-in-the-loop runs it on the ECU with real I/O against a real-time plant.
- Back-to-back testing
- Running the same test inputs on two versions, for example model and generated code, and checking that their outputs agree within a tolerance.
- Execution profiling
- Measuring how long each generated function takes on the target, used to check that the controller fits its time budget.
- Time gap
- The ACC set-point for following distance expressed as time, so the desired gap grows with speed.
Step-by-step guide
- 1
Write requirements and the test plan
Write ACC requirements in Requirements Toolbox: hold set speed within 1 km/h when free, follow at a selected time gap of 1.4 or 2.0 s, limit commanded deceleration to 3 m/s² and acceleration to 2 m/s², hand over to the driver when more braking is needed, and run every 20 ms. Define the test levels and their pass rules: MIL against requirements, SIL and PIL against MIL within tolerance, HIL against requirements with timing.
Checkpoint: A requirement set with IDs and a test plan stating what each test level must show.
- 2
Build the controller and plant
Model the ACC in Simulink: a Stateflow chart for off, standby, speed control and gap control modes, a speed PI controller and a gap controller on spacing error and relative speed, with a minimum-select between them and acceleration limits. Build a separate plant model with longitudinal vehicle dynamics, an actuator lag and a lead-vehicle trajectory from Automated Driving Toolbox scenarios. Keep the controller in its own model referenced by the harness.
Checkpoint: In MIL, the ACC follows a lead vehicle in a cut-in scenario without violating acceleration limits.
- 3
Create test cases and MIL baseline
Use Simulink Test to create a harness for the controller and at least ten test cases: set-speed step, lead-vehicle braking, cut-in, cut-out, stop-and-go and sensor dropouts. Add verify statements or custom criteria for each requirement, such as maximum deceleration, steady time gap error and settling time. Link test cases to requirements. Run them and record the MIL baseline outputs for later comparison.
Checkpoint: All MIL test cases pass and the requirement coverage report shows every requirement tested.
- 4
Prepare the model for code generation
Set a fixed-step discrete solver with a 20 ms step, choose the ert.tlc target and define data types. Decide whether to use single-precision floats, which the Cortex-M3 emulates in software, or fixed-point types, and record the reasoning. Run the code generation advisor checks and fix issues. Generate code and read it to understand the step function and its inputs and outputs. Keep a record of code size reported after compilation.
Checkpoint: Generated code compiles without warnings and the step function interface matches the model ports.
- 5
Run SIL back-to-back tests
Run the same test cases in SIL mode, where the generated code is compiled and executed on the PC. Use Simulink Test equivalence tests to compare SIL outputs against MIL with absolute and relative tolerances chosen from the signal ranges. Investigate any difference, for example from data type conversions or integrator implementations. Collect model and code coverage if Simulink Coverage is available.
Checkpoint: SIL outputs match MIL within the stated tolerances for every test case.
- 6
Run PIL on the STM32
Install the Embedded Coder support package for STM32 processors and configure the kit as the target with a serial link for PIL communication. Run the test cases in PIL mode so the controller code runs on the Cortex-M3 while the harness runs on the PC. Enable execution profiling to measure the time per step. Compare PIL outputs with MIL and check that the worst-case execution time fits well inside the 20 ms period.
Checkpoint: PIL outputs match MIL within tolerance, with a profiling report showing worst-case execution time.
- 7
Build the bench HIL loop
Deploy the controller to the kit as a standalone application that receives ego speed, lead range and range rate in a CAN message every 20 ms and returns the acceleration command and mode. On the PC, run the plant and scenario in Simulink paced to real time with Simulink Desktop Real-Time, sending and receiving CAN frames through Vehicle Network Toolbox blocks and the USB-CAN adapter. Show the ACC mode on the kit LCD and LEDs.
Checkpoint: The closed loop runs in real time over CAN and the cut-in scenario completes with the kit in control.
- 8
Run HIL tests and fault cases
Run the test cases in the HIL loop and evaluate the same requirement criteria. Measure the loop latency from plant output to received command using timestamps. Add fault cases that only HIL can show: delayed frames, a missing message and bus-off recovery. Specify what the controller must do on loss of input, such as fall back to standby with a driver alert, and test it.
Checkpoint: A HIL results table with requirement verdicts, measured loop latency and behaviour on message loss.
- 9
Compare levels and report
Compile a comparison of MIL, SIL, PIL and HIL results: output differences, execution time, latency and verdicts per test case. Explain each difference that appeared and at which level it was caught. Discuss what a production HIL adds that this bench does not: real sensor simulation, electrical fault injection and certified real-time hardware. Provide models, test files and reports so the full chain can be rerun.
Checkpoint: A report with a level-by-level comparison table and an explanation of every observed difference.
Testing & validation
- MIL test pass rate and requirement coverage.
- SIL and PIL equivalence with MIL within tolerance.
- Worst-case execution time on the STM32 against the 20 ms budget.
- HIL loop latency and requirement verdicts.
- Controller behaviour on message loss and delay.
Expected results
A complete MIL-SIL-PIL-HIL validation chain for an ACC controller on low-cost hardware, with quantified equivalence, timing and fault behaviour at each level.
Research angle for your M.Tech thesis
Research questions: which classes of defects are caught at each test level, and how should test effort be divided between MIL, SIL, PIL and HIL for an ADAS controller? Metrics: output deviation between levels, execution time, loop latency, defects found per level and test time per level. Seeding known defects, such as type overflows, timing faults and message losses, and recording where each is first detected gives a quantitative basis for a thesis chapter on test strategy.
Take it further
- Replace the PI gap controller with an MPC and compare execution time on the target.
- Add an AEB function sharing the same CAN interface and test arbitration.
- Automate the full chain in a continuous integration job.
- Inject sensor noise and dropouts from the PC side during HIL.
Viva and review questions
What does SIL catch that MIL does not?
Differences introduced by code generation and data types, such as rounding, overflow or a changed integrator implementation, because SIL runs the actual generated C code.
Why run PIL if SIL already passed?
PIL runs the code compiled for the real processor, so it shows compiler and processor effects and gives real execution times.
What makes your bench setup HIL rather than PIL?
The controller runs standalone on the board with its real CAN interface and timing, exchanging messages with a real-time plant, rather than being called step by step by the simulation.
What should the ACC do when its input message stops arriving?
Detect the timeout, stop acting on stale data, move to a safe state such as standby and alert the driver, as defined in the requirements.
Learn it at DIYguru
These DIYguru courses and programmes teach what this project needs.
