生成代码以计算MATLAB中的最佳MPC移动
此示例显示了如何使用mpcmoveceDgeneration
命令生成C代码以计算实时应用程序的最佳MPC控制移动。
在模拟控制器之后mpcmove
, you usempcmoveceDgeneration
to simulate the controller using optimized data structures, reproducing the same results. Then you generate an executable having the same inputs and outputs asmpcmoveceDgeneration
。最后,您使用生成的可执行文件模拟控制器,使用与您使用的相同代码和数据结构mpcmoveceDgeneration。
Plant Model
The plant is a single-input, single-output, stable, 2nd order linear plant.
plant = tf(5,[1 0.8 3]);
Set a sampling time of one second, convert the plant to discrete-time, state-space form, and specify a zero initial states vector.
Ts = 1; plant = ss(c2d(plant,Ts)); x0 = zeros(size(plant.B,1),1);
设计MPC控制器
创建具有默认视野和指定采样时间的MPC控制器。
MPCOBJ = MPC(Plant,TS);
-->The "PredictionHorizon" property is empty. Assuming default 10. -->The "ControlHorizon" property is empty. Assuming default 2. -->The "Weights.ManipulatedVariables" property is empty. Assuming default 0.00000. -->The "Weights.ManipulatedVariablesRate" property is empty. Assuming default 0.10000. -->The "Weights.OutputVariables" property is empty. Assuming default 1.00000.
指定控制器调整权重。
mpcobj.weights.mv = 0;mpcobj.weights.mvrate = 0.5;mpcobj.weights.ov = 1;
Specify initial constraints on the manipulated variable and plant output. These constraints will be updated at run time.
mpcobj.MV.Min = -1; mpcobj.MV.Max = 1; mpcobj.OV.Min = -1; mpcobj.OV.Max = 1;
模拟在线约束使用mpcmove
命令
在闭环模拟中,约束并馈送到mpcmove
以每个控制间隔命令。
ympcmove = [];umpcMove = [];
设置仿真时间。
Tsim = 20;
初始化网络约束数据。
MVMinData = -0.2-[1 0.95 0.9 0.85 0.8 0.75 0.7 0.65 0.6 0.55 0.5。。。0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1];mvmaxdata = 0.2+[1 0.95 0.9 0.85 0.8 0.75 0.7 0.65 0.65 0.6 0.55 0.5 0.5。。。0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1];ovmindata = -0.2- [1 0.95 0.9 0.85 0.8 0.75 0.7 0.65 0.65 0.6 0.55 0.5 0.5 0.5。。。0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1];OVMaxData = 0.2+[1 0.95 0.9 0.85 0.8 0.75 0.7 0.65 0.6 0.55 0.5。。。0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1];
Initialize plant states.
x = x0;
初始化MPC状态。注意XMPC
is an handle object pointing to the current (always updated) state of the controller.
xmpc = mpcstate(mpcobj);
- >假设添加到测量的输出通道#1中的输出干扰是集成的白噪声。- >“ model.noise”属性为空。假设每个测得的输出上都有白噪声。
通过打电话运行闭环模拟mpcmove
in a loop.
选项= mpcmoveopt;forct = 1:round(Tsim/Ts)+1% Update and store plant output.y = plant.c*x;yMPCMOVE = [yMPCMOVE y];%更新约束。options.MVMin = MVMinData(ct); options.MVMax = MVMaxData(ct); options.OutputMin = OVMinData(ct); options.OutputMax = OVMaxData(ct);%计算控制动作和存储工厂输入。u = mpcmove(mpcobj,xmpc,y,1,[],options); uMPCMOVE = [uMPCMOVE u];%更新植物状态。x = plant.a*x + plant.b*u;end
验证模拟结果与mpcmoveceDgeneration
命令
To prepare for generating code that computes optimal control moves from MATLAB, it is recommended to reproduce the same control results with thempcmoveceDgeneration
使用之前的命令codegen
MATLAB编码器产品的命令。
yCodeGen = []; uCodeGen = [];
Initialize plant states.
x = x0;
Create data structures to use withMPCMoveCeDgeneration使用
getCodegenerationData
。
[coredata,statedata,onlinedata] = getCodeGenerationData(mpcobj);
通过打电话运行闭环模拟mpcmoveceDgeneration
in a loop.
forct = 1:round(Tsim/Ts)+1% Update and store plant output.y = plant.c*x;ycodegen = [ycodegen y];% Update measured output in online data.onLinedata.signals.ym = y;% Update reference in online data.OnLinedata.Signals.Ref = 1;% Update constraints in online data.onlinedata.limits.umin = MVMinData(ct); onlinedata.limits.umax = MVMaxData(ct); onlinedata.limits.ymin = OVMinData(ct); onlinedata.limits.ymax = OVMaxData(ct);% Compute and store control action.[u,statedata] = mpcmoveCodeGeneration(coredata,statedata,onlinedata); uCodeGen = [uCodeGen u];%更新植物状态。x = plant.a*x + plant.b*u;end
模拟结果与使用的结果相同mpcmove
。
t = 0:Ts:Tsim; figure; subplot(1,2,1) plot(t,yMPCMOVE,' - *',t,yCodeGen,'o'); grid legend(“ mpcmove','codgen') 标题('Plant Output') subplot(1,2,2) plot(t,uMPCMOVE,' - *',t,ucodegen,'o'); grid legend(“ mpcmove','codgen') 标题('Controller Moves')
Generate MEX Function FrommpcmoveceDgeneration
命令
从mpcmoveceDgeneration
command, use thecodegen
MATLAB编码器产品的命令。In this example, generate a MEX functionmpcmoveMEX
复制模拟结果MATLAB。您可以使用不同的集合,将代码生成目标更改为C/C ++静态库,动态库,可执行文件等。coder.config
settings.
当生成C代码mpcmoveceDgeneration
command:
由于在输入参数上没有执行数据完整性检查,因此您必须确保所有输入数据具有正确的类型,维度和值。
您必须定义第一个输入参数,
mpcmove_struct
,作为使用时常数codegen
command.The second input argument,
mpcmove_state
,由命令更新,并返回为第二个输出。在大多数情况下,您无需修改其内容,应该在下一个控制间隔中简单地将其传递回命令。唯一的例外是启用自定义状态估计时,在这种情况下,您必须使用此参数提供当前状态估计。
% check MATLAB coder license如果〜许可证('测试','matlab_coder')disp('MATLAB Coder(TM) is required to run this example.')返回end
Generate MEX function.
fun =“ mpcmoveceDgeneration';funOutput ='mpcmovemex';cfg = coder.config('mex'); Cfg.DynamicMemoryAllocation ='离开';Codegen(Codegen)('-config',Cfg,fun,'-o',funOutput,'-args',。。。{coder.Constant(coredata),statedata,onlinedata});
Code generation successful.
Initialize data storage.
ymex = [];umex = [];
Initialize plant states.
x = x0;
采用getCodegenerationData
to create data structures to use withmpcmoveceDgeneration
。
[coredata,statedata,onlinedata] = getCodeGenerationData(mpcobj);
通过打电话运行闭环模拟the generatedmpcmoveMEX
functions in a loop.
forct = 1:round(Tsim/Ts)+1% Update and store the plant output.y = plant.c*x;yMEX = [yMEX y];% Update measured output in online data.onLinedata.signals.ym = y;% Update reference in online data.OnLinedata.Signals.Ref = 1;% Update constraints in online data.onlinedata.limits.umin = MVMinData(ct); onlinedata.limits.umax = MVMaxData(ct); onlinedata.limits.ymin = OVMinData(ct); onlinedata.limits.ymax = OVMaxData(ct);% Compute and store control action.[u,satedata] = mpcmovemex(coredata,estateata,onlinedata);umex = [umex u];%更新植物状态。x = plant.a*x + plant.b*u;end
模拟结果与使用的结果相同mpcmove
。
figure subplot(1,2,1) plot(t,yMPCMOVE,' - *',t,ymex,'o')网格传奇(“ mpcmove','mex') 标题('Plant Output') subplot(1,2,2) plot(t,uMPCMOVE,' - *',T,Umex,'o')网格传奇(“ mpcmove','mex') 标题('Controller Moves')
See Also
mpcmoveceDgeneration
|getCodegenerationData