Model Predictive Control: Optimisation Over a Time Horizon
MPC plans over a rolling time horizon, optimises at each step, and executes only the first action. It handles constraints, works with linear and non-linear models, and requires real-time optimisation to close the loop.
What MPC Is
Model Predictive Control is a feedback control strategy that uses a model of the system to plan ahead. At every time step:
- Measure the current system state
- Optimise a sequence of control inputs over a future time horizon
- Apply only the first action from that sequence
- Repeat at the next time step with updated measurements
This receding-horizon approach means MPC is always looking forward but acting cautiously. It commits to one step at a time. The result is a controller that handles constraints naturally and anticipates future states.
MPC optimises future system trajectories through predictions using a dynamical model of the system. MPC does not improve itself through data like ML.
System Model
The general system:
- State : system state
- Input : control input
- Output : system output (what you measure)
The model can be linear or non-linear. The linear case:
where and are matrices. governs how the state evolves on its own; maps control input to state change.
The Feedback Loop
System → y → [compare to target] → MPC → u → System
The MPC block receives the measured output , compares it to the target (e.g. ), computes the optimal control input over the time horizon, and feeds back into the system. This closes the loop.
The optimisation happens at every time step, only for the next value, not the entire future trajectory all at once: “we optimise over the time horizon at step 1.”
What Makes MPC Powerful
- Constraint handling: MPC natively enforces input and output constraints (e.g. actuator limits, safety bounds) as part of the optimisation
- Linear and non-linear: works with both model types
- Look-ahead: planning over a horizon allows anticipation of future disturbances
- Complexity: computationally expensive compared to simpler controllers like PID; the optimisation must solve in real time at every step
Key Terms
Linear Quadratic Regulator (LQR): a special case of MPC for linear systems with a quadratic cost. Has a closed-form solution.
Kalman Filter: used inside MPC for state estimation when the full state cannot be measured directly.
System Identification: the process of finding a model of the system from input-output data. Often the hardest step in deploying MPC.
Real-time optimisation: the core computational requirement. The solve must complete within one time step of the physical system.
MPC vs Machine Learning
MPC uses a fixed dynamical model and optimises trajectories. It does not learn from new data. ML learns patterns from data and generalises to new inputs. The two are complementary: ML can be used for system identification (learning the model), and MPC uses that model for control.
What You Can Do Now
The code below runs a simple 1D MPC loop: a scalar system with a target setpoint, optimising a sequence of control inputs over a short horizon at each step.
import numpy as np
from itertools import product
# System: x_{t+1} = A*x + B*u (scalar, A=1 means no natural decay)
A, B = 1.0, 0.5
target = 10.0
horizon = 3 # look-ahead steps
u_candidates = np.linspace(-3, 3, 13) # discrete control options
def simulate_horizon(x0, u_seq):
"""Simulate system over the horizon, return total cost."""
x, cost = x0, 0.0
for u in u_seq:
x = A * x + B * u
cost += (x - target)**2 + 0.1 * u**2 # state error + control effort
return cost
x = 0.0 # initial state
print(f"{'Step':>4} {'State':>8} {'Control':>8} {'Error':>8}")
for step in range(15):
# Optimise over all combinations of u over the horizon (brute force, small horizon)
best_cost, best_u0 = np.inf, 0.0
for u_seq in product(u_candidates, repeat=horizon):
cost = simulate_horizon(x, u_seq)
if cost < best_cost:
best_cost, best_u0 = cost, u_seq[0]
x = A * x + B * best_u0 # apply only the first action
print(f"{step+1:>4} {x:>8.3f} {best_u0:>8.3f} {abs(x-target):>8.3f}")
Increase horizon to see the controller anticipate further ahead (at higher compute cost). Adjust the 0.1 * u**2 weight to trade off control effort against tracking accuracy. A larger weight makes the controller more conservative.