主要内容

定点数据空燃比控制系统

本示例展示了如何为用Simulink®和Stateflow®设计的定点空燃比控制系统生成和优化代码。万博1manbetx有关模型的详细说明,请参见:

本例使用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®模块组成。万博1manbetx它是为其生成代码的模型的一部分。

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 (“是”的万博1manbetx仿真软件。立体图”);hDemo.c = hDemo.m.find (“是”“Stateflow。图表的“——”“名字”“control_logic”);hDemo.c.visible = false;close_system (“sldemo_fuelsys / fuel_rate_control”);

只建立空燃比控制系统。一旦代码生成过程完成,就会显示一个HTML报告,详细说明生成的代码。代码的主体位于fuel_rate_control.c

slbuild (“sldemo_fuelsys / fuel_rate_control”);
###开始构建过程:fuel_rate_control成功完成构建过程:fuel_rate_control构建摘要顶层模型目标:模型动作重建原因================================================================================================== fuel_rate_control生成和编译的代码生成信息文件不存在。构建1 / 1模型(0个模型已经更新)构建持续时间:0h 0m 25.349s

图5显示了为查找表Pumping Constant生成的代码片段。

要查看泵送常数的代码,右键单击块并选择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”);

计算两个断点平均间隔幂的新表数据。

被忽视的热带病。SpeedVect = 64: 2^5: 640;% 32 rad/秒被忽视的热带病。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。PumpCon, ntd.PressVect ntd.SpeedVect);被忽视的热带病。pressence = interp2(td.ThrotVect,td.SpeedVect,td. pressence,ntd.ThrotVect', td.SpeedVect);被忽视的热带病。SpeedEst = interp2(td.PressVect,td.ThrotVect,td.SpeedEst,ntd.PressVect',ntd.ThrotVect);被忽视的热带病。ThrotEst = interp2(td.PressVect,td.SpeedVect,td.ThrotEst, td.PressVect', td.SpeedVect);

重新计算斜坡速率表数据。

被忽视的热带病。RampRateKiZ =(1:长度(ntd.RampRateKiX))' *(1:长度(ntd.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.ThrotVect,td.SpeedVect,td. pres最强),等待网格(ntd.ThrotVect ntd.SpeedVect ntd.PressEst)包含(“ThrotVect”), ylabel (“SpeedVect”), zlabel (“总统”)标题(sprintf ('压力估计\ norig原始间距(%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),稍等,网格(ntd.PressVect,ntd.ThrotVect,ntd.SpeedEst) xlabel(“PressVect”), ylabel (“ThrotVect”), zlabel (“速度”)标题(sprintf ('速度估计\ norig原始间距(%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 ('节流估计\ norig原始间距(%dx%d) vs.两个间距的功率(%dx%d)'...大小(td.ThrotEst, 1),大小(td.ThrotEst, 2),大小(ntd.ThrotEst, 1),大小(ntd.ThrotEst, 2)));

坡道速率Ki次间隔的功率

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]);
当前剧情保持当前剧情保持

重建空燃比控制系统,并比较生成的查找表代码中的差异。

slbuild (“sldemo_fuelsys / fuel_rate_control”);
###开始构建过程:fuel_rate_control成功完成构建过程:fuel_rate_control构建摘要构建的顶层模型目标:模型动作重建原因================================================================================= fuel_rate_control生成和编译的代码生成的代码已经过时。构建1 / 1模型(0个模型已经更新)构建持续时间:0h 0m 21.114s

图6显示了为‘Pumping Constant’查找表生成的相同代码片段。为两个断点的等间距幂所生成的代码明显比非等间距断点的情况更有效。该代码由两个简单的断点计算和一个对2D查找表数据的直接索引组成。避免了昂贵的除法,并且在内存中不需要断点数据。

rtwtrace (“sldemo_fuelsys / fuel_rate_control airflow_calc /注入恒定的);

图6:为抽取常量查找生成的代码(两个断点的幂值均匀间隔)

关闭示例。

关闭(findobj (0,“标签”“CloseMe”));清晰的hDemo *道明被忽视的热带病close_system (“sldemo_fuelsys”, 0);rtwdemoclean;

代码效率模型顾问

通过使用两个断点的均匀间隔功率来提高代码效率是定点代码生成的几个重要优化之一。Simu万博1manbetxlink®Model Advisor是一个很好的工具,用于识别其他提高Simulink®和Stateflow®模型代码效率的方法。请确保在Embedded Coder®文件夹或Simulink Coder®下运行检查。万博1manbetx

相关的例子

相关的话题