自动驾驶—CARLA仿真(28)地图与导航(Maps and navigation)

地图(The map)

一张地图既包含城镇的3D模型,也包含其道路定义。地图的道路定义基于OpenDRIVE文件------一种标准化、带注释的道路定义格式。OpenDRIVE 1.4标准对道路、车道、交叉口等元素的定义方式,决定了Python API的功能及其设计决策背后的逻辑。

Python API充当一个高级查询系统,用于在这些道路中进行导航。该API持续演进,以提供更丰富的工具集。

更换地图(Changing the map)

要更换地图,必须同时更换世界(world)。模拟将从头开始重新创建。你可以选择使用相同地图重启一个新世界,也可以同时更换地图和世界:

  • reload_world():使用相同地图创建一个新的世界实例。
  • load_world():更换当前地图并创建一个新世界。
python 复制代码
world = client.load_world('Town01')

每张地图都有一个name属性,与当前加载的城市名称一致(例如Town01)。要获取可用地图列表:

python 复制代码
print(client.get_available_maps())

地标(Landmarks)

OpenDRIVE文件中定义的交通标志会被转换为CARLA中的地标(landmark)对象,并可通过API进行查询。以下方法和类可用于操作和处理地标对象:

  • carla.Landmark 对象表示OpenDRIVE信号。该类的属性和方法描述了地标的特性及其影响范围。
  • carla.LandmarkOrientation 表示地标相对于道路几何定义的方向。
  • carla.LandmarkType 包含常见的地标类型,便于转换为OpenDRIVE类型。
  • carla.Waypoint 可获取位于其前方指定距离内的地标,并可指定要获取的地标类型。
  • carla.Map 可检索地标集合,返回地图中所有地标,或具有相同ID、类型或组的地标。
  • carla.World 作为地标与模拟中代表它们的 carla.TrafficSigncarla.TrafficLight 之间的中介。
python 复制代码
my_waypoint.get_landmarks(200.0, True)

路径点(Waypoints)

carla.Waypoint 是CARLA世界中一个带有方向的3D点,对应于OpenDRIVE中的车道。所有与路径点相关的操作均在客户端完成;仅需一次与服务器通信即可获取包含路径点信息的地图对象。

每个路径点包含一个 carla.Transform,用于说明其在地图上的位置及所在车道的方向。变量 road_idsection_idlane_ids 对应于OpenDRIVE道路定义。路径点的ID由这四个值的哈希组合生成。

注意

同一条道路内间距小于2厘米的路径点共享相同的ID。

路径点保存了其所在车道的信息,包括左右车道标线、是否位于交叉口内、车道类型、宽度以及变道权限等。

python 复制代码
# 从路径点访问车道信息
inside_junction = waypoint.is_junction()
width = waypoint.lane_width
right_lm_color = waypoint.right_lane_marking.color

车道(Lanes)

OpenDRIVE 1.4标准定义的车道类型在API中通过 carla.LaneType 以一系列枚举值表示。

车道周围的标线通过 carla.LaneMarking 访问。车道标线由以下变量定义:

  • colorcarla.LaneMarkingColor 枚举值,定义标线颜色。
  • lane_changecarla.LaneChange 指明该车道是否允许向左、向右、双向或禁止变道。
  • typecarla.LaneMarkingType 枚举值,根据OpenDRIVE标准定义标线类型。
  • width:定义标线的厚度。

以下示例展示了如何获取特定路径点处的车道类型、车道标线及变道权限信息:

python 复制代码
# 获取路径点的车道类型
lane_type = waypoint.lane_type

# 获取左侧车道标线类型
left_lanemarking_type = waypoint.left_lane_marking.type()

# 获取该路径点允许的变道方向
lane_change = waypoint.lane_change

交叉口(Junctions)

carla.Junction 表示一个OpenDRIVE交叉口。该类通过一个包围盒(bounding box)来识别交叉口内的车道或车辆。

carla.Junction 类包含 get_waypoints 方法,为交叉口内每条车道返回一对路径点。每对路径点分别位于交叉口边界的起点和终点。

python 复制代码
waypoints_junc = my_junction.get_waypoints()

环境对象(Environment Objects)

CARLA地图上的每个对象都有一组关联变量(详见相关文档)。其中包括一个唯一ID,可用于切换该对象在地图上的可见性。你可以使用Python API根据对象的语义标签(semantic tag)获取其ID:

