Main Content

使用时序逻辑控制图的执行

时序逻辑通过时间控制 Stateflow 图的执行。在状态动作和转移中,可以使用两种类型的时序逻辑:

  • 基于事件的时序逻辑会跟踪重复发生的事件。可以将任何显式或隐式事件用作基础事件。

  • 绝对时间时序逻辑会跟踪从状态激活以来经过的时间。绝对时间时序逻辑运算符的计时取决于 Stateflow® 图的类型:

    • Simulink® 模型中的图根据仿真时间定义绝对时间时序逻辑。

    • MATLAB® 中的独立图根据挂钟时间定义绝对时间时序逻辑,其精度限制在 1 毫秒。

时序逻辑运算符

要基于时序逻辑定义 Stateflow 图的行为,请使用下表中列出的运算符。这些运算符可以出现在以下项中:

  • 状态的 on 动作

  • 源自某一状态的转移路径上的动作

每个时序逻辑运算符都有一个关联状态,它是动作所在的状态或转移路径的来源状态。Stateflow 图会在每次关联状态重新激活时重置每个运算符使用的计数器。

运算符语法描述示例
after

after(n,E)

n 是正整数或计算结果为正整数值的表达式。

E 是运算符的基础事件。

如果自关联状态激活以来 E 事件至少已发生 n 次,则返回 true。否则,运算符返回 false

当图处理事件 E 的广播时,从状态激活后 E 的第三次广播开始显示状态消息。

on after(3,E): disp("ON");

当图处理事件 E 的广播时,从关联状态激活后 E 的第五次广播开始,发生转出关联状态的转移。

after(5,E)

after(n,tick)

n 是正整数或计算结果为正整数值的表达式。

如果图自关联状态激活以来至少唤醒了 n 次,则返回 true。否则,运算符返回 false

当 Simulink 模型中的 Stateflow 图有输入事件时,不支持隐式事件 tick。有关详细信息,请参阅通过使用隐式事件控制图行为

当图自关联状态激活以来至少唤醒了七次,且变量 temp 大于 98.6 时,发生转出关联状态的转移。

after(7,tick)[temp > 98.6]

after(n,sec)

after(n,msec)

after(n,usec)

n 是正实数或计算结果为正实数的表达式。

如果自关联状态激活以来至少已经过 n 个时间单位,则返回 true。否则,运算符返回 false

在 Simulink 模型的图中,以秒 (sec)、毫秒 (msec) 或微秒 (usec) 作为时间单位。

在 MATLAB 的独立图中,以秒 (sec) 作为时间单位。运算符创建一个 MATLAB timer 对象,该对象生成隐式事件来唤醒图。MATLAB timer 对象的精度限制在 1 毫秒。有关详细信息,请参阅Events in Standalone Charts

从关联状态激活后的 12.3 秒开始,每次图被唤醒时,都将 temp 变量设置为 LOW

on after(12.3,sec): temp = LOW;
at

at(n,E)

n 是正整数或计算结果为正整数值的表达式。

E 是运算符的基础事件。

如果自关联状态激活以来 E 事件恰好发生了 n 次,则返回 true。否则,运算符返回 false

状态激活后,在图处理 E 事件的第三次广播时,显示状态消息。

on at(3,E): disp("ON");

状态激活后,在图处理 E 事件的第五次广播时,发生转出关联状态的转移。

at(5,E)

at(n,tick)

n 是正整数或计算结果为正整数值的表达式。

如果图自关联状态激活以来恰好唤醒了 n 次,则返回 true。否则,运算符返回 false

当 Simulink 模型中的 Stateflow 图有输入事件时,不支持隐式事件 tick。有关详细信息,请参阅通过使用隐式事件控制图行为

当图自关联状态激活以来第七次被唤醒,且变量 temp 大于 98.6 时,发生转出关联状态的转移。

at(7,tick)[temp > 98.6]

at(n,sec)

n 是正实数或计算结果为正实数的表达式。

如果自关联状态激活以来恰好经过了 n 秒,则返回 true。否则,运算符返回 false

仅 MATLAB 中的独立图支持使用 at 作为绝对时间时序逻辑运算符。运算符创建一个 MATLAB timer 对象,该对象生成隐式事件来唤醒图。MATLAB timer 对象的精度限制在 1 毫秒。有关详细信息,请参阅Events in Standalone Charts

如果状态已激活恰好 12.3 秒,则将 temp 变量设置为 HIGH

on at(12.3,sec): temp = HIGH;
before

