2. Python API入门

好,咱们正式开始动手了。这一章是整个CARLA实验的基石——说白了,就是让你学会怎么用Python跟CARLA服务器“对话”。

我个人习惯把这一章叫做“Hello World”进阶版。你想想看,别的仿真工具上来先让你拖拽界面,CARLA不一样,它逼着你用代码说话。刚开始可能觉得别扭,但等你习惯了,会发现这才是真正的生产力。

2.1 连接服务器:建立你的第一条通信链路

CARLA采用客户端-服务器架构。服务器负责渲染和物理计算,客户端(也就是你的Python脚本)负责发指令。两者通过TCP/IP通信。

连接代码其实就一行:

import carla

# 连接到本地默认端口(2000)
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)  # 设置超时时间,单位秒

这里有个坑,我刚开始学的时候踩过——忘记设置超时时间。默认超时时间很短,如果服务器还没启动完,脚本直接就崩了。所以我建议你养成习惯,上来就设个10秒。

⚠️ 注意: 如果连接失败,先检查CARLA服务器是否在运行。终端里没看到CARLA的启动日志?那就先启动服务器再说。

2.2 获取世界:你的仿真沙盒

连接上服务器之后,下一步就是获取“世界”。世界是什么?你可以把它理解成一个容器,里面装着地图、天气、车辆、行人……所有东西都在这个世界里。

# 获取当前激活的世界
world = client.get_world()

# 或者,你也可以指定地图名称
# world = client.load_world('Town01')

我个人习惯用get_world(),因为服务器启动时已经加载了默认地图。但如果你需要切换地图,load_world()是你的选择。

这里有个小技巧:client.get_available_maps()可以列出所有可用的地图。我在项目中经常用这个来确认当前环境有哪些地图可选。

2.3 生成车辆:让世界动起来

有了世界,接下来就是往里面放东西。生成车辆需要三步:

  1. 获取蓝图库——蓝图就是车辆的“模板”
  2. 选择一个生成点——车辆不能凭空出现,得有个位置
  3. 生成车辆——调用API
# 1. 获取蓝图库
blueprint_library = world.get_blueprint_library()

# 2. 筛选出车辆蓝图(过滤掉行人、传感器等)
vehicle_blueprints = blueprint_library.filter('vehicle.*')

# 3. 选择一辆车,比如奥迪
bp = blueprint_library.find('vehicle.audi.a2')

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

# 5. 生成车辆
vehicle = world.spawn_actor(bp, spawn_point)

💡 核心要点: spawn_actor()如果返回None,说明生成失败。最常见的原因是生成点被占用了。我在项目中遇到过这种情况,后来改用try_spawn_actor(),它会返回None而不是抛异常,更安全。

2.4 控制车辆移动:让车跑起来

车生出来了,但它不会自己动。你需要给它施加控制指令。CARLA的控制接口叫VehicleControl,主要参数有:

参数 类型 说明
throttle float (0.0 ~ 1.0) 油门,0是松油,1是地板油
steer float (-1.0 ~ 1.0) 转向,负左正右
brake float (0.0 ~ 1.0) 刹车,0不刹,1刹死
hand_brake bool 手刹,一般不用
reverse bool 倒车

来个完整的例子,让车直线前进:

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.audi.a2')
spawn_point = world.get_map().get_spawn_points()[0]
vehicle = world.spawn_actor(bp, spawn_point)

# 控制车辆:油门踩到底,方向回正
control = carla.VehicleControl(throttle=1.0, steer=0.0)
vehicle.apply_control(control)

# 让车跑5秒
time.sleep(5)

# 停车
control.throttle = 0.0
control.brake = 1.0
vehicle.apply_control(control)

# 清理
vehicle.destroy()

🔧 避坑指南: 我曾经犯过一个低级错误——忘记调用vehicle.destroy()。结果跑一次脚本就多一辆车,最后场景里堆了十几辆车,卡得不行。记住:生成的Actor一定要手动销毁,否则它们会一直留在服务器里。

2.5 知识体系总览

这一章的内容其实就围绕一个核心流程:连接 → 获取 → 生成 → 控制 → 清理。我画了张图帮你理清逻辑:

连接服务器 获取世界 生成车辆 控制移动 循环控制(每帧更新) 清理销毁

嗯,这张图把整个流程串起来了。你写代码的时候,脑子里就过一遍这个流程,基本不会出错。

2.6 本章小结

这一章我们干了四件事:连服务器、拿世界、生车、开车。说白了就是让CARLA动起来的第一步。代码量不大,但每个环节都有细节要注意。

我个人建议你把这几个API记熟:Client()、get_world()、spawn_actor()、apply_control()、destroy()。后面所有章节都离不开它们。

最后提醒一句:别忘了清理Actor。我当年因为这个被导师骂过,现在想想都是泪。

📌 课后练习: 试着生成两辆车,让它们并排停在路上,然后同时起步。看看能不能做到同步控制?