Main Content

使用控制流逻辑

什么是控制流子系统?

当由控制流模块启用时,控制流子系统将在当前时间步执行一次或多次。控制流模块实现类似于以编程语言的控制流语句(例如 if-thenwhile-doswitchfor)所表示的控制逻辑。

等效的 C 语言语句

您可以使用模块图对与以下 C 编程语言语句等效的控制流逻辑进行建模:

  • for

  • if-else

  • switch

  • while

条件控制流逻辑

您可以使用以下模块执行条件控制流逻辑。

C 语句等效的模块

if-else

If, If Action Subsystem

switch

Switch Case, Switch Case Action Subsystem

If-Else 控制流

下图表示 if-else 控制流。

Control flow digram when using if-else conditions

构造一个 if-else 控制流图,如下所示:

  1. 提供 If 模块的数据输入用于构造 if-else 条件。

    在 If 模块参数对话框中,设置 If 模块的输入。在内部,这些输入被指定为 u1, u2,..., un 并用于构造输出条件。

  2. 在 If 模块参数对话框中,为 If 模块设置输出端口 if-else 条件。

    在 If 模块参数对话框中,设置输出端口。使用输入值 u1, u2, ..., un 表示对话框中 if、elseif、else 条件字段的条件。其中,仅 if 字段是必需的。您可以输入多个 elseif 条件并选中某个复选框以启用相应的 else 条件。

  3. 将每个条件输出端口连接到一个执行子系统。

    将 If 模块上的每个 if、elseif 和 else 条件输出端口连接到一个当端口条件为 true 时执行的子系统。

    通过在子系统中放置一个 Action Port 模块创建这些子系统。这将创建一个原子执行子系统,该子系统具有一个名为 Action 的端口,然后您再将该端口连接到 If 模块上的一个条件。

    一旦建立连接,该子系统将充当它所连接到的条件,且行为类似于使能子系统。

有关更多详细信息,请参阅 IfAction Port 模块。

注意

IfSwitch Case 模块驱动的执行子系统中的所有模块都必须以与驱动模块相同的速率运行。

切换控制流

下图表示 switch 控制流。

Control flow diagram when using Switch Case conditions

构造一个 switch 控制流语句,如下所示:

  1. 为 Switch Case 模块的参量输入提供数据输入。

    Switch Case 模块的输入是 switch 控制流语句的参量。此值确定要执行的适当 case。此端口的非整数输入将被截断。

  2. 基于参量输入的数值向 Switch Case 模块添加 case。

    使用 Switch Case 模块的参数对话框向 Switch Case 模块添加 case。Case 可以是单值或多值。您也可以添加可选的默认 case(即如果没有其他 case 为 true,则此 case 为 true)。一旦添加,这些 case 会显示为 Switch Case 模块上的输出端口。

  3. 将每个 Switch Case 模块的 case 输出端口连接到一个执行子系统。

    Switch Case 模块的每个 case 输出连接到一个子系统,当端口的 case 为 true 时便会执行该子系统。您可以通过在子系统中放置一个 Action Port 模块创建这些子系统。这将创建一个原子子系统,该子系统具有一个名为 Action 的端口,然后您再将该端口连接到 Switch Case 模块上的一个条件)。一旦建立连接,该子系统将充当它所连接到的条件,且行为类似于使能子系统。将对该 case 执行的所有模块编程放在此子系统中。

有关更多详细信息,请参阅 Switch CaseAction Port 模块的文档。

注意

在执行针对特定 case 的子系统后,会执行隐含的中断,这会同时退出 switch 控制流语句。Simulink® switch 控制流语句的实现并不具备 C switch 语句的“落空”(fall through) 行为。

While 和 For 循环

使用以下模块执行 whilefor 循环。

While 循环

下图说明 while 循环。

Control flow digram when using While loop

在此示例中,Simulink 在每个时间步重复执行 While Iterator 子系统的内容,直到满足 While Iterator 模块指定的条件。特别是,对于 While Iterator 模块指定的循环的每次迭代,Simulink 会调用 While 子系统中所有模块的更新和输出方法,且调用顺序与在非迭代原子子系统中调用这些方法的顺序一样。

注意

在 While 子系统的迭代执行期间,仿真时间不会前进。不过,While 子系统中的模块将每次迭代视为一个时间步。因此,在 While 子系统中,具有状态的模块(即模块的输出取决于其上一个输入)的输出会反映 while 循环的上一个迭代的输入值。输出并不反映该模块在上一个仿真时间步的输入。例如,While 子系统中 Unit Delay 模块输出其在 while 循环的上一个迭代的输入值,而不是在上一个仿真时间步的值。