before(n,E)

n 是正整数或计算结果为正整数值的表达式。

E 是运算符的基础事件。

如果自关联状态激活以来 E 事件的发生次数少于 n 次,则返回 true。否则,运算符返回 false

时序逻辑运算符 before 仅在 Simulink 模型的 Stateflow 图中受支持。

状态激活后,在图处理 E 事件的第一次和第二次广播时,显示状态消息。

on before(3,E): disp("ON");

当图处理事件 E 的广播时,仅在关联状态激活后 E 的广播次数少于五次时,发生转出关联状态的转移。

before(5,E)

before(n,tick)

n 是正整数或计算结果为正整数值的表达式。

如果图自关联状态激活以来的唤醒次数少于 n 次,则返回 true。否则,运算符返回 false

当 Simulink 模型中的 Stateflow 图有输入事件时,不支持隐式事件 tick。有关详细信息,请参阅通过使用隐式事件控制图行为

时序逻辑运算符 before 仅在 Simulink 模型的 Stateflow 图中受支持。

当图被唤醒时,仅在自关联状态激活以来的唤醒次数少于七次,且变量 temp 大于 98.6 时,发生转出关联状态的转移。

before(7,tick)[temp > 98.6]

before(n,sec)

before(n,msec)

before(n,usec)

n 是正实数或计算结果为正实数的表达式。

如果自关联状态激活以来经过的时间少于 n 个单位,则返回 true。否则,运算符返回 false

指定时间,单位为秒 (sec)、毫秒 (msec) 或微秒 (usec)。

时序逻辑运算符 before 仅在 Simulink 模型的 Stateflow 图中受支持。

在关联状态激活后的 12.3 秒之内,每次图被唤醒时,都将 temp 变量设置为 MED

on before(12.3,sec): temp = MED;
every

every(n,E)

n 是正整数或计算结果为正整数值的表达式。

E 是运算符的基础事件。

自关联状态激活以来,E 事件每发生 n时,返回 true。否则,运算符返回 false

状态激活后,在图每处理三次 E 事件的广播时,显示状态消息。

on every(3,E): disp("ON");

状态激活后,在图每处理五次 E 事件的广播时,发生转出关联状态的转移。

every(5,E)

every(n,tick)

n 是正整数或计算结果为正整数值的表达式。

自关联状态激活以来,图每唤醒 n时,返回 true。否则,运算符返回 false

当 Simulink 模型中的 Stateflow 图有输入事件时,不支持隐式事件 tick。有关详细信息,请参阅通过使用隐式事件控制图行为

自关联状态激活以来,每发生七次 tick 事件且变量 temp 大于 98.6 时,发生转出关联状态的转移。

every(7,tick)[temp > 98.6]

every(n,sec)

n 是正实数或计算结果为正实数的表达式。

自关联状态激活以来,每经过 n 秒时,返回 true。否则,运算符返回 false

仅 MATLAB 中的独立图支持使用 every 作为绝对时间时序逻辑运算符。运算符创建一个 MATLAB timer 对象,该对象生成隐式事件来唤醒图。MATLAB timer 对象的精度限制在 1 毫秒。有关详细信息,请参阅Events in Standalone Charts

状态激活后,每过 12.3 秒 temp 变量增加 5。

on every(12.3,sec): temp = temp+5;
temporalCount

temporalCount(E)

E 是运算符的基础事件。

返回自关联状态激活以来事件 E 的发生次数。

仅在 Simulink 模型的 Stateflow 图中支持使用 temporalCount 作为基于事件的时序逻辑运算符。

每次图处理 E 事件的广播时,访问数组 M 的连续元素。

on E: y = M(temporalCount(E));
temporalCount(tick)

返回自关联状态激活以来图唤醒的次数。

当 Simulink 模型中的 Stateflow 图有输入事件时,不支持隐式事件 tick

仅在 Simulink 模型的 Stateflow 图中支持使用 temporalCount 作为基于事件的时序逻辑运算符。

将输入数据 u 的值存储在数组 M 的连续元素中。

en,du:
   M(temporalCount(tick)+1) = u;

temporalCount(sec)

temporalCount(msec)

temporalCount(usec)

返回自关联状态激活以来经过的时间长度。

指定时间,单位为秒 (sec)、毫秒 (msec) 或微秒 (usec)。

存储自状态激活以来的毫秒数。

en,du:
   y = temporalCount(msec);
elapsed

elapsed(sec)

