Main Content

Simulate Linear MPC Controller with Nonlinear Plant Using Successive Linearizations


This example shows a no-longer-recommended way to simulate an MPC controller in closed loop with a nonlinear plant in MATLAB®. The method is shown for illustrative purposes only, and relies on successive linearizations of a Simulink® CSTR model and successive re-instantiations of an MPC controller object. Recommended options to simulate an MPC controller with a nonlinear plant are discussed in What is Model Predictive Control?. To implement a successive linearization approach in MATLAB, use mpcmoveAdaptive. For an example using Simulink, see Adaptive MPC Control of Nonlinear Chemical Reactor Using Successive Linearization. For more detail, see Adaptive MPC.

Control of a Linearized Plant Model

If your plant is a nonlinear Simulink model, you can linearize the plant (see Linearization Using Model Linearizer in Simulink Control Design) and design a controller for the linearized model (see Design MPC Controller in Simulink).

You then have several options to simulate the closed loop.

  • Using MPC Designer allows you to simulate the linear closed loop response while at the same time tuning the controller parameters.

  • Using MATLAB, you can simulate the linear closed loop using sim, or you can simulate either the linear or nonlinear closed loop using mpcmove. The first option is more straightforward but limited to linear plants and predetermined disturbance signals, while the second option allows for more flexibility in the choice of sampling strategy, plant, disturbance, and custom state estimation.

  • Using Simulink, you can use the MPC Controller block (which takes your mpc object as a parameter) in closed loop with your plant model built in Simulink. This option allows for the greatest flexibility in simulating more complex systems and for easy generation of production code from your controller.

Often the plant to be controlled can be accurately approximated by a linear plant only locally, around a given operating point. This approximation might no longer be accurate as time passes and the plant operating point changes.

Control of the Nonlinear CSTR Model

The CSTR model described in CSTR Model is strongly nonlinear with respect to reactor temperature variations and can be open-loop unstable during the transition from one operating condition to another. As shown in Design MPC Controller in Simulink, a linear controller can regulate this plant, but degrades (and might even become unstable) if the operating point changes significantly.

You can still control the CSTR plant over a wide operating range using traditional MPC control techniques. To do so, you have a few options:

  • If a linear plant model cannot be obtained at run time, first you need to obtain several linear plant models offline at different operating conditions that cover the typical operating range. Next you can choose one of the two approaches to implement MPC control strategy:

(1) Design several MPC controllers offline, one for each plant model. At run time, use the Multiple MPC Controller block (in Simulink) or mpcmoveMultiple (in MATLAB) to switch MPC controllers from one to another based on a desired scheduling strategy. For more details, see Gain-Scheduled MPC Control of Nonlinear Chemical Reactor. Use this approach when the plant models have different orders or time delays.

(2) Design one MPC controller offline at the initial operating point. At run time, use the Adaptive MPC Controller block (in Simulink) or mpcmoveAdaptive (in MATLAB) to update the predictive model at each control interval. The Linear Parameter Varying (LPV) System block can supply linear plant models with a given scheduling strategy, given some input scheduling parameters. See Adaptive MPC Control of Nonlinear Chemical Reactor Using Linear Parameter-Varying System for more details. Use this approach when all the plant models have the same order and time delay.

  • If a linear plant model with a fixed order and time delay can be obtained at run time, you should use the Adaptive MPC Controller block (in Simulink) or mpcmoveAdaptive (in MATLAB) to achieve nonlinear control. There are two typical ways to obtain a linear plant model online:

(1) Use successive linearizations when a nonlinear plant model is available and can be linearized at run time. This example shows an old method to perform successive linearization while simulating the CSTR in MATLAB. This approach is no longer recommended, and is only shown for comparison purposes. Use Adaptive MPC and mpcmoveAdaptive instead. Among other benefits, with Adaptive MPC you can define an MPC controller only once at the beginning and update it at run time, thereby avoiding to redefine of a linear MPC controller from scratch at each time step, as in the following example. See Adaptive MPC for more details. For an example on how to implement Adaptive MPC in Simulink using the successive linearization approach, see Adaptive MPC Control of Nonlinear Chemical Reactor Using Successive Linearization.

(2) Use online estimation to identify a linear model in closed loop. See Adaptive MPC Control of Nonlinear Chemical Reactor Using Online Model Estimation for more details. Use this approach when a linear plant model cannot be obtained from either an LPV system or from successive linearization.

The entire range of options to control a nonlinear plant, including Nonlinear MPC, is discussed in What is Model Predictive Control?.

