3. 高精地图基础
做自动驾驶感知这几年,我越来越觉得高精地图就像车的「第二双眼睛」。传感器能看到的范围有限,但地图可以告诉你前方200米外有个弯道,或者第三条车道即将汇入。今天我们就来聊聊高精地图的核心基础。
高精地图的图层结构
高精地图不是一张简单的图片。它是一层层叠加起来的「数字世界」。我习惯把它拆成三个核心图层:道路层、车道线层、交通标志层。
1. 道路层
这是最底层的骨架。它定义了道路的几何形状、坡度、曲率。说白了,就是告诉车「路在哪里」。我在项目中遇到过一个问题:某段高架桥和地面道路在GPS坐标上几乎重叠,但高度差了十几米。如果没有道路层的海拔信息,车就会以为自己在天上开。
- 道路中心线:一条平滑的曲线,代表道路的走向
- 道路边界:左右两侧的路沿或护栏位置
- 道路连接:交叉口、匝道、环岛的拓扑关系
2. 车道线层
这一层比道路层更精细。它定义了每条车道的宽度、类型(直行、左转、右转)、以及车道之间的连接关系。你想想看,如果车道线层缺失,车连「我在哪条道上」都不知道,变道、转弯根本没法做。
3. 交通标志层
这一层包含红绿灯、限速牌、停止线、人行横道等。嗯,这里要注意:交通标志的位置不是随便标个点就完事了。它必须和车道线层关联。比如「这个红绿灯控制的是哪几条车道?」「停止线对应哪个车道?」
我曾经踩过一个坑:某个路口的红绿灯和停止线距离标错了5米。结果车在距离路口10米的地方就停了,后面的车差点追尾。从那以后,我对图层间的关联关系格外敏感。
矢量地图与栅格地图
这两种地图格式,说白了就是「用点线面描述」和「用像素描述」的区别。
矢量地图
矢量地图用坐标点、线段、曲线来描绘道路。比如一条车道线,就是一系列经纬度坐标点连成的折线或样条曲线。它的优点是精度高、数据量小、容易编辑。
- 每个点用 (x, y, z) 表示,精度可达厘米级
- 支持拓扑关系:车道A连接到车道B
- 适合做路径规划和决策
栅格地图
栅格地图就是把地图切成一个个小格子,每个格子存一个值。比如0表示可通行,1表示障碍物。它的优点是结构简单,适合做感知融合和占用网格。
- 分辨率决定精度:10cm/格 vs 50cm/格,差别很大
- 数据量大:一张1km²的地图,10cm分辨率就是1亿个格子
- 不适合做拓扑分析,但适合做碰撞检测
| 对比项 | 矢量地图 | 栅格地图 |
|---|---|---|
| 存储方式 | 点、线、面 | 像素矩阵 |
| 精度 | 高(厘米级) | 依赖分辨率 |
| 数据量 | 小 | 大 |
| 典型用途 | 路径规划、决策 | 感知融合、占用网格 |
OpenDRIVE标准简介
OpenDRIVE是目前最主流的高精地图标准。它用XML格式描述道路网络。我第一次接触它的时候,觉得XML嵌套太深了,看得头疼。但用久了你会发现,它的设计其实很巧妙。
核心概念
- Road:一条道路,包含多个车道段
- LaneSection:车道段,描述某一段道路上所有车道的横截面
- Lane:单个车道,包含宽度、类型、边界线等
- Junction:交叉口,连接多条道路
举个简单的例子,一条双向四车道的高速公路,在OpenDRIVE里是这样描述的:
<road name="高速A段" length="500.0" junction="-1">
<lanes>
<laneSection s="0.0">
<left>
<lane id="-1" type="driving">
<width sOffset="0.0" a="3.5" b="0.0" c="0.0" d="0.0"/>
</lane>
<lane id="-2" type="driving">
<width sOffset="0.0" a="3.5" b="0.0" c="0.0" d="0.0"/>
</lane>
</left>
<center>
<lane id="0" type="none">
<width sOffset="0.0" a="0.15" b="0.0" c="0.0" d="0.0"/>
</lane>
</center>
<right>
<lane id="1" type="driving">
<width sOffset="0.0" a="3.5" b="0.0" c="0.0" d="0.0"/>
</lane>
<lane id="2" type="driving">
<width sOffset="0.0" a="3.5" b="0.0" c="0.0" d="0.0"/>
</lane>
</right>
</laneSection>
</lanes>
</road>
知识体系总览
下面这张图是我自己梳理的高精地图知识结构,你可以把它当作学习路线图:
这张图把今天讲的内容串起来了。图层结构是基础,地图格式是载体,OpenDRIVE是标准。三者缺一不可。我个人习惯先理解图层结构,再去看OpenDRIVE的具体实现,这样不容易迷失在XML的细节里。