主要内容

使用a重复一个算法为每个子系统

如果您通过复制和粘贴块和子系统来重复图表中的算法,那么维护模型就会变得很困难。单独的信号线和子系统会使图表拥挤不堪,降低了可读性,并使简单的更改变得困难。变量还会使工作区拥挤,降低模型的可移植性。随着时间的推移,当您添加到设计中时,模型可能会产生这些效率问题。

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

探索示例模型

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

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

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

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

  5. 返回到模型的顶层。的内存块在输入信号进入Analysis_Delay子系统。

  6. 看一下数据导入/导出对话框中的。该模型使用了变量传感器输入t作为模拟输入。

    在仿真过程中,矩阵变量中的九列中的每一列传感器输入为一个应用程序提供输入数据轮廓尺寸块在模型的顶层。

利用总线降低信号线密度

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

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

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

  1. 打开总线编辑器。

    buseditor

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

  3. 删除图中所示的块,只留下Burner_1_Sensor1燃烧器1延迟1块作为其余两个子系统的输入。

  4. 信号属性选项卡的Burner_1_Sensor1轮廓尺寸“块”对话框,设置数据类型总线:SensorData

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

  5. 打开子系统Burner_1_Analysis.删除三个信号输出行轮廓尺寸块。删除In2在3轮廓尺寸块。

  6. 添加总线选择器街区的右边轮廓尺寸块。连接轮廓尺寸块输出到总线选择器块。

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

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

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

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

重复一个算法

一个为每个子系统块对输入信号进行分区,并在每个分区上顺序执行算法。例如,如果子系统的输入是一个由六个信号组成的阵列,则可以将子系统配置为对六个信号中的每一个执行相同的算法。

您可以使用为每个子系统以迭代的方式重复一个算法。该方法提高了模型的可读性,易于修改重复算法。

  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_AnalysisBurner_1_Analysis_Delay.连接的新为每个子系统在他们的地方。

  7. 信号属性“Burner_1_Sensor1”页签轮廓尺寸“块”对话框,设置端口尺寸3.

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

  8. 创建一个万博1manbetxSimulink.SimulationData.Dataset对象,轮廓尺寸块可用于导入仿真数据。您可以使用此代码创建对象并将其存储在变量中传感器输入

    首先,创建一个结构数组,其中的字段值为% timeseries对象i = 1:3%燃烧器数量%传感器1eval ([“tempInput(1)”num2str(我)”)。sensor1 = '...timeseries (SensorsInput (:,num2str(3*(i-1)+1)”),t),“])%传感器2eval ([“tempInput(1)”num2str(我))。传感器2...timeseries (SensorsInput (:,num2str(3 *(张)+ 2)”),t),“])%传感器3eval ([“tempInput(1)”num2str(我)”)。sensor3 = '...timeseries (SensorsInput (:,num2str(3 *(张)+ 3)”),t),“])结束%创建数据集对象。SensorsInput = 万博1manbetxSimulink.SimulationData.Dataset;SensorsInput = addElement (SensorsInput tempInput,element1的);清晰的tempInputt

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

    然后代码就会覆盖传感器输入用一个新的万博1manbetxSimulink.SimulationData.Dataset对象,并补充说tempInput作为对象的一个元素。

  9. 设置输入配置参数为传感器输入

    自从传感器输入的形式提供模拟输入数据timeseries对象,则不需要指定包含时间数据的变量。

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

    i = 1:3%燃烧器数量%传感器1eval ([“initForDelay(”num2str(我)”)。sensor1 = '...“initDelay_”num2str(我)“_sensor1;”])%传感器2eval ([“initForDelay(”num2str(我))。传感器2...“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评估([“paramsNormal(”num2str(我)”)。获得= gainNormal_ 'num2str(我)“;”eval ()) (“paramsNormal(”num2str(我)”)。抵消= offsetNormal_ 'num2str(我)“;”eval ()) (“paramsNormal(”num2str(我)”)。我nit = initNormal_'num2str(我)“;”])结束

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

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

  3. 参数和对话框窗格中的参数点击编辑.对于新的掩码参数,设置促使参数结构的名字paramStruct.点击好吧

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

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

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

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

  7. 创建一个结构数组,该数组参数化Burner_Analysis_Delay为每个子系统,并将数组存储在变量中paramsForDelay

    i=1:3评估([“paramsForDelay(”num2str(我)”)。获得= gainDelayed_ 'num2str(我)“;”eval ()) (“paramsForDelay(”num2str(我)“)。偏移量=偏移量延迟”num2str(我)“;”eval ()) (“paramsForDelay(”num2str(我)”)。我nit = initDelayed_'num2str(我)“;”])结束

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

  9. 参数和对话框窗格中的参数点击编辑.对于新的掩码参数,设置促使参数结构的名字paramStruct.点击好吧

  10. 在面具里为每个子系统积木参数结构paramsForDelay

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

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

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

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

    %清除你替换的旧参数变量%带有结构数组清晰的-正则表达式_%清除迭代变量清晰的

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

检查转换后的模型

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

模型输入是一个由三个总线组成的数组。该模型使用了两个为每个子系统在输入阵列的三条总线上执行这两个算法。

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

提示

您可以在For Each子系统中记录非总线信号。但是,不能对for Each子系统中的总线或总线阵列使用信号日志记录。使用一个总线选择器块以选择要记录或添加的总线元素信号外港在子系统外阻塞,然后记录那个信号。有关详细信息,请参见为每个子系统记录信号

使用For Each子系统的示例

每个子系统使用的矢量化算法

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

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

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

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

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

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

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

不改变模型结构的模型参数变化。这个例子展示了如何在算法中建模参数变化。它使用了上面示例中的For Each子系统分区模型,并在保持模型简单性的同时为每个输入信号创建不同的过滤器。一组滤波系数馈送到为每个子系统块作为标记为分区的掩码参数。的每次迭代为每个子系统块,一个分割的滤波系数阵列馈给转移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

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

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

如果您按Ctrl + B要生成代码,结果代码使用单个输出函数。这三个函数是共享的为每个子系统实例。

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

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

该模型中的其余两个子系统显示了如何为使用为每个子系统块。再一次,按Ctrl + B生成代码提供了单个函数的代码重用。

另请参阅

对象

阻碍

相关的话题