4、生成车辆:使用蓝图生成车辆、设置生成点、处理生成失败
好,咱们进入正题。上一章我们把地图和天气搞定了,这一章该让车跑起来了。
生成车辆这件事,说白了就是三步:选车 → 选位置 → 把车变出来。听起来简单,但我在项目里踩过的坑可不少。比如车卡在地底下、车飞到天上、或者干脆生成不出来——嗯,这些我都遇到过。
4.1 蓝图是什么?
在CARLA里,每辆车都有一个“设计图纸”,这就是蓝图(Blueprint)。蓝图里存了车的型号、颜色、物理属性、传感器配置等等。
你可以把蓝图想象成汽车的“出生证明”。有了它,CARLA才知道你要造一辆什么样的车。
核心概念:蓝图库(Blueprint Library)里存了所有可用的车辆模型。你需要先从库里挑一个,再用它来生成实体车。
我个人习惯先把蓝图库遍历一遍,看看有哪些车可以用。代码很简单:
# 获取所有车辆蓝图
blueprint_library = world.get_blueprint_library()
vehicle_blueprints = blueprint_library.filter('vehicle.*')
# 打印前5个看看
for bp in vehicle_blueprints[:5]:
print(bp.id)
输出大概长这样:
vehicle.audi.a2
vehicle.bmw.grandtourer
vehicle.chevrolet.impala
vehicle.dodge.charger_police
vehicle.ford.mustang
你看,命名规则是 vehicle.品牌.型号。想选哪辆,直接写名字就行。
4.2 设置生成点
车选好了,接下来得找个地方放它。CARLA地图里预置了很多生成点(Spawn Points),每个点包含位置和朝向。
获取生成点的方法:
spawn_points = world.get_map().get_spawn_points()
print(f"地图共有 {len(spawn_points)} 个生成点")
我建议你第一次跑的时候,先打印一下生成点的数量。不同地图差别很大——Town01可能只有几十个,Town05能有上百个。
小技巧:生成点是有编号的。你可以用 spawn_points[0] 取第一个,或者随机选一个。我个人习惯用随机,这样每次跑仿真都不一样。
import random
# 随机选一个生成点
spawn_point = random.choice(spawn_points)
4.3 生成车辆
蓝图和位置都准备好了,接下来就是见证奇迹的时刻:
# 选一辆车
bp = blueprint_library.find('vehicle.audi.a2')
# 生成车辆
vehicle = world.spawn_actor(bp, spawn_point)
print(f"车辆已生成: {vehicle.type_id}")
就这么简单?嗯,大部分情况是的。但我要提醒你——生成失败是家常便饭。
4.4 处理生成失败
为什么会失败?我总结了几种常见情况:
| 失败原因 | 表现 | 解决办法 |
|---|---|---|
| 生成点被占用 | 抛异常 | 换个生成点,或先清空该位置 |
| 生成点不合理 | 车卡在建筑物里 | 检查生成点是否在路面上 |
| 蓝图无效 | 找不到指定蓝图 | 确认蓝图ID拼写正确 |
| 超出最大车辆数 | 生成被拒绝 | 减少车辆数量或销毁旧车 |
我曾经在项目里遇到过一个问题:连续生成20辆车,到第15辆就报错了。查了半天才发现是地图的生成点不够用,有些点被前面的车占了。
解决方案很简单——用 try-except 包起来,失败了就换下一个点:
def spawn_vehicle_safely(world, blueprint, spawn_points):
"""安全生成车辆,失败自动重试"""
for spawn_point in spawn_points:
try:
vehicle = world.spawn_actor(blueprint, spawn_point)
return vehicle
except:
continue
print("所有生成点都试过了,还是失败")
return None
注意: spawn_actor 如果失败会抛出 RuntimeError。别问我怎么知道的——我第一次写的时候没加异常处理,程序直接崩了。
4.5 批量生成车辆
实际仿真中,我们经常要生成多辆车。比如模拟十字路口的车流,至少得有个七八辆吧。
批量生成的套路是这样的:
# 选5辆不同的车
blueprints = blueprint_library.filter('vehicle.*')
selected_bps = random.choices(blueprints, k=5)
# 选5个不同的生成点
selected_points = random.sample(spawn_points, k=5)
# 批量生成
vehicles = []
for bp, point in zip(selected_bps, selected_points):
try:
v = world.spawn_actor(bp, point)
vehicles.append(v)
print(f"生成成功: {v.type_id}")
except Exception as e:
print(f"生成失败: {e}")
print(f"成功生成 {len(vehicles)} 辆车")
你想想看,如果每辆车都手动指定位置,那得多累。用随机选择,省时省力。
4.6 车辆生成后的设置
车生成了,不代表就完事了。我一般会做几件事:
- 设置自动驾驶模式:让车自己跑起来
- 调整颜色:方便区分不同车辆
- 设置物理参数:比如最大速度、碰撞检测等
设置自动驾驶最简单:
vehicle.set_autopilot(True)
改颜色也不难:
# 获取可用的颜色列表
colors = bp.get_attribute('color').recommended_values
# 选一个随机颜色
random_color = random.choice(colors)
bp.set_attribute('color', random_color)
小提示:颜色属性是在生成之前设置的。生成之后改颜色?嗯,我试过,不行。所以记得在 spawn_actor 之前把颜色调好。
4.7 知识体系总览
这一章的内容,我用一张图帮你理清楚:
4.8 完整示例代码
最后,给你一个可以直接跑的完整示例。我平时写仿真脚本,基本就是这个结构:
import carla
import random
def main():
# 连接CARLA
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
world = client.get_world()
# 获取蓝图和生成点
blueprint_library = world.get_blueprint_library()
spawn_points = world.get_map().get_spawn_points()
# 选一辆车,设置颜色
bp = blueprint_library.find('vehicle.audi.a2')
color = random.choice(bp.get_attribute('color').recommended_values)
bp.set_attribute('color', color)
# 安全生成
vehicle = None
for point in spawn_points:
try:
vehicle = world.spawn_actor(bp, point)
break
except:
continue
if vehicle is None:
print("生成失败,所有生成点都试过了")
return
# 开启自动驾驶
vehicle.set_autopilot(True)
print(f"车辆 {vehicle.type_id} 已上路,颜色: {color}")
# 让仿真跑一会儿
import time
time.sleep(10)
# 清理
vehicle.destroy()
print("仿真结束")
if __name__ == '__main__':
main()
这段代码我反复用过很多次,基本没出过问题。你拿去改改就能用。
核心要点回顾:
- 蓝图是车的“设计图纸”,从蓝图库里选
- 生成点决定了车的位置和朝向
- 生成失败很正常,用 try-except 兜底
- 颜色等属性要在生成前设置好
好了,这一章就到这里。车已经能跑起来了,下一章我们聊聊怎么控制它——嗯,到时候见。
可可精品资料库