python 复制代码
# 获取世界中的建筑物
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)

CARLA中的导航(Navigation in CARLA)

CARLA中的导航通过路径点API(Waypoint API)实现,该API结合了 carla.Waypointcarla.Map 的方法。

客户端最初需与服务器通信一次,以获取包含路径点信息的地图对象。此后所有查询均在客户端本地完成。

路径点导航(Navigating through waypoints)

路径点API提供了多种方法,使路径点相互连接,从而构建供车辆导航的道路路径:

  • next(d):沿车道方向返回距离约为 d 的路径点列表。若存在多个可能的分支,列表中会包含每个分支对应的路径点。
  • previous(d):沿车道反方向返回距离约为 d 的路径点列表,同样包含所有可能分支。
  • next_until_lane_end(d)previous_until_lane_start(d):分别返回从当前路径点到其所在车道末端和起点的一系列路径点,相邻点间距约为 d
  • get_right_lane()get_left_lane():返回相邻车道中对应的路径点(如果存在)。通过查找右侧/左侧车道的下一个路径点并移动至该点,即可实现变道操作。
python 复制代码
# 查找前方2米处的下一个路径点
waypoint = waypoint.next(2.0)

客户端需向服务器请求 .xodr 地图文件,并将其解析为 carla.Map 对象。此操作只需执行一次。

获取地图对象:

python 复制代码
map = world.get_map()

地图对象包含推荐的车辆生成点(spawn points)。可通过以下方法获取这些生成点列表(每个生成点均为一个 carla.Transform)。请注意,生成点可能已被占用,导致因碰撞而无法成功生成车辆。

python 复制代码
spawn_points = world.get_map().get_spawn_points()

你可以通过以下方式开始使用路径点:获取距离某位置最近的路径点,或根据地图OpenDRIVE定义中的 road_idlane_ids 值获取对应路径点:

python 复制代码
# 获取最近的Driving或Sidewalk车道中心路径点
waypoint01 = map.get_waypoint(vehicle.get_location(), project_to_road=True, lane_type=(carla.LaneType.Driving | carla.LaneType.Sidewalk))

# 根据OpenDRIVE参数指定获取最近路径点
waypoint02 = map.get_waypoint_xodr(road_id, lane_id, s)

以下示例展示如何生成一组路径点以可视化城市车道。该操作将在地图所有道路和车道上创建路径点,间距约为2米:

python 复制代码
waypoint_list = map.generate_waypoints(2.0)

要生成道路拓扑的最小图结构,可使用以下示例。该方法返回一个路径点对(元组)列表,每对中的第一个路径点连接到第二个,二者分别定义地图中每条车道的起点和终点。更多详情请参阅Python API文档。

python 复制代码
waypoint_tuple_list = map.get_topology()

以下示例将 carla.Transform 转换为地理经纬度坐标(carla.GeoLocation 格式):

python 复制代码
my_geolocation = map.transform_to_geolocation(vehicle.transform)

使用以下示例可将道路信息以OpenDRIVE格式保存到磁盘:

python 复制代码
info_map = map.to_opendrive()

CARLA地图(CARLA maps)

CARLA生态系统中共有八座城镇(实际列出十座),每座城镇均有两种地图类型:非分层地图(non-layered)和分层地图(layered)。"层"(Layers)指地图中按类别分组的对象,包括:

  • NONE
  • Buildings(建筑物)
  • Decals(贴花)
  • Foliage(植被)
  • Ground(地面)
  • ParkedVehicles(停放车辆)
  • Particles(粒子效果)
  • Props(道具)
  • StreetLights(路灯)
  • Walls(围墙)
  • All(全部)

非分层地图(Non-layered maps)

下表列出了非分层地图(点击城镇名称可查看俯视布局图)。此类地图中所有图层始终存在,无法开启或关闭。在CARLA 0.9.11版本之前,仅提供此类地图。

注意

用户可自定义地图,甚至创建全新地图用于CARLA仿真。

