CARLA 笔记(07)— 地图和导航(Landmarks、Waypoints、Lanes、Junctions、Environment Objects、路径点导航、地图导航、分层和非分层地图)

1. 地图

地图包括城镇的 3D 模型和道路定义。地图的道路定义基于 OpenDRIVE 文件,这是一种标准化的带注释的道路定义格式。

OpenDRIVE 定义道路、车道、路口等的方式决定了 Python API 的功能以及做出决策背后的原因。

1.1 更换地图

要改变地图,世界也必须改变。仿真将从零开始重新创建。也可以在新的世界中使用相同的地图重新开始,或者同时改变地图和世界。

  • reload_world() 使用同样的地图创建一个世界的对象
  • load_world() 改变当前地图并创建一个新的世界
# 加载地图
world = client.load_world('Town01')
# world = client.reload_world()

# 获取可用地图列表
print(client.get_available_maps())

每个地图都有一个与当前加载的城市名称相匹配的 name 属性,例如 Town01 。在客户端可以获取可用地图的列表:

print(client.get_available_maps())

1.2 Landmarks

opendrive 文件中定义的交通标志被转换为 CARLA ,作为可以从 API 中查询的地标对象。以下方法和类可用于操作和处理地标对象:

  • carla.Landmark:对应 OpenDRIVEsignals

carla.LandmarkOrientation:根据道路的几何形状定义地标的方向
carla.LandmarkType:地标类型

  • carla.Waypoint:根据距离来获取 landmarks
  • carla.Map 可以查询地图中的所有地标,或者某一类型的地标
  • carla.Worldlandmarkscarla.TrafficSigncarla.TrafficLight 的中介
# 获取地标
print(world)
map = world.get_map()
print(map)
waypoints = map.generate_waypoints(100000)
print(waypoints)
waypoint = waypoints[4]
print(waypoint)
landmarks = waypoint.get_landmarks(20000.0, True)
print(landmarks)

1.3 Waypoints

carla.WaypointCARLA 世界中的一个 3D 定向点,对应于 OpenDRIVE 车道。所有与路径点相关的内容都发生在客户端,与服务器的通信只需要一次就可以获得包含路径点信息的映射对象。

同一道路内距离小于 2 厘米的路径点 id 相同。

每一个 waypoint 包含一个 carla.Transform 对象,它表示在地图中的位置以及包含它的车道方向。carla 中的变量 road_idsection_idlane_ids 对应 OpenDRIVER 中的道路。waypoint 中的 id 是由这 4 个值的哈希组合而成。

Waypoint 保存有关包含它的车道的信息。这些信息包括车道的左车道和右车道标记,一个布尔值,用于确定它是否在路口内,车道类型、宽度和车道更改许可。

# Access lane information from a waypoint
inside_junction = waypoint.is_junction()
width = waypoint.lane_width
right_lm_color = waypoint.right_lane_marking.color

1.4 Lanes

OpenDRIVE standard 1.4 定义的车道类型被转换成 Carla 中 carla.LaneType 的一系列枚举值。

车道周围的车道标记通过 carla.LaneMarking 访问。车道标记由一系列变量定义:

  • color: carla.LaneMarkingColor 是定义标记颜色的枚举值。
  • lane_change: carla.LaneChange 说明车道是否允许左转、右转、双转或不允许。
  • type: carla.LaneMarkingTypeenum 值,根据 OpenDRIVE 标准定义标记类型。
  • width: 定义标记的厚度。

下面的例子显示了获取有关特定航路点的车道类型、车道标记和换道许可的信息:

# Get the lane type of the waypoint
lane_type = waypoint.lane_type

# Get the type of lane marking on the left.
left_lanemarking_type = waypoint.left_lane_marking.type()

# Get available lane changes for this waypoint.
lane_change = waypoint.lane_change

1.5 Junctions

carla.Junction 代表一个 OpenDRIVEjunction 。这个类包含一个带有边界框的路口,用于识别其中的车道或车辆。

carla.Junction 类包含一个 get_waypoints 方法, 该方法为路口内的每个车道返回一对路点。每一对位于接合边界的起点和终点。

waypoints_junc = my_junction.get_waypoints()

1.6 Environment Objects

Carla 地图上的每个对象都有一组相关的变量,可以在 carla.EnvironmentObject 找到。这些变量中包含一个 unique ID,可用于 切换 该对象在地图上的可见性。你可以使用 Python API 根据每个环境对象的语义标签获取 semantic tag::

    # Get the buildings in the world
    world = client.get_world()
    env_objs = world.get_environment_objects(carla.CityObjectLabel.Buildings)

    # Access individual building IDs and save in a set
    building_01 = env_objs[0]
    building_02 = env_objs[1]
    objects_to_toggle = {building_01.id, building_02.id}

    # Toggle buildings off
    world.enable_environment_objects(objects_to_toggle, False)
    # Toggle buildings on
    world.enable_environment_objects(objects_to_toggle, True)

2. 导航

Carla 中的导航是通过 Waypoint API 来管理的,是一些列来自 carla.Waypointcarla.Map 方法的组合。

