3、Python API入门:安装carla Python库、导入模块、连接客户端、获取世界对象、获取蓝图库、生成车辆与行人

好,咱们正式开始动手了。

前面两章我们把Carla的架构和地图聊了一遍,算是热身。这一章,才是真正进入编程环节。说白了,就是让你学会怎么用Python跟Carla仿真器“对话”。

我个人习惯,学一个新工具,第一件事就是先把它的API跑通。哪怕只是生成一辆车停在路边,也比看十遍文档强。你想想看,代码跑起来的那一刻,那种掌控感,才是学习的动力。

3.1 安装carla Python库

这一步其实很简单,但坑也不少。我记得我第一次装的时候,直接用了pip install carla,结果装了个不知道什么版本的包,跟我的仿真器版本对不上,折腾了半天。

正确做法是:用Carla安装包自带的Python库。

你下载完Carla的压缩包,解压后,在 PythonAPI/carla/dist/ 目录下,就能找到一个 .whl 文件。比如我用的0.9.14版本,文件名是 carla-0.9.14-cp39-cp39-win_amd64.whl

然后打开终端,用pip安装它:

pip install carla-0.9.14-cp39-cp39-win_amd64.whl
注意:Python版本必须跟whl文件名里的版本一致。比如上面那个是cp39,你就得用Python 3.9。我曾经因为图省事,用Python 3.10去装3.9的包,结果报错说“不支持的平台”。嗯,这个坑我替你们踩过了。

装完之后,在Python里试试:

import carla
print(carla.__version__)

如果能正常输出版本号,恭喜你,第一步走通了。

3.2 导入模块与连接客户端

库装好了,接下来就是写脚本。我一般会先建一个 main.py 文件,然后开始写。

首先,导入必要的模块:

import carla
import random
import time

carla 是核心库,randomtime 是Python自带的,后面生成随机车辆和等待时会用到。

然后,连接客户端。Carla仿真器启动后,默认会在本地 localhost:2000 端口监听。我们只需要创建一个客户端对象:

client = carla.Client('localhost', 2000)
client.set_timeout(10.0)  # 设置超时时间,单位秒

这里有个小细节:set_timeout 一定要设。如果不设,网络一波动,脚本就会卡死在那。我刚开始写的时候没设,有一次仿真器卡住了,我的脚本也一直挂在那,还以为死机了。后来养成习惯,上来就先设个10秒超时。

3.3 获取世界对象

客户端连上了,接下来要获取“世界”。在Carla里,“世界”就是整个仿真环境的根对象。地图、天气、车辆、行人,全都挂在它下面。

world = client.get_world()

就这么一行。拿到 world 对象之后,你就可以为所欲为了。比如获取当前地图的名字:

print(world.get_map().name)

我一般会先打印一下地图名,确认自己连对了。毕竟有时候开了多个仿真器,容易搞混。

3.4 获取蓝图库

蓝图(Blueprint)是什么?你可以把它理解成“车型模板”。Carla内置了上百种车辆、行人、传感器的模板。每个模板都定义了模型、颜色、物理属性等。

获取蓝图库很简单:

blueprint_library = world.get_blueprint_library()

然后你可以看看里面都有什么车:

for bp in blueprint_library.filter('vehicle.*'):
    print(bp.id)

这里 filter('vehicle.*') 是过滤出所有以 vehicle. 开头的蓝图。Carla的蓝图命名很规范,比如 vehicle.audi.a2vehicle.bmw.grandtourer 等等。

小技巧:如果你只想生成某一种车,可以直接用 blueprint_library.find('vehicle.audi.a2')。我写测试脚本时,经常固定用几款车,这样每次生成的场景都一样,方便对比。

3.5 生成车辆与行人

好,重头戏来了。生成一辆车,需要三个要素:蓝图、位置、旋转角度。

我们先随机选一辆车:

vehicle_bp = random.choice(blueprint_library.filter('vehicle.*'))

然后找一个生成点。Carla地图里预置了很多 spawn_point,我们可以随机选一个:

spawn_points = world.get_map().get_spawn_points()
spawn_point = random.choice(spawn_points)

最后,生成车辆:

vehicle = world.spawn_actor(vehicle_bp, spawn_point)

就这么简单。车就出现在路上了。

如果你想生成行人,流程类似,只是蓝图要换成 walker.pedestrian.*

walker_bp = random.choice(blueprint_library.filter('walker.pedestrian.*'))
walker_spawn_point = carla.Transform()
walker_spawn_point.location = spawn_point.location + carla.Location(x=5, y=0, z=0)
walker = world.spawn_actor(walker_bp, walker_spawn_point)

注意,行人没有预置的 spawn_point,所以我们需要自己构造一个 Transform。我一般会在车辆旁边偏移几米生成行人,这样看起来更自然。

完整示例代码:
import carla
import random
import time

client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
world = client.get_world()

blueprint_library = world.get_blueprint_library()

# 生成车辆
vehicle_bp = random.choice(blueprint_library.filter('vehicle.*'))
spawn_points = world.get_map().get_spawn_points()
spawn_point = random.choice(spawn_points)
vehicle = world.spawn_actor(vehicle_bp, spawn_point)
print(f'生成车辆: {vehicle_bp.id}')

# 生成行人
walker_bp = random.choice(blueprint_library.filter('walker.pedestrian.*'))
walker_spawn_point = carla.Transform()
walker_spawn_point.location = spawn_point.location + carla.Location(x=5, y=0, z=0)
walker = world.spawn_actor(walker_bp, walker_spawn_point)
print(f'生成行人: {walker_bp.id}')

time.sleep(5)  # 让场景保持5秒

# 清理
vehicle.destroy()
walker.destroy()
print('清理完成')

3.6 避坑指南

最后,分享几个我实际项目中遇到的坑:

  • 生成位置冲突:如果两个车生成在同一个点,会报错。所以尽量用 random.choicespawn_points 里选,别自己硬编码坐标。
  • 蓝图不存在:有时候 blueprint_library.find() 会返回 None,如果你没检查就直接 spawn_actor,会崩溃。记得加个 if bp is not None 的判断。
  • 忘记清理:生成的Actor如果不 destroy(),会一直留在仿真器里。我刚开始经常忘了清理,结果跑几次脚本后,仿真器里堆满了车,卡得不行。后来我习惯在脚本末尾统一清理,或者用 try...finally 保证清理。

嗯,这一章的内容就这些。说白了就是“连上、拿世界、拿蓝图、生成东西”。下一章我们会让这些车真正跑起来,加上传感器,开始采集数据。到时候就有意思了。