城镇 简介
Town01 小型简单城镇,含河流和多座桥梁。
Town02 小型简单城镇,混合住宅与商业建筑。
Town03 较大的城市地图,含环岛和大型交叉口。
Town04 山区小镇,拥有特殊的"8字形"无限高速公路。
Town05 方格状城镇,含十字交叉口和桥梁,每方向多车道,适合变道测试。
Town06 多车道长高速公路,含多个出入口,还有michigan左转设计。
Town07 乡村环境,道路狭窄,有玉米地、谷仓,几乎无交通灯。
Town08 用于Leaderboard挑战赛的"隐藏"城镇。
Town09 用于Leaderboard挑战赛的"隐藏"城镇。
Town10 市中心城区,含摩天大楼、住宅区和滨海步道。
Town11 未装饰的大型地图,用于验证"大型地图"功能。
Town12 大型地图,包含高层、住宅和乡村等多种区域。

注意

Town06和Town07为额外内容,不包含在标准CARLA包中。导入方法详见"附加地图"部分。

分层地图(Layered maps)

分层地图的布局与非分层地图相同,但可动态开关各图层。存在一个无法关闭的最小布局,包含道路、人行道、交通灯和交通标志。分层地图通过后缀 _Opt 识别(例如 Town01_Opt)。可通过Python API加载/卸载图层:

python 复制代码
# 加载Town01分层地图,包含最小布局+建筑物+停放车辆
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)

自定义地图(Custom maps)

CARLA设计为高度可扩展和可定制,适用于专业应用场景。除内置的众多地图和资源外,用户还可创建并导入新地图、路网和资源,以构建专属的CARLA仿真环境。以下文档详细说明了构建和集成自定义地图的步骤:

靠左行驶(Left handed traffic)

CARLA支持OpenDRIVE文件中定义的靠左行驶规则。要在任意道路上启用靠左行驶,需在OpenDRIVE XML文件中添加 rule="LHT" 属性:

xml 复制代码
<road name="Road 0" length="1.3310253693587601e+1" id="0" junction="-1" rule="LHT">
    <link>
        <predecessor elementType="road" elementId="3" contactPoint="end" />
        <successor elementType="road" elementId="10" contactPoint="start" />
    </link>
...
</road>

注意

默认采用靠右行驶规则。未指定 rule 属性(或参数无效)的道路将被视为靠右行驶。也可显式添加 rule="RHT" 以明确设置。

CARLA将对所有设置了 rule="LHT" 属性的道路应用靠左行驶规则。

请注意,靠左或靠右行驶规则不仅影响交通行为,还会影响作用于该道路的交通标志和信号。因此,若地图中手动放置了适用于靠右行驶的资产(如路牌或交通灯),则需相应调整。对于在OpenDRIVE定义中为靠左行驶设置的交通灯,CARLA在导入地图时会自动将其放置在合适位置。

附加地图(Additional maps)

每个CARLA版本均提供一个额外的资源和地图包,其中包含Town06和Town07地图。为减小主安装包体积,这些内容单独存放,需在主包安装完成后另行导入。

  1. 下载与你使用的CARLA版本对应的附加包。

  2. 解压该包:

    Linux系统:

    将包移至 Import 文件夹,运行以下脚本解压:

    bash 复制代码
    cd path/to/carla/root
    ./ImportAssets.sh

    Windows系统:

    直接将包内容解压至CARLA根目录。

相关推荐
Lightning-py2 小时前
伟大思想
人工智能
Wang201220132 小时前
LSTM和Transformer对比
人工智能·算法·架构
CES_Asia2 小时前
2026科技热点预言:CES Asia“具身智能”展区已成产业风向标
大数据·人工智能·科技·机器人
core5122 小时前
神经网络 (Neural Networks):模仿大脑的超级机器
人工智能·深度学习·神经网络
GitCode官方2 小时前
Qwen-Image-Edit-2509 正式上线 AtomGit AI:重新定义 AI 图像编辑体验!
人工智能·计算机视觉·atomgit
SCBAiotAigc2 小时前
Chrome的cookie编辑插件EditThisCookie
人工智能·chrome·python·ubuntu
啊阿狸不会拉杆2 小时前
《数字图像处理》实验6-图像分割方法
图像处理·人工智能·算法·计算机视觉·数字图像处理
不惑_2 小时前
通俗理解什么是神经网络
人工智能·深度学习·神经网络
愚公搬代码2 小时前
【愚公系列】《扣子开发 AI Agent 智能体应用》014-基于大模型的企业知识库(知识库的理论基础 RAG)
人工智能