nlmpcmoveCodeGeneration
Syntax
Description
[
computes optimal nonlinear MPC control moves and supports code generation for deployment to
real-time targets. Control moves are calculated using the current prediction model states
(mv
,newOnlineData
]
= nlmpcmoveCodeGeneration(coreData
,x
,lastMV
,onlineData
)x
), the control moves from the previous control interval
(lastMV
), and input data structures (coreData
and nlOnlineData
) generated using getCodeGenerationData
.
nlmpcmoveCodeGeneration
does not check input arguments for correct
dimensions and data types.
[___,
returns additional information about the optimization result, including the number of
iterations and the objective function cost.info
] = nlmpcmoveCodeGeneration(___)
Examples
Compute Nonlinear MPC Control Moves Using Code Generation Data Structures
Create a nonlinear MPC controller with four states, two outputs, and one input.
nlobj = nlmpc(4,2,1);
Zero weights are applied to one or more OVs because there are fewer MVs than OVs.
Specify the sample time and horizons of the controller.
Ts = 0.1; nlobj.Ts = Ts; nlobj.PredictionHorizon = 10; nlobj.ControlHorizon = 5;
Specify the state function for the controller, which is in the file pendulumDT0.m
. This discrete-time model integrates the continuous time model defined in pendulumCT0.m
using a multistep forward Euler method.
nlobj.Model.StateFcn = "pendulumDT0";
nlobj.Model.IsContinuousTime = false;
The prediction model uses an optional parameter, Ts
, to represent the sample time. Specify the number of parameters and create a parameter vector.
nlobj.Model.NumberOfParameters = 1; params = {Ts};
Specify the output function of the model, passing the sample time parameter as an input argument.
nlobj.Model.OutputFcn = "pendulumOutputFcn";
Define standard constraints for the controller.
nlobj.Weights.OutputVariables = [3 3]; nlobj.Weights.ManipulatedVariablesRate = 0.1; nlobj.OV(1).Min = -10; nlobj.OV(1).Max = 10; nlobj.MV.Min = -100; nlobj.MV.Max = 100;
Validate the prediction model functions.
x0 = [0.1;0.2;-pi/2;0.3]; u0 = 0.4; validateFcns(nlobj,x0,u0,[],params);
Model.StateFcn is OK. Model.OutputFcn is OK. Analysis of user-provided model, cost, and constraint functions complete.
Only two of the plant states are measurable. Therefore, create an extended Kalman filter for estimating the four plant states. Its state transition function is defined in pendulumStateFcn.m
and its measurement function is defined in pendulumMeasurementFcn.m
.
EKF = extendedKalmanFilter(@pendulumStateFcn,@pendulumMeasurementFcn);
Define initial conditions for the simulation, initialize the extended Kalman filter state, and specify a zero initial manipulated variable value.
x0 = [0;0;-pi;0]; y0 = [x0(1);x0(3)]; EKF.State = x0; mv0 = 0;
Create code generation data structures for the controller, specifying the initial conditions and parameters.
[coreData,extData] = getCodeGenerationData(nlobj,x0,mv0,params);
Specify the output reference value in the online data structure.
extData.ref = [0 0];
To verify the controller operation, run a simulation for 10
seconds. During each control interval:
Correct the previous prediction using the current measurement.
Compute optimal control moves using
nlmpcmoveCodeGeneration
. This function returns the computed optimal sequences inextData
. Passing the updated data structure tonlmpcmoveCodeGeneration
in the next control interval provides initial guesses for the optimal sequences.Predict the model states.
Apply the first computed optimal control move to the plant, updating the plant states.
Generate sensor data with white noise.
Save the plant states.
mv = mv0; y = y0; x = x0; Duration = 10; xHistory = x0; for ct = 1:(Duration/Ts) % Correct previous prediction xk = correct(EKF,y); % Compute optimal control move [mv,extData] = nlmpcmoveCodeGeneration(coreData,xk,mv,extData); % Predict prediction model states for the next iteration predict(EKF,[mv; Ts]); % Implement first optimal control move x = pendulumDT0(x,mv,Ts); % Generate sensor data y = x([1 3]) + randn(2,1)*0.01; % Save plant states xHistory = [xHistory x]; end
Generate a MEX function with MATLAB® Coder™.
cfg = coder.config('mex'); cfg.EnableDynamicMemoryAllocation = false; mexfun = buildMEX(nlobj, 'nlmpcmoveMEX', coreData, extData, cfg);
Generating MEX function "nlmpcmoveMEX" from nonlinear MPC to speed up simulation. Code generation successful. MEX function "nlmpcmoveMEX" successfully generated.
Input Arguments
coreData
— Nonlinear MPC configuration parameters
structure
Nonlinear MPC configuration parameters that are constant at run time, specified as a
structure generated using getCodeGenerationData
.
Note
When using codegen
(MATLAB Coder), coreData
must be defined as coder.Constant
(MATLAB Coder).
x
— Current prediction model states
column vector
Current prediction model states, specified as a vector of
lengthNx, where
Nx is the number of prediction model
states. The prediction model state function is defined in
nlobj.Model.StateFcn
.
Since the nonlinear MPC controller does not perform state estimation, you must either measure or estimate the current prediction model states at each control interval. For more information on nonlinear MPC prediction models, see Specify Prediction Model for Nonlinear MPC.
lastMV
— Control signals used in plant at previous control interval
column vector
Control signals used in plant at previous control interval, specified as a column vector of lengthNmv, where Nmv is the number of manipulated variables.
Note
Specify lastMV
as the manipulated variable signals applied to
the plant in the previous control interval. Typically, these signals are the values
generated by the controller (mv
). However, this is not always the
case. For example, if your controller is offline and running in tracking mode; that
is, the controller output is not driving the plant, then feeding the actual control
signal to last_mv
can help achieve bumpless transfer when the
controller is switched back online.
onlineData
— Online controller data
structure
Online controller data that you must update at run time, specified as a structure
with the following fields. Generate the initial structure using getCodeGenerationData
. Some structure fields are not required, depending
on the configuration of the controller and what weights or constraints vary at run
time.
ref
— Output reference values
row vector | array
Plant output reference values, specified as a row vector of length Ny or an array with Ny columns, where Ny is the number of output variables.
To use the same reference values across the prediction horizon, specify a row vector.
To vary the reference values over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the reference values for one prediction horizon step. If you specify fewer than p rows, the values in the final row are used for the remaining steps of the prediction horizon.
If your controller cost function does not use ref
, leave
ref
at its default value.
mvTarget
— Manipulated variable targets
row vector | array
Manipulated variable targets, specified as a row vector of length Nmv or an array with Nmv columns, where Nmv is the number of manipulated variables.
To use the same manipulated variable targets across the prediction horizon, specify a row vector.
To vary the targets over the prediction horizon (previewing) from time k to time k+p-1, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the targets for one prediction horizon step. If you specify fewer than p rows, the final targets are used for the remaining steps of the prediction horizon.
If your controller cost function does not use mvTarget
,
leave mvTarget
at its default value.
X0
— Initial guesses for the optimal state solutions
vector | array
Initial guesses for the optimal state solutions, specified as a row vector of length Nx or an array with Nx columns, where Nx is the number of states.
To use the same initial guesses across the prediction horizon, specify a row vector.
To vary the initial guesses over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the initial guesses for one prediction horizon step. If you specify fewer than p rows, the final guesses are used for the remaining steps of the prediction horizon.
In general, during closed-loop simulation, you do not specify
X0
yourself. Instead, when calling nlmpcmoveCodeGeneration
, return the
newOnlineData
output argument, which contains updated
X0
estimates. You can then pass
newOnlineData
in as the onlineData
input argument to nlmpcmoveCodeGeneration
for the next
control interval.
MV0
— Initial guesses for the optimal manipulated variable solutions
vector | array
Initial guesses for the optimal manipulated variable solutions, specified as a row vector of length Nmv or an array with Nmv columns, where Nmv is the number of manipulated variables.
To use the same initial guesses across the prediction horizon, specify a row vector.
To vary the initial guesses over the prediction horizon from time k to time k+p-1, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the initial guesses for one prediction horizon step. If you specify fewer than p rows, the final guesses are used for the remaining steps of the prediction horizon.
In general, during closed-loop simulation, you do not specify
MV0
yourself. Instead, when calling nlmpcmoveCodeGeneration
, return the
newOnlineData
output argument, which contains updated
MV0
estimates. You can then pass
newOnlineData
in as the onlineData
input argument to nlmpcmoveCodeGeneration
for the next
control interval.
Slack0
— Initial guess for the slack variable at the solution
nonnegative scalar
Initial guess for the slack variable at the solution, specified as a nonnegative scalar.
In general, during closed-loop simulation, you do not specify
Slack0
yourself. Instead, when calling nlmpcmoveCodeGeneration
, return the
newOnlineData
output argument, which contains updated
Slack0
estimates. You can then pass
newOnlineData
in as the onlineData
input argument to nlmpcmoveCodeGeneration
for the next
control interval.
md
— Measured disturbance values
row vector | array
Measured disturbance values, specified as a row vector of length
Nmd or an array with
Nmd columns, where
Nmd is the number of measured
disturbances. If your controller has measured disturbances, you must specify
md
. If your controller has no measured disturbances, then
getCodeGenerationData
omits this field.
To use the same disturbance values across the prediction horizon, specify a row vector.
To vary the disturbance values over the prediction horizon from time k to time k+p, specify an array with up to p+1 rows. Here, k is the current time and p is the prediction horizon. Each row contains the disturbance values for one prediction horizon step. If you specify fewer than p rows, the values in the final row are used for the remaining steps of the prediction horizon.
Parameters
— Parameter values
cell vector
Parameter values used by the prediction model, custom cost function, and
custom constraints, specified as a cell vector with length equal to the
Model.NumberOfParameters
property of the controller. If the
controller has no parameters, then getCodeGenerationData
omits this field.
The order of the parameters must match the order defined for the prediction model, custom cost function, and custom constraints.
OutputWeights
— Output variable tuning weights
row vector | array
Output variable tuning weights that replace the default tuning weights at run
time, specified as a row vector of length
Ny or an array with
Ny columns, where
Ny is the number of output
variables. If you expect your output variable weights to vary at run time, you
must add this field to the online data structure when you call
getCodeGenerationData
.
To use the same weights across the prediction horizon, specify a row vector.
To vary the weights over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the weights for one prediction horizon step. If you specify fewer than p rows, the final weights are used for the remaining steps of the prediction horizon.
MVWeights
— Manipulated variable tuning weights
row vector | array
Manipulated variable tuning weights that replace the default tuning weights at
run time, specified as a row vector of length
Nmv or an array with
Nmv columns, where
Nmv is the number of manipulated
variables. If you expect your manipulated variable weights to vary at run time,
you must add this field to the online data structure when you call
getCodeGenerationData
.
To use the same weights across the prediction horizon, specify a row vector.
To vary the weights over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the weights for one prediction horizon step. If you specify fewer than p rows, the final weights are used for the remaining steps of the prediction horizon.
MVRateWeights
— Manipulated variable rate tuning weights
row vector | array
Manipulated variable rate tuning weights that replace the default tuning
weights at run time, specified as a row vector of length
Nmv or an array with
Nmv columns, where
Nmv is the number of manipulated
variables. If you expect your manipulated variable rate weights to vary at run
time, you must add this field to the online data structure when you call
getCodeGenerationData
.
To use the same weights across the prediction horizon, specify a row vector.
To vary the weights over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the weights for one prediction horizon step. If you specify fewer than p rows, the final weights are used for the remaining steps of the prediction horizon.
ECRWeight
— Slack variable tuning weight
positive scalar
Slack variable rate tuning weight that replaces the default tuning weight at
run time, specified as a positive scalar. If you expect your slack variable weight
to vary at run time, you must add this field to the online data structure when you
call getCodeGenerationData
.
OutputMin
— Output variable lower bounds
row vector | array
Output variable lower bounds that replace the default lower bounds at run
time, specified as a row vector of length
Ny or an array with
Ny columns, where
Ny is the number of output
variables. If you expect your output variable lower bounds to vary at run time,
you must add this field to the online data structure when you call
getCodeGenerationData
.
To use the same bounds across the prediction horizon, specify a row vector.
To vary the bounds over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the bounds for one prediction horizon step. If you specify fewer than p rows, the final bounds are used for the remaining steps of the prediction horizon.
OutputMax
— Output variable upper bounds
row vector | array
Output variable upper bounds that replace the default upper bounds at run
time, specified as a row vector of length
Ny or an array with
Ny columns, where
Ny is the number of output
variables. If you expect your output variable upper bounds to vary at run time,
you must add this field to the online data structure when you call
getCodeGenerationData
.
To use the same bounds across the prediction horizon, specify a row vector.
To vary the bounds over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the bounds for one prediction horizon step. If you specify fewer than p rows, the final bounds are used for the remaining steps of the prediction horizon.
StateMin
— State lower bounds
row vector | array
State lower bounds that replace the default lower bounds at run time,
specified as a row vector of length Nx
or an array with Nx columns, where
Nx is the number of states. If you
expect your state lower bounds to vary at run time, you must add this field to the
online data structure when you call
getCodeGenerationData
.
To use the same bounds across the prediction horizon, specify a row vector.
To vary the bounds over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the bounds for one prediction horizon step. If you specify fewer than p rows, the final bounds are used for the remaining steps of the prediction horizon.
StateMax
— State upper bounds
row vector | array
State upper bounds that replace the default upper bounds at run time,
specified as a row vector of length Nx
or an array with Nx columns, where
Nx is the number of states. If you
expect your state upper bounds to vary at run time, you must add this field to the
online data structure when you call
getCodeGenerationData
.
To use the same bounds across the prediction horizon, specify a row vector.
To vary the bounds over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the bounds for one prediction horizon step. If you specify fewer than p rows, the final bounds are used for the remaining steps of the prediction horizon.
MVMin
— Manipulated variable lower bounds
row vector | array
Manipulated variable lower bounds that replace the default lower bounds at run
time, specified as a row vector of length
Nmv or an array with
Nmv columns, where
Nmv is the number of manipulated
variables. If you expect your manipulated variable lower bounds to vary at run
time, you must add this field to the online data structure when you call
getCodeGenerationData
.
To use the same bounds across the prediction horizon, specify a row vector.
To vary the bounds over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the bounds for one prediction horizon step. If you specify fewer than p rows, the final bounds are used for the remaining steps of the prediction horizon.
MVMax
— Manipulated variable upper bounds
row vector | array
Manipulated variable upper bounds that replace the default upper bounds at run
time, specified as a row vector of length
Nmv or an array with
Nmv columns, where
Nmv is the number of manipulated
variables. If you expect your manipulated variable upper bounds to vary at run
time, you must add this field to the online data structure when you call
getCodeGenerationData
.
To use the same bounds across the prediction horizon, specify a row vector.
To vary the bounds over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the bounds for one prediction horizon step. If you specify fewer than p rows, the final bounds are used for the remaining steps of the prediction horizon.
MVRateMin
— Manipulated variable rate lower bounds
row vector | array
Manipulated variable rate lower bounds that replace the default lower bounds
at run time, specified as a row vector of length
Nmv or an array with
Nmv columns, where
Nmv is the number of manipulated
variables. If you expect your manipulated variable rate lower bounds to vary at
run time, you must add this field to the online data structure when you call
getCodeGenerationData
.
To use the same bounds across the prediction horizon, specify a row vector.
To vary the bounds over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the bounds for one prediction horizon step. If you specify fewer than p rows, the final bounds are used for the remaining steps of the prediction horizon.
MVRateMax
— Manipulated variable rate upper bounds
row vector | array
Manipulated variable rate upper bounds that replace the default upper bounds
at run time, specified as a row vector of length
Nmv or an array with
Nmv columns, where
Nmv is the number of manipulated
variables. If you expect your manipulated variable rate upper bounds to vary at
run time, you must add this field to the online data structure when you call
getCodeGenerationData
.
To use the same bounds across the prediction horizon, specify a row vector.
To vary the bounds over the prediction horizon from time k+1 to time k+p, specify an array with up to p rows. Here, k is the current time and p is the prediction horizon. Each row contains the bounds for one prediction horizon step. If you specify fewer than p rows, the final bounds are used for the remaining steps of the prediction horizon.
Output Arguments
mv
— Optimal manipulated variable control action
column vector
Optimal manipulated variable control action, returned as a column vector of length Nmv, where Nmv is the number of manipulated variables.
If the solver converges to a local optimum solution
(info.ExitFlag
is positive), then mv
contains
the optimal solution.
If the solver reaches the maximum number of iterations, finds a feasible suboptimal
solution (info.ExitFlag = 0
) and:
coredata.usesuboptimalsolution
istrue
, thenmv
contains the suboptimal solutioncoredata.usesuboptimalsolution
isfalse
, thenmv
containslastMV
If the solver fails to find a feasible solution (info.ExitFlag
is
negative), then mv
contains lastMV
.
newOnlineData
— Updated online controller data
structure
Updated online controller data, returned as a structure. This structure is the same
as onlineData
, except that the decision variable initial guesses
(X0
, MV0
, and Slack0
) are
updated.
For subsequent control intervals, warm start the solver by
modifying the online data in newOnlineData
and passing the updated
structure to nlmpcmoveCodeGeneration
as
onlineData
. Doing so allows the solver to use the decision
variable initial guesses as a starting point for its solution.
info
— Solution details
structure
Solution details, returned as a structure with the following fields.
MVopt
— Optimal manipulated variable sequence
array
Optimal manipulated variable sequence, returned as a (p+1)-by-Nmv array, where p is the prediction horizon and Nmv is the number of manipulated variables.
MVopt(i,:)
contains the calculated optimal manipulated
variable values at time k+i-1
, for i =
1,...,p
, where k
is the current time.
MVopt(1,:)
contains the same manipulated variable values as
output argument mv
. Since the controller does not calculate
optimal control moves at time k+p
,
MVopt(p+1,:)
is equal to
MVopt(p,:)
.
Xopt
— Optimal prediction model state sequence
array
Optimal prediction model state sequence, returned as a (p+1)-by-Nx array, where p is the prediction horizon and Nx is the number of states in the prediction model.
Xopt(i,:)
contains the calculated state values at time
k+i-1
, for i = 2,...,p+1
, where
k
is the current time. Xopt(1,:)
is the
same as the current states in x
.
Yopt
— Optimal output variable sequence
array
Optimal output variable sequence, returned as a (p+1)-by-Ny array, where p is the prediction horizon and Ny is the number of outputs.
Yopt(i,:)
contains the calculated output values at time
k+i-1
, for i = 2,...,p+1
, where
k
is the current time. Yopt(1,:)
is
computed based on the current states in x
and the current
measured disturbances in md
, if any.
Topt
— Prediction horizon time sequence
column vector
Prediction horizon time sequence, returned as a column vector of length
p+1, where p is the prediction horizon.
Topt
contains the time sequence from time
k to time k+p, where
k is the current time.
Topt(1)
= 0 represents the current time. Subsequent time
steps Topt(i)
are Ts*(i-1)
, where
Ts
is the controller sample time.
Use Topt
when plotting the MVopt
,
Xopt
, or Yopt
sequences.
Slack
— Slack variable at optimum
nonnegative scalar
Slack variable at optimum, ε, used in constraint softening, returned as a nonnegative scalar value.
ε = 0 — All soft constraints are satisfied over the entire prediction horizon.
ε > 0 — At least one soft constraint is violated. When more than one constraint is violated, ε represents the worst-case soft constraint violation (scaled by your ECR values for each constraint).
ExitFlag
— Optimization exit code
integer
Optimization exit code, returned as one of the following:
Positive Integer — Optimal solution found
0
— Feasible suboptimal solution found after the maximum number of iterationsNegative integer — No feasible solution found
Iterations
— Number of iterations
positive integer
Number of iterations used by the solver, returned as a positive integer.
Cost
— Objective function cost
nonnegative scalar
Objective function cost, returned as a nonnegative scalar value. The cost quantifies the degree to which the controller has achieved its objectives.
The cost value is only meaningful when ExitFlag
is
nonnegative.
Extended Capabilities
C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.
Usage notes and limitations:
nlmpcmoveCodeGeneration
supports generating code only for nonlinear MPC controllers that use the defaultfmincon
solver with the SQP algorithm. However, you can simulate controllers using otherfmincon
algorithms.When used for code generation, nonlinear MPC controllers do not support anonymous functions for the prediction model, custom cost function, or custom constraint functions. However,
nlmpcmoveCodeGeneration
can still simulate controllers that use anonymous functions.Your custom functions must be on the MATLAB® path and compatible with MATLAB Coder™. For more information on checking compatibility, see Check Code by Using the Code Generation Readiness Tool (MATLAB Coder).
Code generation for nonlinear MPC controllers supports only double-precision data.
To generate code for computing optimal control moves for a nonlinear MPC controller:
Generate data structures from a nonlinear MPC controller using
getCodeGenerationData
.To verify that your controller produces the expected closed-loop results, simulate it using
nlmpcmoveCodeGeneration
in place ofnlmpcmove
.Generate code for
nlmpcmoveCodeGeneration
usingcodegen
(MATLAB Coder). This step requires MATLAB Coder software.
Version History
Introduced in R2020a
See Also
Functions
nlmpcmove
|getSimulationData
|getCodeGenerationData
|buildMEX
|codegen
(MATLAB Coder)
Objects
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)