1. 项目概述:为什么在 CARLA 里“动地图”比“调车辆”更难也更重要
你刚打开 CARLA,跑通了第一个自动驾驶 demo,车辆能绕圈、能避障、能按导航走——但很快就会发现:它对红绿灯的反应像蒙着眼过马路,对禁停标志视而不见,对左转专用道毫无概念。不是代码写错了,是地图本身没“说清楚”。CARLA 默认提供的 Town01–Town10 地图,本质上是一套 静态几何模型 + 基础语义标签 ,它告诉你“这里有一根杆子”,但不告诉你“这根杆子顶部挂的是红绿灯,控制方向为东向西,周期 90 秒,当前相位为红灯”。而真实自动驾驶系统依赖的,从来不是“有没有一根杆子”,而是“这根杆子此刻在表达什么交通规则”。
这就是“自定义地图:红绿灯和标志”这个标题背后的真实战场——它不是教你怎么改贴图或挪个路牌位置,而是带你深入 CARLA 的底层数据流:从 OpenDRIVE 路网定义、OpenSCENARIO 信号逻辑、到 CARLA Python API 中 carla.TrafficLight 和 carla.TrafficSign 的实例化机制,再到如何让这些静态对象真正参与仿真时序、响应车辆传感器、触发控制逻辑。我带团队做过 7 个不同城市路口的高保真重建项目,其中 5 个卡点都出在地图层:比如某次复现深圳福田口岸早高峰,车辆总在黄灯变红瞬间急刹,查了三天才发现 OpenDRIVE 文件里该路口的 traffic_light_controller 缺少 phase duration 定义,CARLA 默认用 3 秒硬编码覆盖,而实际是 4.2 秒——差那 1.2 秒,就导致整个决策链错位。
这个内容适合三类人:第一类是正在用 CARLA 做端到端感知训练的同学,你需要让模型看到“红灯亮起”时,背后是真实的信号状态变化,而不是靠图像分类强行打标签;第二类是做行为预测或规划模块验证的工程师,你得确保仿真中“前车因红灯停车”是物理引擎驱动的结果,而非脚本硬塞的 pose;第三类是高校研究者,当你论文要对比“不同信号配时方案对通行效率影响”时,地图就是你的实验台,改一个参数就得重跑 200 次仿真,没这套自定义能力,连 baseline 都搭不稳。
核心关键词“红绿灯”“标志”“CARLA 模拟器”“中文文档”已经划出边界:我们不碰 ROS 桥接、不讲 Unreal Engine 材质编辑、不涉及真实硬件在环(HIL),所有操作均基于 CARLA 0.9.14+ 官方 Python API 和标准 OpenDRIVE 1.6 规范。接下来的内容,是我把三年来踩过的坑、压测过的参数、验证过的最小可行路径,全部摊开给你看。
2. 地图设计底层逻辑:CARLA 如何把“一根杆子”变成“可交互的交通实体”
2.1 CARLA 地图的三层结构:几何层、语义层、行为层
CARLA 地图不是一张 PNG 图,而是一个分层加载的运行时对象体系。理解这三层,是动手修改的前提:
-
几何层(Geometry Layer) :由
.xodr(OpenDRIVE)文件定义,描述道路中心线、车道线、路沿、坡度、曲率等纯空间信息。它决定“车轮压在哪条线上”,但不决定“这条线能不能压”。例如,<road>标签下<lanes>中的<lane>元素通过type="driving"或type="stopping"区分功能,但 CARLA 默认只读type="driving",stopping类型车道不会被导航系统识别——除非你手动在 Python 中调用world.get_map().get_waypoint()并强制指定 lane type。 -
语义层(Semantic Layer) :由
.t7(Torch7 格式,CARLA 自研)语义分割标签文件提供,将每个像素映射到 13 个预设类别(如TrafficLight、TrafficSign、RoadMark)。这是视觉感知模块的输入源,但它只是“快照”——告诉模型“此刻画面里有红绿灯”,却不告诉模型“这个红绿灯属于哪个路口、受谁控制、下一秒变什么色”。 -
行为层(Behavior Layer) :这才是红绿灯和标志“活起来”的关键。它由两部分构成:
- OpenSCENARIO 信号控制器 :在
.xodr文件中通过<controller>和<trafficSignalController>定义信号组、相位、持续时间、依赖关系。CARLA 启动时解析此部分,生成carla.TrafficLight实例并注入世界。 - Python API 动态绑定 :通过
world.get_actors()获取TrafficLight对象后,调用set_state()、set_red_time()等方法实时干预。注意: 只有 OpenSCENARIO 定义过的信号,才能被 Python API 控制;未定义的“装饰性红绿灯”(如建筑外立面贴图)永远是静态模型 。
- OpenSCENARIO 信号控制器 :在
提示:很多新手以为改
.png贴图就能改红绿灯状态,这是根本性误解。CARLA 的红绿灯状态切换是 CPU 侧的逻辑计算(基于 OpenSCENARIO 时间轴),不是 GPU 侧的纹理替换。你看到的“灯变色”,是渲染器根据TrafficLight.state属性实时选择对应材质球的结果。
2.2 红绿灯的三种存在形态:哪一种你真能控制?
在 CARLA 地图中,“红绿灯”这个词对应三个完全不同的技术实体,混淆它们会导致 90% 的调试失败:
| 类型 | 数据来源 | 可控性 | 典型问题 |
|---|---|---|---|
| 装饰性红绿灯(Deco Traffic Light) | .fbx 模型文件直接导入,无 OpenSCENARIO 定义 |
❌ 完全不可控 | 在 Town05 中大量存在,仅作为背景元素, world.get_actors() 查不到, set_state() 报错 |
| 基础信号灯(Basic Traffic Light) | .xodr 中 <object> 标签定义,含 name="traffic_light" ,但无 <controller> 关联 |
⚠️ 仅支持 set_state() 强制设色,无时序逻辑 |
车辆不会自动响应,需在 Python 中写循环检测 state 并触发刹车,违背真实交通流建模原则 |
| 智能信号控制器(Smart Controller) | .xodr 中完整 <controller> + <trafficSignalController> + <phase> 定义 |
✅ 全功能可控:时序、相位、依赖、事件触发 | 配置错误导致 carla.World.tick() 卡死,或相位跳变异常(如红→绿→黄→红缺失) |
我实测过 Town03 的一个路口:官方标注为“支持信号控制”,但打开 .xodr 文件发现其 <controller> 下只有两个 <pha


406

被折叠的 条评论
为什么被折叠?



