The problem
EV drives must respect limits on voltage, current and rate of change while tracking demand. MPC handles constraints explicitly, but solving an optimisation every sample is hard on a small MCU. Explicit MPC moves the optimisation offline, but its region count and memory can explode.
Objectives
- Identify a discrete-time model of the motor and encoder
- Design a constrained MPC and compute its explicit solution offline
- Implement region search and evaluation in fixed point within flash and time budgets
- Compare explicit MPC, on-line MPC and PID on quantified metrics
What you need
From the EV Embedded Development Kit
- STM32F103C8T6 microcontroller unit (Arm Cortex-M3)
- Motor driver for PWM motor-control experiments
- Analog potentiometer input
- Serial UART interface
- 16×2 LCD
Software
- STM32CubeIDE with HAL TIM (PWM, encoder) and UART
- Embedded C
- MATLAB with the Multi-Parametric Toolbox (MPT3) or a Python multi-parametric QP tool
- Python with NumPy, SciPy, pandas and matplotlib
Extra parts
- A small brushed DC gear motor with a quadrature encoder, within the motor driver's rating — The kit has no motor and no speed sensor; the encoder provides the measured state.
Key concepts
- Explicit MPC
- For a linear model with linear constraints and a quadratic cost, the optimal control is a piecewise-affine function of the state, defined over polyhedral regions computed offline.
- Point location
- On-line, the controller finds which region contains the current state and evaluates that region's affine law; a binary search tree reduces search time compared with checking regions in sequence.
- Constraints
- Duty limits, duty rate limits and a speed band can be written into the optimisation, so the controller respects them by design instead of through clipping.
- Worst-case execution time
- The longest time the controller can take per sample; for explicit MPC it depends on the search structure and is what matters for real-time guarantees.
Step-by-step guide
- 1
Define the research questions
Write research questions about tracking quality, constraint satisfaction, region count, flash use and worst-case execution time for explicit MPC compared with PID and with an on-line MPC solver. Fix the sample rate, for example 100 Hz, and set constraints on duty and duty rate from the motor and motor-driver ratings. State acceptance limits for memory, such as a share of the 64 KB flash, and for execution time per sample.
Checkpoint: A written set of questions, metrics and acceptance limits for memory and timing.
- 2
Board setup and data logging
Use the DIP switches to enable the motor driver and LCD. Configure the 72 MHz clock, a 20 kHz PWM channel, a timer in encoder mode, a 100 Hz control timer and UART logging at a baud rate high enough to log speed and duty every sample without drops. Verify the speed measurement against a timed count of revolutions, and add a sequence counter to the log so any dropped sample is detected.
Checkpoint: Speed and duty can be logged at 100 Hz without drops.
- 3
System identification
Excite the motor with a pseudo-random binary duty sequence around several operating points and log speed and duty. In Python fit a discrete second-order model by least squares, including the previous duty in the regressor so rate constraints can be modelled. Validate on separate data using normalised RMS error, and look closely at low speed, where friction makes the motor nonlinear. Record where the linear model is good enough and where it is not.
Checkpoint: Model fit on validation data meets a stated error, for example normalised RMS error.
- 4
MPC design
Formulate a tracking MPC with an augmented state of speed, previous duty and reference, a quadratic cost on tracking error and duty change, and linear constraints on duty and duty rate. Choose the horizon and weights in simulation using the identified model, and check closed-loop behaviour for steps, ramps and load disturbances. Confirm in simulation that the constraints are never violated and that tracking meets your targets.
Checkpoint: Simulated responses meet tracking targets and never violate constraints.
- 5
Compute the explicit solution
Use MPT3 in MATLAB or a Python multi-parametric QP tool to compute the polyhedral regions and their affine control laws. Record how the region count grows with horizon length, and simplify by merging regions that share the same control law where the tool supports it. Build a binary search tree for point location, and estimate the flash needed for each horizon to find designs that fit the limit you set.
Checkpoint: A region count and estimated flash size for each horizon, with at least one design under the flash limit.
- 6
Export to C in fixed point
Generate C tables for the region hyperplanes, the search-tree nodes and the affine control laws. Choose a fixed-point format from the known ranges of each state, and write the search and evaluation code to use it. On the PC, run the C code and the toolbox solution for many thousands of random states inside the feasible set, and check that the largest difference stays within the bound expected from quantisation.
Checkpoint: Maximum difference between C output and toolbox output is within the quantisation bound.
- 7
Run on hardware
Run the explicit MPC in the 100 Hz control interrupt with the potentiometer as the speed reference. Measure the execution time of every call with the DWT cycle counter and record the mean and the worst case over long runs with varied references. Check that the motor tracks the reference and that the duty and duty-rate limits hold on the real hardware, not just in simulation, and log any sample where the state falls outside the feasible set.
Checkpoint: The motor tracks the reference and execution time stays within budget.
- 8
Implement baselines
Implement two baselines on the same hardware: a tuned PID with anti-windup and output clamping, and an on-line MPC for the same problem that runs a fixed number of iterations of a simple projected-gradient method each sample. Measure their execution times with the DWT cycle counter in the same way. Tune each baseline fairly, recording the tuning effort, so the comparison is not biased toward the explicit controller.
Checkpoint: All three controllers run on the same hardware with logged timings.
- 9
Comparative experiments
Run reference steps, ramps and load disturbances with each controller, repeating each test several times. Compute integral of absolute error, overshoot, settling time, constraint violations for both amplitude and rate, and control effort. Present the results as a table with spread across repeats and overlaid response plots. Comment on cases where a controller behaved differently on hardware than in simulation and why.
Checkpoint: A comparison table with spread across repeats for every controller and test.
- 10
Analyse scalability
Show how region count, flash, RAM and worst-case execution time grow with horizon length and with added constraints for explicit MPC, and how execution time grows with iteration count for the on-line solver. Plot both on the same axes to find the point where the on-line solver becomes the better choice for this MCU. Discuss the effect of model mismatch from friction on each controller's performance.
Checkpoint: Plots of memory and time against horizon for explicit and on-line MPC.
- 11
Write up
Write a paper-style chapter covering system identification, controller design, the fixed-point implementation and its verification, hardware results and the scalability analysis. Be explicit about the limits of the study, such as a single motor, a linear model and one sample rate, and about how friction affected the results. Release the identification data, design scripts, generated C tables and firmware, so the results can be reproduced and the method applied to another drive by someone else.
Checkpoint: A paper-style chapter with reproducible results.
Testing & validation
- Model validated on held-out identification data
- C implementation matched against toolbox output for random states
- Worst-case execution time measured with the DWT cycle counter
- Closed-loop comparison with PID and on-line MPC on tracking and constraint metrics
Expected results
An explicit MPC speed controller running on a Cortex-M3 within flash and time limits, with a quantified comparison against PID and on-line MPC and a scalability analysis that shows when each approach fits a small MCU.
Research angle for your PhD
Research questions: up to what horizon and constraint set does explicit MPC fit the memory and timing of a Cortex-M3, how does fixed-point quantisation affect optimality and constraint satisfaction, and when is a bounded-iteration on-line solver better? Metrics: region count, flash and RAM, worst-case and mean execution time, IAE, constraint violations. Baselines: PID with anti-windup and on-line projected-gradient MPC. A publishable contribution would give measured scaling laws and a quantisation-aware design method validated on hardware.
Take it further
- Add an offset-free formulation with a disturbance observer
- Apply the method to a current-limited drive with an INA219 current monitor
- Compare region-search structures for worst-case time
Viva and review questions
Why is explicit MPC fast on-line?
The optimisation is solved offline for all states; on-line the controller only finds the right region and evaluates an affine law.
What limits explicit MPC?
The number of regions can grow quickly with horizon, constraints and state dimension, which can exceed flash and increase search time.
How did you verify the C code?
By comparing its control output with the toolbox solution for many random states and checking differences stay within the quantisation bound.
Why include the previous duty in the state?
It allows constraints on the rate of change of duty, which protects the drive and smooths torque.