使用逻辑和时序评估测试交通信号灯控制
此示例显示如何使用逻辑和时序评估来测试双灯交通路口的信号逻辑。它还展示了如何最大限度地减少未经测试的结果。
本例中使用的模型代表双灯交通路口的控制器。交通灯状态之间的变化取决于交通灯和 Stateflow® 图中定义的时间延迟参数。有关模型中使用的 Stateflow 逻辑的更多信息,请参阅 使用激活状态数据监视图的活动 (Stateflow)。
打开并运行模型
打开并仿真模型。
model = 'sltestTrafficLight';
open_system(model)
sim(model)
在仿真数据检查器中绘制两个灯的状态。
runData = Simulink.sdi.Run.getLatest; LightState1 = getSignalsByName(runData,'Light1'); LightState2 = getSignalsByName(runData,'Light2'); Simulink.sdi.setSubPlotLayout(2,1); plotOnSubPlot(LightState1,1,1,true); plotOnSubPlot(LightState2,1,1,false); plotOnSubPlot(LightState2,2,1,true); plotOnSubPlot(LightState1,2,1,false); Simulink.sdi.view
交通信号灯的时间表大致相反。当一盏灯处于 Green
状态时,另一盏灯处于 Red
状态,反之亦然。此外,灯光从 Green
转移到 Red
时必须经过 Yellow
状态。
要探索 Stateflow 逻辑,请考虑:
在两个原子子图之一中添加一个断点来逐步执行逻辑。有关调试状态图的更多信息,请参阅 Set Breakpoints to Debug Charts (Stateflow)。
使用序列查看器检查逻辑。
使用仿真数据检查器可视化不同的信号。
模型的需求和枚举类型
为了测试交通控制器的逻辑,Stateflow 图输出与灯光的 Red
、Yellow
或 Green
状态相对应的枚举类型。默认情况下,Stateflow 会自动生成枚举类型定义。要创建自定义枚举定义,请参阅 Define State Activity Enumeration Type (Stateflow)。
仿真模型创建内置的枚举定义。要确认枚举类型定义 LightModeType
存在,请使用 which
LightModeType
。
设计需求
本示例中的测试文件根据多项需求测试交通灯模型::
在红灯处等待的汽车数量总是大于或等于零。
在任何时间点,至少有一盏灯是红色的。
每次灯变成黄色时,它会在 0.5 秒的容差差值内保持黄色一段时间,然后变为红色。
每次灯变绿时,它会在最短时间和最长时间之间(容差为 0.5 秒)保持绿色,然后才变为黄色。
测试文件使用边界检查评估、自定义评估和两个触发响应 评估来测试需求。有关链接到需求的更多信息,请参阅 将时序评估与需求联系起来。
运行逻辑和时序评估
加载测试文件并在测试管理器中打开测试评估。
sltest.testmanager.load('test_traffic.mldatx');
sltest.testmanager.view;
运行边界检查测试
使用边界检查逻辑评估来检查在红灯处等待的汽车数量是否始终大于或等于零。符号 NumCars
被映射到 Car_Monitor1
子系统的输出。Car_Monitor1
子系统输出 int32
类型,因此下限 表达式被转换为 int32(0)
。有关数据类型需求的更多信息,请参阅 评估条件中的数据类型。
在测试管理器中,点击测试浏览器窗格中的
New Test Case 1
。展开测试管理器的逻辑和时序评估部分
在表中选择等待车辆,并验证其评估逻辑是否正确。
在可视化表示窗格的右上角,点击探索模式图标以打开模式资源管理器。
查看通过和失败的示例。这张图显示了一个示例:
6.选择等待汽车评估后,运行 测试用例。
7.要查看结果,请展开结果和工件面板中的结果。
8.选择新测试用例 1 > 逻辑和时序评估> 等待汽车。
运行自定义逻辑评估
使用自定义逻辑评估比较所有时间步中两个灯的状态。
出于安全原因,任何时候都不应同时有两盏灯是绿灯。此外,其他配置也是不理想的,例如一盏绿灯和一盏黄灯或者两盏黄灯。评估确保其中一个灯始终为红色。
在逻辑和时序评估部分中,此评估使用符号 Red
和 Yellow
,它们分别对应于枚举类型定义中的各自颜色。例如,Red
符号的 Expression
字段引用 LightModeType
枚举的 Red
枚举成员 - LightModeType.Red
。Green
符号显示为未使用的符号,因为直到实施绿色到黄色评估时才会使用它。请参阅 创建触发响应评估以评估绿色到黄色的转变。
请注意,视觉表现预览是空白的,因为它仅适用于边界检查和触发响应评估。此外,自定义检查的自定义表达式字段必须遵循 逻辑和时序评估条件 中描述的语法规则。
返回测试浏览器窗格并展开逻辑和时序评估部分。
选择两个灯的安全检查。
重新运行测试用例。
要查看结果,请展开结果和工件窗格中的结果,然后选择新测试用例 1 > 逻辑时序评估> 两个灯安全检查。
运行触发响应逻辑评估
使用触发响应逻辑评估来评估 Light1
从 Yellow
状态转移为 Red
状态时的逻辑。当 Light1
进入 Yellow
状态时,评估就会触发。如 Stateflow 图所示,对于每个原子子图中的 after(YELLOWDELAY,sec)
转移,状态在 YELLOWDELAY
秒的固定延迟后从 Yellow
切换到 Red
。为了满足需求,YELLOWDELAY
值通过容差差值 tol
进行调整,以便在评估回调中评估。
在逻辑和时序评估下,启用 Light1 YellowToRed 转移评估。
验证其评估逻辑摘要。
展开摘要和触发器部分并将 time-reference 设置为
rising edge of trigger
。运行测试用例。
在结果和工件窗格中,点击新测试用例 1 > 逻辑和时序评估> Light1 YellowToRed 转移。
观测到评估失败。
预期行为 和实际结果图表显示评估失败,解释部分描述了失败。故障发生在评估触发的四个点上。在错误 1/4 中,触发条件在 t = 132.1
时变为 true,而解释部分解释说,测试预期响应条件在 132.1 秒时为 true。这个结果与灯光在变为红色之前保持黄色一定时间的需求相矛盾。评估失败,因为响应的评估是在触发器的上升沿进行的。在触发器为 false 之前,不应评估 Light1 == Red
响应。
在测试浏览器窗格中,将时间参考调整为 falling edge of trigger
。此设置确保仅当 Light1
不再为黄色时才评估 Light1 == Red
响应。
重新运行测试用例。现在,评估在仿真的四个点处通过,其中 Light1
变为黄色。此外,在 t = 984.5
处有一个标记点,该点对应于评估不再可评估的点。该逻辑规定触发条件必须在最多 YellowDelayWithTol
秒(即 15.5 秒)内保持为 true。在 t
= 984.5
之后,仿真中没有足够的时间来准确评估逻辑。
您可能会注意到,基于提供给触发器的计时参数的其他评估也有类似的行为。
您可以重新评估以尽量减少未经测试的结果。
在当前结果中单击新建测试用例 1。
在左下角的属性-值窗格底部,启用扩展评估结果。评估被重新评估并且结果被更新。
现在图表显示没有未经测试的结果。
创建触发响应评估来评估绿色到黄色的转变
此次评估评估了仿真前半部分中从 Green
到 Yellow
的 Light1
转变。当灯光从 Red
变为 Green
时,评估就会触发。如 使用激活状态数据监视图的活动 (Stateflow) 的交通信号灯时序部分所述,从 Green
到 Yellow
的转移发生在基于 greenLightRequested
参数的固定时间窗口内。要设置参数并使用内置符号 t
将评估限制在仿真的前半部分,请创建评估回调。
设置参数
在测试管理器中,展开逻辑和时序评估部分。
点击添加评估并选择触发响应。
点击名称字段。将评估重命名为
Light1 GreenToYellow
。设置触发条件。点击触发器字段旁边的下拉菜单并选择
becomes true and stays true for between
。这种逻辑是必需的,因为灯在变为黄色之前必须保持绿色。选择触发器类型后,条件、最小时间(秒)、最大时间(秒)和时间参考字段将变为可见。对于条件,输入
t<500 & Light1 == Green
。评估使用内置符号t
,当仿真的前 500 秒内Light1
变为Green
时触发检查。对于最短时间(秒),输入
GreenMin
。对于最大时间(秒),输入
GreenMax
。请注意,GreenMin
和GreenMax
尚未定义,并在符号窗格中显示为未解析的符号。将
falling edge of trigger
,这确保仅当 Light1 不再为绿色时才评估Light1
变为黄色时的响应。将延迟保留为
with no delay
。将响应设置为
must be true
。此选项评估单个时间实例并捕获是否发生到Yellow
的转移。选择响应类型后,条件字段变为可见。对于条件,输入
Light1 == Yellow
。通过将此评估回调代码添加到评估回调中的现有代码中,解析
GreenMin
和GreenMax
符号。回调提取与Green
转移相对应的 Stateflow 参数,然后根据需求中指定的容差差值进行调整,为min-time
和max-time
触发字段做好准备。
greenMin = maskObj.getParameter('MINGREENDELAY'); greenMin = str2double(greenMin.Value); greenMinAdj = greenMin - tol; greenMax = maskObj.getParameter('GREENDELAY'); greenMax = str2double(greenMax.Value); greenMaxAdj = greenMax + tol;
13.在符号中,右键单击符号名称 GreenMin
并选择 Map to expression
。
14.在表达式字段中,输入变量名称 greenMinAdj
。
15.通过重复步骤 13 和 14 并使用 greenMaxAdj
作为表达式来解析符号 GreenMax
。
查看 Light1 GreenToYellow 逻辑
折叠评估以阅读其逻辑摘要:
您可以使用可视化表示来预览评估的逻辑。Light1
变绿后,必须在最小时间和最大时间内保持绿色一段时间。当 Light1
触发器为 false 且灯不再为绿色时,Light1
触发器为 true 且灯变为黄色。
运行评估并查看结果
运行评估。
在结果和工件窗格中,展开新测试用例 1 > 逻辑和时序评估。选择 Light1 GreenToYellow 并观测评估在仿真的前半部分触发两次。当 Light1
在 t = 12.1
和 t = 282.2
进入 Green
状态时,触发时间与初始仿真数据检查器结果一致。