定点数据空燃比控制系统
这个例子展示了如何为用Simulink®和Stateflow®设计的定点空燃比控制系统生成和优化代码。金宝app有关该模型的详细说明,请参见:
定点燃油率控制系统(定点设计师)
本例使用Embedded Coder®系统目标文件(ert.tlc
).
模型的相关部分
的相关部分如图1-4所示sldemo_fuelsys
模型,它是一个闭环系统,包含一个设备子系统和一个控制器子系统。该装置允许工程师在设计周期的早期通过模拟验证控制器。在本例中,为相关的控制器子系统生成代码,fuel_rate_control
.图1显示了顶层仿真模型。
打开|sldemo_fuelsys|,设置参数并更新模型图%,查看信号数据类型。close_system (“sldemo_fuelsys”, 0) load_system (“sldemo_fuelsys”);rtwconfiguredemo (“sldemo_fuelsys”,“导”,“固定”);sldemo_fuelsys_data (“sldemo_fuelsys”,“switch_data_type”,“固定”);sldemo_fuelsys_data (“sldemo_fuelsys”,“set_info_text”,“rtwdemo_fuelsys_fxp_script”);sldemo_fuelsys_data (“sldemo_fuelsys”,“top_level_logging”,“上”);set_param (“sldemo_fuelsys”,“ShowPortDataTypes”,“上”);set_param (“sldemo_fuelsys”,“SampleTimeColors”,“上”);set_param (“sldemo_fuelsys”,“脏”,“关闭”);sldemo_fuelsys ([],[],[],“编译”);sldemo_fuelsys ([],[],[],“术语”);
图1:设备和控制器的顶层模型
空燃比控制系统由Simulink®和Stateflow®模块组成。金宝app它是为其生成代码的模型的一部分。
open_system (“sldemo_fuelsys / fuel_rate_control”);
图2:空燃比控制器子系统
进气气流估计和闭环校正系统包含两个查找表,泵送常数和斜坡速率Ki。
open_system (“sldemo_fuelsys / fuel_rate_control / airflow_calc”);
图3:airflow_calc子系统
控制逻辑是一个指定不同操作模式的Stateflow®图表。
open_system (“sldemo_fuelsys / fuel_rate_control / control_logic”);
图4:燃料比控制器逻辑
把窗户上的杂物清理掉。
close_system (“sldemo_fuelsys / fuel_rate_control / airflow_calc”);close_system (“sldemo_fuelsys / fuel_rate_control / fuel_calc”);close_system (“sldemo_fuelsys / fuel_rate_control / control_logic”);hDemo.rt = sfroot; hDemo.m = hDemo.rt.find (“是”,的金宝app仿真软件。立体图”);hDemo.c = hDemo.m.find (“是”,“Stateflow。图表的,“——”,“名字”,“control_logic”);hDemo.c.visible = false;close_system (“sldemo_fuelsys / fuel_rate_control”);
只建立空燃比控制系统。一旦代码生成过程完成,就会显示一个详细描述所生成代码的HTML报告。代码的主体位于fuel_rate_control.c
.
rtwbuild (“sldemo_fuelsys / fuel_rate_control”);
已成功完成:fuel_rate_control的构建过程构建总结已构建的顶级模型目标:模型操作重建原因================================================================================================== fuel_rate_control生成和编译的代码生成信息文件不存在。构建1个模型(0个模型已经更新)构建持续时间:0h 0m 24.465s
图5显示了为查找表抽水常数生成的代码片段。
要查看抽水常数的代码,右键单击该块并选择C/ c++代码>导航到C/ c++代码.
rtwtrace (“sldemo_fuelsys / fuel_rate_control airflow_calc /注入恒定的);
泵送常数的代码包含两个断点搜索和一个2D插值。的SpeedVect
断点的间隔不均匀,而PressVect
断点是均匀间隔的,没有两个间隔的权力。当前的间隔导致额外的代码(ROM),包括除法,并要求所有断点都位于内存(RAM)中。
图5:为泵送常量查找生成的代码(包含间隔不均匀的断点)
用两个断点的均匀间距优化代码
您可以通过使用两个断点的均匀间隔来优化生成的代码性能。在本例中,根据现有的测量数据重新映射空燃比控制系统中的查找表数据。
当您加载模型时,模型PostLoadFcn
在模型工作区中创建查找表数据。通过检索原始表数据sldemo_fuelsys_data
,将其修改为均匀间隔的2的幂,并在模型工作区中重新分配它。
Td = sldemo_fuelsys_data(“sldemo_fuelsys”,“get_table_data”);
计算两个断点的等间隔幂的新表数据。
被忽视的热带病。speedvector = 64: 2^5: 640;32 rad/sec被忽视的热带病。PressVect = 2*2^-5: 2^-5: 1-(2*2^-5);% 0.03 bar被忽视的热带病。ThrotVect = 0:2^1:88;% 2度被忽视的热带病。RampRateKiX = 128:2^7:640;128 rad/秒被忽视的热带病。RampRateKiY = 0:2^-2:1;% 0.25 bar
重映射表数据。
被忽视的热带病。PumpCon = interp2(td. pressvect,td. speedvect,td. speedvect)。PumpCon, ntd.PressVect ntd.SpeedVect);被忽视的热带病。pres本= interp2(td.ThrotVect,td.SpeedVect,td. pres本,nt . throtvect ',nt . speedvect);被忽视的热带病。SpeedEst = interp2(td.PressVect,td.ThrotVect,td.SpeedEst,nt . pressvect ',nt . throtvect);被忽视的热带病。ThrotEst = interp2(td.PressVect,td.SpeedVect,td.ThrotEst,nt . pressvect ',nt . speedvect);
重新计算Ramp Rate表数据。
被忽视的热带病。RampRateKiZ = (1:length(nt . rampratekix))' * (1:length(nt . rampratekiy)) * td.Ki;
双间距泵浦恒定功率
图(“标签”,“CloseMe”);网格(td.PressVect td.SpeedVect td.PumpCon)在网格(ntd.PressVect ntd.SpeedVect ntd.PumpCon)包含(“PressVect”), ylabel (“SpeedVect”), zlabel (“PumpCon”)标题(sprintf ('抽运常量/ norigoriginal间距(%dx%d) vs.二次间距(%dx%d)',...大小(td.PumpCon, 1),大小(td.PumpCon, 2),大小(ntd.PumpCon, 1),大小(ntd.PumpCon, 2)));
两个间距的压力估计功率
clf mesh(td. throtect,td.SpeedVect,td. pres本),等待在网格(ntd.ThrotVect ntd.SpeedVect ntd.PressEst)包含(“ThrotVect”), ylabel (“SpeedVect”), zlabel (“总统”)标题(sprintf (“压力估计\ norigoriginal间距(%dx%d) vs.两个间距的功率(%dx%d)”,...大小(td.PressEst, 1),大小(td.PressEst, 2),大小(ntd.PressEst, 1),大小(ntd.PressEst, 2)));
两个间距的速度估计功率
clf mesh(td.PressVect,td.ThrotVect,td.SpeedEst),等待在, net (nt . pressvect,nt . throtvect,nt . speedest) xlabel(“PressVect”), ylabel (“ThrotVect”), zlabel (“速度”)标题(sprintf ('速度估计\ norigoriginal间距(%dx%d) vs.两个间距的功率(%dx%d)',...大小(td.SpeedEst, 1),大小(td.SpeedEst, 2),大小(ntd.SpeedEst, 1),大小(ntd.SpeedEst, 2)));
油门估计功率的两个间距
clf mesh(td.PressVect,td.SpeedVect,td.ThrotEst),保持在网格(ntd.PressVect ntd.SpeedVect ntd.ThrotEst)包含(“PressVect”), ylabel (“SpeedVect”), zlabel (“ThrotEst”)标题(sprintf ('节流估计\ norigoriginal间距(%dx%d) vs.两个间距的功率(%dx%d)',...大小(td.ThrotEst, 1),大小(td.ThrotEst, 2),大小(ntd.ThrotEst, 1),大小(ntd.ThrotEst, 2)));
两个间距的斜率
clf mesh(td.RampRateKiX,td.RampRateKiY,td.RampRateKiZ'),保持在网格(ntd.RampRateKiX ntd.RampRateKiY ntd.RampRateKiZ”),隐藏的从包含(“RampRateKiX”), ylabel (“RampRateKiY”), zlabel (“RampRateKiZ”)标题(sprintf ('斜坡速率Ki\ norigoriginal间距(%dx%d) vs.二次间距的幂(%dx%d)',...大小(td.RampRateKiZ, 1),大小(td.RampRateKiZ, 2),大小(ntd.RampRateKiZ, 1),大小(ntd.RampRateKiZ, 2)));
默认配置导致模型记录顶级信号的模拟数据。这些模拟结果存储在工作区变量中sldemo_fuelsys_output
.在用新数据更新模型工作区之前,将模拟结果保存在hDemo.orig_data
为以后与等距幂的两表进行对比模拟。
set_param (“sldemo_fuelsys”,“StopTime”,“8”) sim卡(“sldemo_fuelsys”) hDemo。Orig_data = sldemo_fuelsys_output;
在模型工作区中重新分配新的表数据。
hDemo。hWS = get_param(“sldemo_fuelsys”,“ModelWorkspace”);hDemo.hWS.assignin (“总统”, ntd.PressEst);hDemo.hWS.assignin (“PressVect”, ntd.PressVect);hDemo.hWS.assignin (“PumpCon”, ntd.PumpCon);hDemo.hWS.assignin (“速度”, ntd.SpeedEst);hDemo.hWS.assignin (“SpeedVect”, ntd.SpeedVect);hDemo.hWS.assignin (“ThrotEst”, ntd.ThrotEst);hDemo.hWS.assignin (“ThrotVect”, ntd.ThrotVect);hDemo.hWS.assignin (“RampRateKiX”, ntd.RampRateKiX);hDemo.hWS.assignin (“RampRateKiY”, ntd.RampRateKiY);hDemo.hWS.assignin (“RampRateKiZ”, ntd.RampRateKiZ);
为均匀间隔的数据重新配置查找表。
hDemo。lookupTables = find_system(get_param)“sldemo_fuelsys”,“处理”),...“BlockType”,“Lookup_n-D”);为hDemo_blkIdx = 1: length(hDemo. lookuptables)blkH = hDemo.lookupTables(hDemo_blkIdx);set_param (hDemo.blkH“IndexSearchMethod”,“均匀间隔点”) set_param (hDemo.blkH“InterpMethod”,“无-平”) set_param (hDemo.blkH“ProcessOutOfRangeInput”,“没有”)结束
重新运行两个实现的均匀间隔功率的模拟,并将模拟结果存储在hDemo.pow2_data
.
sim卡(“sldemo_fuelsys”) hDemo。Pow2_data = sldemo_fuelsys_output;
对燃油流量和空燃比的仿真结果进行了比较。模拟练习了抽水常数和斜坡速率Ki查找表,并显示了两个断点相对于原始表数据的均匀间隔功率的良好匹配。
图(“标签”,“CloseMe”);次要情节(2,1,1);情节(hDemo.orig_data.get (“燃料”) .Values.Time,...hDemo.orig_data.get (“燃料”) .Values.Data,的r -);持有情节(hDemo.pow2_data.get (“燃料”) .Values.Time,...hDemo.pow2_data.get (“燃料”) .Values.Data,“b -”);ylabel (“FuelFlowRate (g /秒)”);标题(“燃料控制系统:表格数据比较”);传奇(“原始”,“2的偶次幂”);轴([0 8 .75 2.25]);次要情节(2,1,2);情节(hDemo.orig_data.get (“air_fuel_ratio”) .Values.Time,...hDemo.orig_data.get (“air_fuel_ratio”) .Values.Data,的r -);持有情节(hDemo.pow2_data.get (“air_fuel_ratio”) .Values.Time,...hDemo.pow2_data.get (“air_fuel_ratio”) .Values.Data,“b -”);ylabel (空气/燃料比的);包含(的时间(秒));传奇(“原始”,“2的偶次方”,“位置”,“东南”);轴([0 8 11 16]);
当前剧情保持当前剧情保持
重新构建空气-燃料比控制系统,并比较生成的查找表代码中的差异。
rtwbuild (“sldemo_fuelsys / fuel_rate_control”);
成功完成:fuel_rate_control的构建过程构建总结已构建的顶级模型目标:模型操作重建原因================================================================================= fuel_rate_control已生成和编译的代码已过时。构建1个模型(0个模型已经更新)构建持续时间:0h 0m 22.607s
图6显示了为“抽水常数”查找表生成的相同代码片段。为两个断点的均匀间隔幂生成的代码比不均匀间隔的断点情况要有效得多。该代码由两个简单的断点计算和对2D查找表数据的直接索引组成。避免了昂贵的除法,并且在内存中不需要断点数据。
rtwtrace (“sldemo_fuelsys / fuel_rate_control airflow_calc /注入恒定的);
图6:为泵送常量查找生成的代码(两个断点的平均间隔幂)
关闭示例。
关闭(findobj (0,“标签”,“CloseMe”));清晰的hDemo *道明被忽视的热带病close_system (“sldemo_fuelsys”, 0);rtwdemoclean;
代码效率模型顾问
通过使用两个断点的均匀间隔功率来提高代码效率是定点代码生成的几个重要优化之一。Simu金宝applink®模型顾问是一个伟大的工具,用于识别其他方法,以提高Simulink®和Stateflow®模型的代码效率。确保在Embedded Coder®文件夹或Simulink Coder®下运行检查。金宝app
相关的例子
定点设计:定点燃油率控制系统(定点设计师)
生产C/ c++代码生成:带状态流程图的空燃比控制系统