本页对应的英文页面已更新,但尚未翻译。 若要查看最新内容,请点击此处访问英文页面。

使用动作定义图行为

状态和转移动作是您在状态或转移旁编写的指令,用于定义 Stateflow® 图在仿真过程中的行为。有关详细信息,请参阅对有限状态机建模

例如,下图中的动作定义了一个以实验方式验证 Collatz 猜想实例的状态机。对于给定的数值输入 u,该图通过迭代以下规则来计算冰雹序列 n0 = u, n1, n2, n3, …

  • 如果 ni 为偶数,则 ni+1 = ni / 2

  • 如果 ni 为奇数,则 ni+1 = 3ni+1

Collatz 猜想指出,每个正整数都有一个最终达到 1 值的冰雹序列。

该图由三个状态组成。在仿真开始时,Init 状态初始化图数据:

  • 本地数据 n 设置为输入 u 的值。

  • n 除以 2 时,本地数据 n2 设置为余数。

  • 输出数据 y 设置为 false

根据输入的奇偶性,图转移到 EvenOdd 状态。当状态活动在 EvenOdd 状态之间切换时,图会计算冰雹序列中的数字。当序列达到 1 值时,输出数据 y 变为 true,并触发 Simulink® 模型中的 Stop Simulation 模块。

状态动作类型

状态动作定义当状态被激活时 Stateflow 图的动作。最常见的状态动作类型是 entryduringexit 动作。

状态动作的类型缩写说明
entryen当状态被激活时,动作在时间步上发生。
duringdu当状态已激活并且图未转移出该状态时,动作在时间步上发生。
exitex当图转移出状态时,动作在时间步上发生。

您可以通过状态动作的完整关键字(entryduringexit)或其缩写(enduex)指定状态动作的类型。您还可以使用逗号组合各状态动作类型。例如,组合类型 entry,during 当状态被激活时在时间步上发生,并且在状态保持激活时在每个后续时间步上发生。

下表列出了冰雹图中每个状态动作的结果。

状态动作结果
Init

entry:
 n2 = rem(n,2);
 y = false;

在仿真开始,Init 被激活时,确定 n 的奇偶性并将 y 设置为 false

exit:
 y = isequal(n,1);

当经过一个时间步后转移出 Init 时,确定 n 是否等于 1。
Even

entry,during:
 n = n/2;
 n2 = rem(n,2);

计算冰雹序列的下一个数字 (n / 2) 并在以下时间步上更新其奇偶性:

  • Even 首次被激活时的时间步。

  • Even 保持激活的每个随后的时间步。

Odd

entry,during:
 n = 3*(n-y)+1;
 n2 = rem(n,2);

计算冰雹序列的下一个数字 (3n+1) 并在以下时间步上更新其奇偶性:

  • Odd 首次被激活时的时间步。

  • Odd 保持激活的每个随后的时间步。

在整个仿真过程的大部分阶段,y 的计算结果为零。在最后一个时间步上,当 n = 1 时,y 的计算结果为 1,因此该动作在仿真停止之前不修改 nn2

转移动作的类型

转移动作定义当转移出激活状态时 Stateflow 图执行的动作。最常见的转移动作类型是条件和条件动作。要指定转移动作,请使用采用以下语法的标签:

[condition]{conditional_action}
condition 是布尔表达式,用于确定是否发生转移。如果不指定条件,则假定采用一个计算结果为 true 的隐含条件。

conditional_action 是在判断转移的条件为 true 时执行的指令。条件动作发生在条件后,但在任何 exitentry 状态动作之前。

下表列出了冰雹图中每个转移动作的结果。

转移动作动作类型结果
Init 的默认转移

n = u

条件动作在仿真开始时,将输入值 u 赋给本地数据 n
InitEven 的转移

n2 == 0

条件n 为偶数时,发生转移。此转移起始处的数字 1 表示此转移将先于指向 Odd 的转移进行计算。
InitOdd 的转移 n 为奇数时,发生转移。此转移起始处的数字 2 表示此转移将在指向 Even 的转移之后进行计算。
OddEven 的转移

n2 == 0

条件n 为偶数时,发生转移。
EvenOdd 的转移

n2 ~= 0

条件n 为奇数时,发生转移。

y = isequal(n,1)

条件动作在发生转移时,确定 n 是否等于 1。

检查图行为

假设您要计算从 9 开始的冰雹序列。

  1. 在 Model Configuration Parameters 对话框的 Solver 下,选择以下选项:

    • Start time0.0

    • Stop timeinf

    • Type:“Fixed-step

    • Fixed-step size1

  2. 在 Property Inspector 中,选择符号 n 进行记录。

  3. Constant 模块中,输入 u = 9

  4. 点击 Run 图标

图用下列动作予以响应:

  • 在时间 t = 0 处,默认转移到 Init 发生。

    • 转移动作将 n 的值设置为 9。

    • Init 状态被激活。

    • Init 中的 entry 动作将 n2 设置为 1 且将 y 设置为 false

  • 在时间 t = 1 处,条件 n2 == 0 为 false,因此图准备转移到 Odd

    • Init 中的 exit 动作将 y 设置为 false

    • Init 状态变为非激活。

    • Odd 状态被激活。

    • Odd 中的 entry 动作将 n 设置为 28,将 n2 设置为 0。

  • 在时间 t = 2 处,条件 n2 == 0 为 true,因此图准备转移到 Even

    • Odd 状态变为非激活。

    • Even 状态被激活。

    • Even 中的 entry 动作将 n 设置为 14,将 n2 设置为 0。

  • 在时间 t = 3 处,条件 n2 ~= 0 为 false,因此图不会发生转移。

    • Even 状态保持激活。

    • Even 中的 during 动作将 n 设置为 7,将 n2 设置为 1。

  • 在时间 t = 4 处,条件 n2 ~= 0 为 true,因此图准备转移到 Odd

    • 转移动作将 y 设置为 false

    • Even 状态变为非激活。

    • Odd 状态被激活。

    • Odd 中的 entry 动作将 n 设置为 22,将 n2 设置为 0。

  • 该图继续计算冰雹序列,直到它在时间 t = 19 处达到 n = 1 的值。

  • 在时间 t = 20 处,图准备从 Even 转移到 Odd

    • Even 状态变为未激活之前,转移动作将 y 设置为 true

    • Odd 状态被激活。

    • Odd 中的 entry 动作不会修改 nn2

    • 连接到输出信号 yStop Simulation 模块停止仿真。

相关主题