Main Content

buildMEX

Build MEX file that solves nonlinear MPC control problem

Description

example

mexFcn = buildMEX(nlmpcobj,mexName,coreData,onlineData) builds a MEX file that solves the nonlinear MPC control problem faster than nlmpcmove. The MEX file is created in the current working folder.

mexFcn = buildMEX(nlmpcobj,mexName,coreData,onlineData,mexConfig) generates a MEX function using the code generation configuration object mexConfig. Use this syntax to customize your MEX code generation.

Examples

collapse all

Create a nonlinear MPC controller with four states, two outputs, and one input.

nlobj = nlmpc(4,2,1);
In standard cost function, zero weights are applied by default 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,onlineData] = getCodeGenerationData(nlobj,x0,mv0,params);

Specify the output reference value in the online data structure.

onlineData.ref = [0 0];

Build a MEX function for solving the nonlinear MPC control problem. The MEX function is created in the current working directory.

mexFcn = buildMEX(nlobj,"myController",coreData,onlineData);
Generating MEX function "myController" from nonlinear MPC to speed up simulation.
MEX function "myController" successfully generated.

Run the simulation for 10 seconds. During each control interval:

  1. Correct the previous prediction using the current measurement.

  2. Compute optimal control moves using the MEX function. This function returns the computed optimal sequences in onlineData. Passing the updated data structure to the MEX function in the next control interval provides initial guesses for the optimal sequences.

  3. Predict the model states.

  4. Apply the first computed optimal control move to the plant, updating the plant states.

  5. Generate sensor data with white noise.

  6. 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,onlineData] = myController(xk,mv,onlineData);
    % 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

Plot the resulting state trajectories.

figure
subplot(2,2,1)
plot(0:Ts:Duration,xHistory(1,:))
xlabel('time')
ylabel('z')
title('cart position')
subplot(2,2,2)
plot(0:Ts:Duration,xHistory(2,:))
xlabel('time')
ylabel('zdot')
title('cart velocity')
subplot(2,2,3)
plot(0:Ts:Duration,xHistory(3,:))
xlabel('time')
ylabel('theta')
title('pendulum angle')
subplot(2,2,4)
plot(0:Ts:Duration,xHistory(4,:))
xlabel('time')
ylabel('thetadot')
title('pendulum velocity')

Input Arguments

collapse all

Nonlinear model predictive controller, specified as an nlmpc object.

Your controller must use the default fmincon solver with the SQP algorithm. Also, your controller must not use anonymous functions for its prediction model, custom cost function, or custom constraint functions.

MEX function name, specified as a string or character vector.

Nonlinear MPC configuration parameters that are constant at run time, specified as a structure generated using getCodeGenerationData.

Initial online controller data, specified as a structure generated using getCodeGenerationData. For more information on setting the fields of onlineData, see nlmpcmoveCodeGeneration.

Code generation configuration object, specified as a MexCodeConfig object.

To create the configuration object, use the following code.

mexConfig = coder.config('mex');

To customize your MEX code generation, modify the settings of this object. For example, to detect run-time memory access violations during debugging, set IntegrityChecks to true.

mexConfig.IntegrityChecks = true;

By default, to improve the performance of the generated code, checks such as IntegrityChecks and ResponsivenessChecks are disabled by buildMEX.

buildMEX overwrites the following configuration settings with the values indicated.

Configuration SettingValue
cfg.DynamicMemoryAllocation 'AllVariableSizeArrays'
cfg.ConstantInputs'Remove'

Output Arguments

collapse all

Generated MEX function, returned as a function handle. This MEX function has the following signature.

[mv,newOnlineData,info] = mexFcn(x,lastMV,onlineData)

The MEX function has the following input arguments, which are the same as the corresponding input arguments of nlmpcmoveCodeGeneration.

Input ArgumentDescription
x

Current prediction model states, specified as a vector of length Nx, where Nx is the number of prediction model states.

lastMV

Control signals used in plant at previous control interval, specified as a vector of length Nmv, where Nmv is the number of manipulated variables.

onlineDataOnline controller data that you must update at run time, specified as a structure. Generate the initial structure using getCodeGenerationData. For more information on setting the fields of onlineData, see nlmpcmoveCodeGeneration.

The MEX function has the following output arguments, which are the same as the output arguments of nlmpcmoveCodeGeneration.

Output ArgumentDescription
mv

Optimal manipulated variable control action, returned as a column vector of length Nmv, where Nmv is the number of manipulated variables.

newOnlineData

Updated online controller data, returned as a structure. This structure is the same as onlineData, except that the decision variable initial guesses are updated.

infoSolution details, returned as a structure.

To simulate a controller using the generated MEX function, use the initial online data structure onlineData for the first control interval. For subsequent control intervals, modify the online data in newOnlineData and pass the updated structure to the MEX function as onlineData.

Introduced in R2020a