3. ScenarioRunner概述

在CARLA自动驾驶仿真生态中,ScenarioRunner是一个承上启下的关键组件。它并不负责渲染三维世界,也不直接控制车辆动力学,而是把"场景描述"翻译成"可执行的仿真动作",并在仿真过程中持续判断场景是否成功、失败或超时。理解ScenarioRunner的定位,是后续编写自定义场景、搭建自动测试流水线的前提。

一、ScenarioRunner的定位

ScenarioRunner是CARLA官方提供的场景执行引擎,位于CARLA服务端与测试用例之间。它读取用Python定义的场景脚本,调用CARLA的Python API完成车辆生成、行为控制、传感器读取和事件判定,最终输出每个场景的通过/失败结果。可以把它理解为"仿真世界里的测试运行器":CARLA提供舞台和演员,ScenarioRunner负责导演剧本并记录演出是否达标。

它的核心价值在于把零散的API调用封装为可复用的场景抽象,使测试人员不必从零编写车辆控制逻辑,而只需关注"什么条件下发生什么、判定标准是什么"。

二、发展历史与与CARLA的关系

ScenarioRunner最初作为CARLA的配套工具随CARLA 0.8.x发布,早期仅支持少量预设场景。随着CARLA 0.9.x系列迭代,它逐步引入OpenSCENARIO解析、原子行为(Atomic Behavior)、行为树(Behavior Tree)和PythonAPI自定义场景等能力。CARLA 0.9.9之后,ScenarioRunner独立为单独仓库,版本号与CARLA主版本解耦,但仍保持紧密兼容。

两者的关系可以概括为:CARLA是仿真内核,ScenarioRunner是场景层。ScenarioRunner依赖CARLA的Python API,必须与CARLA服务端版本匹配;CARLA升级可能改变API签名,因此ScenarioRunner通常需要同步更新。下表对比了两者的职责边界。

维度CARLAScenarioRunner
核心职责三维渲染、物理仿真、传感器模拟场景编排、行为执行、结果判定
输入地图、车辆、传感器配置场景脚本、OpenSCENARIO文件
输出仿真世界状态、传感器数据场景通过/失败、日志、判据结果
接口C++/Python API、ROS bridgePython API、命令行入口
版本关系主版本决定API需与CARLA版本兼容

三、核心功能

ScenarioRunner的功能围绕"场景生命周期"展开,主要包括以下几类:

  • 场景加载与解析:支持Python自定义场景和OpenSCENARIO 1.x文件,将场景描述转换为内部行为树。
  • 参与者管理:按场景要求生成ego车辆、NPC车辆、行人、静态障碍物,并配置传感器。
  • 行为执行:提供原子行为如LaneChange、Accelerate、FollowLeadingVehicle、Turn等,可组合成复杂行为序列。
  • 触发与判定:通过Trigger条件(距离、时间、速度、碰撞)启动行为,通过Criterion(到达目标、无碰撞、超时)判定结果。
  • 结果输出:生成JSON/XML格式的测试报告,记录每个场景的判据状态和关键事件。

下面是一个典型的场景脚本片段,展示ego车辆在路口等待后左转的基本结构:

class LeftTurnAtJunction(AtomicBehavior):
    def __init__(self, ego_vehicle, junction, duration=10):
        super().__init__("LeftTurn", ego_vehicle, duration=duration)
        self._junction = junction

    def run(self):
        # 等待触发条件:ego进入路口范围
        while not self._junction.contains(self._ego.get_location()):
            self._ego.apply_control(carla.VehicleControl(brake=1.0))
            yield
        # 执行左转行为
        self._ego.apply_control(carla.VehicleControl(throttle=0.4, steer=-0.5))
        yield

四、典型应用场景

ScenarioRunner被广泛用于以下测试任务:

  1. 法规符合性测试:如Euro NCAP的AEB、LKA场景,验证车辆在标准工况下的表现。
  2. 边缘场景回归:把事故复现、cut-in、鬼探头等危险场景固化为脚本,每次代码更新后自动回归。
  3. 算法对比:同一场景下运行不同感知/规划算法,比较通过率和接管次数。
  4. 大规模参数扫描:通过修改场景参数(车速、距离、天气)批量生成测试用例。
提示:ScenarioRunner自带一批示例场景,位于 srunner/scenarios 目录,可直接运行体验,也是学习场景编写的最佳模板。

五、常见误区与复盘

初学者容易把ScenarioRunner当成"自动驾驶算法"或"仿真器本身",实际上它只是测试执行框架。另一个常见误区是忽略版本匹配:CARLA升级后未同步更新ScenarioRunner,常导致API调用失败或场景行为异常。建议在项目初期就固定CARLA与ScenarioRunner的版本组合,并纳入依赖管理。

注意:ScenarioRunner的判定结果依赖场景脚本中定义的Criterion,若判据设置过松,可能出现"假通过";设置过严则导致大量误报。判据设计应与测试目标严格对齐。

下图展示了ScenarioRunner在CARLA仿真栈中的位置及其与场景脚本、CARLA API、测试报告之间的数据流关系。

ScenarioRunner 在 CARLA 仿真栈中的位置与数据流 场景脚本 / OpenSCENARIO Python 场景类 .xosc 文件 ScenarioRunner 场景解析 · 行为树 · 触发判定 参与者管理 · 结果输出 (场景执行引擎) CARLA Server 渲染 · 物理 · 传感器 Python API 加载 API 调用 世界状态 / 传感器数据 测试报告 JSON / XML · 通过/失败 · 判据 输出结果 关键关系: ScenarioRunner 依赖 CARLA Python API 驱动仿真;场景脚本定义"做什么",CARLA 提供"在哪里做",测试报告回答"是否通过"。 版本匹配是稳定运行的前提:CARLA 升级 → API 变化 → ScenarioRunner 需同步更新。