This example shows how to solve, in MATLAB, an MPC problem in which some manipulated variables belong to a discrete set.
Fix the random generator seed for reproducibility.
Create a discrete-time strictly proper plant with 4 states, two inputs and one output.
plant = drss(4,1,2); plant.D = 0;
Set the sampling time to 0.1s, and increase the control authority of the first input, to better illustrate its control contribution.
plant.Ts = 0.1; plant.B(:,1)=plant.B(:,1)*2;
Create an MPC controller with one second sampling time,
20 steps prediction horizon and
5 steps control horizon.
mpcobj = mpc(plant,0.1,20,5);
-->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.
Specify the first manipulated variable as belonging to a discrete set of seven possible values (you could also specify the type as an integer using the instruction
mpcobj.MV(1).Type = 'integer';)
mpcobj.MV(1).Type = [-1 -0.7 -0.3 0 0.2 0.5 1];
Use rate limits to enforce maximum increment and decrement values for the first manipulated variable.
mpcobj.MV(1).RateMin = -0.5; mpcobj.MV(1).RateMax = 0.5;
Set limits on the second manipulated variable, whose default type (continuous) has not been changed.
mpcobj.MV(2).Min = -2; mpcobj.MV(2).Max = 2;
simCommand and Plot Results
Set the number of simulation steps.
simsteps = 50;
Create an output reference signal equal to zero from steps
35 and equal to
0.6 before and after.
r = ones(simsteps,1)*0.6; r(20:35) = 0;
Simulate the closed loop using the
sim command. Return the plant input and output signals.
[YY,~,UU,~,~,~,status] = sim(mpcobj,simsteps,r);
-->Assuming output disturbance added to measured output channel #1 is integrated white noise. -->The "Model.Noise" property of the "mpc" object is empty. Assuming white noise on each measured output channel.
figure(1) subplot(211) % plant output plot([YY,r]); grid title("Tracking control"); subplot(223) % first plant input stairs(UU(:,1)); grid %title("MV(1) discrete set "+ num2str(mpcobj.MV(1).Type','%0.1f ')) title("MV(1) discrete set ") subplot(224) % second plant input stairs(UU(:,2)); grid title("MV(2) continuous between [-2 2]")
As expected, the first manipulated variable is restricted to the values specified in the discrete set (with jumps less than the specified limit), while the second one can vary continuously between
2. The plant output tracks the reference value after a few seconds.
mpcmoveCommand and Plot Results
Get handle to
mpcobj state and initialize plant state.
xmpc = mpcstate(mpcobj); x = xmpc.Plant;
Initialize arrays that store signals.
YY = ; RR = ; UU = ; XX = ;
Perform simulation using the
mpcmove command to calculate the control actions.
for k = 1:simsteps XX = [XX;x']; % store plant state y = plant.C*x; % calculate plant output YY = [YY;y]; % store plant output RR = [RR;r(k)]; % store reference u = mpcmove(mpcobj,xmpc,y,r(k)); % calculate optimal mpc move UU = [UU;u']; % store plant input x = plant.A*x+plant.B*u; % update plant state % is the last line necessary since x=xmpc.Plant gets updated anyway? end
figure(2) subplot(211) % plant output plot([YY,r]); grid title("Tracking control"); subplot(223) % first plant input stairs(UU(:,1)); grid title("MV(1) discrete set") subplot(224) % second plant input stairs(UU(:,2)); grid title("MV(2) continuous between [-2 2]")
The simulation results are identical as the ones achieved using the