MATLAB Answers

How to improve an MPC (Model Predictive Control) performance?

15 views (last 30 days)
David Cho
David Cho on 30 Jan 2018
Answered: Arkadiy Turevskiy on 16 Aug 2018
Hi, I'd like to regulate an output of a second-order system using MPC. But I always get a result with a huge undershoot. Could anyone let me know how to remove this undershoot? I've changed weight matrices and prediction/control horizons, but still failed to get a good result. Below is the code I've made. Thank you.
clear all; clc;
A=[1 1;0 1];
B=[0.5;1];
C=[1 0];
D=zeros(1,1);
IC=[1;0];
Ts=0.1;
SYS=ss(A,B,C,D,Ts);
MSYS = minreal(SYS);
np=10; % prediction horizon
nc=4; % control horizon
mpcobj=mpc(MSYS,Ts,np,nc);
Q=1.e+3;
R=1.e+0;
mpcobj.Weights.OutputVariables={Q};
mpcobj.Weights.ManipulatedVariables={R};
Tstop=20;
Tf=round(Tstop/Ts);
r=zeros(Tf,1);
options=mpcsimopt(mpcobj);
options.PlantInitialState=IC;
[y,t,u]=sim(mpcobj,Tf,r,options);
figure;
subplot(1,2,1);plot(t,u);xlabel('Time');ylabel('Control');
subplot(1,2,2);plot(t,y);xlabel('Time');ylabel('Output');

  0 Comments

Sign in to comment.

Answers (1)

Arkadiy Turevskiy
Arkadiy Turevskiy on 16 Aug 2018
The undershoot you are seeing is due to two reasons:
1. Mismatch between plant and controller initial conditions.
2. Controller is tuned in such a way that even with initial conditions matching, it would produce a significant overshoot for a step response.
Unless initial conditions are matched, you will have some overshoot. You can improve controller design to help with issue 2 though.
I am pasting the code below where I did the following:
a. Changed the scaling factor on output variable to make the problem better conditioned numerically. You can determine that scaling needs to be done if you do review(mpcobj) on your controller - you will see the advice to change the scaling factor.
b. I tweaked the weights, including adding a weight on mv.rate
c. I initialized controller IC to match plant IC. You can comment this line out if you want to keep controller IC mismatched to plant IC.
clear all; clc;
%%plant
A=[1 1;0 1];
B=[0.5;1];
C=[1 0];
D=zeros(1,1);
IC=[1;0];
Ts=0.1;
SYS=ss(A,B,C,D,Ts);
% MSYS = minreal(SYS); %does not reduce any states
np=10; % prediction horizon
nc=3; % control horizon %note change to 3
mpcobj=mpc(SYS,Ts,np,nc);
mpcobj.OV(1).ScaleFactor = 100; %note the use of scaling factor - helps with overshoot
%%specify overall adjustment factor applied to weights
% these weights are result of trial and error in the MPC Designer app
beta = 0.26714;
%%specify weights
mpcobj.Weights.MV = 1*beta;
mpcobj.Weights.MVRate = 0.1/beta;
mpcobj.Weights.OV = 100*beta;
mpcobj.Weights.ECR = 1000000;
%%Need to initialize controller state, otherwise can't avoid initial undershoot
xmpc=mpcstate(mpcobj);
xmpc.Plant=IC;
Tstop=20;
Tf=round(Tstop/Ts);
% keep stepoint at 0 for first 10 secs, then step to 1 - to check transient
% response
r=zeros(Tf,1);
r(100:size(r))=r(100:size(r))+1;
%%set pland and controller initial conditions
options=mpcsimopt(mpcobj);
options.PlantInitialState=IC;
options.ControllerInitialState=xmpc;
[y,t,u]=sim(mpcobj,Tf,r,options);
figure;
subplot(1,2,1);plot(t,u);xlabel('Time');ylabel('Control');
subplot(1,2,2);plot(t,y);xlabel('Time');ylabel('Output');

  0 Comments

Sign in to comment.

Sign in to answer this question.