返回自关联状态激活以来经过的时间长度。

等效于 temporalCount(sec)

存储自状态激活以来的秒数。

en,du:
   y = elapsed(sec);
et执行 elapsed(sec) 的另一种方式。

当图处理事件 E 的广播时,发生转出关联状态的转移,并显示自状态激活以来经过的时间。

E{disp(et);}
count

count(C)

C 是计算结果为 truefalse 的表达式。

返回自条件表达式 C 变为 true 以及关联状态激活以来,图唤醒的次数。

如果条件表达式 C 变为 false 或关联状态变为非激活,Stateflow 图会重置 count 运算符的值。

在 Simulink 模型的图中,count 的值可能取决于步长。更改模型的求解器或步长会影响 count 运算符生成的结果。

当变量 x 大于或等于 2 的时间超过五次图执行时间时,发生转出关联状态的转移。

[count(x>=2) > 5]

存储自变量 x 变为大于 5 以来图执行的次数。

en,du:
   y = count(x>5);
duration

duration(C)

duration(C,sec)

duration(C,msec)

duration(C,usec)

  • C 是计算结果为 truefalse 的表达式。

返回自条件表达式 C 变为 true 且关联状态激活以来经过的时间长度。

指定时间,单位为秒 (sec)、毫秒 (msec) 或微秒 (usec)。默认单位为秒。

如果条件表达式 C 变为 false 或关联状态变为非激活,Stateflow 图会重置 duration 运算符的值。

MATLAB 中的独立图不支持时序逻辑运算符 duration

当变量 x 大于或等于 0 的时间超过 0.1 秒时,发生转出状态的转移。

[duration(x>=0) > 0.1]

存储自变量 x 大于 5 且状态激活以来经过的毫秒数。

en,du:
   y = duration(x>5,msec);

您可以使用引号将关键字 'tick''sec''msec''usec' 括起来。例如,after(5,'tick') 等效于 after(5,tick)

注意

时序逻辑运算符 afteratbeforeevery 将阈值 n 与整数类型的内部计数器进行比较。如果 n 是通过非 2 的整数次幂斜率或非零偏置定义的定点数,则由于舍入,比较可能会产生意外的结果。有关详细信息,请参阅Relational Operations for Fixed-Point Data

时序逻辑示例

定义时滞

此示例说明如何在连续时间图中定义两个绝对时滞。

图的执行遵循以下步骤:

  1. 当图唤醒时,状态 Input 先激活。

  2. 仿真执行 5.33 毫秒后,会发生从 InputOutput 的转移。

  3. 状态 Input 变为非激活,状态 Output 被激活。

  4. 仿真执行 10.5 秒后,会发生从 OutputInput 的转移。

  5. 状态 Output 变为非激活,状态 Input 被激活。

在仿真结束之前,会重复步骤 2 到 5。

如果 Stateflow 图具有离散采样时间,则该图中的任何动作都会在该采样时间的整数倍时发生。例如,如果 Simulink® 求解器使用大小为 0.1 秒的固定步长,则从状态 Input 到状态 Output 的第一个转移发生在 t = 0.1 秒处。发生此行为的原因在于求解器不会在正好 t = 5.33 毫秒时唤醒图。在这种情况下,求解器会在 0.1 秒的整数倍时唤醒图,例如 t = 0.0 秒和 0.1 秒时。

检测已用时间

在此示例中,Step (Simulink) 模块向 Stateflow 图提供一个单位阶跃输入。

图决定输入 u 何时等于 1:

  • 如果输入在 t = 2 秒之前等于 1,则发生从 StartFast 的转移。

  • 如果输入在 t = 2 秒和 t = 5 秒之间等于 1,则发生从 StartMedium 的转移。

  • 如果输入在 t = 5 秒后等于 1,则发生从 StartSlow 的转移。

在使能子系统中使用绝对时间时序逻辑

您可以在位于条件执行子系统的 Stateflow 图中使用绝对时间时序逻辑。当该子系统被禁用时,该 Stateflow 图变为非活动图,当该 Stateflow 图处于休眠状态时,时序逻辑运算符会暂停。在重新启用该子系统并且该图唤醒前,该运算符不会继续对仿真时间进行计数。

此模型具有一个使能子系统,其启用时的状态参数设置为 held

该子系统包含一个使用 after 运算符触发转移的 Stateflow 图。

信号编辑器 (Simulink) 模块提供具有以下特征的输入信号:

  • 信号在 t = 0 时激活子系统。

  • 信号在 t = 2 时禁用子系统。

  • 信号在 t = 6 时重新激活子系统。

