This example shows how to vary input and output saturation limits in real-time control.
Possible limits specified in the MPC object are overridden by limit values fed to the MPC block. If left unconnected, the original limit defined in the MPC controller is used.
|On this page…|
Plant to be controlled and model used by MPC.
Ts = 0.1; % plant and controller's sampling time plant = c2d(tf(1,[1 .8 3]),Ts); [A,B,C,D] = ssdata(plant);
Create MPC controller with horizons and sampling time.
p = 10; % prediction horizon (take default one) m = 4; % control horizon mpcobj = mpc(plant,Ts,p,m); % Specify weights mpcobj.Weights.MV = 0; mpcobj.Weights.MVrate = 0.5; mpcobj.Weights.OV = 1;
-->The "Weights.ManipulatedVariables" property of "mpc" object is empty. Assuming default 0.00000. -->The "Weights.ManipulatedVariablesRate" property of "mpc" object is empty. Assuming default 0.10000. -->The "Weights.OutputVariables" property of "mpc" object is empty. Assuming default 1.00000.
As we want to change umin umax, and ymax on line to finite values, and want instead leave ymin unconstrained, we must change the MPC object to enforce dummy finite values on MV.Min, MV.Max, OV.Max. These will be changed by MPCMOVE or by input signals to MPC block.
mpcobj.MV.Min=1; mpcobj.MV.Max=1; mpcobj.OV.Max=1;
To run this example, Simulink® is required.
if ~mpcchecktoolboxinstalled('simulink') disp('Simulink(R) is required to run this example.') return end
Set output set-point.
ref = 1; % Set simulation time. Tsim = 20; % Open Simulink(R) Model. mdl = 'mpc_varbounds'; open_system(mdl); % Turn off input/output not connected warnings since they are irrelevant. set_param(mdl,'UnconnectedInputMsg','off') set_param(mdl,'UnconnectedOutputMsg','off')
Start Simulation For consistency with the following step-by-step simulation, convert the dynamics of the plant to discrete time
open_system([mdl '/I//O']); sim(mdl);
-->Converting the "Model.Plant" property of "mpc" object to state-space. -->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. The MPC block inport "ymin" is unconnected. Limits specified in the controller object will be used. This behavior differs from earlier releases.
Initial state of the plant and controller
x = zeros(size(B,1),1); xmpc = mpcstate(mpcobj); % Store the closed-loop MPC trajectories in arrays YY,UU,XX. YY=; UU=; XX=; % Store weights in an @MPCMOVEOPT object options=mpcmoveopt; % Start main simulation loop for t=0:round(Tsim/Ts), XX = [XX,x]; %#ok<*AGROW> % Plant equations: output update (no feedthrough from MV to Y) y = C*x; YY = [YY;y']; % Get reference signal ref = yout.Data(t+1,2); % Update weights in @MPCMOVEOPT object 'options' options.MVMin = uout.Data(t+1,2); options.MVMax = uout.Data(t+1,3); options.OutputMax = yout.Data(t+1,3); % Compute control action u = mpcmove(mpcobj,xmpc,y,ref,,options); % Plant equations: state update x = A*x + B*u; UU = [UU;u']; end
figure(1); clf; subplot(121) plot(0:Ts:Tsim,[YY yout.Data(:,1) yout.Data(:,3)]) grid title('output') subplot(122) plot(0:Ts:Tsim,[UU uout.Data(:,1) uout.Data(:,2) uout.Data(:,3)]) grid title('input')
Simulation results are the same.
fprintf('\n\nDifference between MPC Simulink block and MPCMOVE simulations: %g\n',... norm(UU-uout.Data(:,1)) + norm(YY-yout.Data(:,1)));
Difference between MPC Simulink block and MPCMOVE simulations: 0