Simulation-Based MPC in 3D

A quadrotor follows a path in 3D by model predictive control (MPC). At every step of Δt = 0.25 s it predicts where each plan of accelerations would take it, scores every plan by a cost, drops the plans that come too close to the other drone, an obstacle or the ground, or go too fast, and carries out the first step of the cheapest one. Click the drone, the other drone or an obstacle and drag its arrows to move it in 3D; drag elsewhere to turn the view, scroll to zoom; hover a plan or a cell of the cost grid to see its cost.
The 3D version of Simulation-Based MPC, from the video Model Predictive Control (MPC) Explained, on the kernel in sbmpc/.
cheapdear
the cheapest plan
dropped: breaks a constraint
the other drone, dsafe
t = 0.0 s

Plans

Cost

Constraints

The drone

Off the path [m]: across (+ to the right) and above, measured and planned

Speed |v| [m/s]: measured, and planned

Acceleration [m/s²]: carried out, and planned

The cheapest plan, now

Cost of the cheapest plan for each first acceleration

Things to try

How it works

The model is a point mass driven by its acceleration, with p = [xn, yn, zn]⊤ the position north, east and down (the altitude is h = −zn), v the velocity and a the acceleration, held over each step (exactly, for a constant a):

pk+1 = pk + Δt vk + ½ Δt² ak
vk+1 = vk + Δt ak

A quadrotor's attitude loop is fast: it tilts its thrust to get the acceleration it is asked for, so its acceleration is what a plan can choose (the drone drawn here tilts by it).

A plan holds an acceleration for each of one, two or three segments, each one of a lattice: an evenly spaced set of values from −amax to amax on each axis, every combination of north, east and up. After the last segment it coasts (a = 0) to the horizon NΔt.

The cost adds up the squared distance from a reference point rk, which sets off from the point on the path nearest the drone and moves along it at the speed U (so the cost asks for both the path and the speed on it), and the squared accelerations:

J = Σk=1N |pk − rk|2 + λ Σk=0N−1 |ak|2

The constraints: |a| ≤ amax on each axis (no plan asks for more), |pk − qk| ≥ dsafe with the other drone predicted straight on at its present velocity, dclear from the surface of each obstacle, an altitude of at least 1 m, and |vk| ≤ vmax. A plan that breaks one is dropped, from the step where it does. When every plan is dropped, the drone carries out the one that breaks a constraint latest.

Plans that start the same way share that part of the prediction. The kernel walks the plans as a tree: it predicts each first segment once, each second segment once for each first, and so on, and when a first segment already breaks a constraint it drops every plan that starts with it at once.

The drone is simulated as the same model, every 20 ms, except that its acceleration follows the commanded one with a first-order lag τ, and the wind pushes it east; the model leaves both out. The other drone flies back and forth across the first leg, climbing as it goes east.

The kernel, sbmpc/ in this repository, is a small library with no dependencies that runs in a browser or Node: give it a model, the controls each segment may pick from, cost terms and constraints, and it returns every plan's prediction and cost and the cheapest one. Given the 2D app's model, plans, cost and constraints, it scores every plan as the 2D app does (its tests check this).

T. A. Johansen, T. Perez and A. Cristofaro, "Ship collision avoidance and COLREGS compliance using simulation-based control behavior selection with predictive hazard assessment," IEEE Transactions on Intelligent Transportation Systems, 17(12), 3407–3422, 2016. S. Liu et al., "Search-based motion planning for quadrotors using linear quadratic minimum time control," IROS, 2017 (acceleration motion primitives).