英文名字为“Control Chart Execution by Using Temporal Logic”
1. 前言
时序逻辑通过时间控制 Stateflow 图的执行。在状态动作和转移中,可以使用两种类型的时序逻辑:
- 基于事件的时序逻辑会跟踪重复发生的事件。可以将任何显式或隐式事件用作基础事件
- 绝对时间时序逻辑会跟踪从状态激活以来经过的时间, 绝对时间时序逻辑运算符的计时取决于Stateflow图的类型:
- Simulink模型中的图(chart)根据仿真时间定义绝对时间时序逻辑
- Matlab中的独立图(Standalone charts)根据挂钟时间(wall-clock time)定义绝对时间时序逻辑,其精度限制在1毫秒
2. 时序逻辑运算符
存在几种时序逻辑运算符,这些运算符一般出现在:
- 状态的on动作(状态激活)
- 源自某一状态的转移路径上的动作
每个时序逻辑运算符都有一个关联状态,它是动作所在的状态或转移路径的来源状态。Stateflow 图会在每次关联状态重新激活时重置每个运算符使用的计数器。
2.1 运算符after
after(n,E)
%{
n 是正整数或计算结果为正整数值的表达式。
E 是运算符的基础事件。
}%
说明:
如果自关联状态激活以来 E 事件至少已发生 n 次,则返回 true。否则,运算符返回 false。
after(n,tick)
%{
n 是正整数或计算结果为正整数值的表达式。
}%
说明:
如果图自关联状态激活以来至少唤醒了n次,则返回true;否则,运算符返回false。
当Simulink模型中的Stateflow图有输入事件时,不支持隐性事件tick。
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。
2.2 运算符at
at运算符与after运算符类似,只是after代表“至少经过了”,而at代表“恰好经过了”
2.3 运算符before
before运算符与after运算符类似,只是after代表“至少经过了”,而before代表“少于n次”
2.4 运算符every
every运算符与after运算符类似,只是after代表“至少经过了”,而every代表“每经过n次”
2.5 运算符temporalCount
temporalCount(E)
% E是运算符的基础事件
说明:
返回自关联状态激活以来事件 E 的发生次数。
仅在 Simulink 模型的 Stateflow 图中支持使用 temporalCount 作为基于事件的时序逻辑运算符。
temporalCount(tick)
说明:
返回自关联状态激活以来图唤醒的次数。
当 Simulink 模型中的 Stateflow 图有输入事件时,不支持隐式事件 tick。
仅在 Simulink 模型的 Stateflow 图中支持使用 temporalCount 作为基于事件的时序逻辑运算符。
temporalCount(sec)
temporalCount(msec)
temporalCount(usec)
说明:
返回自关联状态激活以来经过的时间长度。
指定时间,单位为秒 (sec)、毫秒 (msec) 或微秒 (usec)。
2.6 运算符elapsed
elapsed(sec)
% 等效于temporalCount(sec)
2.7 运算符count
count(C)
% C 是计算结果为 true 或 false 的表达式。
说明:
返回自条件表达式 C 变为 true 以及关联状态激活以来,图唤醒的次数。
如果条件表达式 C 变为 false 或关联状态变为非激活,Stateflow 图会重置 count 运算符的值。
在 Simulink 模型的图中,count 的值可能取决于步长大小。更改模型的求解器或步长大小会影响 count 运算符生成的结果。
2.8 运算符duration
duration(C)
duration(C,sec)
duration(C,msec)
duration(C,usec)
% C是计算结果为 true 或 false 的表达式。
说明:
返回自条件表达式 C 变为 true 且关联状态激活以来经过的时间长度。
指定时间,单位为秒 (sec)、毫秒 (msec) 或微秒 (usec)。默认单位为秒。
如果条件表达式 C 变为 false 或关联状态变为非激活,Stateflow 图会重置 duration 运算符的值。
MATLAB 中的独立图不支持时序逻辑运算符 duration。
3. 时序逻辑示例
3.1 定义时滞(time delay)
如上图,chart的执行步骤:
- 当图唤醒时,状态Input先激活
- 仿真执行5.33秒后,会发生从Input到Output的转移
- 状态Input变为非激活,状态Output被激活
- 仿真执行10.5秒后,会发生从Output到Input的转移
- 状态Output变为非激活,状态Input被激活
- 在仿真结束前,会重复步骤2到步骤5.
示波器可显示这一过程:
3.2 检测已用时间
在该示例中,Step模块向Stateflow图提供了一个单位阶跃输入。
图决定输入u何时等于1:
- 如果输入在t=2秒之前等于1,则发生从Start到Fast的转移
- 如果输入在t=2秒和t=5秒之间等于1,则发生Start到Medium的转移
- 如果输入在t=5秒后等于1,则发生从Start到Slow的转移。
3.3 在使能子系统中使用绝对时间时序逻辑
可以在位于条件执行子系统的 Stateflow 图中使用绝对时间时序逻辑。当该子系统被禁用时,该 Stateflow 图变为非活动图,当该 Stateflow 图处于休眠状态时,时序逻辑运算符会暂停。在重新启用该子系统并且该图唤醒前,该运算符不会继续对仿真时间进行计数。
举例:
该模型具有一个使能子系统,其States when enabling 参数设置为held。
该子系统包含一个使用after运算符的Stateflow图:
而Signal Builder模块提供如下输入信号:
- 信号在t=0时激活子系统
- 信号在t=2时禁用子系统
- 信号在t=6时重新激活子系统
下图显示在激活状态(A或B)下所经过的总时间:
特别要注意,2~6秒内处于未激活状态,所以计时是停止的。在t=9秒时,才由状态A转为状态B。
此模型行为只适用于 Enable 模块参数 States when enabling 设为 held 的子系统。如果该参数设为 reset,则当重新激活子系统时,Stateflow 图会完全重新初始化。换句话说,会执行默认转移,所有时序逻辑计数器都重置为 0。
4. 转移中基于事件的时序逻辑的表示法
在 Simulink 模型的 Stateflow 图中,运算符 after、at 和 before 支持两种不同表示法来表示转移中基于事件的时序逻辑。
4.1 触发器表示法
触发器表示法定义仅依赖时序逻辑运算符的基础事件的转移,语法如下:
temporalLogicOperator(n,E)[C]
其中:
- temporalLogicOperator是一个布尔时序逻辑运算符
- n是运算符的出现次数
- E是运算符的基础事件
- C是一个可选条件表达式
当您使用触发器表示法时,仅当图处理基础事件E的广播时才会发生转移。
4.2 条件表示法
条件表示法定义依赖基础事件和非基础事件的转移。条件表示法遵循以下语法:
F[temporalLogicOperator(n,E) && C]
其中:
- temporalLogicOperator是一个布尔时序逻辑运算符
- n是运算符的出现次数
- E是运算符的基础事件
- F是可选的非基础事件
- C是一个可选条件表达式
当你对非基础事件 F 使用条件表示法时,仅当图处理 F 的广播时才会发生转移。如果忽略非基础事件(不写F,4.3例二),则当图处理任何显式或隐式事件时都可以发生转移。
MATLAB 中的独立图不支持时序逻辑运算符的条件表示法。
4.3 举例
例如,以下转移标签使用触发表示法来指示当图处理基础事件 E 的广播时,从关联状态激活后 E 的第五次广播开始,发生转出关联状态的转移。
after(5,E)
而下面的转移标签则使用条件表示法来指示当状态激活后基础事件 E 的广播次数至少为五次时发生转出关联状态的转移,即使图没有处理 E 的广播也是如此。
[after(5,E)]
即触发表示法处理的是事件E,而条件表示法处理的是事件F。
注意:
运算符 every 支持触发器表示法和条件表示法。不过,这两种表示法对于此运算符是等效的。转移标签 every(5,E) 和 [every(5,E)] 均指示当图在状态激活后处理基础事件 E 的第 k次广播时(其中 k 是 5 的倍数),发生转出关联状态的转移。
5. 注意事项
一些在应用过程中需要注意的事项。
5.1 不要在没有源状态的转移路径中使用时序逻辑
时序逻辑运算符的值取决于其关联状态何时激活。为了确保每个时序逻辑运算符都有唯一关联状态,请仅在以下项中使用这些运算符:
- 状态的on动作
- 源自某一状态的转移路径上的动作
不要对默认转移或图形函数中的转移使用时序逻辑运算符,因为这些状态并非从某一状态发出的转移。
5.2 在 Simulink 模型的图中使用绝对时间时序逻辑,而不要使用 tick
在 Simulink 模型的图中,使用绝对时间时序逻辑表示的时滞值在语义上独立于模型的采样时间。与之相反,使用基于隐式事件 tick 的时序逻辑表示的时滞则取决于 Simulink 求解器使用的步长大小。
此外,具有输入事件的图支持绝对时间时序逻辑。当 Simulink 模型中的 Stateflow 图有输入事件时,不支持隐式事件 tick。
5.3 不要在 Simulink 模型的图中用 at 来表示绝对时间时序逻辑
在 Simulink 模型的图中,不支持使用 at 作为绝对时间时序逻辑运算符。请改用 after 运算符。例如,假设您要使用表达式 at(5.33, sec) 定义时滞。
为了防止运行时错误,请将转移标签更改为 after(5.33, sec)。
5.4 不要在 Simulink 模型的图中用 every 来表示绝对时间时序逻辑
在 Simulink 模型的图中,不支持使用 every 作为绝对时间时序逻辑运算符。请改为使用通过 after 运算符实现的外部自环转移。例如,假设您想要在 Stateflow 图执行期间每 2.5 秒为某个激活状态打印一条状态消息。
为了防止运行时错误,请用外部自环转移替换状态动作。
在状态中添加一个历史结点,以使 Stateflow 图在每次自环转移之前记住状态设置。
5.5 在 MATLAB 的独立图中,不要在具有多个源的转移路径中使用时序逻辑
MATLAB 的独立图不支持在具有多个源状态的转移路径中使用时序逻辑运算符。例如,以下独立图会产生运行时错误,因为时序逻辑表达式 after(10,sec) 会触发具有多个源状态的转移路径。
要解决此问题,请改为对单独的转移路径(每个转移路径都有单一源状态)使用时序逻辑表达式。
5.6 避免在 MATLAB 的独立图的转移路径中混合使用绝对时间时序逻辑和条件逻辑
在 MATLAB 的独立图中,运算符 after、at 和 every 都会创建 MATLAB timer 对象,这种对象可生成隐式事件来唤醒图。将这些运算符与同一个转移路径中的条件结合使用会导致意外行为:
- 如果当 timer 唤醒图时转移路径上的条件为 false,则图执行激活状态的 during 和 on 动作。
- 图不会重置与运算符 after 和 at 关联的 timer 对象。即使转移路径上的条件随后变为 true,如果没有另一个显式或隐式事件来唤醒图,转移也不会发生。
例如,在下图中,从状态 A 到状态 B 的转移路径上同时使用了绝对时间时序逻辑触发器 after(1,sec) 和条件 [guard]。从状态 A 到状态 C 的转移具有绝对时间时序逻辑触发器 after(5,sec)。每个转移都与一个生成隐式事件的 timer 对象相关联。最初,局部变量 guard 为 false。
当您执行图时,状态 A 被激活。图执行 entry 动作,并显示消息 ‘Hello!’。在 1 秒后,与从 A 到 B 的转移相关联的 timer 唤醒图。由于转移无效,图在 A 状态下执行 during 动作,并再次显示消息 ‘Hello!’。
假设在 2 秒后,图接收到输入事件 E。图在 A 状态下执行 on 动作,并将 guard 的值更改为 true。由于图不会重置与运算符 after 相关联的 timer,因而在另一个事件唤醒图之前,不会发生从 A 到 B 的转移。
在 5 秒后,与从 A 到 C 的转移相关联的 timer 唤醒图。由于从 A 到 B 的转移有效并且具有更高的执行顺序,因而图不会发生到状态 C 的转移,也不会显示消息 ‘Farewell!’。取而代之的是,状态 B 被激活,图显示消息 ‘Good bye!’。
5.7 使用带离散采样时间的 Stateflow 图实现更加高效的代码生成
若离散图不在触发子系统或使能子系统内,则生成代码时使用整数计数器来跟踪时间,而不是使用 Simulink 提供的时间。从管理开销和内存方面来看,此行为可以实现更加高效的代码生成,且可以让此代码用在软件在环 (SIL) 和处理器在环 (PIL) 两种仿真模式中。有关详细信息,请参阅SIL 和 PIL 仿真 (Embedded Coder)。