4. CARLA世界构建:地图加载与切换、天气系统控制、静态与动态物体生成、蓝图库(BLUEPRINT)使用
好,我们进入第四章。这一章,咱们要真正动手搭建CARLA世界了。
说实话,我刚开始接触CARLA时,最兴奋的就是这部分。你想想看,一个空荡荡的虚拟城市,通过几行代码就能变得车水马龙、阴晴雨雪。这种掌控感,很爽。
但别急,爽归爽,坑也不少。我一个个说。
4.1 地图加载与切换
CARLA自带的地图不少,比如Town01到Town10。每个地图的布局、复杂度都不一样。
我个人习惯,测试简单场景用Town01,做复杂交通流用Town03或Town05。Town07是赛道,适合测极限工况。
加载地图的代码很简单:
import carla
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
# 加载Town03
world = client.load_world('Town03')
print(f"当前地图: {world.get_map().name}")
嗯,这里要注意。 load_world() 会重新加载整个世界,所有之前的对象都会被清空。如果你在仿真运行中切换地图,记得先保存必要数据。
如果你只想重置当前地图,可以用 reload_world():
# 重置当前世界
world = client.reload_world()
它不会改变地图,但会清空所有动态物体,恢复到初始状态。适合做场景重置。
4.2 天气系统控制
天气系统是CARLA的一大亮点。你可以控制阳光、云层、雨雪、风速,甚至路灯亮度。
说白了,就是一套参数化的环境调节器。
先看一个基础例子:
weather = carla.WeatherParameters(
cloudiness=80.0, # 云量 0-100
precipitation=30.0, # 降水量 0-100
sun_altitude_angle=45.0 # 太阳高度角 0-90
)
world.set_weather(weather)
为什么太阳高度角这么重要? 我建议你试试设成10度和80度,看看摄像头图像的区别。低角度时,阴影拉得很长,对视觉感知算法是个考验。
CARLA还内置了几种预设天气:
| 预设名称 | 适用场景 |
|---|---|
| ClearNoon | 晴天正午,标准测试 |
| CloudyNoon | 阴天,光照均匀 |
| WetNoon | 雨后路面,反光明显 |
| HardRainNoon | 暴雨,能见度低 |
| ClearSunset | 黄昏,逆光场景 |
用法很简单:
world.set_weather(carla.WeatherParameters.HardRainNoon)
4.3 蓝图库(BLUEPRINT)使用
蓝图库,说白了就是CARLA的“造物清单”。里面存着所有可以生成的东西——车辆、行人、传感器、交通标志等等。
获取蓝图库:
blueprint_library = world.get_blueprint_library()
然后你可以筛选:
# 获取所有车辆蓝图
vehicle_blueprints = blueprint_library.filter('vehicle.*')
# 获取所有行人蓝图
walker_blueprints = blueprint_library.filter('walker.pedestrian.*')
# 获取特定车型
audi_blueprint = blueprint_library.find('vehicle.audi.a2')
我记得第一次用蓝图库时,我直接 filter('*') 打印了所有蓝图,好家伙,几百个。后来我学会了按类别筛选,效率高多了。
蓝图还可以设置属性:
blueprint = blueprint_library.find('vehicle.audi.a2')
blueprint.set_attribute('color', '255,0,0') # 红色
blueprint.set_attribute('role_name', 'hero') # 角色名
role_name 属性很重要。自动驾驶车通常设为 'hero',其他车辆设为 'autopilot' 或 'scenario'。这样在日志分析时能快速区分。
4.4 静态与动态物体生成
有了蓝图,生成物体就水到渠成了。
4.4.1 生成车辆
# 选择一个生成点
spawn_points = world.get_map().get_spawn_points()
spawn_point = spawn_points[0]
# 生成车辆
vehicle = world.spawn_actor(blueprint, spawn_point)
你想想看,如果生成点被占了怎么办? spawn_actor() 会直接报错。所以 我建议用 try_spawn_actor():
vehicle = world.try_spawn_actor(blueprint, spawn_point)
if vehicle is None:
print("生成失败,换个位置试试")
4.4.2 生成行人
walker_bp = blueprint_library.find('walker.pedestrian.0001')
walker = world.spawn_actor(walker_bp, carla.Transform(location))
行人需要控制器才能动起来:
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)
4.4.3 生成静态物体
静态物体包括路灯、垃圾桶、路障等。它们属于 static.prop 类别:
prop_bp = blueprint_library.find('static.prop.streettrash')
prop = world.spawn_actor(prop_bp, carla.Transform(location))
4.5 综合示例:构建一个测试场景
最后,我给你们看一个完整的例子。这是我做传感器融合测试时常用的场景:
import carla
import random
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
world = client.load_world('Town03')
# 设置天气
world.set_weather(carla.WeatherParameters.CloudyNoon)
# 获取蓝图
bp_lib = world.get_blueprint_library()
vehicle_bp = bp_lib.find('vehicle.audi.a2')
vehicle_bp.set_attribute('role_name', 'hero')
# 生成主车
spawn_points = world.get_map().get_spawn_points()
hero = world.spawn_actor(vehicle_bp, spawn_points[0])
# 生成10辆随机车辆
for i in range(10):
bp = random.choice(bp_lib.filter('vehicle.*'))
point = random.choice(spawn_points)
vehicle = world.try_spawn_actor(bp, point)
if vehicle:
vehicle.set_autopilot(True)
# 生成5个行人
for i in range(5):
bp = random.choice(bp_lib.filter('walker.pedestrian.*'))
location = carla.Location(x=100+random.uniform(-10,10),
y=100+random.uniform(-10,10),
z=0.5)
walker = world.try_spawn_actor(bp, carla.Transform(location))
print("场景构建完成!")
print(f"主车: {hero.type_id}")
print(f"车辆数: {len(world.get_actors().filter('vehicle.*'))}")
print(f"行人: {len(world.get_actors().filter('walker.*'))}")
这个例子涵盖了地图加载、天气设置、蓝图筛选、车辆和行人生成。你跑一遍,就能看到一个活生生的虚拟世界。
好,这一章就到这儿。下一章我们聊聊传感器——摄像头、激光雷达、毫米波雷达,怎么配、怎么用、怎么采数据。到时候见。