1.前言
在自动驾驶中,路径规划是高度依赖于高精地图的,因此在系列课程的第一节,先讲一下高精地图大概的概念,以及lanelet2格式高精地图的表示方法,还有AutowareAuto中是如何发布和可视化lanelet2高精地图的,打造基础印象和概念。
2.高精地图
2.1高精地图的作用
为自动驾驶车辆提供短期不变的先验信息,以弥补感知设计的传感器的局限性,比如:单目视觉的尺度丢失问题,lidar在雨雾天气的效果以及反射等问题。
2.2.高精地图保存的信息
可能包括(此处不全面,后面补充)车道线,掉头,停止线,让行标志等路面因素,也可能包括架通信号灯,标志牌,龙门架,杆子等高出地面的信息。
2.3.高精地图的表示方式
不同的图商有不同的格式,比如apollo的OpenDRIVE格式, Autoware使用的lanelet2格式,每种格式表达信息的方式不同,本文中将讲解lanelet2格式。
3.lanelet2 高精地图
3.1 lanelet2是什么
Lanelet2是一套面向自动驾驶(highly automated driving ,HAD)的地图框架,使用C++实现。
3.2 lanelet2 设计理念
下图描述了自动驾驶模块对于HAD map(为HAD服务的地图我们把它简称为HAD map)的使用情况:
从上图可以看出高精地图在自动驾驶中起到的作用为:
(1)使用路网(road network)信息进行全局路线规划(routing)、行为决策以及目标预测;
(2)需要结合车道和其他图层的信息的模块:诸如路径规划(path planning)、场景理解等;
(3)需要直接访问图层元素的模块:主要是定位模块,将地图的某些图层(比如点云图)用于配准定位;
routing和path planning的区别:routing是指在导航中获取的从起点到终点的路线,是全局的规划,而path planning是指根据当前的全局规划选择接下来的100米的路径,包括走哪条车道、是否变道等,是局部的规划,两者相交(路径规划需要满足routing的要求)但不相同。
从这三个方面理解lanelet2的设计理念:
(1)路网
路网即地图中道路的拓扑关系,路网语义的主要目的之一就是产生routing,即起点到终点的全局路线,自动驾驶系统中的routing不仅需要知道车的路线(road级别),还需要知道车道(lane)级别的信息,比如说可以走哪些车道、车道是不是公交专用道、车道能否变道、能否借道等等。行为决策也和路网信息高度相关,目前的HAD系统里,行为决策的实现依然是基于交通规则的,对规则列表的适配需要结合routing信息。目标的预测也类似,道路交通中的目标预测一个重要的先验就是目标在多数情况下会在自己的车道上行驶或者遵循交通规则变道,针对不同的道路参与者,交通规则也不一定相同,所以,一个合格的自动驾驶地图,应当包含所有交通参与者的道路规则,比如说非机动车道以及行人可能出现的区域和运动的方向等。
(2)车道和环境要素信息
车道的几何信息对于AD系统的规划尤其是动作规划尤为关键,HAD规划系统产生的轨迹并不一定严格遵循车道中心线,在安全和 车道道宽 允许的情况下动作规划模块通常倾向于产生平滑且舒适度高的轨迹,这就意味着我们不仅需要知道车道中心线的位置,车道的边缘坐标对于HAD系统也是非常有意义的。
(3)物理元素
基于配准的定位需要直接访问某些地图中的某些物理元素,这些物理元素的类别和具体的定位方法相关。包括landmark(路标)、护栏、道路边缘等信息,HAD map理论上应该包含这些物理元素以支持基于地图的配准定位。
设计理念总结:
称上述可以被观测到的要素为地图的 物理层(physical layer) ,诸如路标、红绿灯、交通标志、防撞栏等等,其他的所有地图元素,比如车道(lane),是这些物理元素的一种抽象表示。同样地,交通规则是规则源(例如交通信号灯)与其所应用的车道之间的关联。根据这些物理元素我们可以追踪这些关联信息,我们称这些元素为地图的 关联层(relational layer)。
并非地图的所有元素都可以与物理层相关联,因为道路交通中往往会包含隐含的规则,比如说在路口内,车道线和车道边缘并没有画出来,但是它们是存在的,HAD map必须包含这些隐含的元素以保证路网拓扑的连通性,这些元素都是我们的行为“常识”引入的,不和实际的可观测元素关联。站在地图可验证性的角度来看, Lanelet2作者认为应当尽可能避免这种“常识”元素和规则,一方面是因为缺乏物理元素关联,给地图验证带来困难,另一方面,“常识”有时候也是会发生变化的。
可拓展性也是HAD map必须具备的特性,随着无人车算法的发展,必然对于地图的需求也会发生变化,另外地图得适配各个国家的交通规则,这些都对地图的可扩展性提出了要求。总的来说,为了设计面向自动驾驶的地图,lanelet2认为需要遵循一下原则:
- 可以通过将地图上的所有信息与可观察元素(物理元素)相关联来进行验证;
- 涵盖所有潜在的可通行区域,包括道路以外的;
- 地图上各个车道与区域之间的交互必须是可识别且可理解的,通过地图要能够知道哪些车道间可以进行变道;
- 地图应当包含对其他类型交通参与者(比如说行人、非机动车)的交通规则和信息;
- 应当将地图的信息源和其对道路交通的影响进一步分离,以保证元素变更的可追踪性;
- 可扩展性和模块化;
- 可以轻松修改,以实现地图的更新;
结合以上基本原则,我们来看一下Lanelet2对于地图元素的划分和定义,以及结合osm的Lanelet2地图格式。
3.3 Lanele2架构
由上述的设计理念可知,Lanelet2地图可以划分为:
- 物理层(physical layer):主要包含一些能具体观测到的元素
- 关联层(relational layer):物理层的元素被进一步关联到车道、区域和交通规则等信息
- 拓扑层(topological layer)
Lanelet2默认的格式为XML形式的OSM地图格式,可以使用OSM地图编辑器进行编辑和可视化。Lanelet2假定地图中的所有元素均能投射到平面,不过元素的高度信息也会被保存,以避免将立交桥处理成十字路口的情况。当加载地图的时候,为了方便地图的使用,会采用通用莫卡托投射(UTM,Universal Transverse Mercator)将地图投射到笛卡尔坐标系。
Lanelet2 基础元素:
Lanelet2地图主要包含6类基元(18年论文中为5类,后扩展为6类),分别是:
- Points:点
- Linestrings: 由点前后连接构成的折线序列
- Polygons:多边形
- Lanelets:车道的原子单元,或者说对车道的最小划分
- Areas:区域,类似与lanelet,但是它一般用于描述建筑、停车区等独立区域
- Regulatory elements:控制元素,能产生交通规则的元素,如信号灯、限速牌等
前三类为物理层,其余为关联层,每一个元素都有自己唯一的ID,我们逐一分析基元的含义。
Points:
Points是地图的最基础元素,单个的Points也能表示一些含义,比如说一个柱子,但是更多情况下,点是作为Linestrings的一部分出现的。一个Point会包含三维位置信息,Points也是Lanelet2中唯一真实包含位置信息的基础元素,其他基元直接或间接地由点组成。
Lanelet2中的Points会被直接映射为OSM中的Node,其中的ele的tag主要描述点的海拔高度(WGS84坐标系下)。下面是一个points的例子:
<node id="1001" visible="true" version="1" lat="35.61834168094" lon="139.78068648494">
<tag k="ele" v="-2.5" />
<tag k="local_x" v="89576.40395318175" />
<tag k="local_y" v="42302.65455295006" />
<tag k="mgrs_code" v="54SUE895423" />
<tag k="subtype" v="" />
<tag k="type" v="" />
</node>
Linestrings
如下图所示,Linestrings是对一组有序的点进行线性插值构成的线串,用于描述地图中元素的轮廓,包括道路标线、路缘、外墙、栅栏等,它也能描述一些虚拟的线,比如说车道线等,Linestrings不能包含重复的点,且不能相交,Linestrings必须包含type属性以确定其用途。
Polygons
Polygons也就是多边形的意思,和Linestrings类似,也是一组折线,区别在于Polygons的第一个点和最后一个点是连接的,从而能够闭环形成一个图形。多边形通常用作自定义元素(例如感兴趣的区域)。
Lanelet
Lanelet定义了地图中车道的原子段,原子段即最小分割,指在这一段lane上交通规则是不变的。下图是lanelet的定义,可见一个lanelet包含左右两条lanestrings分别表示车道的左右边缘,构成了lanelet的可行驶区域(drivable area)。lanelet通常还会包含Regulatory elements指定该lanelet上的交通规则,连续的两端lanelet共享左右linestrings的端点,Lanelet边缘的类型将被用于判断能否变道。车道中心线是非必须元素,可以指定也可以不指定,不指定的话在加载osm是Lanelet2库会自动生产中心线。
下面是一个lanelet的例子,我们必须能够直接从lanelet元素中获得车道的限速,可以通过两种方法指定lanelet的限速:第一是通过关联一个type为SpeedLimit的控制元素来指定限速,第二则是如下例所示设定location的tag来指定限速(如果是在德国市区,那么限速就是50kph)。
<relation id='45064' visible='true' version='1'>
<member type='way' ref='43822' role='left' />
<member type='way' ref='43564' role='right' />
<tag k='location' v='urban' />
<tag k='one_way' v='yes' />
<tag k='region' v='de' />
<tag k='subtype' v='road' />
<tag k='type' v='lanelet' />
</relation>
lanelet元素对应于OSM格式中的relation,下图是该lanelet(id为45064)在JOSM中的可视化效果(图中粉色线):
Area
Area类似于Lanelet,是指由多个linestrings构成的一片区域, 通常用来描述停车位、绿化带、建筑物等,Area也可以关联控制元素以添加交通规则。下图使用Area描述了两个停车区:
具体到osm format中,采用type为multipolygon的relation描述Area,停车区的例子如下:
<relation id='45420' visible='true' version='1'>
<member type='way' ref='44024' role='outer' />
<member type='way' ref='44402' role='outer' />
<member type='way' ref='44768' role='outer' />
<tag k='location' v='urban' />
<tag k='region' v='de' />
<tag k='subtype' v='parking' />
<tag k='type' v='multipolygon' />
</relation>
该Area元素对应于下图中粉红色框内的停车区:
Regulatory elements(控制元素)
控制元素定义了地图中的交通规则,诸如限速、优先规则、信号灯等,控制元素需要被lanelet或者area引用才能发挥作用。下图描述的是信号灯的控制元素,该控制元素包含停止线以及红路灯:
4.Lanelet2项目
Lanelet2论文的另外一个工作就是基于以上设计理念和基本要素开源了一套C++编写的地图框架,lanelet2项目依靠catkin编译,所以每个模块都是以ros package的形式进行管理,各个模块内容如下:
-
lanelet2:基础模块,没有具体实现
-
lanelet2_core:实现了基元、地理计算等核心库
-
lanelet2_io:lanelet地图的IO库
-
lanelet2_traffic_rules:提供地图交通规则的支持
-
lanelet2_projection:提供WGS84坐标系到指定坐标系下的投影的实现
-
lanelet2_routing:提供基于lanelet地图的routing功能
-
lanelet2_maps:lanelet2官方提供的示例地图
-
lanelet2_python:lanelet2的python接口
-
lanelet2_validation:验证Lanelet2地图
-
lanelet2_examples:教程和示例
可以通过lanelet2_examples下面的代码进一步学习lanelet2项目的API的使用。具体使用方法本文不再赘述,下面我们主要关注lanelet2在自动驾驶系统Autoware中的应用。
5.Autoware对lanelet2的扩展
Autoware最新的Map模块已经舍弃了先前的基于csv的map format,转而使用基于lanelet2的OSM格式地图,Autoware的map模块在AD系统中的结构和数据流如下图所示:
lanelet2地图在系统中被称为vector map,主要描述道路交通的语义信息,目前来说vector map主要被用于planning和perception两个模块,其作用主要为:
Perception:
-
使用vector map预测目标的轨迹(基于车道的)
-
用于红绿灯检测
Planning: -
计算当前位置到目标终点的routing路线
-
在lane follow场景下(注意,最新的Autoware也采用了类似Apollo的规划模块设计,基于场景进行了划分)计算沿车道的轨迹
-
交通规则的读取
为了方便自动驾驶系统各个模块调用HAD Map,Autoware对lanelet2进行了一些扩展,扩展内容包括必须属性和非必须属性,表现为OSM中的Tag,下面详细讨论:
额外的必须属性
海拔信息(ele)
point的海拔信息在lanelet2中是非必须的,但是对于Autoware来说,在执行信号灯检测模块时依赖该信息,所以Autoware要求OSM中所有的point(node)都应该包含名为ele的海拔信息及具体的数值,如下所示:
<node id='1' visible='true' version='1' lat='49.00501435943' lon='8.41687458512'>
<tag k='ele' v='3.0'/>
</node>
SpeedLimit属性
在lanelet2中,lanelet(osm对应于ralation)的speedlimit是非必须tag,因为lanelet2有三种设定speedlimit的方式(前面已经讨论),为了避免混淆,Autoware将其作为必须tag,如下:
<relation id="34408" visible="true" version="1">
<member type="way" ref="34406" role="left" />
<member type="way" ref="34407" role="right" />
<tag k="speed_limit" v="30m/h" />
<tag k="subtype" v="road" />
<tag k="type" v="lanelet" />
</relation>
信号灯
默认的lanelet2允许使用linestring和Polygon来描述信号灯,Autoware为了避免混淆仅允许使用linestring描述信号灯,如下图所示,仅用一条linestring描述一个红绿灯,linestring的起点为左下,终点为右下角,通过定义height指定信号灯的高度,如下实例所示:
<way id='13' visible='true' version='1'>
<nd ref='6' />
<nd ref='5' />
<tag k='type' v='traffic_light' />
<tag k='subtype' v='red_yellow_green' />
<tag k='height' v='0.5'/> <!-- this tag is mandatory for Autoware!! -->
</way>
道路方向
路口内的lanelet需要包含turn_direction属性以支持左右转向灯的功能,示例如下:
<relation id='1' visible='true' version='1'>
<member type='way' ref='2' role='left' />
<member type='way' ref='3' role='right' />
<member type='relation' ref='4' role='regulatory_element' />
<tag k='location' v='urban' />
<tag k='one_way' v='yes' />
<tag k='subtype' v='road' />
<tag k='type' v='lanelet' />
<tag k='turn_direction' v='left' /> <!-- this tag is mandatory for lanelets at intersections!! -->
</relation>
以上就是关于lanelet2高精地图的介绍,大部分内容为转载,以后有了新的理解会进行更新,下一篇文章会对AutowareAuto 的 mapping/ 下的had_map模块进行解析,探索lanelet2在使用中是如何解析发布的。
参考链接: