3. 场景分类体系:功能场景、逻辑场景、具体场景的层级关系与转化

场景分类这件事,说白了就是给自动驾驶的测试对象「建个档」。你想想看,路上跑的工况千千万,如果不分个层级,测试根本没法落地。我个人习惯把场景分成三层:功能场景、逻辑场景、具体场景。这三层不是并列关系,而是从抽象到具体的逐级细化。

3.1 三层场景的定义与定位

先给个直观的定义。我做过好几个项目的经验告诉我,这三层对应的是「需求→参数→实例」的转化过程。

层级 核心特征 表达方式 典型用途
功能场景 语义级描述,不含具体数值 自然语言 + 场景图 需求分析、功能定义
逻辑场景 参数空间 + 取值范围 参数表 + 约束条件 测试用例生成、参数探索
具体场景 参数取具体值,可仿真执行 OSI/OpenSCENARIO 仿真测试、实车验证

关键认知:功能场景是「做什么」,逻辑场景是「在什么范围内做」,具体场景是「怎么做」。三者缺一不可。

3.2 功能场景:从需求出发的语义层

功能场景是最上层的抽象。它用自然语言描述一个交通场景的「本质」。比如:「自车在高速公路上行驶,前方有一辆慢车切入本车道,自车需要减速避让。」

这里没有具体速度、没有距离、没有切入角度。为什么?因为功能场景是用来对齐需求的。我记得有一次,功能安全团队和系统团队因为「切入场景」的定义吵了一周——一个说「切入就是变道」,另一个说「切入必须压线」。后来我们统一用功能场景的语义模板才解决。

功能场景的构成要素,我一般用「5W1H」来拆解:

  • Who:自车、目标车、行人、障碍物
  • Where:道路类型、车道位置、路口结构
  • When:白天/夜晚、天气、光照条件
  • What:主行为(跟车、换道、制动)
  • Why:触发原因(前车减速、行人横穿)
  • How:交互方式(博弈、礼让、强制)

我的习惯:功能场景一定要写「场景标题」+「一句话描述」+「场景图草图」。别偷懒,这一步省了,后面逻辑场景的参数范围会漏掉。

3.3 逻辑场景:参数空间的量化

逻辑场景是功能场景的「参数化版本」。它把语义描述中的每个要素,都变成一个参数变量,并给出取值范围。

举个例子,刚才的「慢车切入」功能场景,到了逻辑场景层就变成:

场景:高速慢车切入
参数:
  - 自车速度:80 ~ 120 km/h
  - 目标车速度:60 ~ 90 km/h
  - 切入角度:5° ~ 30°
  - 切入距离(纵向):20 ~ 80 m
  - 路面摩擦系数:0.4 ~ 0.9
  - 光照强度:0 ~ 100000 lux

这里要注意,逻辑场景的参数范围不是随便写的。我曾经在一个项目中,把切入角度设到了45°,结果仿真里目标车直接横着飘过来——物理上根本不可能。后来我们加了「车辆动力学约束」作为参数范围的边界条件。

逻辑场景的价值在于:它定义了「测试空间」。你想想看,如果每个参数取10个值,6个参数就是10^6 = 100万个组合。逻辑场景帮你划出「有意义」的边界。

避坑指南:逻辑场景的参数范围一定要考虑「物理可行性」和「功能触发条件」。我曾经见过一个团队把自车速度范围设到0~200 km/h,结果生成了大量无效场景——自车静止时根本不会触发切入场景。参数范围要基于ODD(运行设计域)来裁剪。

3.4 具体场景:可执行的测试实例

具体场景是逻辑场景中每个参数取一个具体值后的结果。它是「可执行的」——可以直接丢给仿真软件或实车运行。

比如从上面的逻辑场景中,我们可以生成这样一个具体场景:

具体场景实例 #001:
  - 自车速度:100 km/h
  - 目标车速度:70 km/h
  - 切入角度:15°
  - 切入距离:50 m
  - 路面摩擦系数:0.8
  - 光照强度:50000 lux(白天)
  - 天气:晴朗

