2. 基础知识
在进入 OpenSCENARIO 的语法与工程实践之前,必须先建立一套清晰的“场景世界观”。动态场景开发不是简单地写几行 XML,而是要把真实交通世界中随时间变化的参与者、道路环境、触发条件和评价目标,抽象成可被仿真器、测试平台和验证工具共同理解的模型。OpenSCENARIO 正是这套模型的描述语言,它回答的是“谁在什么时间、什么位置、以什么方式运动”,而 OpenDRIVE 回答“道路长什么样”,OpenCRG 回答“路面微观起伏如何”。三者共同构成从静态道路到动态行为再到高精度路面反馈的完整链条。
一、动态场景的基本概念
动态场景(Dynamic Scenario)是指在某一初始状态下,交通参与者、环境要素和外部事件随时间演化的过程描述。与静态场景只描述道路、标线、路侧设施不同,动态场景的核心是“变化”:车辆加速、行人横穿、信号灯切换、前车急刹、天气突变等。一个完整的动态场景通常包含以下要素:
- 场景对象:车辆、行人、动物、障碍物、交通信号、路侧设备等。
- 初始状态:对象在仿真开始时刻的位置、速度、朝向、姿态和属性。
- 行为与动作:跟驰、变道、超车、停车、开门、横穿等。
- 触发条件:时间触发、距离触发、速度触发或事件触发。
- 环境条件:天气、光照、路面附着系数、时间等。
- 评价目标:碰撞、舒适性、通行效率、法规符合性等。
这些要素在 OpenSCENARIO 中被组织为 Storyboard 结构:Story 描述一个完整故事,Act 是故事中的阶段,ManeuverGroup 是同一组参与者的动作集合,Maneuver 是具体动作,Event 是触发动作的条件,Action 是实际执行的行为。理解这一层级,是后续编写场景文件的基础。
二、术语体系:从场景到测试用例
在工程实践中,场景相关术语经常被混用。为了避免沟通歧义,建议采用如下术语体系:
| 术语 | 含义 | 典型示例 |
|---|---|---|
| 场景(Scenario) | 对交通环境、参与者和事件的高层描述 | 前车紧急制动场景 |
| 场景实例(Scenario Instance) | 给定具体参数后的可执行场景 | 本车 60 km/h,前车 50 km/h,TTC=1.5 s |
| 测试用例(Test Case) | 场景实例加上通过/失败判据 | 是否发生碰撞、减速度是否超过 5 m/s² |
| 场景库(Scenario Library) | 按功能、风险或 ODD 分类的场景集合 | 城市路口场景库、高速切入场景库 |
| ODD | 运行设计域,描述系统可工作的条件范围 | 晴天、高速公路、车速 0~120 km/h |
此外,OpenSCENARIO 还定义了参数(Parameter)、变量(Variable)、实体(Entity)、参考(Reference)等概念。参数用于在场景实例化时注入具体数值,变量用于运行过程中动态计算,实体是场景中可被引用的对象,参考则用于绑定 OpenDRIVE 道路或 OpenCRG 路面。掌握这些术语,才能在团队协作中准确表达需求。
三、应用场景:动态场景用在哪里
动态场景的应用贯穿智能驾驶研发的多个阶段。在功能开发阶段,工程师用场景验证算法逻辑,例如自动紧急制动是否在合理 TTC 下触发;在仿真测试阶段,场景被批量注入 CarMaker、PreScan、CARLA、VTD 等平台,进行数百万公里的虚拟路测;在硬件在环阶段,场景通过实时接口驱动雷达、摄像头和域控制器;在实车测试阶段,场景被转化为测试规程,指导场地试验和道路试验;在法规认证阶段,场景用于证明系统满足 ISO 21448、ISO 26262 或 NCAP 要求。
四、与 OpenDRIVE 和 OpenCRG 的关系
OpenSCENARIO、OpenDRIVE 和 OpenCRG 被称为 ASAM 仿真三件套,它们分工明确又紧密耦合。OpenDRIVE 提供道路几何、车道拓扑、交通标志和信号灯布局,是动态场景的“舞台”;OpenSCENARIO 提供参与者行为、触发逻辑和故事板,是舞台上的“剧本”;OpenCRG 提供路面高程、坡度和纹理等微观信息,是舞台的“地面质感”。
在文件层面,OpenSCENARIO 通过 <RoadNetwork> 引用 OpenDRIVE 文件,通过 <Catalog> 或 <Reference> 引用 OpenCRG 文件。仿真器加载时,先解析 OpenDRIVE 建立道路网络,再叠加 OpenCRG 修正路面高度,最后按 OpenSCENARIO 的时间线驱动实体运动。如果缺少 OpenDRIVE,车辆没有车道可走;如果缺少 OpenCRG,车辆在坡道和路缘上的动力学反馈会失真;如果缺少 OpenSCENARIO,道路只是空壳,无法产生交互行为。
五、案例:一个完整的动态场景如何落地
以“高速公路前车紧急制动”为例,说明三件套如何协同。首先,用 OpenDRIVE 定义一条三车道高速公路,包含车道宽度、曲率、限速标志和应急车道。然后,用 OpenCRG 定义该路段的路面高程和横向坡度,使车辆在制动时产生真实的俯仰和侧倾。接着,用 OpenSCENARIO 编写场景:主车在左侧车道以 100 km/h 行驶,前车在正前方 80 m 处以 90 km/h 行驶;当主车与前车距离小于 50 m 时,前车以 6 m/s² 减速度制动;主车搭载的 AEB 算法需要在 TTC 小于 1.5 s 时触发制动。最后,仿真器加载三个文件,输出主车减速度、碰撞状态和 TTC 曲线,形成测试报告。
<OpenSCENARIO>
<RoadNetwork>
<LogicFile filepath="highway.xodr"/>
<SceneGraphFile filepath="highway.crg"/>
</RoadNetwork>
<Storyboard>
<Story name="AEB_Test">
<Act name="BrakePhase">
<ManeuverGroup>
<Actors><EntityRef entity="LeadCar"/></Actors>
<Maneuver name="EmergencyBrake">
<Event name="BrakeEvent">
<Action name="BrakeAction">
<LongitudinalAction>
<SpeedAction>
<SpeedActionDynamics dynamicsShape="linear" value="6.0"/>
</SpeedAction>
</LongitudinalAction>
</Action>
</Event>
</Maneuver>
</ManeuverGroup>
</Act>
</Story>
</Storyboard>
</OpenSCENARIO>
六、常见误区与复盘
误区一:把 OpenSCENARIO 当成道路描述文件。OpenSCENARIO 不定义道路几何,只引用 OpenDRIVE。如果场景中车辆“飘”在路外,通常是 OpenDRIVE 坐标系或车道参考线配置错误。
误区二:忽略 OpenCRG 的坐标匹配。OpenCRG 的高程数据必须与 OpenDRIVE 的 s/t 坐标系对齐,否则路面修正会错位,导致车辆异常颠簸或悬空。
误区三:场景参数写死。把速度、距离、TTC 阈值直接写进 XML,会导致场景无法批量实例化。正确做法是使用 ParameterDeclaration 和 ParameterAssignment,在外部注入参数。
误区四:触发条件过于单一。只用时间触发会忽略交通交互的真实性。建议组合使用 EntityTrigger、DistanceTrigger 和 SpeedTrigger,使场景更接近真实交通。