You can use
sim to simulate a closed-loop
system consisting of a linear plant model and an MPC controller.
If your plant is a nonlinear Simulink® model, you must linearize the plant (see Linearization Using Linear Analysis Tool in Simulink Control Design) and design a controller for the linear model (see Design Controller in Simulink). To simulate the system, specify the controller in the MPC block parameter MPC Controller field and run the closed-loop Simulink model.
Alternatively, your nonlinear model might be a MEX-file, or
you might want to include features unavailable in the MPC block, such
as a custom state estimator. The
is the Model Predictive Control Toolbox™ computational engine, and
you can use it in such cases. The disadvantage is that you must duplicate
the infrastructure that the
sim function and
the MPC block provide automatically.
The rest of this section covers the following topics:
CSTR model described in Linearize Simulink Models is a strongly
nonlinear system. As shown in Design Controller in Simulink,
a controller can regulate this plant, but degrades (and might even
become unstable) if the operating point changes significantly.
The objective of this example is to redefine the predictive controller at the beginning of each control interval so that its predictive model, though linear, represents the latest plant conditions as accurately as possible. This will be done by linearizing the nonlinear model repeatedly, allowing the controller to adapt as plant conditions change. See references  and  for more details on this approach.
In the following code, the simulation begins at the
nominal operating point (concentration = 8.57) and moves to a lower
point (concentration = 2) where the reaction rate is much higher.
The required code is as follows:
[sys, xp] = CSTR_INOUT(,,,'sizes'); up = [10 298.15 298.15]; u = up(3); tsave = ; usave = ; ysave = ; rsave = ; Ts = 1; t = 0; while t < 40 yp = xp; % Linearize the plant model at the current conditions [a,b,c,d]=linmod('CSTR_INOUT', xp, up ); Plant = ss(a,b,c,d); Plant.InputGroup.ManipulatedVariables = 3; Plant.InputGroup.UnmeasuredDisturbances = [1 2]; Model.Plant = Plant; % Set nominal conditions to the latest values Model.Nominal.U = [0 0 u]; Model.Nominal.X = xp; Model.Nominal.Y = yp; dt = 0.001; simOptions.StartTime = num2str(t); simOptions.StopTime = num2str(t+dt); simOptions.LoadInitialState = 'on'; simOptions.InitialState = 'xp'; simOptions.SaveTime = 'on'; simOptions.SaveState = 'on'; simOptions.LoadExternalInput = 'on'; simOptions.ExternalInput = '[t up; t+dt up]'; simOut = sim('CSTR_INOUT',simOptions); T = simOut.get('tout'); XP = simOut.get('xout'); YP = simOut.get('yout'); Model.Nominal.DX = (1/dt)*(XP(end,:)' - xp(:)); % Define MPC Toolbox controller for the latest model MPCobj = mpc(Model, Ts); MPCobj.W.Output = [0 1]; % Ramp the setpoint r = max([8.57 - 0.25*t, 2]); % Compute the control action if t <= 0 xd = [0; 0]; x = mpcstate(MPCobj, xp, xd, , u); end u = mpcmove(MPCobj, x, yp, [0 r], ); % Simulate the plant for one control interval up(3) = u; simOptions.StartTime = num2str(t); simOptions.StopTime = num2str(t+Ts); simOptions.InitialState = 'xp'; simOptions.ExternalInput = '[t up; t+Ts up]'; simOut = sim('CSTR_INOUT',simOptions); T = simOut.get('tout'); XP = simOut.get('xout'); YP = simOut.get('yout'); % Save results for plotting tsave = [tsave; T]; ysave = [ysave; YP]; usave = [usave; up(ones(length(T),1),:)]; rsave = [rsave; r(ones(length(T),1),:)]; xp = XP(end,:)'; t = t + Ts; end figure(1) plot(tsave,[ysave(:,2) rsave]) title('Residual Concentration') figure(2) plot(tsave,usave(:,3)); title('Coolant Temperature')
The plotted results appear below. Note the following points:
The setpoint is being ramped from the initial concentration to the desired final value (see the step-wise changes in the reactor concentration plot below). The reactor concentration tracks this ramp smoothly with some delay (see the smooth curve), and settles at the final state with negligible overshoot. The controller works equally well (and achieves the final concentration more rapidly) for a step-wise setpoint change, but it makes unrealistically rapid changes in coolant temperature (not shown).
The final steady state requires a coolant temperature of 305.20 K (see the coolant temperature plot below). An interesting feature of this nonlinear plant is that if one starts at the initial steady state (coolant temperature = 298.15 K), stepping the coolant temperature to 305.20 and holding will not achieve the desired final concentration of 2. In fact, under this simple strategy the reactor concentration stabilizes at a final value of 7.88, far from the desired value. A successful controller must increase the reactor temperature until the reaction "takes off," after which it must reduce the coolant temperature to handle the increased heat load. The relinearization approach provides such a controller (see following plots).
the plant as its state evolves. This function was discussed previously
in Linearization Using MATLAB Code.
The code also resets the linear model's nominal conditions to the latest values. Note, however, that the first two input signals, which are unmeasured disturbances in the controller design, always have nominal zero values. As they are unmeasured, the controller cannot be informed of the true values. A non-zero value would cause an error.
a new controller based on the relinearized plant model. The output
weight tuning ignores the temperature measurement, focusing only on
At t = 0, the
initializes the controller's extended state vector,
which is an mpcstate object. Thereafter, the
mpcmove function updates it automatically
using the controller's default state estimator. It would also be possible
to use an Extended Kalman Filter (EKF) as described in  and ,
in which case the EKF would reset the
variables at each step.
uses the latest controller definition and state, the measured plant
outputs, and the setpoints to calculate the new coolant temperature
at each step.
simulates the nonlinear plant from the beginning to the end of the
control interval. Note that the final condition from the previous
step is being used as the initial plant state, and that the plant
inputs are being held constant during each interval.
Remember that a conventional feedback controller or a fixed Model Predictive Control Toolbox controller tuned to operate at the initial condition would become unstable as the plant moves to the final condition. Periodic model updating overcomes this problem automatically and provides excellent control under all conditions.