第2章:Carla基础架构与地图体系
好,咱们正式开始啃这块硬骨头。Carla这个仿真器,说白了就是个高度封装的游戏引擎套壳——但它套得漂亮。我刚开始接触的时候,也被它那一堆文件后缀搞懵过。.umd是什么?.fbx不是3D模型吗?怎么还有.json?别急,这一章我带你把这些东西捋清楚。
2.1 Carla核心架构解析
Carla的架构,我习惯把它分成三层来看:
- 底层引擎层:基于Unreal Engine 4,负责渲染、物理、碰撞检测。你看到的车、路、树、行人,都是UE4在背后撑着。
- 中间服务层:Carla Server,管理世界状态、传感器数据流、交通逻辑。它跑在UE4之上,但独立于渲染循环。
- 上层客户端层:Python API,你写脚本控制车辆、读取数据、设置场景。客户端和服务端通过RPC通信。
嗯,这里要注意:Carla Server和UE4进程是绑定的。你启动Carla时,其实是在启动一个UE4的Game Mode。我早期踩过一个坑——以为Server可以单独跑,结果发现没有UE4窗口,传感器数据根本出不来。
核心要点:Carla的地图加载,本质上是UE4加载一个Level(关卡)。这个Level里包含了静态网格体、光照、碰撞体,以及我们最关心的——路网数据。
2.2 地图文件结构:.umd, .fbx, .json
你打开Carla的Content目录,会发现每个地图都有三个关键文件。我一个个说。
2.2.1 .umd 文件
这是Carla自定义的地图数据包。说白了,它就是个UE4的Package,里面打包了所有静态网格体、材质、纹理。你没法直接编辑它——得用UE4编辑器打开。我个人习惯把.umd看作「地图的躯体」,它决定了你看到什么。
2.2.2 .fbx 文件
这个就有意思了。.fbx是三维交换格式,Carla用它来存储路网几何数据。包括道路中心线、车道边界、路口形状。为什么不用.umd存?因为.fbx可以被其他工具读取——比如Blender、Maya,方便你手动调整路网形状。
我在项目中遇到过一件事:客户给的高精地图是OpenDRIVE格式,但Carla不直接支持。我就把OpenDRIVE转成.fbx,再导入Carla。嗯,过程有点折腾,但可行。
2.2.3 .json 文件
这是地图的「灵魂」。.json里存的是语义信息:
- 车道数量、宽度、类型(直行、左转、右转)
- 交通标志的位置和类型
- 红绿灯的相位和关联车道
- 路口的连接关系
你想想看,.fbx只告诉你路长什么样,.json才告诉你这条路能不能走、怎么走。我调试自动驾驶规划算法时,90%的时间都在跟.json打交道。
我的小技巧:修改地图时,尽量只改.json。除非你要改变道路的物理形状,否则别碰.fbx。改.json的风险小得多,而且可以热加载——不用重启Carla。
2.3 坐标系统与坐标系转换
这是最容易让人头大的部分。Carla里至少有三套坐标,搞混了你的车会飞到天上去。我刚开始学的时候,就犯过这种低级错误。
2.3.1 UE4坐标(世界坐标)
Carla底层用的是UE4的坐标系:
- X轴:向前(车头方向)
- Y轴:向右
- Z轴:向上
单位是厘米。注意,是厘米!不是米。我见过有人把100当成1米用,结果车缩成了蚂蚁大小。
2.3.2 Carla世界坐标
Carla的Python API里,坐标单位是米。API内部会自动做厘米到米的转换。但底层UE4还是用厘米。所以你在Python里设置位置为(10, 0, 0),实际UE4里是(1000, 0, 0)。
避坑指南:我曾经在自定义传感器数据时,直接用了UE4的厘米值传给Python,结果定位全乱了。记住:Python API用米,UE4用厘米。写代码时最好加个注释提醒自己。
2.3.3 GPS坐标(经纬度)
Carla支持将世界坐标转换为GPS经纬度。它内部用了一个简单的墨卡托投影。转换公式大致如下:
# Carla内置转换示例
import carla
world = client.get_world()
location = carla.Location(x=100, y=50, z=0)
geo_location = world.get_map().transform_to_geolocation(location)
print(f"纬度: {geo_location.latitude}, 经度: {geo_location.longitude}")
但要注意:Carla的GPS转换是近似值。它假设地球是完美的球体,没有考虑椭球修正。如果你需要高精度GPS(比如厘米级),得自己用PROJ库做转换。
2.3.4 坐标系转换实战
我整理了一个常用转换表,你写代码时直接参考:
| 源坐标系 | 目标坐标系 | 转换方法 | 注意事项 |
|---|---|---|---|
| UE4 (cm) | Carla世界 (m) | 除以100 | Z轴方向一致 |
| Carla世界 (m) | GPS经纬度 | transform_to_geolocation() | 精度约1-5米 |
| GPS经纬度 | Carla世界 (m) | transform_from_geolocation() | 需要地图原点信息 |
| 车辆坐标系 | Carla世界 | 车辆变换矩阵 | 注意车辆朝向 |
核心经验:我建议你在项目里统一使用Carla世界坐标(米)作为中间格式。所有传感器数据、控制指令、地图查询,都先转成这个坐标系。这样能减少80%的坐标bug。
2.4 本章小结
嗯,这一章信息量不小。你记住三件事就行:
- 地图三件套:.umd管渲染、.fbx管几何、.json管语义。改地图优先改.json。
- 坐标三件套:UE4用厘米、Carla用米、GPS用度。转换时留个心眼。
- 架构三层:UE4底层、Carla服务层、Python客户端。出了问题先定位是哪一层。
下一章,我们开始动手——把一张真实的高精地图导入Carla。到时候你会用到今天讲的这些知识。准备好了吗?