! MPC synthesis in MPT3
Synthesis of MPC controllers in MPT3 is based on two principles:
# Constraints and penalties are specified directly in the prediction model
# Every MPC controller in MPT3 starts as an on-line MPC regulator. Explicit controllers are only synthesized on demand.
To create an MPC controller in MPT3, use the @@MPCController@@ constructor:
(:source lang=MATLAB -getcode:) [@
mpc = MPCController(sys)
@]
where @@sys@@ represents the prediction model, created by @@LTISystem@@, @@PWASystem@@ or @@MLDSystem@@ constructors ([[UI.Systems|see here]]).
As an example, let use consider an LTI prediction model, represented by the state-update equation @@x^+ = A x + B u@@ with @@A = [1 1; 0 1]@@ and @@B = [1; 0.5]@@:
(:source lang=MATLAB -getcode:) [@
model = LTISystem('A', [1 1; 0 1], 'B', [1; 0.5]);
@]
Next we specify more properties of the model:
* Add state constraints @@ [-5; -5] <= x <= [5; 5]@@:
(:source lang=MATLAB -getcode:) [@
model.x.min = [-5; -5];
model.x.max = [5; 5];
@]
* Add input constraints @@-1 <= u <= 1@@:
(:source lang=MATLAB -getcode:) [@
model.u.min = -1;
model.u.max = 1;
@]
* Add quadratic state penalty, i.e., penalize @@x_k^T Q x_k@@ with @@Q = [1 0; 0 1]@@:
(:source lang=MATLAB -getcode:) [@
model.x.penalty = Penalty([1 0; 0 1], 2); % 2 = quadratic penalty
@]
* Use quadratic penalization of inputs, i.e., @@u_k^T Q u_k@@ with @@Q = 1@@:
(:source lang=MATLAB -getcode:) [@
model.u.penalty = Penalty(1, 2);
@]
A number of other constraints and penalties can be added using the [[UI.Filters|concept of filters]].
Finally, we can synthesize an MPC controller with prediction horizon say @@N=5@@:
(:source lang=MATLAB -getcode:) [@
N = 5;
mpc = MPCController(model, N)
@]
Now the @@mpc@@ object is ready to be used as an MPC controller. For instance, we can ask it for the optimal control input for a given value of the initial state:
(:source lang=MATLAB -getcode:) [@
x0 = [4; 0];
u = mpc.evaluate(x0)
u =
-1
@]
You can also retrieve the full open-loop predictions:
(:source lang=MATLAB -getcode:) [@
[u, feasible, openloop] = mpc.evaluate(x0)
openloop =
cost: 32.4898
U: [-1 -1 0.1393 0.3361 -5.2042e-16]
X: [2x6 double]
Y: [0x5 double]
@]
Please consult [[UI.ClosedLoop|this page]] to learn how to perform closed-loop simulations in MPT3.
Once you are satisfied with the controller's performance, you can convert it to an explicit form by calling the @@toExplicit()@@ method:
(:source lang=MATLAB -getcode:) [@
expmpc = mpc.toExplicit();
@]
This will generate an instance of the @@EMPCController@@ class, which represents all explicit MPC controllers in MPT3. Explicit controllers can be used for evaluation/simulation in exactly the same way, i.e.,
(:source lang=MATLAB -getcode:) [@
[u, feasible, openloop] = expmpc.evaluate(x0)
openloop =
cost: 32.4898
U: [-1 -1 0.1393 0.3361 -5.2042e-16]
X: [2x6 double]
Y: [0x5 double]
@]
h1. Adding terminal set and terminal penalty
Consider an oscillator model defined in 2D.
(:source lang=MATLAB -getcode:) [@
A = [ 0.5403, -0.8415; 0.8415, 0.5403];
B = [ -0.4597; 0.8415];
C = [1 0];
D = 0;
@]
Linear discrete-time model with sample time 1
(:source lang=MATLAB -getcode:) [@
sys = ss(A,B,C,D,1);
model = LTISystem(sys);
@]
Set constraints on output
(:source lang=MATLAB -getcode:) [@
model.y.min = -10;
model.y.max = 10;
@]
Set constraints on input
(:source lang=MATLAB -getcode:) [@
model.u.min = -1;
model.u.max = 1;
@]
Include weights on states/inputs
(:source lang=MATLAB -getcode:) [@
model.x.penalty = Penalty(eye(2),2);
model.u.penalty = Penalty(1,2);
@]
Compute terminal set
(:source lang=MATLAB -getcode:) [@
Tset = model.LQRSet;
@]
Compute terminal weight
(:source lang=MATLAB -getcode:) [@
PN = model.LQRPenalty;
@]
Add terminal set and terminal penalty
(:source lang=MATLAB -getcode:) [@
model.x.with('terminalSet');
model.x.terminalSet = Tset;
model.x.with('terminalPenalty');
model.x.terminalPenalty = PN;
@]
Formulate finite horizon MPC problem
(:source lang=MATLAB -getcode:) [@
ctrl = MPCController(model,5);
@]