构造一个 while 循环,如下所示:

  1. 将 While Iterator 模块放置在子系统中。

    宿主子系统标签更改为 while {...} 以指示它正在对 while 循环进行建模。这些子系统的行为类似于触发子系统。此子系统是您要使用 While Iterator 模块执行迭代的模块编程的宿主。

  2. 为 While Iterator 模块的初始条件数据输入端口提供数据输入。

    While Iterator 模块要求为其第一次迭代提供初始条件数据输入(标记为 IC)。这必须源于 While 子系统外部。如果此值为非零,则发生第一次迭代。

  3. 为 While Iterator 模块的条件端口提供数据输入。

    剩余迭代的条件被传递到标记为 cond 的数据输入端口。此端口的输入必须源于 While 子系统内部。

  4. (可选)通过 While Iterator 模块的属性对话框将该模块设置为输出其迭代器值。

    迭代器在第一次迭代时的值为 1,之后每迭代一次,值增加 1。

  5. (可选)通过 While Iterator 模块的属性对话框将该模块的迭代更改为 do-while

    这会将宿主子系统的标签更改为 do {...} while。使用 do-while 迭代时,While Iteration 模块不再具有初始条件 (IC) 端口,因为在检查条件端口(标记为 cond)之前子系统中的所有模块都会执行一次。

  6. 在子系统中创建用于定义子系统输出的模块图。

    注意

    该图不能包含具有连续状态的模块(例如,来自 Continuous 模块库的模块)。所有模块的采样时间必须为继承 (-1) 或固定 (inf)

有关详细信息,请参阅 While Iterator 模块。

For 循环建模

下图表示 for 循环:

Control flow diagram when using For loop

在此示例中,Simulink 在每个时间步多次执行 For Iterator 子系统的内容。For Iterator 模块的输入指定迭代次数。对于 for 循环的每次迭代,Simulink 会调用 For 子系统中所有模块的更新和输出方法,且调用顺序与在非迭代原子子系统中调用这些方法的顺序一样。

注意

在 For 子系统的迭代执行期间,仿真时间不会前进。不过,For 子系统中的模块将每次迭代视为一个时间步。因此,在 For 子系统中,具有状态的模块(即模块的输出取决于其上一个输入)的输出会反映 for 循环的上一个迭代的输入值。输出并不反映该模块在上一个仿真时间步的输入。例如,For 子系统中 Unit Delay 模块输出其在 for 循环的上一个迭代的输入值,而不是在上一个仿真时间步的值。

构造一个 for 循环,如下所示:

  1. 从库浏览器或 Library 窗口中将 For Iterator Subsystem 模块拖到您的模型中。

  2. (可选)将 For Iterator 模块设置为接受外部或内部输入,作为它执行迭代的次数。

    通过 For Iterator 模块的属性对话框,您可以将其设置为通过标记为 N 的端口接受输入,输入值为迭代次数。此输入必须来自 For Iterator Subsystem 外部。

    您还可以在属性对话框中直接设置迭代次数。

  3. (可选)将 For Iterator 模块设置为输出其迭代器值以用于 For Iterator Subsystem 的模块编程。

    迭代器在第一次迭代时的值为 1,之后每迭代一次,值增加 1。

  4. 在子系统中创建用于定义子系统输出的模块图。

    注意

    该图不能包含具有连续状态的模块(例如,来自 Continuous 模块库的模块)。所有模块的采样时间必须为继承 (-1) 或固定 (inf)

将 For 循环与 Assignment 模块结合使用

For Iterator 模块与 Assignment 模块搭配使用,可以很好地在向量或矩阵中重新赋值。以下示例说明如何使用 For Iterator 模块。请注意所传递的数据中的矩阵维度。

For Iterator subsystem containing Assignment block

Reassign values in a matrix iteratively using a For loop

以上示例使用包含 Assignment 模块的 For 子系统输出一个采用 2×5 矩阵(2 行、5 列)输入的正弦值。过程如下所示。

  1. 将一个 2×5 矩阵作为 Selector 模块和 Assignment 模块的输入。

  2. Selector 模块从输入矩阵中按照 For Iterator 模块的当前迭代值指示的列值剥离一个 2×1 矩阵。

  3. 得到 2×1 矩阵的正弦值。

  4. 2×1 矩阵的正弦值被传递给 Assignment 模块。

  5. Assignment 模块(该模块接受原始 2×5 矩阵作为它的一个输入)在迭代值所指示的列位置将该 2×1 矩阵重新赋回原始矩阵。

    上例中在 Assignment 模块的属性对话框中指定的重新赋值的行是 [1,2]。由于原始矩阵中仅有两行,您也可以为行指定 -1(即所有行)。

    注意

    Trigonometric Function 模块本身可以接受矩阵的正弦值。上例仅将 Trigonometric Function 模块作为示例来说明如何结合使用 Assignment 模块和 For Iterator 模块来更改矩阵的每个元素。

另请参阅

| | | | |