Model Predictive Control Toolbox

Improving Control Performance with Look-Ahead (Previewing)

This example shows how to design a model predictive controller with look-ahead (previewing) on reference and measured disturbance trajectories.

Plant Model and Simulation Setup

We define the plant model as a linear time invariant system with two inputs (one manipulated variable and one measured disturbance) and one output.

sys = ss(tf({1,1},{[1 .5 1],[1 1]}),'min');

Then we get the state-space matrices of the plant model and specify the initial condition.

[A,B,C,D] = ssdata(sys);
Ts = 0.2; % Sample time
[Ad,Bd,Cd,Dd] = ssdata(c2d(sys,Ts));
x0 = [0;0;0];

Model Predictive Controller Setup

Define type of input signals.

sys = setmpcsignals(sys,'MV',1,'MD',2);

Setup MPC object.

MV = struct('Min',0,'Max',2); % constraints on the manipulated variable.
p = 20;                       % prediction horizon
m = 10;                       % control horizon
Weights = struct('MV',0,'MVRate',0.1,'Output',1); % weights

Create the MPC object.

mpc1 = mpc(sys,Ts,p,m,Weights,MV);

Simulation Setup

We also specify simulation time as well as reference and measured disturbance signals used in simulation.

Tstop = 30;  % simulation time.
time = (0:Ts:(Tstop+p*Ts))'; % time vector
r = double(time>10); % reference signal
v = -double(time>20); % measured disturbance signal

Simulation Using Simulink®

if mpcchecktoolboxinstalled('simulink')
    % Define the reference signal in structure
    ref.time = time;
    ref.signals.values = r;
    % Define the measured disturbance
    md.time = time;
    md.signals.values = v;
    % Open Simulink model
    open_system('mpc_preview')
    % Start simulation
    sim('mpc_preview',Tstop);
else
    disp('Simulink(R) is required to run this part of the example.')
end
-->Converting model to discrete time.
-->Integrated white noise added on measured output channel #1.
-->The "Model.Noise" property of the "mpc" object is empty. Assuming white noise on each measured output channel.

MATLAB Simulation

Let us run now the same simulation in MATLAB.

time = 0:Ts:Tstop;

We Use MPCSIMOPT object to turn on previewing feature in the closed-loopu simulation.

params = mpcsimopt(mpc1);
params.MDLookAhead='on';
params.RefLookAhead='on';

Simulate in MATLAB with SIM command.

YY1 = sim(mpc1,Tstop/Ts+1,r,v,params);
-->Converting model to discrete time.
-->Integrated white noise added on measured output channel #1.
-->The "Model.Noise" property of the "mpc" object is empty. Assuming white noise on each measured output channel.

Plot results and compare with the previous results -- They coincide.

figure
plot(time,r(1:length(time)),'c:',time,YY1,'r-',time,ySL,'bo');
xlabel('Time');
ylabel('Plant Output');
legend({'Reference';'From SIM command';'From Simulink'},'Location','SouthEast');
grid

Step-by-Step Simulation Using MPCMOVE

We may just want to compute the MPC control action inside our simulation code. Let's see how to do this.

We store the closed-loop MPC trajectories.

YY2 = [];
% We use MPCSTATE object to specify the initial state of MPC
x = x0;
xmpc = mpcstate(mpc1);

Main simulation loop

for t=0:round(Tstop/Ts),
    % Plant equations: output update
    y = C*x+D(:,2)*v(t+1);
    % Store signals
    YY2 = [YY2,y]; %#ok<*AGROW>
    % Compute MPC law. Extracts references r(t+1),r(t+2),...,r(t+p) and
    % measured disturbances v(t),v(t+1),...,v(t+p) for previewing.
    u = mpcmove(mpc1,xmpc,y,r(t+2:t+p+1),v(t+1:t+p+1));
    % Plant equations: state update
    x = Ad*x+Bd(:,1)*u+Bd(:,2)*v(t+1);
end

Plot results.

figure
plot(time,r(1:length(time)),'c:',time,YY2,'r-',time,ySL,'bo');
xlabel('Time');
ylabel('Plant Output');
legend({'Reference';'From MPCMOVE command';'From Simulink'},'Location','SouthEast');
grid

If at any time during the simulation we want to check the optimal predicted trajectories, we can use an extended version of MPCMOVE. Assume we want to start from the current state and have a set-point change to 0.5 in 5 steps, and assume the measured disturbance has disappeared.

r1 = [ones(5,1);0.5*ones(p-5,1)];
v1 = zeros(p+1,1);
[~,Info] = mpcmove(mpc1,xmpc,y,r1(1:p),v1(1:p+1));
-->Converting model to discrete time.
-->Integrated white noise added on measured output channel #1.
-->The "Model.Noise" property of the "mpc" object is empty. Assuming white noise on each measured output channel.

We now extract the optimal predicted trajectories and plot them.

topt = Info.Topt;
yopt = Info.Yopt;
uopt = Info.Uopt;

figure
subplot(211)
title('Optimal sequence of predicted outputs')
stairs(topt,yopt);
grid
axis([0 p*Ts -2 2]);
subplot(212)
title('Optimal sequence of manipulated variables')
stairs(topt,uopt);
axis([0 p*Ts -2 2]);
grid

Linearization of MPC Controller

When the constraints are not active, the MPC controller behaves like a linear controller. We can then get the state-space form of the MPC controller, with y, [r(t+1);r(t+2);...;r(t+p)], and [v(t);v(t+1);...;v(t+p)] as inputs to the controller.

Get state-space matrices of linearized controller.

LTIMPC = ss(mpc1,'rv','on','on');
[AL,BL,CL,DL] = ssdata(LTIMPC);

We store the closed-loop MPC trajectories in arrays YY,RR.

YY3 = [];
% Setup initial state of the MPC controller
x = x0;
xL = [x0;0;0];

Main simulation loop

for t=0:round(Tstop/Ts),
    % Plant output update
    y = Cd*x+Dd(:,2)*v(t+1);
    % Save output and refs value
    YY3 =[YY3,y];
    % Compute the linear MPC control action
    u = CL*xL+DL*[y;r(t+2:t+p+1);v(t+1:t+p+1)];
    % Note that the optimal move provided by MPC would be: mpcmove(MPCobj,xmpc,y,ref(t+2:t+p+1),v(t+1:t+p+1));
    % Plant update
    x = Ad*x+Bd(:,1)*u+Bd(:,2)*v(t+1);
    % Controller update
    xL = AL*xL+BL*[y;r(t+2:t+p+1);v(t+1:t+p+1)];
end

Plot results.

figure
plot(time,r(1:length(time)),'c:',time,YY3,'r-');
xlabel('Time');
ylabel('Plant Output');
legend({'Reference';'Unconstrained MPC'},'Location','SouthEast');
grid

if mpcchecktoolboxinstalled('simulink')
    bdclose('mpc_preview')
end