2. SOTIF基础
做SOTIF场景库,最头疼的问题是什么?我个人的经验是——场景太多、太杂,不知道怎么管。
你想想看,一个十字路口,晴天是一种场景,雨天是另一种,晚上再来个远光灯对向车,组合就爆炸了。如果每个场景都当独立个体去采集、标注、存储,那场景库很快就会变成一团乱麻。
所以,我们需要一套分类体系。把场景按抽象程度分层,每一层干每一层的事。这样,场景才能复用,迭代才有抓手。
四层场景模型:从抽象到具体
业内公认的分层方式,是PEGASUS项目提出的四层模型。我直接说人话:
- 功能场景——用自然语言描述的场景。比如“车辆在城市道路直行,前方有静止障碍物”。
- 抽象场景——把功能场景里的要素提取出来,变成带标签的参数列表。比如“道路类型=城市道路,主车动作=直行,目标物=静止车辆”。
- 逻辑场景——给参数加上取值范围和分布。比如“主车速度∈[0, 60] km/h,目标物距离∈[10, 100] m”。
- 具体场景——从逻辑场景里采样出一组具体的参数值。比如“主车速度=40 km/h,目标物距离=30 m”。
说白了,就是从“讲个故事”到“定个参数”再到“跑个用例”的逐步细化过程。
核心观点:场景库的复用能力,取决于你在哪一层做抽象。抽象得越好,复用的面就越宽。
功能场景:起点是“讲故事”
功能场景是场景库的入口。它不需要精确的参数,只需要把“发生了什么”说清楚。
举个例子:
场景:主车在城市双向两车道直行,前方约50米处有一辆静止的故障车辆,
占用部分车道。对向有来车。天气晴朗,白天。
这个描述,工程师看得懂,测试经理看得懂,甚至产品经理也能参与讨论。这就是功能场景的价值——它是跨团队沟通的通用语言。
我的习惯:功能场景用模板写。固定结构是“道路环境 + 主车状态 + 目标物状态 + 环境条件”。这样写出来的场景,转成抽象场景时不会漏要素。
抽象场景:把故事变成标签
功能场景写好了,下一步就是把它结构化。抽象场景的核心工作,是“要素提取”。
还是上面那个例子,提取出来就是:
| 要素类别 | 标签 |
|---|---|
| 道路类型 | 城市双向两车道 |
| 主车动作 | 直行 |
| 目标物类型 | 静止车辆 |
| 目标物位置 | 前方,部分占用本车道 |
| 对向交通 | 有来车 |
| 天气 | 晴天 |
| 光照 | 白天 |
抽象场景的好处是什么?它让场景变得可检索、可分类、可组合。你可以在场景库里搜“目标物类型=静止车辆”,一下子拉出所有相关场景。
我曾经踩过的坑:一开始做抽象场景时,我把标签定义得太细。比如“目标物位置”分了“正前方10米、正前方20米、正前方30米……”结果标签数量爆炸,根本管不过来。后来我改成“前方近距离、前方中距离、前方远距离”这种区间标签,复用性一下子提高了。
逻辑场景:给参数加上边界
抽象场景只有标签,没有数值。逻辑场景要干的事,就是给每个参数定义取值范围和分布。
比如:
- 主车速度:
[0, 60] km/h,均匀分布 - 目标物距离:
[10, 80] m,重点在[10, 30] m区间加密采样 - 对向车速度:
[30, 60] km/h - 车道宽度:
[3.0, 3.75] m
逻辑场景是测试设计的核心。它定义了“我们要测哪些情况”,而不是“具体测哪一组值”。
我个人习惯把逻辑场景分成两类:
- 边界逻辑场景——参数取极端值,比如速度上限、距离下限。用来找系统在边界处的行为。
- 覆盖逻辑场景——参数在范围内均匀或按分布采样。用来评估系统在典型工况下的表现。
具体场景:跑起来的那一下
具体场景就是从逻辑场景的参数空间里,取出一组具体的值。它可以直接喂给仿真器,或者写成路测脚本。
举个例子:
具体场景实例:
- 主车速度: 45 km/h
- 目标物距离: 28 m
- 对向车速度: 50 km/h
- 车道宽度: 3.5 m
- 天气: 晴天
- 光照: 白天
一个逻辑场景,可以生成成千上万个具体场景。这就是“场景复用”的真正含义——你不需要为每个测试用例单独写场景描述,只需要在逻辑层定义好参数空间,然后批量采样。
关键认知:场景库的迭代,主要在逻辑场景层进行。功能场景和抽象场景相对稳定,具体场景是消耗品——跑完就扔,但逻辑场景要持续维护和优化。
层级间的转换方法
四层模型不是摆设,它们之间的转换有固定的方法。我总结了三步走:
| 转换步骤 | 输入 | 输出 | 关键动作 |
|---|---|---|---|
| 功能 → 抽象 | 自然语言场景描述 | 结构化标签列表 | 要素提取、本体映射 |
| 抽象 → 逻辑 | 标签列表 | 参数空间定义 | 参数化、取值范围设定、分布定义 |
| 逻辑 → 具体 | 参数空间 | 具体参数值组合 | 采样策略(随机/边界/正交/组合) |
这里有个细节要注意:从抽象到逻辑的转换,是最容易出问题的环节。为什么?因为取值范围定得太宽,测试成本高;定得太窄,又可能漏掉危险场景。
我的建议:取值范围先参考行业标准(比如ISO 21448里提到的典型工况),再结合你们自己采集的真实路测数据去校准。别拍脑袋定范围,我见过太多团队因为范围定得离谱,导致场景库里的用例要么跑不出问题,要么根本跑不通。
场景库的复用逻辑
讲完层级关系,我想聊聊复用。很多人以为场景复用就是“把同一个场景文件复制粘贴到不同项目里”。其实不是。
真正的复用,发生在抽象层和逻辑层:
- 抽象场景复用:同一个“前方静止车辆”的抽象场景,可以复用到城市道路、高速公路、乡村道路等多个功能场景里。只需要改一下道路类型的标签值。
- 逻辑场景复用:同一个逻辑场景,可以通过不同的采样策略,生成适用于仿真测试、HIL测试、路测的不同具体场景集。
- 具体场景不直接复用:具体场景是绑定到特定测试环境的。换了传感器配置、换了算法版本,原来的具体场景可能就不适用了。但它的“父级”逻辑场景可以继续用。
嗯,这一点想明白了,场景库的架构就不会走偏。
避坑指南:不要试图把所有具体场景都存下来。我见过一个团队,跑了10万次仿真,存了10万个具体场景文件。结果想查一个特定工况时,根本找不到。正确的做法是:存逻辑场景 + 采样种子,具体场景随用随生成。
好了,场景分类体系这部分就讲到这里。四层模型是场景库的骨架,理解清楚每一层的定位和转换方法,后面的复用和迭代才有基础。下一层,我们会聊场景库的构建流程——怎么从零开始搭一个能用的场景库。