4. Python API入门:CARLA Python API概览、连接服务器、获取世界对象、基本对象操作
好,咱们正式开始动手了。
前面几章聊了CARLA的架构、传感器、地图这些概念,说白了都是在「看」。从这一章开始,我们要真正用代码去控制这个仿真世界。我个人觉得,Python API是CARLA最友好的入口——你不需要编译C++,不需要折腾复杂的依赖,一个pip install就能跑起来。
嗯,先给你吃颗定心丸:这一章的内容,你跟着敲一遍,半小时内就能跑通。
4.1 CARLA Python API 到底长什么样?
CARLA的Python API,说白了就是一组Python类和方法,封装了客户端和服务器之间的通信协议。你写的每一行Python代码,最终都会转成一条消息发给CARLA服务器,服务器执行完再给你返回结果。
我刚开始接触的时候,总觉得这玩意儿很神秘。后来拆开看了源码才发现,核心就几个类:
| 类名 | 作用 | 我常用的场景 |
|---|---|---|
carla.Client |
连接CARLA服务器 | 创建客户端、设置超时 |
carla.World |
代表仿真世界 | 获取地图、生成车辆、控制天气 |
carla.Actor |
所有可移动/可交互对象的基类 | 车辆、行人、传感器都继承它 |
carla.BlueprintLibrary |
蓝图库,存放所有可生成的对象模板 | 挑选车型、传感器型号 |
carla.Transform |
位置+旋转 | 设置生成点、移动对象 |
你看,其实没几个类。记住这五个,你就能搞定80%的日常开发。
核心思路:Client → World → Actor,一条线串起来。先连服务器,再拿世界,最后操作对象。
4.2 连接服务器——别小看这一步
连接服务器,代码就两行:
import carla
client = carla.Client('localhost', 2000)
client.set_timeout(10.0) # 设置超时,单位秒
但这里有个坑,我曾经踩过。
我曾经遇到过:客户端连上了,但一执行操作就报超时。查了半天,发现是服务器没开。CARLA服务器必须提前启动,客户端只是「敲门」,门没开当然进不去。
所以,连接之前请确认:
- CARLA服务器已经启动(能看到那个UE4窗口)
- 端口号一致(默认2000,你改了就用你的)
- 超时时间别设太短(网络波动时5秒可能不够,我习惯设10秒)
连接成功后,你会得到一个client对象。这时候你可以试试:
print(client.get_client_version())
print(client.get_server_version())
如果两个版本号能对上,恭喜你,通信链路通了。
4.3 获取世界对象——你的仿真舞台
有了客户端,下一步就是获取世界对象。世界对象就是整个仿真环境的「总管」。
world = client.get_world()
就这么一行。但你知道吗?get_world()返回的是当前正在运行的世界。如果你加载了不同地图,世界对象也会变。
我个人习惯在获取世界后,先看一眼当前地图:
print(world.get_map().name)
这样能确认你确实在预期的地图里。我在项目里遇到过好几次,代码跑着跑着发现车在Town03,但我以为在Town05——嗯,那种感觉就像你开车导航错了城市。
世界对象能干的事太多了,我列几个最常用的:
world.get_actors()— 获取场景里所有对象world.spawn_actor()— 生成一个新对象world.get_weather()— 获取当前天气world.set_weather()— 设置天气(下雨、大雾、夜晚)world.tick()— 让仿真前进一步
小技巧:如果你需要反复获取世界对象,建议把它存成全局变量。每次调用get_world()其实都有开销,尤其是在高频率循环里。
4.4 基本对象操作——生成你的第一辆车
好了,重头戏来了。咱们来生成一辆车。
生成一个Actor需要三步:
- 从蓝图库里选一个模板
- 指定生成位置(Transform)
- 调用
spawn_actor()
看代码:
# 1. 获取蓝图库
blueprint_library = world.get_blueprint_library()
# 2. 筛选出所有车辆蓝图
vehicle_bps = blueprint_library.filter('vehicle.*')
# 3. 选一辆车,比如奥迪
bp = vehicle_bps.find('vehicle.audi.a2')
# 4. 找一个生成点
spawn_points = world.get_map().get_spawn_points()
transform = spawn_points[0]
# 5. 生成车辆
vehicle = world.spawn_actor(bp, transform)
print(f'生成了车辆:{vehicle.type_id},位置:{transform.location}')
跑完这段,你应该能在CARLA窗口里看到一辆奥迪停在路上。
这里有几个细节我想强调一下:
- 蓝图筛选:
filter('vehicle.*')用的是通配符,你也可以精确到'vehicle.audi.*' - 生成点:每个地图都有预设的
spawn_points,但数量有限。如果你要生成100辆车,可能不够用,需要自己算位置 - 生成失败:如果位置被占了,
spawn_actor会抛异常。我建议用try-except包一下
避坑指南:我曾经在循环里批量生成车辆,没做异常处理。结果第50辆车生成失败,整个程序崩了。从那以后,我生成Actor必加try-except。
4.5 对象操作——动起来
车生出来了,但它是静止的。怎么让它动?
两种方式:
- 设置速度:
vehicle.set_velocity() - 设置自动驾驶:
vehicle.set_autopilot(True)
我个人更推荐先用自动驾驶模式测试,省心:
vehicle.set_autopilot(True)
就这么一行,车就会自己跑了。CARLA内置了一个简单的交通管理器,会控制车辆加速、刹车、转弯。
如果你想手动控制,可以这样:
import carla
# 创建一个速度向量(x向前,y向左,z向上)
velocity = carla.Vector3D(10.0, 0.0, 0.0)
vehicle.set_velocity(velocity)
但注意,set_velocity设置的是瞬时速度,不是持续加速。如果你想模拟油门控制,需要用vehicle.apply_control():
control = carla.VehicleControl()
control.throttle = 0.5 # 50%油门
control.steer = 0.0 # 方向盘回正
vehicle.apply_control(control)
嗯,这里要提醒你:apply_control需要每帧调用,否则车会停下来。所以一般放在游戏循环里。
4.6 清理工作——别忘了解放资源
仿真结束后,记得销毁生成的Actor。不然下次启动时,上一轮的车还停在路上。
vehicle.destroy()
如果你生成了很多Actor,可以批量销毁:
for actor in world.get_actors().filter('vehicle.*'):
actor.destroy()
注意:销毁Actor后,这个对象就不能再用了。如果你还想用,得重新生成。我见过有人销毁后还去调用get_location(),直接报错。
4.7 本章知识体系
下面这张图,帮你把这一章的核心逻辑串起来:
你看,整个流程其实很清晰。先连服务器,再拿世界,最后操作对象。后面所有章节的内容,都是在这个框架上做加法。
我的建议:这一章的代码,你至少手敲三遍。第一遍照着抄,第二遍理解每行在干嘛,第三遍尝试改参数、换车型。三遍下来,Python API的基本功就扎实了。
好了,这一章就到这里。代码不多,但都是基础中的基础。你想想看,连服务器、拿世界、生成车、让车跑起来——这四个动作,几乎贯穿了所有CARLA仿真项目。后面不管你做传感器融合、路径规划还是强化学习,都离不开它们。
去试试吧,有问题随时翻回来看看。