Example Code for Successive Linearization

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. For more details on this approach, see [1] and [2].

In the following code, the simulation begins at the nominal operating point of the CSTR model (concentration = 8.57) and moves to a lower point (concentration = 2) where the reaction rate is much higher. The required code is as follows:

% Get initial states from simulink model
[sys, xp] = CSTR_INOUT([],[],[],'sizes');

% Set initial inputs
up = [10 298.15 298.15];
u = up(3); % coolant temperature = control input

% Define storage arrays
tsave = [];
usave = [];
ysave = [];
rsave = [];

% Define Sample time
Ts = 1;

% Simulation loop
t = 0;
while t < 40

    % Assume plant output equal to plant state
    yp = xp;

    % Linearize the plant model at the current conditions
    [a,b,c,d] = linmod('CSTR_INOUT',xp,up);

    % Create MPC internal model
    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 = 1/1000th of control interval
    dt = 0.001;
    % set up simOptions
    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]';
    % Simulate open loop Simulink CSTR model for 1/1000th 
    % of control interval while maintaining fixed input
    simOut = sim('CSTR_INOUT',simOptions);
    % Collect open loop simulation outputs
    T = simOut.get('tout');
    XP = simOut.get('xout');
    YP = simOut.get('yout');

    % Get nominal value of dxp/dt
    Model.Nominal.DX = (1/dt)*(XP(end,:)' - xp(:));
    % Define MPC controller for the latest model
    mpcobj = mpc(Model, Ts);
    mpcobj.W.Output = [0 1];
    % Define setpoint as a ramp signal
    r = max([8.57 - 0.25*t, 2]);
    % At the beginning of the simulation, get a 
    % pointer to the state of the MPC controller
    if t <= 0
        xd = [0; 0];
        x = mpcstate(mpcobj,xp,xd,[],u);
    % Calculate control action
    u = mpcmove(mpcobj,x,yp,[0 r],[]);
    % Set plant input to control action
    up(3) = u;

    % Set up simulation options
    simOptions.StartTime = num2str(t);
    simOptions.StopTime = num2str(t+Ts);
    simOptions.InitialState = 'xp';
    simOptions.ExternalInput = '[t up; t+Ts up]';
    % Simulate the plant for one control interval
    simOut = sim('CSTR_INOUT',simOptions);
    % Collect simulation outputs
    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),:)];
    % Update plant state
    xp = XP(end,:)';

    % Update time
    t = t + Ts;

%  Plot residual concentration
plot(tsave,[ysave(:,2) rsave])
title('Residual Concentration')

% Plot coolant temperature
title('Coolant Temperature')

CSTR Results and Discussion

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).

    Residual concentration plot, showing the residual concentration along with its reference value. Both signals decrease from a value close to 8.6 to a value close to 2 in about 30 seconds.

    Coolant temperature plot, showing the coolant temperature oscillating before reaching a steady state after about 30 seconds.

  • linmod (Simulink) relinearizes the plant as its state evolves. In general, linearize is preferred. See also Linearization Using MATLAB Code and Linearize Nonlinear Models (Simulink Control Design).

  • 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.

  • Prior to defining a new MPC controller, sim is used to simulate the plant for a small fraction of the control interval. This is done to calculate, numerically, the nominal value of the time derivative of the plant state, at the current operating point.

  • Function mpc defines a new controller based on the relinearized plant model. The output weight tuning ignores the temperature measurement, focusing only on the concentration.

  • At t = 0, the mpcstate function gets an handle to the initial extended state vector of the controller, x. Thereafter, the mpcmove function updates the controller state automatically using the controller's default state estimator. It would also be possible to use an Extended Kalman Filter (EKF) as described in [1] and [2], in which case the EKF would reset the mpcstate input variables at each step.

  • The mpcmove function uses the latest controller definition and state, the measured plant outputs, and the setpoints to calculate the new coolant temperature at each step.

  • The Simulink sim function simulates the nonlinear plant from the beginning to the end of the control interval. 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.


[1] Lee, J. H. and N. L. Ricker, "Extended Kalman Filter Based Nonlinear Model Predictive Control," Ind. Eng. Chem. Res., Vol. 33, No. 6, pp. 1530–1541 (1994).

[2] Ricker, N. L., and J. H. Lee "Nonlinear Model Predictive Control of the Tennessee Eastman Challenge Process," Computers & Chemical Engineering, Vol. 19, No. 9, pp. 961–981 (1995).

See Also




Related Examples

More About