客户端首先必须与服务端通信来获取地图对象,其中包含路径点信息。这只需要执行一次,所有的后续查询操作都在客户端执行。

2.1 通过路径点导航

Waypoint API 公开了一些方法,这些方法允许路径点相互连接,并沿着道路构建一条道路供车辆导航。

  • next(d) 创建一个位于车道方向近似距离 d 之内的路径点列表,该列表包含每个可能偏差的一个路径点。
  • previous(d) 创建一个位于车道相反方向近似距离 d 之内的路径点列表,该列表包含每个可能偏差的一个路径点。
  • next_until_lane_end(d)previous_until_lane_start(d) 返回一个以 d 为间隔的路径点列表,列表分别从当前路径点到达其路径的起点和终点。
  • get_right_lane()get_left_lane() 返回相邻车道中的等效路径点(如果有的话)。换道机动可以通过找到左/右车道上的下一个航路点,并移动到它。
# Find next waypoint 2 meters ahead.
waypoint = waypoint.next(2.0)

2.2 生成地图导航

客户端需要向服务端发送请求以获取 .xodr 地图文件并解析为 carla.Map 对象,这仅仅需要执行一次。

map = world.get_map()	# 获取地图对象

地图对象包含用于创建车辆推荐的生成点,可以获得生成点的一个列表,每一个生成点包含一个 carla.Transform 。有些生成点可能已经被占用了,这样会因为碰撞而无法创建车辆。

spawn_points = world.get_map().get_spawn_points()

你可以从路径点开始,通过获得最近的路径点到一个指定的位置或到地图的 OpenDRIVE 定义中的一个特定的 road_id , lane_ids 值:

# Nearest waypoint in the center of a Driving or Sidewalk lane.
waypoint01 = map.get_waypoint(vehicle.get_location(),project_to_road=True, lane_type=(carla.LaneType.Driving | carla.LaneType.Sidewalk))

#Nearest waypoint but specifying OpenDRIVE parameters. 
waypoint02 = map.get_waypoint_xodr(road_id,lane_id,s)

下面的示例演示如何生成一组路径点来可视化城市车道。这将在地图上为每个道路和车道创建路径点。它们之间的距离大约是 2 米:

waypoint_list = map.generate_waypoints(2.0)

要生成道路拓扑的最小图,请使用下面的示例。这将返回一个路径点对(元组)列表。每一对中的第一个元素与第二个元素连接,它们都定义了地图中每个车道的起点和终点。有关此方法的更多信息可以在 PythonAPI 中找到。

waypoint_tuple_list = map.get_topology()

下面的例子将 carla.Transform 转换为 carla.GeoLocation 形式的地理维度和经度坐标。

my_geolocation = map.transform_to_geolocation(vehicle.transform)

将路况信息以 OpenDRIVE 格式保存到磁盘,示例如下:

info_map = map.to_opendrive()

3. 地图分类

carla 生态系统中有 8 个城镇,每个城镇都有两种地图,非分层和分层。图层指的是地图中的分组对象,由以下几个部分组成:

  • 空的
  • 建筑
  • 贴花
  • 树叶
  • 地面
  • 泊车
  • 粒子
  • 道具
  • 路灯
  • 所有

3.1 不分层地图

非分层地图如下表所示(点击城镇名称可以查看布局的俯视图)。在 carla 0.9.11 之前所有的层在任何时候都存在,并且不能在这些映射中切换打开或关闭,这是唯一一种可用的地图。

用户可以 自定义地图,甚至 创建一个新的地图 来在 CARLA 中使用。

  • Town01 由 “T形路口” 组成的基本城镇布局。
  • Town02 与 Town01 相似,但是更小
  • Town03 最复杂的城镇,有5车道的交叉路口,一个环形,不平,一条隧道,等等。
  • Town04 一条有高速公路和一个小镇的无限环线。
  • Town05 有十字路口和一座桥的方格城镇。每个方向都有多个车道。对变道很有用。
  • Town06 高速公路长,有许多高速公路出入口。它也有密歇根左翼。
  • Town07 乡村环境,道路狭窄,有谷仓,几乎没有红绿灯。
  • Town10 城市环境与不同的环境,如大道或步道,和更现实的纹理。

3.2 分层地图

分层地图的布局与非分层地图相同,但可以在地图的图层上切换和关闭。有一个不能切换的最小布局,由道路、人行道、交通灯和交通标志组成。可以使用后缀 _Opt 标识分层映射,例如,Town01_Opt 。使用这些地图,可以通过 Python API 加载卸载 层:

# Load layered map for Town 01 with minimum layout plus buildings and parked vehicles
world = client.load_world('Town01_Opt', carla.MapLayer.Buildings | carla.MapLayer.ParkedVehicles)

# Toggle all buildings off
world.unload_map_layer(carla.MapLayer.Buildings)

# Toggle all buildings on   
world.load_map_layer(carla.MapLayer.Buildings)

查看所有层按顺序加载和卸载的示例:
demo

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wohu007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值