主要内容

重复一个算法使用对于每个子系统

如果您通过复制和粘贴块和子系统来在图中重复算法,那么维护模型将变得非常困难。单独的信号线和子系统会使图变得拥挤,降低可读性,使简单的更改变得困难。变量也会拥挤工作空间,降低模型的可移植性。随着时间的推移,当您添加到设计中时,模型可以开发这些效率问题。

要重复一个算法,可以在分组为数组和结构的信号、子系统和参数上迭代该算法。这个例子展示了如何将一个效率低下的复杂重复算法转换为更易于管理的紧凑形式。

探索范例模型

  1. 打开示例模型ex_repeat_algorithm.该模型在基本工作区中创建了大约30个变量。

  2. 检查子系统Burner_1_Analysis.这个子系统通过使用基本工作空间变量作为块中的参数来执行算法常数而且离散时间积分器

  3. 检查子系统Burner_2_Analysis而且Burner_3_Analysis.所有三个子系统执行相同的算法,但使用不同的工作空间变量来参数化块。

  4. 检查这三个Analysis_Delay子系统。这些子系统重复不同的算法分析子系统。

  5. 返回到模型的顶层。的内存块延迟输入信号之前,他们进入Analysis_Delay子系统。

  6. 看看数据导入/导出“配置参数”对话框中的“配置参数”。模型使用变量SensorsInput而且t作为模拟输入。

    在模拟过程中,矩阵变量中的九列中的每一列SensorsInput对象的输入数据轮廓尺寸块在模型的顶层。

减少公共汽车的信号线密度

您可以使用总线将相关信号分组为单个结构化信号,减少线密度并提高模型可读性。

示例模型中的每个子系统都需要三个信号输入。你可以把每组三个信号组合成一个总线。

您可以修改示例模型中的所有子系统以使用总线。但是,由于有些子系统是相同的,您可以删除它们,然后用对于每个子系统块。

  1. 打开总线编辑器。

    buseditor

  2. 创建总线类型SensorData有三个信号元件:sensor1sensor2,sensor3

  3. 删除如图所示的块,只留下Burner_1_Sensor1而且Burner_1_Delay1块作为其余两个子系统的输入。

  4. 信号的属性的TABBurner_1_Sensor1轮廓尺寸块对话框,设置数据类型总线:SensorData

    该块的输出是一个包含三个信号元素的总线sensor1sensor2,sensor3

  5. 打开子系统Burner_1_Analysis.删除三者的信号输出行轮廓尺寸块。删除In2而且In3轮廓尺寸块。

  6. 添加一个总线选择器块的右边三机一体轮廓尺寸块。连接轮廓尺寸块输出到总线选择器块。

  7. 总线选择器方块对话框,选择信号sensor1sensor2,sensor3

    总线选择器块从输入总线中提取三个信号元素。模型中的其他块可以使用提取的信号元素。

  8. 在子系统中,如图所示连接块。

  9. 在子系统中Burner_1_Analysis_Delay,使用总线选择器块提取总线中的信号。使用与在子系统中相同的技术Burner_1_Analysis

重复一种算法

一个对于每个子系统Block对输入信号进行分区,并在每个分区上依次执行算法。例如,如果子系统的输入是一个包含6个信号的数组,则可以配置子系统对这6个信号中的每一个执行相同的算法。

