3、CARLA入门:CARLA架构解析、安装与启动、Python API基础、客户端与服务器模型
好,咱们正式开始啃CARLA这块硬骨头。说实话,我第一次接触CARLA的时候,也被它的架构搞得有点懵。但别担心,我带你捋一遍,你会发现它其实挺清晰的。
3.1 CARLA架构解析:到底谁在干活?
CARLA本质上是一个客户端-服务器架构。你想想看,这就像打网络游戏——服务器负责渲染画面、计算物理、管理世界;客户端负责发指令、收数据。嗯,就是这么回事。
具体来说:
- 服务器(Server):运行虚幻引擎4,负责仿真世界的运行。包括车辆动力学、传感器模拟、交通流、天气变化等等。服务器是核心,它不关心谁来连它。
- 客户端(Client):通过Python API与服务器通信。你写的脚本就是客户端。客户端可以控制车辆、配置环境、读取传感器数据。
核心要点:一个服务器可以同时服务多个客户端。我在项目中就试过,一个客户端控制主车,另一个客户端跑路测场景,互不干扰。但要注意,多个客户端操作同一个对象时,可能会打架。
为什么会设计成这种架构?说白了,就是为了解耦。服务器专心做仿真,客户端专心做算法。你可以在本地跑服务器,在远程跑客户端,完全没问题。
3.2 安装与启动:别踩我踩过的坑
安装CARLA其实不复杂,但有几个细节我吃过亏,你注意一下。
3.2.1 系统要求
| 组件 | 最低要求 | 推荐配置 |
|---|---|---|
| 操作系统 | Windows 10 / Ubuntu 18.04 | Ubuntu 20.04 |
| GPU | NVIDIA GTX 1060 | NVIDIA RTX 2070 以上 |
| 内存 | 8 GB | 16 GB |
| 硬盘 | 20 GB 空闲 | SSD 50 GB |
3.2.2 安装步骤(以Ubuntu为例)
我个人习惯用预编译包,省事。你如果喜欢从源码编译,也行,但第一次建议别折腾。
# 1. 下载CARLA包
wget https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/CARLA_0.9.13.tar.gz
# 2. 解压
tar -xzf CARLA_0.9.13.tar.gz
# 3. 进入目录
cd CARLA_0.9.13
# 4. 安装Python依赖
pip install -r PythonAPI/examples/requirements.txt
# 5. 启动服务器
./CarlaUE4.sh
警告:我曾经在Windows上遇到过路径中文导致启动失败的问题。所以,安装路径千万别带中文,也别带空格。血的教训。
3.2.3 启动服务器
启动服务器后,你会看到一个虚幻引擎的窗口。别急着关,这就是仿真世界。你可以用鼠标拖拽视角,看看这个虚拟城市长什么样。
如果你想在无头模式下运行(没有图形界面),可以加参数:
./CarlaUE4.sh -RenderOffScreen
嗯,这个在服务器上跑特别有用。我经常在远程服务器上这样搞,省显卡资源。
3.3 Python API基础:你的遥控器
Python API是CARLA的灵魂。说白了,你通过它跟仿真世界对话。
3.3.1 连接服务器
第一步永远是建立连接:
import carla
# 创建客户端,连接到本地服务器的2000端口
client = carla.Client('localhost', 2000)
# 设置超时时间,我习惯设10秒
client.set_timeout(10.0)
# 获取世界对象
world = client.get_world()
print("连接成功!")
你想想看,如果连不上,后面什么都干不了。所以超时时间别设太短,网络波动很正常。
3.3.2 世界与蓝图
世界对象代表整个仿真环境。蓝图(Blueprint)则是物体的模板,比如车辆、行人、传感器。
# 获取所有可用的蓝图
blueprint_library = world.get_blueprint_library()
# 找一个特定的车辆蓝图
vehicle_bp = blueprint_library.find('vehicle.tesla.model3')
# 或者随机选一个
spawn_point = world.get_map().get_spawn_points()[0]
# 生成车辆
vehicle = world.spawn_actor(vehicle_bp, spawn_point)
print(f"生成了车辆:{vehicle.type_id}")
小技巧:我建议你先把蓝图库打印出来看看,熟悉一下有哪些车型和传感器。用 print(blueprint_library.filter('vehicle.*')) 就能过滤出所有车辆。
3.3.3 控制车辆
生成车辆后,怎么让它动起来?通过控制指令:
# 创建控制对象
control = carla.VehicleControl()
# 设置油门和转向
control.throttle = 0.5 # 50%油门
control.steer = -0.3 # 左转
# 应用控制
vehicle.apply_control(control)
# 让仿真跑几步
for _ in range(100):
vehicle.apply_control(control)
world.tick() # 推进一帧
注意,world.tick() 是手动推进仿真。如果你不调用,世界是静止的。我记得刚开始做的时候,忘了加tick,车死活不动,查了半天才发现这个坑。
3.4 客户端与服务器模型:深入理解
咱们再深入聊聊这个模型。你可能会问:为什么非要搞成客户端-服务器?
原因有三:
- 并行开发:算法团队和仿真团队可以独立工作。服务器升级不影响客户端代码。
- 分布式部署:服务器跑在GPU服务器上,客户端跑在普通PC上,甚至可以在Jupyter Notebook里写代码。
- 多语言支持:虽然官方推荐Python,但理论上任何支持TCP/IP的语言都能写客户端。
3.4.1 同步模式 vs 异步模式
这是个大坑,我详细说说。
- 同步模式:客户端调用
world.tick()后,服务器才推进一帧。适合需要精确控制的场景,比如强化学习训练。 - 异步模式:服务器自己按固定帧率跑,客户端只管收数据。适合数据采集,但控制精度差一些。
# 设置为同步模式
settings = world.get_settings()
settings.synchronous_mode = True
settings.fixed_delta_seconds = 0.05 # 20 FPS
world.apply_settings(settings)
# 之后必须手动tick
world.tick()
注意:我曾经在异步模式下做控制,结果发现车辆反应延迟了200ms。后来改成同步模式,问题就解决了。所以,如果你做精确控制,一定要用同步模式。
3.4.2 多客户端场景
一个服务器可以连多个客户端。比如:
# 客户端1:控制主车
client1 = carla.Client('localhost', 2000)
world1 = client1.get_world()
# 客户端2:监控传感器
client2 = carla.Client('localhost', 2000)
world2 = client2.get_world()
# 两个客户端操作同一个世界
# 但要注意,不要同时修改同一个actor
嗯,这个特性在测试V2X场景时特别有用。一个客户端模拟主车,另一个模拟路侧单元。
3.5 实战:跑通第一个仿真
光说不练假把式。咱们写个完整的例子,把上面讲的串起来。
import carla
import random
import time
def main():
# 连接服务器
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
world = client.get_world()
# 设置同步模式
settings = world.get_settings()
settings.synchronous_mode = True
settings.fixed_delta_seconds = 0.05
world.apply_settings(settings)
# 生成车辆
blueprint_library = world.get_blueprint_library()
vehicle_bp = random.choice(blueprint_library.filter('vehicle.*'))
spawn_point = random.choice(world.get_map().get_spawn_points())
vehicle = world.spawn_actor(vehicle_bp, spawn_point)
print(f"生成了 {vehicle.type_id}")
# 控制车辆前进
control = carla.VehicleControl()
control.throttle = 0.6
# 跑100帧
for i in range(100):
vehicle.apply_control(control)
world.tick()
time.sleep(0.05) # 模拟真实时间
if i % 20 == 0:
print(f"第 {i} 帧,车辆位置:{vehicle.get_location()}")
# 清理
vehicle.destroy()
print("仿真结束")
if __name__ == "__main__":
main()
这个例子虽然简单,但包含了连接、配置、生成、控制、清理的完整流程。你跑通了这个,后面学传感器、地图、交通流就顺了。
总结一下:CARLA的客户端-服务器模型,说白了就是「服务器管世界,客户端管逻辑」。你只要记住三步:连服务器、拿世界、操作Actor。剩下的,都是细节。
好,这一章就到这儿。下一章咱们开始玩传感器——摄像头、激光雷达、GPS,一个都不能少。