下图显示图中经过的总时间。当输入信号在时间 t = 0 激活子系统时,状态 A 被激活。当系统被激活时,经过时间会增加。当子系统在 t = 2 禁用时,图进入休眠状态,经过时间停止增加。当 2 < t < 6 时,经过时间因为系统被禁用而冻结在 2 秒。当图在 t = 6 唤醒时,经过时间再次开始增加。

从状态 A 到状态 B 的转移取决于状态 A 处于激活状态时所经过的时间,而不是取决于仿真时间。因此,当状态 A 中的经过时间等于 5 秒时,也就是 t = 9 时发生转移。当转移发生时,输出值 y 从 0 变为 1。

此模型行为只适用于 Enable 模块参数启用时的状态设为 held 的子系统。如果该参数设为 reset,则当重新激活子系统时,Stateflow 图会完全重新初始化。执行默认转移,所有时序逻辑计数器都重置为 0。

转移中基于事件的时序逻辑的表示法

在 Simulink 模型的 Stateflow 图中,运算符 afteratbefore 支持两种不同表示法来表示转移中基于事件的时序逻辑。

  • 触发器表示法定义仅依赖时序逻辑运算符的基础事件的转移。触发器表示法遵循以下语法:

    temporalLogicOperator(n,E)[C]
    其中:

    • temporalLogicOperator 是一个布尔时序逻辑运算符。

    • n 是运算符的出现次数。

    • E 是运算符的基础事件。

    • C 是一个可选条件表达式。

    当您使用触发器表示法时,仅当图处理基础事件 E 的广播时才会发生转移。

  • 条件表示法定义依赖基础事件和非基础事件的转移。条件表示法遵循以下语法:

    F[temporalLogicOperator(n,E) && C]
    其中:

    • temporalLogicOperator 是一个布尔时序逻辑运算符。

    • n 是运算符的出现次数。

    • E 是运算符的基础事件。

    • F 是可选的非基础事件。

    • C 是一个可选条件表达式。

    当您对非基础事件 F 使用条件表示法时,仅当图处理 F 的广播时才会发生转移。如果忽略非基础事件,则当图处理任何显式或隐式事件时都可以发生转移。

    MATLAB 中的独立图不支持时序逻辑运算符的条件表示法。

例如,以下转移标签使用触发表示法来指示当图处理基础事件 E 的广播时,从关联状态激活后 E 的第五次广播开始,发生转出关联状态的转移。

after(5,E)

而下面的转移标签则使用条件表示法来指示当状态激活后基础事件 E 的广播次数至少为五次时发生转出关联状态的转移,即使图没有处理 E 的广播也是如此。

[after(5,E)]

注意

运算符 every 支持触发器表示法和条件表示法。不过,这两种表示法对于此运算符是等效的。转移标签 every(5,E)[every(5,E)] 均指示当图在状态激活后处理基础事件 E 的第 k 次广播时(其中 k 是 5 的倍数),发生转出关联状态的转移。

时序逻辑的最佳做法

不要在没有源状态的转移路径中使用时序逻辑

时序逻辑运算符的值取决于其关联状态何时激活。为了确保每个时序逻辑运算符都有唯一关联状态,请仅在以下项中使用这些运算符:

  • 状态的 on 动作

  • 源自某一状态的转移路径上的动作

不要对默认转移或图形函数中的转移使用时序逻辑运算符,因为这些转移并非从某一状态发出的转移。

Simulink 模型的图中使用绝对时间时序逻辑,而不要使用 tick

在 Simulink 模型的图中,使用绝对时间时序逻辑表示的时滞值在语义上独立于模型的采样时间。与之相反,使用基于隐式事件 tick 的时序逻辑表示的时滞则取决于 Simulink 求解器使用的步长。

此外,具有输入事件的图支持绝对时间时序逻辑。当 Simulink 模型中的 Stateflow 图有输入事件时,不支持隐式事件 tick

不要在 Simulink 模型的图中用 at 来表示绝对时间时序逻辑

在 Simulink 模型的图中,不支持使用 at 作为绝对时间时序逻辑运算符。请改用 after 运算符。例如,假设您要使用表达式 at(5.33,sec) 定义时滞。

Chart with a transition that uses at as an absolute-time temporal logic operator.

为了防止运行时错误,请将转移标签更改为 after(5.33,sec)