你可以用对于每个子系统S以迭代的方式重复一个算法。该方法提高了模型的可读性,并使重复算法的修改变得容易。

  1. 添加两个对于每个子系统块到模型。说出其中一个子系统Burner_Analysis.命名另一个子系统Burner_Analysis_Delay

  2. 复制子系统的内容Burner_1_Analysis进入子系统Burner_Analysis.在粘贴块之前,请删除轮廓尺寸而且外港块中的对于每个子系统

  3. 为每一个的“块”对话框Burner_Analysis子系统,选择复选框对输入进行分区三机一体

  4. 复制子系统的内容Burner_1_Analysis_Delay进入子系统Burner_Analysis_Delay

  5. 为每一个的“块”对话框Burner_Analysis_Delay子系统,选择复选框对输入进行分区三机一体

  6. 在模型的顶层,删除子系统Burner_1_Analysis而且Burner_1_Analysis_Delay.连接新事物对于每个子系统在他们的地方。

  7. 信号的属性选项卡的“Burner_1_Sensor1 .轮廓尺寸块对话框,设置港维3.

    块输出是总线的三元素数组。的对于每个子系统模型中的S对数组中的三个总线中的每一个都重复一个算法。

  8. 创建一个金宝appSimulink.SimulationData.Dataset反对轮廓尺寸块可以用来导入仿真数据。您可以使用此代码创建对象并将其存储在变量中SensorsInput

    首先,创建一个结构数组,其字段值为%时间序列对象I = 1:3燃烧器编号%%传感器1eval ([“tempInput(1)”num2str(我)”)。Sensor1 = '...timeseries (SensorsInput (:,num2str(3 *(张)+ 1)”),t),“])%传感器2eval ([“tempInput(1)”num2str(我)”)。Sensor2 = '...timeseries (SensorsInput (:,num2str(3 *(张)+ 2)”),t),“])%传感器3eval ([“tempInput(1)”num2str(我)”)。Sensor3 = '...timeseries (SensorsInput (:,num2str(3 *(张)+ 3)”),t),“])结束创建Dataset对象。传感器sinput = Sim金宝appulink.SimulationData.Dataset;SensorsInput = addElement(SensorsInput,tempInput,element1的);清晰的tempInputt

    代码首先创建一个变量tempInput它包含三个结构的数组。每个结构都有三个字段,对应于总线类型中的信号元素SensorData,每个字段存储一个MATLAB®timeseries对象。每一个timeseries对象存储来自变量的九列数据中的一列SensorsInput,存储每个传感器的模拟输入数据。

    然后重写代码SensorsInput有了新的金宝appSimulink.SimulationData.Dataset对象并添加tempInput作为对象的一个元素。

  9. 设置输入配置参数为SensorsInput

    SensorsInput的形式提供模拟输入数据timeseries对象时,不需要指定包含时间数据的变量。

  10. 创建一个初始化剩余结构的结构数组内存块,并将数组存储在变量中initForDelay.使用现有初始化变量的值指定结构字段,例如initDelay_1_sensor1

    I = 1:3燃烧器编号%%传感器1eval ([“initForDelay(”num2str(我)”)。Sensor1 = '...“initDelay_”num2str(我)“_sensor1;”])%传感器2eval ([“initForDelay(”num2str(我)”)。Sensor2 = '...“initDelay_”num2str(我)“_sensor2;”])%传感器3eval ([“initForDelay(”num2str(我)”)。Sensor3 = '...“initDelay_”num2str(我)“_sensor3;”])结束

    来查看新变量的内容initForDelay,双击基本工作区中的变量名。变量包含三个结构的数组,每个结构有三个字段:sensor1sensor2,sensor3

  11. 内存块对话框,设置初始条件initForDelay

    内存块输出是需要初始化的总线数组。总线数组中的每个信号元素从结构数组中的相应字段获得一个初始值。

将参数组织到结构数组中

基本工作区包含示例模型用于块参数的许多变量。要减少工作空间变量的数量,请将它们打包到结构数组中,并使用单个结构字段来指定块参数。

一个对于每个子系统块可以对指定为掩码参数的值数组进行分区。子系统的每次迭代使用数组的单个分区来指定块参数。如果将参数指定为结构数组,子系统的每次迭代都可以使用数组中的一个结构。

  1. 类参数化的结构数组Burner_Analysis对于每个子系统,并将数组存储在变量中paramsNormal.使用现有参数变量的值指定结构字段,例如gainNormal_1offsetNormal_1,initDelayed_1

    I = 1:3 eval([“paramsNormal(”num2str(我)”)。gain = gainNormal_'num2str(我)“;”eval ()) (“paramsNormal(”num2str(我)”)。offset = offsetNormal_'num2str(我)“;”eval ()) (“paramsNormal(”num2str(我)”)。我nit = initNormal_'num2str(我)“;”])结束

    变量包含三个结构的数组,每个结构有三个字段:获得抵消,初始化

  2. 在模型中,右键单击Burner_Analysis对于每个子系统并选择面具>创建面具

  3. 参数&对话框窗格的对话框,在参数,点击编辑.对于新的掩码参数,请设置提示参数结构而且的名字paramStruct.点击好吧

  4. 在面具里Burner_Analysis子系统,参数结构paramsNormal

  5. 打开子系统。在为每一个方块对话框,就参数分区窗格中,选中复选框对参数进行分区paramStruct.集分区维度2

  6. 对于子系统中的块,需要设置这些参数。

    参数名称 参数值
    获得 获得 paramStruct.gain
    离散时间积分器 初始条件 paramStruct.init
    常数 恒定值 paramStruct.offset

  7. 类参数化的结构数组Burner_Analysis_Delay对于每个子系统,并将数组存储在变量中paramsForDelay

    I = 1:3 eval([“paramsForDelay(”num2str(我)”)。gain = gainDelayed_'num2str(我)“;”eval ()) (“paramsForDelay(”num2str(我)”)。offset = offsetDelayed_'num2str(我)“;”eval ()) (“paramsForDelay(”num2str(我)”)。我nit = initDelayed_'num2str(我)“;”])结束

  8. 在模型的顶层,右键单击Burner_Analysis_Delay对于每个子系统并选择面具>创建面具

  9. 参数&对话框窗格的对话框,在参数,点击编辑.对于新的掩码参数,请设置提示参数结构而且的名字paramStruct.点击好吧

  10. 在面具里对于每个子系统块,设置参数结构paramsForDelay

  11. 打开子系统。在为每一个方块对话框,就参数分区窗格中,选中复选框对参数进行分区paramStruct.集分区维度2

  12. 对于子系统中的块,需要设置这些参数。

    参数名称 参数值
    获得 获得 paramStruct.gain
    离散时间积分器 初始条件 paramStruct.init
    常数 恒定值 paramStruct.offset

  13. 从基本工作区中清除不必要的变量。

    清除已替换的旧参数变量。使用结构数组清晰的正则表达式_清除迭代变量清晰的

    模型在基本工作区中只需要很少的变量。

检查转换后的模型

要查看新的信号和子系统组织,请更新图。

模型输入是由三个总线组成的数组。该模型使用两个对于每个子系统在输入数组中的三个总线中的每一个上执行这两个算法。

在基本工作区中,结构数组替换了模型使用的许多变量。从数学上讲,修改后的模型与开始时的表现相同,因为结构数组包含所有旧变量的值。

提示

您可以在For Each子系统中记录非总线信号。但是,不能对for Each子系统中的总线或总线数组使用信号日志记录。要么使用总线选择器块,以选择要记录或添加的总线元素信号外港在子系统外部阻塞,然后记录该信号。详情请参见为每个子系统登录信号

为每个子系统工作的例子

用于各子系统的向量化算法

这个例子展示了如何简化向量化算法的建模。使用对于每个子系统Blocks简化了一个模型,其中三个输入信号被三个相同的信号过滤转移Fcn块。此示例还展示了如何通过更改子系统每次迭代的系数来为过滤器添加更多的控制。

这个模型使用相同的转移Fcn块独立处理输入正弦波信号的每个元素。一个向量连接块连接结果输出信号。这个重复的过程在图形上很复杂,很难维护。向信号中添加另一个元素还需要对模型进行大量的重做。

您可以通过将重复的操作替换为单个操作来简化此模型对于每个子系统块。

对于每个子系统块包含为每一个块和一个表示三个块的算法模型转移Fcn块。的为每一个块指定如何将输入信号向量划分为单独的元素,以及如何将处理过的信号连接起来以形成输出信号向量。每个具有状态的块为在给定执行步骤中处理的每个输入元素维护一组单独的状态。

对于本例,选择输入信号进行分区。的分区维度而且分区宽度For Each块上的参数都设置为1对于输入。

“为每个块参数”对话框的截图,输入分区选项卡

您可以扩展此方法,添加更多的信号,而不必显著更改模型。这种方法易于伸缩,图形化也更简单。

模型参数变化不改变模型结构。这个例子展示了如何在算法中建模参数的变化。它使用上面示例中的For Each Subsystem划分模型,为每个输入信号创建不同的过滤器,同时保持模型的简单性。一个滤波器系数数组被馈送到对于每个子系统块作为标记为分区的掩码参数。在每一次迭代中对于每个子系统块中,一个划分的滤波系数数组被馈送到转移Fcn块。

  1. 打开模型ex_ForEachSubsystem_Partitioning.为for Each Subsystem块创建一个掩码,并添加一个可编辑掩码参数。将名称设置为FilterCoeffs和提示滤波系数矩阵.有关如何添加掩码参数的信息,请参见创建一个简单的蒙版

  2. 打开对于每个子系统块。在子系统内部,打开为每一个对话框。

  3. 参数分区选项卡,选中控件旁边的复选框FilterCoeffs参数,以启用此参数的分区。保持分区宽度而且分区维度参数的默认值为1。

    每个块参数对话框的截图,参数分区选项卡

  4. 双击对于每个子系统阻塞并输入你的滤波系数矩阵,为每个输入信号有一排滤波系数。例如,输入[0.0284 0.2370 0.4692 0.2370 0.0284;-0.0651 0 0.8698 0 -0.0651;0.0284 -0.2370 0.4692 -0.2370 0.0284]为每个输入信号实现不同的四阶滤波器。

  5. 对于每个子系统块,双击转移Fcn阻止并进入FilterCoeffs分母系数参数。该设置使块从掩码参数中获取其系数。

对于每个子系统Block将输入参数切片为宽度为1的水平分区,这相当于一行系数。系数的参数由单个数组转换而来

分为三行参数:

改进了每个子系统的代码重用。这个例子展示了当您有两个或多个相同的代码时如何改进代码重用对于每个子系统块。考虑下面的模型,rtwdemo_foreachreuse

目的是让三个子系统——矢量SS1、矢量SS2和矢量SS3——在各自的输入处对矢量信号的每个标量元素应用相同的处理。因为这三个子系统执行相同的处理,所以它们需要为为该模型生成的代码中的所有三个子系统生成一个共享的Output(和Update)函数。例如,Vector SS3子系统包含这些块。

要为三个子系统生成一个共享函数,它们对输入信号执行的分区配置必须相同。对于Vector SS1和Vector SS3,此配置非常简单,因为您可以将分区尺寸和宽度设置为1。然而,为了让向量SS2也沿着维1划分它的输入信号,你必须插入一个数学函数块将1 × 8的行向量转换为8 × 1的列向量。然后,可以使用设置为的第二个Math Function块将子系统的输出转换回1 × 8的行向量转置操作符。

如果你按Ctrl + B为了生成代码,生成的代码使用一个输出函数。这三个人都有这个功能对于每个子系统实例。

/* *输出和更新迭代器系统:* '<根>/Vector SS1' * '<根>/Vector SS2' * '<根>/Vector SS3' */ void VectorProcessing(int32_T numters, const real_T rtu_In1[], real_T rty_Out1[], rtDW_VectorProcessing *localDW)

函数有一个输入参数NumIters它表示独立标量的个数对于每个子系统是为了过程。使用形参调用该函数三次NumIters分别设置为10、8和7。

模型中的其余两个子系统展示了如何为矩阵信号生成可重用代码,这些信号使用对于每个子系统块。再一次,按Ctrl + B为了生成代码,提供了单个函数的代码重用。

另请参阅

对象

相关的话题