4、CARLA基础入门:CARLA世界模型、客户端与服务器架构、基本API调用

说实话,刚接触CARLA那会儿,我也挺懵的。一个自动驾驶仿真器,怎么还分客户端和服务器?世界模型又是什么鬼?别急,这一章咱们就把这些概念掰开揉碎了讲清楚。

4.1 CARLA世界模型:你就是在搭建一个虚拟世界

CARLA的世界模型,说白了就是一个虚拟的沙盒。你可以在里面放道路、放建筑、放车辆、放行人,甚至控制天气和时间。

我个人习惯把这个世界模型想象成一个大舞台:

  • 地图(Map):舞台的布景,包括道路、车道线、红绿灯、路标。
  • 参与者(Actor):舞台上的演员,包括车辆、行人、传感器。
  • 天气(Weather):舞台的灯光和特效,晴天、雨天、雾天随便调。
  • 蓝图(Blueprint):演员的“出生证明”,定义了车辆型号、颜色、传感器配置。

我在项目中遇到过一个问题:明明加载了地图,但车辆就是不动。后来发现,是我忘了把车辆“生成”到世界里。你想想看,舞台搭好了,演员没上场,戏怎么演?

核心概念:CARLA的世界模型是一个World对象,它管理着地图、参与者列表、天气设置和帧率。所有操作都围绕这个对象展开。

4.2 客户端与服务器架构:谁在干活?

CARLA采用的是客户端-服务器(C/S)架构。这个设计很有意思,我刚开始也觉得多此一举,后来才发现它有多香。

简单来说:

  • 服务器(Server):负责渲染画面、物理计算、传感器数据生成。它是个“闷头干活的壮汉”。
  • 客户端(Client):负责发送指令、接收数据、控制逻辑。它是个“发号施令的指挥官”。

为什么会这样设计?因为仿真计算量很大,尤其是多车协同、传感器融合的场景。把渲染和逻辑分开,你就可以在一台高性能机器上跑服务器,在另一台机器上跑客户端,甚至多个客户端同时连接一个服务器。

我的经验:调试的时候,我习惯在本地开一个服务器窗口,再开一个Python终端当客户端。这样改代码不用重启服务器,效率高很多。

下面这张图,是我自己画的一个架构流程图,帮你理清关系:

CARLA 服务器 渲染引擎 物理引擎 传感器数据生成 世界状态管理 (端口:2000) CARLA 客户端 Python API 控制逻辑 数据接收与处理 用户脚本 (你的代码) 指令(生成、控制) 数据(图像、激光雷达)
注意:服务器和客户端必须使用相同版本的CARLA,否则会连接失败。我曾经因为版本不匹配,折腾了整整一个下午。

4.3 基本API调用:让车跑起来

好了,理论说完了,咱们直接上代码。我习惯先连上服务器,再一步步操作。

4.3.1 连接服务器与加载世界

import carla

# 连接服务器,默认端口2000
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)  # 设置超时,防止卡死

# 获取世界对象
world = client.get_world()

# 或者加载指定地图
# world = client.load_world('Town03')

嗯,这里要注意:set_timeout一定要设。我第一次写的时候没设,结果网络一波动,脚本直接卡死,连错误提示都没有。

4.3.2 生成一辆车

生成车辆需要三步:获取蓝图、选择生成点、生成。

# 1. 获取蓝图库
blueprint_library = world.get_blueprint_library()

# 2. 选择一辆车(我习惯用特斯拉Model 3)
vehicle_bp = blueprint_library.find('vehicle.tesla.model3')

# 3. 获取一个随机生成点
spawn_points = world.get_map().get_spawn_points()
spawn_point = spawn_points[0]  # 选第一个点

# 4. 生成车辆
vehicle = world.spawn_actor(vehicle_bp, spawn_point)
避坑指南:如果生成点被占用了,spawn_actor会报错。我建议用try_spawn_actor,它返回None而不是抛异常,更安全。

4.3.3 控制车辆移动

控制车辆有两种方式:直接控制(手动挡)和自动驾驶(自动挡)。

方式一:手动控制

# 创建一个控制对象
control = carla.VehicleControl()
control.throttle = 0.5   # 油门,0-1
control.steer = 0.0      # 转向,-1到1
control.brake = 0.0      # 刹车,0-1

# 应用控制
vehicle.apply_control(control)

方式二:开启自动驾驶

# 让CARLA内置的AI驾驶
vehicle.set_autopilot(True)

我个人更推荐先用手动控制调试逻辑,等稳定了再开自动驾驶。你想想看,如果连油门刹车都控制不好,直接上自动驾驶,出了问题你都不知道是代码的锅还是AI的锅。

4.3.4 完整示例:生成一辆车并让它跑起来

import carla
import time

# 连接服务器
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
world = client.get_world()

# 生成车辆
bp = world.get_blueprint_library().find('vehicle.tesla.model3')
spawn_point = world.get_map().get_spawn_points()[0]
vehicle = world.spawn_actor(bp, spawn_point)

# 手动控制:先加速,再转弯
control = carla.VehicleControl()
control.throttle = 0.6
vehicle.apply_control(control)

time.sleep(3)  # 直行3秒

control.steer = 0.3  # 右转
vehicle.apply_control(control)

time.sleep(2)

# 清理
vehicle.destroy()
重要:用完的车辆一定要destroy(),否则服务器里会残留一堆“幽灵车”,拖慢仿真速度。我刚开始经常忘,结果仿真越来越卡,还以为是电脑不行。

4.4 常用API速查表

功能 API 说明
连接服务器 carla.Client(host, port) 默认端口2000
获取世界 client.get_world() 获取当前世界
加载地图 client.load_world('Town01') 切换地图
获取蓝图 world.get_blueprint_library() 获取所有可生成对象
生成参与者 world.spawn_actor(blueprint, transform) 返回Actor对象
安全生成 world.try_spawn_actor(blueprint, transform) 失败返回None
应用控制 vehicle.apply_control(control) 传入VehicleControl
自动驾驶 vehicle.set_autopilot(True) 内置AI驾驶
销毁参与者 actor.destroy() 必须调用,释放资源

这一章的内容其实不难,核心就是理解世界模型、C/S架构、API调用这三板斧。你只要把代码敲一遍,跑通了,后面的事情就顺了。我当年也是从这行代码开始的:vehicle.apply_control(control)。看着屏幕上的车真的动起来,那种感觉,嗯,挺爽的。

可可精品资料库