Chart with a transition that uses after as an absolute-time temporal logic operator.

大参数值的意外结果

在进入具有以下条件的状态后,诸如 after(x,sec) 的 Stateflow 绝对时间时序逻辑条件在预期时间的计算结果可能不为 true

  • 图具有周期性的离散采样时间。

  • 图逻辑使状态保持激活状态超过 2147418 个时间单位。时间单位是该状态使用的任何时序逻辑表达式中的最小时间单位。例如,如果状态有两个出向转移,其中一个使用 after(x,sec),另一个使用 after(x,msec),则时间单位为 msec (milliseconds)

通常,当状态中的时间长度大于 2147418 个时间单位时,会出现意外结果。但具体情况取决于图的采样时间。

不要在 Simulink 模型的图中用 every 来表示绝对时间时序逻辑

在 Simulink 模型的图中,不支持使用 every 作为绝对时间时序逻辑运算符。请改为使用通过 after 运算符实现的外部自环转移。例如,假设您想要在 Stateflow 图执行期间每 2.5 秒为某个激活状态打印一条状态消息。

Chart with a state action that uses every as an absolute-time temporal logic operator.

为了防止运行时错误,请用外部自环转移替换状态动作。

Chart with a self-loop transition that uses after as an absolute-time temporal logic operator.

在状态中添加一个历史结点,以使 Stateflow 图在每次自环转移之前记住状态设置。请参阅通过使用历史结点继续先前的子状态活动

MATLAB 的独立图中,不要在具有多个源的转移路径中使用时序逻辑

MATLAB 的独立图不支持在具有多个源状态的转移路径中使用时序逻辑运算符。例如,以下独立图会产生运行时错误,因为时序逻辑表达式 after(10,sec) 会触发具有多个源状态的转移路径。

Standalone chart containing a temporal logic expression on the transition path originating from states Positive and Negative to state End.

要解决此问题,请改为对单独的转移路径(每个转移路径都有单一源状态)使用时序逻辑表达式。

Standalone chart using temporal logic expressions on separate transition paths.

避免在 MATLAB 的独立图的转移路径中混合使用绝对时间时序逻辑和条件

在 MATLAB 的独立图中,运算符 afteratevery 都会创建 MATLAB timer 对象,这种对象可生成隐式事件来唤醒图。将这些运算符与同一个转移路径中的条件结合使用会导致意外行为:

  • 如果当 timer 唤醒图时转移路径上的条件为 false,则图执行激活状态的 duringon 动作。

  • 图不会重置与运算符 afterat 关联的 timer 对象。即使转移路径上的条件随后变为 true,如果没有另一个显式或隐式事件来唤醒图,转移也不会发生。

例如,在下图中,从状态 A 到状态 B 的转移路径上同时使用了绝对时间时序逻辑触发器 after(1,sec) 和条件 [guard]。从状态 A 到状态 C 的转移具有绝对时间时序逻辑触发器 after(5,sec)。每个转移都与一个生成隐式事件的 timer 对象相关联。最初,局部变量 guardfalse

Chart combining an absolute-time temporal logic trigger and a condition on the same transition path.

当您执行图时,状态 A 被激活。图执行 entry 动作,并显示消息 Hello!。在 1 秒后,与从 AB 的转移相关联的 timer 唤醒图。由于转移无效,图在 A 状态下执行 during 动作,并再次显示消息 Hello!

假设在 2 秒后,图接收到输入事件 E。图在 A 状态下执行 on 动作,并将 guard 的值更改为 true。由于图不会重置与运算符 after 相关联的 timer,因而在另一个事件唤醒图之前,不会发生从 AB 的转移。

在 5 秒后,与从 AC 的转移相关联的 timer 唤醒图。由于从 AB 的转移有效并且具有更高的执行顺序,因而图不会发生到状态 C 的转移,也不会显示消息 Farewell!。取而代之的是,状态 B 被激活,图显示消息 Good bye!

使用带离散采样时间的 Stateflow 图实现更加高效的代码生成

若离散图不在触发子系统或使能子系统内,则生成代码时使用整数计数器来跟踪时间,而不是使用 Simulink 提供的时间。从管理开销和内存方面来看,此行为可以实现更加高效的代码生成,且可以让此代码用在软件在环 (SIL) 和处理器在环 (PIL) 两种仿真模式中。有关详细信息,请参阅SIL 和 PIL 仿真 (Embedded Coder)

另请参阅

| | | | | | | | | (Simulink) | (Simulink)

相关主题