4. Carla地图与车辆控制:地图加载与切换、车辆生成与操控、行人及交通流管理
好,咱们今天来聊聊Carla里最核心的几个操作——地图、车辆、行人、交通流。说实话,这部分内容我刚开始接触的时候也觉得挺乱的,但后来发现,只要理清了几个关键点,其实就那么回事。
4.1 地图加载与切换
Carla自带了好几个地图,比如Town01到Town10。每个地图的布局、路况、复杂度都不一样。我个人习惯在调试感知算法时,先用Town01这种简单地图,等模型跑稳了再换到Town05这种带环岛和复杂路口的。
加载地图其实就一行代码:
client.load_world('Town01')
但这里有个坑——切换地图时,之前生成的所有actor(车辆、行人等)都会被自动销毁。嗯,这个设计其实挺合理的,因为地图变了,路网都不同了,之前的actor位置信息全废了。
如果你想看看当前有哪些地图可用,可以这样:
available_maps = client.get_available_maps()
for map_name in available_maps:
print(map_name)
返回的是一串路径,比如/Game/Carla/Maps/Town01。你只需要取最后那个名字就行。
4.2 车辆生成与操控
生成车辆,说白了就是三步:选车型、选位置、spawn。但每一步都有讲究。
4.2.1 选择车型
Carla提供了几十种车辆蓝图。你可以按类型筛选:
blueprint_library = world.get_blueprint_library()
vehicle_bps = blueprint_library.filter('vehicle.*')
我个人建议,做感知测试时尽量用轿车或SUV,别用卡车——视野遮挡太严重,容易把算法搞崩。
4.2.2 设置生成位置
Carla地图里预置了很多spawn point,你可以直接拿来用:
spawn_points = world.get_map().get_spawn_points()
transform = spawn_points[0] # 取第一个
但要注意,不是每个spawn point都能成功生成车辆。如果位置被占了或者地形有问题,spawn会返回None。我曾经在调试时没做这个检查,结果后面代码全崩了。
4.2.3 生成并控制车辆
vehicle = world.spawn_actor(blueprint, transform)
vehicle.set_autopilot(True) # 开启自动驾驶
开启autopilot后,车辆会按照交通规则行驶。但如果你想手动控制,可以设置速度或转向:
vehicle.apply_control(carla.VehicleControl(
throttle=0.5, # 油门 0~1
steer=0.0, # 转向 -1~1
brake=0.0 # 刹车 0~1
))
嗯,这里要注意,apply_control和set_autopilot是互斥的。你开了autopilot再手动控制,车辆会跟你抢方向盘,结果就是车在原地抽搐。别问我怎么知道的...
4.3 行人及交通流管理
做感知算法,光有车不行,还得有行人、自行车、红绿灯这些。不然你的模型一上路就懵了。
4.3.1 生成行人
行人的生成逻辑和车辆类似,但有个区别——行人需要走路,所以得设置行走目标:
walker_bp = blueprint_library.filter('walker.pedestrian.*')[0]
walker = world.spawn_actor(walker_bp, transform)
# 让行人自动行走
walker_controller_bp = blueprint_library.find('controller.ai.walker')
walker_controller = world.spawn_actor(walker_controller_bp, carla.Transform(), walker)
walker_controller.start()
walker_controller.go_to_location(target_location)
这里有个容易忽略的点:行人控制器必须单独生成,不能直接让行人自己走。我刚开始做的时候以为spawn完就完事了,结果行人站在原地一动不动,像个雕塑。
4.3.2 交通流管理
交通流说白了就是让一堆车和行人按照规则跑起来。Carla提供了TrafficManager来管理:
traffic_manager = client.get_trafficmanager()
traffic_manager.set_global_distance_to_leading_vehicle(2.0) # 跟车距离
你可以调整几个关键参数:
| 参数 | 说明 | 推荐值 |
|---|---|---|
| 跟车距离 | 前车距离(米) | 1.0 ~ 3.0 |
| 速度百分比 | 相对于限速的比例 | 80% ~ 120% |
| 是否忽略红绿灯 | 调试时可能用到 | False |
4.3.3 批量生成交通流
如果你想要一个热闹的街道,可以批量生成车辆和行人。我一般会写个函数:
def spawn_traffic(world, num_vehicles=50, num_walkers=30):
# 生成车辆
for _ in range(num_vehicles):
bp = random.choice(vehicle_bps)
spawn_point = random.choice(spawn_points)
vehicle = world.try_spawn_actor(bp, spawn_point)
if vehicle:
vehicle.set_autopilot(True)
# 生成行人
for _ in range(num_walkers):
bp = random.choice(walker_bps)
spawn_point = random.choice(walker_spawn_points)
walker = world.try_spawn_actor(bp, spawn_point)
if walker:
# 设置控制器...
pass
这里用try_spawn_actor而不是spawn_actor,是因为前者在失败时返回None而不是抛异常。嗯,做批量生成时,这个函数能省不少事。
4.4 避坑指南
最后,分享几个我踩过的坑:
- 地图切换后一定要重新获取world,否则你操作的还是旧地图,会报错。
- 不要同时开autopilot和手动控制,车辆会精神分裂。
- 行人控制器必须单独生成,别指望spawn完就能走。
- 批量生成时用try_spawn_actor,别让一个失败搞崩整个流程。
好了,这一章的内容就这些。说白了就是三件事:地图、车辆、交通流。你把这些搞明白了,后面的感知算法部署就有了一个稳定的测试环境。下一章咱们聊聊传感器配置,那才是真正有意思的部分。