具体场景的生成方式有两种:

  1. 组合覆盖法:用正交表或组合测试工具,从逻辑场景的参数空间中采样
  2. 边界值法:取每个参数的边界值(最小值、最大值、临界值)
  3. 随机采样法:在参数空间内随机撒点,适合大规模测试
  4. 场景变异法:基于已知危险场景,微调参数生成变体

我个人更推荐「组合覆盖 + 边界值」的混合策略。为什么?因为纯随机采样容易漏掉边界上的危险点,而纯组合覆盖又可能生成太多冗余场景。

3.5 三层转化:从抽象到具体的映射

这三层不是孤立的,它们之间有明确的转化关系。我画了一张图来说明这个转化过程:

场景三层转化关系图 功能场景 语义级描述 · 自然语言 · 场景图 参数化 逻辑场景 参数变量 + 取值范围 + 约束条件 例:自车速度 [80,120] km/h 实例化 具体场景 参数取具体值 · 可执行 · 仿真/实车 例:自车速度=100 km/h, 目标车速度=70 km/h 转化方法 参数化 正交表 边界值 随机采样 场景变异 组合覆盖 ⚠ 转化过程中必须保持「场景语义一致性」 即:具体场景不能违背功能场景的原始意图

转化过程中有一个容易踩的坑:语义一致性。什么意思?就是具体场景不能违背功能场景的原始意图。比如功能场景是「慢车切入」,结果你生成的具体场景里目标车速度比自车还快——这就不是「慢车」了,变成了「快车超车」。语义变了,测试结论就废了。

3.6 层级间的验证闭环

这三层之间还有一个验证闭环,我习惯叫它「V&V 三角」:

  • 正向验证:功能场景 → 逻辑场景 → 具体场景,确保参数化正确
  • 反向追溯:具体场景 → 逻辑场景 → 功能场景,确保每个测试实例都能追溯到原始需求
  • 覆盖度检查:逻辑场景的参数空间是否覆盖了功能场景的所有语义分支

实战经验:我在做某个L3级高速公路领航项目时,发现功能场景写了「雨天」,但逻辑场景里只设了「降雨强度」一个参数,漏掉了「路面水膜厚度」和「雨刮器状态」。结果仿真测试全过了,实车一跑就出问题——雨刮器没开,摄像头被雨水遮挡。这就是层级转化时「语义丢失」的典型例子。

3.7 工具链与数据格式

实际工程中,这三层场景需要对应不同的数据格式和工具:

层级 推荐格式 常用工具 存储方式
功能场景 PEGASUS 6层模型 / 场景模板 Excel / Confluence / Doors 文档 + 图片
逻辑场景 参数表(CSV/YAML) Python / MATLAB / 自研工具 数据库 / 配置文件
具体场景 OpenSCENARIO / OSI VTD / CarMaker / dSPACE XML / 二进制文件

我个人建议,团队里一定要有一个「场景管理平台」。别用Excel管几千个场景——我见过有人把场景参数写在Excel里,结果版本一乱,测试结果全对不上。用数据库或者专门的场景管理工具,能省很多麻烦。

小技巧:逻辑场景的参数表里,建议加一列「参数来源」。标注这个参数是来自ODD、功能需求、还是经验值。这样后期排查问题时,能快速定位是哪个环节的参数设错了。

3.8 本章小结

功能场景、逻辑场景、具体场景,这三层构成了SOTIF场景分析的骨架。功能场景管「对不对」,逻辑场景管「全不全」,具体场景管「能不能跑」。三层之间的转化,核心是「参数化」和「实例化」,但别忘了保持语义一致性。

嗯,这里再强调一句:别把这三层当成瀑布流——做完功能场景再做逻辑场景。实际项目中,这三层是迭代的。你从具体场景里发现了一个危险点,可能要回溯到逻辑场景去扩参数范围,甚至修改功能场景的定义。闭环思维,比线性思维更重要。