Introduction

Imagine driving toward a stop sign. You do not compute the single correct amount of brake pressure for the whole approach and commit to it. You glance ahead, form a rough plan for the next few seconds, ease off the brake a little, then look again and revise. Model Predictive Control (MPC) is that habit turned into an algorithm.

At every tick, MPC uses a model of the system to predict how it will behave over a short window into the future — the horizon. It searches for the sequence of actions over that window that best reaches a goal without violating any limits: a maximum speed, a temperature ceiling, a fuel budget. Then it does something almost wasteful-looking: it throws away almost the whole plan and applies only its first action.

One tick later, with fresh measurements in hand, it plans again from scratch over a new window shifted one step forward — the receding horizon. That constant re-optimization is not indecision. It is how MPC stays exact about constraints while still reacting to a world that never behaves exactly like the model predicted.

Steer to the Target

Below is a cart on a line. Set a target position and a speed limit, then let the controller drive there. At every step it searches a short horizon of future acceleration sequences, keeps only the ones that never break the speed limit, picks the plan that lands closest to the target, and applies just its first acceleration.

<p class="hint">{{hint_para}}</p>
<div class="controls">
  <label>{{lbl_target}}
    <input type="range" id="target" min="-12" max="12" step="1" value="8">
    <span id="targetVal" class="val">8</span>
  </label>
  <label>{{lbl_vmax}}
    <input type="range" id="vmax" min="0.2" max="2" step="0.1" value="1">
    <span id="vmaxVal" class="val">1.0</span>
  </label>
  <label>{{lbl_horizon}}
    <input type="range" id="horizon" min="2" max="6" step="1" value="4">
    <span id="horizonVal" class="val">4</span>
  </label>
</div>
<canvas id="track" width="560" height="150"></canvas>
<div class="status" id="status">{{status_ready}}</div>
<div class="btns">
  <button id="run" type="button">{{btn_run}}</button>
  <button id="step" type="button">{{btn_step}}</button>
  <button id="reset" type="button" class="ghost">{{btn_reset}}</button>
</div>
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; color: #222; margin: 0; }
.hint { font-size: .9rem; color: #444; margin: 0 0 .7rem; line-height: 1.45; }
.controls { display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: .6rem; }
.controls label { display: flex; flex-direction: column; font-size: .8rem; font-weight: 600; color: #1d3557; gap: .2rem; }
.controls input[type="range"] { width: 150px; }
.val { font: 700 13px ui-monospace, monospace; color: #333; }
canvas { width: 100%; max-width: 560px; height: 150px; background: #f4f6f8; border: 1px solid #cdd9e3; border-radius: 8px; display: block; }
.status { font-size: 1rem; font-weight: 600; margin: .5rem 0; min-height: 1.4em; }
.status.ok { color: #0a7d33; }
.status.info { color: #1d3557; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; }
button { font: 600 14px system-ui, sans-serif; padding: .45rem .9rem; border: 1px solid #1d3557;
         background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
button.ghost { background: #fff; color: #1d3557; }
button:disabled { opacity: .5; cursor: default; }
// Code not found

Push the speed limit down and watch the cart brake earlier — it is not reacting late, it is foreseeing the limit several steps ahead inside its horizon before it becomes urgent. Push the horizon length up or down and you trade foresight for raw compute: at every single tick, MPC resolves the whole small optimization problem again from scratch.

The Real Complexity

MPC is not one algorithm — it is a recipe: at every time step, solve an optimization problem, apply the first move, discard the rest, and repeat. How hard that recipe is depends entirely on what is inside the box.

  • The model. If the system's dynamics are linear and the cost is quadratic, the per-step problem is a quadratic program (QP) — convex, and solvable in polynomial time with well-understood methods. This is the workhorse case, called linear MPC.
  • The horizon. Searching NN steps ahead with mm possible actions per step naively costs O(mN)O(m^{N}) if you enumerate sequences — exactly the brute force the small demo above uses for a horizon short enough to stay fast. Real solvers avoid the explosion with convex optimization or dynamic programming instead of enumeration.
  • The constraints. Simple bounds like a speed limit keep the feasible region convex. But once decisions become discrete — turn this valve on or off, commit to this gear — the problem becomes mixed-integer programming, which is NP-hard in general, the same complexity class behind problems like job-shop scheduling or the knapsack problem.
  • The nonlinearity. If the dynamics themselves are nonlinear (a drone's rotation, a chemical reactor), the per-step problem loses convexity, and solvers can only guarantee a locally optimal plan, not a global one.

So the honest complexity of MPC is really a spectrum, from "solve a small QP a thousand times a second" to "solve an NP-hard puzzle before the plane needs to know what to do next." Engineers spend enormous effort keeping real systems on the cheap end of that spectrum — approximating, linearizing, and simplifying constraints — precisely so the controller can finish thinking before the world moves on.

Where It Matters

MPC became industry's favorite advanced controller because so many real systems share the same shape: a target to chase and hard limits that must never be crossed.

  • Chemical and oil refining: MPC has run large-scale process plants since the 1980s, juggling temperatures, flows and pressures that can never leave safe operating ranges.
  • Autonomous vehicles and robotics: self-driving cars and robot arms plan a short trajectory, respect speed and torque limits, then replan as sensors update — precisely the loop in the demo above.
  • Aerospace: spacecraft rendezvous, rocket landings and drone flight all use MPC variants to hit a target state while obeying fuel, thrust and attitude constraints.
  • Energy systems: power grids and building climate control use MPC to balance supply and demand ahead of time instead of only reacting after the fact.

Any time you hear "the system optimizes over a rolling window and only commits to the next step," you are looking at a relative of the same idea family that connects to linear programming and integer programming at its foundations.

Conclusion

Model Predictive Control turns the ordinary act of steering into a tiny optimization problem, solved again and again, one horizon at a time. Its trick is not cleverness at any single instant — it is the discipline of planning ahead, acting once, and never trusting the plan further than that.

Whether the per-step problem takes a millisecond or minutes depends on the shape hiding inside it: a friendly convex QP, or something as hard as any NP-hard puzzle. Either way, the receding horizon is the same humble idea driving refineries, rovers and robots alike — look ahead, commit briefly, and always be ready to think again.

Share this article

Pick a channel — or use your device's native share sheet.

Comments

Loading comments...

https://www.kipuhub.com/en/article/model-predictive-control/Content licensed under CC BY-NC 4.0.