第4章:CARLA入门——架构、安装与基本API调用
说实话,我第一次接触CARLA的时候,也被它的架构吓了一跳。一个自动驾驶仿真器,怎么搞得跟个分布式系统似的?后来做项目做多了才明白——这种设计,恰恰是它最聪明的地方。
今天我们就来拆解一下CARLA。我会从架构讲起,然后带你完成安装,最后写几行代码让车跑起来。嗯,跟着我来,保证不迷路。
4.1 CARLA架构:客户端与服务器模式
CARLA的核心架构,说白了就是服务器+客户端的模式。你想想看,一个仿真环境里,谁负责渲染画面、计算物理、管理交通?谁又负责控制车辆、采集数据、做决策?
CARLA把这两件事分开了:
- 服务器(Server):负责跑仿真世界。包括渲染、物理引擎、传感器模拟、交通管理。它就像一个游戏引擎,只管把世界跑起来。
- 客户端(Client):负责控制。通过API向服务器发指令,比如“给我生成一辆车”、“让这辆车加速”、“读取摄像头画面”。
这种分离有什么好处?我举个例子。我在做多车协同项目时,需要同时控制十几辆车。如果所有逻辑都塞在服务器里,代码会乱成一锅粥。但用客户端-服务器模式,我可以开多个客户端,每个客户端控制几辆车,互不干扰。
核心理解:服务器是“世界”,客户端是“玩家”。一个世界可以有很多玩家,但每个玩家只能通过API跟世界交互。
下面这张图,是我自己画的架构示意图,帮你理清关系:
你看,服务器在中间,多个客户端通过API跟它通信。每个客户端可以干不同的事——一个采集数据,一个控制交通,互不打架。
4.2 CARLA安装:两种方式,任你选择
安装CARLA,我个人推荐两种方式。你根据自己情况选:
方式一:从源码编译(推荐进阶用户)
这种方式最灵活,但耗时较长。我第一次编译的时候,等了将近两个小时。不过好处是你可以修改源码,甚至加自己的传感器模型。
# 克隆仓库
git clone https://github.com/carla-simulator/carla.git
cd carla
# 更新子模块
git submodule update --init --recursive
# 编译(Ubuntu系统)
make launch
注意:编译需要至少16GB内存,硬盘留出50GB空间。我曾经在8GB的笔记本上试过,编译到一半直接卡死。嗯,血的教训。
方式二:下载预编译包(推荐新手)
这是我最推荐新手的方式。去CARLA官网下载对应系统的压缩包,解压就能用。省心省力。
# 解压后,进入目录
cd CARLA_0.9.14
# 启动服务器
./CarlaUE4.sh
启动后你会看到一个窗口,里面是CARLA的默认小镇。如果窗口一闪而过,检查一下显卡驱动。我遇到过好几次这种问题,基本都是驱动版本不对。
4.3 基本API调用:让车动起来
服务器跑起来了,接下来我们用Python客户端跟它对话。先装依赖:
pip install carla
然后写个最简单的脚本:
import carla
import random
# 连接服务器
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
# 获取世界对象
world = client.get_world()
# 获取蓝图库(所有可生成的模型)
blueprint_library = world.get_blueprint_library()
# 选一辆车
vehicle_bp = blueprint_library.filter('model3')[0]
# 找个出生点
spawn_points = world.get_map().get_spawn_points()
spawn_point = random.choice(spawn_points)
# 生成车辆
vehicle = world.spawn_actor(vehicle_bp, spawn_point)
# 让车动起来
vehicle.apply_control(carla.VehicleControl(
throttle=0.5, # 油门
steer=0.0, # 方向盘
brake=0.0 # 刹车
))
print("车辆已生成,正在行驶...")
这段代码干了什么?
- 连接本地2000端口的CARLA服务器
- 从蓝图库里选了一辆特斯拉Model 3
- 在地图上随机找了个位置生成
- 给了个50%的油门,车就往前跑了
小技巧:如果你看不到车动,检查一下服务器窗口是不是被最小化了。CARLA默认是“无物理”模式?不,默认是有物理的。但如果你用了synchronous_mode,就需要手动推进仿真时间。这个我们后面会细讲。
4.4 客户端与服务器模式详解
刚才我们写了个最简单的客户端。但实际项目中,你可能会遇到几个关键问题:
4.4.1 同步模式 vs 异步模式
这是新手最容易踩的坑。我刚开始做的时候,也搞混过。
| 模式 | 说明 | 适用场景 |
|---|---|---|
| 异步模式(默认) | 服务器自己跑自己的,客户端只管发指令 | 简单测试、可视化演示 |
| 同步模式 | 客户端控制仿真步进,服务器等客户端指令才更新 | 强化学习、数据采集、需要精确时序的场景 |
同步模式的代码长这样:
# 设置为同步模式
settings = world.get_settings()
settings.synchronous_mode = True
world.apply_settings(settings)
# 每步手动推进
while True:
# 让服务器更新一帧
world.tick()
# 读取传感器数据
# 控制车辆
# ...
为什么要用同步模式?举个例子。你在采集训练数据时,需要保证每帧都采集到传感器数据。如果用异步模式,服务器可能在你还没读完数据时就更新了下一帧,导致数据错乱。同步模式就能保证“你一步,我一步”。
4.4.2 多客户端连接
CARLA支持多个客户端同时连接同一个服务器。每个客户端可以控制不同的角色。我在做V2X仿真时,就开了三个客户端:一个控制主车,一个控制路侧单元,一个控制其他交通参与者。
# 客户端A:控制主车
client_a = carla.Client('localhost', 2000)
world_a = client_a.get_world()
# ... 生成主车,控制逻辑
# 客户端B:控制NPC
client_b = carla.Client('localhost', 2000)
world_b = client_b.get_world()
# ... 生成NPC,设置自动驾驶
关键点:多个客户端共享同一个世界状态。你在客户端A生成的车,客户端B也能看到。但每个客户端只能控制自己生成的Actor。
4.5 避坑指南
最后,分享几个我踩过的坑:
- 端口被占用:如果启动服务器时提示端口被占用,用
lsof -i :2000查一下谁在用。我遇到过好几次是之前没关干净的CARLA进程。 - 版本不匹配:客户端和服务器版本必须一致。我曾经用0.9.13的客户端连0.9.14的服务器,API调用直接报错。
- 显卡驱动:CARLA对NVIDIA显卡支持最好。AMD显卡也能用,但性能会差一些。如果你用集成显卡,嗯...建议换个电脑。
- Python版本:推荐Python 3.8或3.9。3.10以上有些依赖包还没适配。
好了,这一章的内容就到这里。你现在应该能理解CARLA的架构,能启动服务器,能用Python让一辆车跑起来了。下一章我们会深入传感器——摄像头、激光雷达、毫米波雷达,看看怎么用它们采集真实数据。