1. 介绍
Carla在0.9.11中扩展了地图功能,增加了许多有意思的扩展功能。
包括在地图上控制指定建筑物的渲染,加载不同的图层等。
We have extended the maps API to provide the ability to toggle on and off every environment object individually. We also have new versions of all our maps, in which users can load and unload the different elements of the map by layers.
加载不同的地图图层(仅在以Opt结尾的地图中可用)。
控制指定建筑物的渲染。
除此在外。Carla_0911还更新了许多新的功能,感兴趣的读者可以参考Carla的版本更新公告。
2. 地图
Carla中地图由建筑物以及道路文件组成。道路文件以OpenDRIVE文件格式定义。
1. 切换地图
加载地图或者重新加载当前地图都会初始化当前Carla World对象。
# 加载Town01
world = client.load_world('Town01')
# 重新加载当前地图
world = client.reload_world()
使用get_available_maps获取可用地图。
print(client.get_available_maps())
2. 路标(Landmarks)
Carla使用路标表示OpenDRIVE中定义的交通标志,可以使用对应的API进行操作,有关的类有:
- carla.Landmark
carla.LandmarkOrientation
carla.LandmarkType - carla.Waypoint
- carla.Map
- carla.World
3. 路点(Waypoints)
Carla使用carla.Waypoints类表示路点。每个路点都包含一个carla.Transform变量,用于说明路点在地图上的位置以及路点相对于所在车道的方向。成员变量road_id,section_id,lane_id和s对应于OpenDRIVE文件中的道路描述,路点的id通过计算这四个值的哈希组合得到的。
一个路点中记录了它所在车道的信息。这些信息包括该车道的左右车道标记,车道是否在路口内,车道类型,车道宽度和是否允许车辆在该车道内变道。
# 使用路点获取车道信息
inside_junction = waypoint.is_junction()
width = waypoint.lane_width
right_lm_color = waypoint.right_lane_marking.color
4. 车道(Lanes)
Carla使用carla.LaneType类表示OpenDRIVE中定义的车道类型,使用carla.LaneMarking类表示车道内的道路标记。道路标记包含以下成员比变量:
- color:颜色
- lane_change:该车道是否允许左转,右转
- type:车道类型
- width:车道宽度
# 获取车道类型
lane_type = waypoint.lane_type
# 获取左侧车道标记的类型。
left_lanemarking_type = waypoint.left_lane_marking.type()
# 是否允许车道变更。
lane_change = waypoint.lane_change
5. 路口(Junctions)
Carla使用carla.Junction类表示OpenDRIVE中定义的路口。类中包含了一个bounding_box,用于识别路口中的车道和车辆,使用get_waypoints方法获取bounding_box内车道的起点和终点。
waypoints_junc = my_junction.get_waypoints()
Each pair is located at the start and end points of the junction boundaries.
6. 建筑物(Environment Objects)
CARLA使用enable_environment_objects方法控制指定建筑物的渲染。示例如下:
# 获取地图中的建筑物
world = client.get_world()
env_objs = world.get_environment_objects(carla.CityObjectLabel.Buildings)# 获取指定建筑物的ID
building_01 = env_objs[0]
building_02 = env_objs[1]
objects_to_toggle = {building_01.id, building_02.id}# 取消渲染
world.enable_environment_objects(objects_to_toggle, False)
# 开启渲染
world.enable_environment_objects(objects_to_toggle, True)
3. 地图图层
Carla地图具有不同的图层,每层图层代表不同的含义。具体如下:
- NONE 只渲染由道路,人行道,交通信号灯和交通标志组成的最小图层
- Buildings 建筑物图层
- Decals 墙砖(?)图层
- Foliage 植被图层
- Ground 地面图层
- ParkedVehicles 停放的车辆
- Particles 粒子特效
- Props 道具
- StreetLights 路灯
- Walls 墙壁
- All 渲染所有图层
There is a minimum layout that cannot be toggled off and consists of roads, sidewalks, traffic lights and traffic signs.
# 渲染最小图层,建筑物图层以及地图中停放的车辆
world = client.load_world('Town01_Opt', carla.MapLayer.Buildings | carla.MapLayer.ParkedVehicles)# 取消渲染建筑物图层
world.unload_map_layer(carla.MapLayer.Buildings)# 渲染建筑物图层
world.load_map_layer(carla.MapLayer.Buildings)
4. 示例代码
以下代码将在Carla中创建一个自定义的测试场景,并在测试车辆的周围添加动态障碍物。
import glob
import os
import sys
import random
import os
try:sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (sys.version_info.major,sys.version_info.minor,'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:pass
import carladef main():try:client = carla.Client('localhost', 2000)client.set_timeout(10.0)world = client.get_world()carla_map = world.get_map()maps = client.get_available_maps()blueprint_library = world.get_blueprint_library()# 创建车辆并开启自动驾驶ego_vehicle_bp = blueprint_library.find('vehicle.mercedes-benz.coupe')ego_vehicle_bp.set_attribute('color', '0, 0, 0')transform = random.choice(world.get_map().get_spawn_points())ego_vehicle = world.spawn_actor(ego_vehicle_bp, transform)ego_vehicle.set_autopilot(True)#创建动态障碍物next_vehicle_bp = blueprint_library.find('vehicle.mercedes-benz.coupe')next_vehicle_bp.set_attribute('color', '0, 255, 0')transform = random.choice(world.get_map().get_spawn_points())next_vehicle = world.spawn_actor(next_vehicle_bp, transform)next_vehicle.set_autopilot(False)previous_vehicle_bp = blueprint_library.find('vehicle.mercedes-benz.coupe')previous_vehicle_bp.set_attribute('color', '0, 0, 255')transform = random.choice(world.get_map().get_spawn_points())previous_vehicle = world.spawn_actor(previous_vehicle_bp, transform)previous_vehicle.set_autopilot(False)right_vehicle_bp = blueprint_library.find('vehicle.mercedes-benz.coupe')transform = random.choice(world.get_map().get_spawn_points())right_vehicle = world.spawn_actor(right_vehicle_bp, transform)right_vehicle.set_autopilot(False)while(True):spectator = world.get_spectator()transform = ego_vehicle.get_transform()spectator.set_transform(carla.Transform(transform.location + carla.Location(z=100),carla.Rotation(pitch=-90)))# 获取ego_vehicle当前所在道路的路点信息waypoint = carla_map.get_waypoint(ego_vehicle.get_location(),project_to_road=True, lane_type=(carla.LaneType.Driving))try:# 获取当前路点前方12m处的路点信息next_waypoint = waypoint.next(12.0)# 首先获取当前路点所在车道的右车道中的等价路点# 然后获取等价路点后方12m处的路点信息previous_waypoint = waypoint.get_right_lane().previous(12.0)# 同上,获取当前路点前方24m处的等价路点right_waypoint = waypoint.get_right_lane().next(24.0)#设置动态障碍物的位置next_vehicle.set_transform(next_waypoint[0].transform)previous_vehicle.set_transform(previous_waypoint[0].transform)right_vehicle.set_transform(right_waypoint[0].transform)except:print("next_waypoint: ",len(next_waypoint))print("previous_waypoint:", len(previous_waypoint))passfinally:actor_list = world.get_actors()# 根据ego_vehicle的id从actor_list中查找ego_vehiclevehicle = actor_list.find(ego_vehicle.id)print(vehicle)# 回收场景中的所有车辆vehicle_list = list(actor_list.filter('vehicle.*'))client.apply_batch([carla.command.DestroyActor(x) for x in vehicle_list])if __name__ == '__main__':try:main()except KeyboardInterrupt:print(' - Exited by user.')
5. 参考资料:
图片来源于Carla版本公告
Carla官方文档——地图
Carla-PythonAPI