第三章 地图表示方法:栅格地图、特征地图、拓扑地图、语义地图
做雷达SLAM这些年,我一直在琢磨一个问题:地图到底该怎么表示?
你想想看,毫米波雷达扫出来的是一堆点云,但机器人或者自动驾驶车辆需要的,是一个能用来定位、导航、决策的环境模型。这中间差了十万八千里。说白了,地图表示就是搭一座桥——把传感器数据转化成机器能理解的空间语言。
我个人习惯把地图表示方法分成四类:栅格地图、特征地图、拓扑地图、语义地图。它们各有各的脾气,也各有各的用武之地。今天咱们就一个一个聊透。
3.1 栅格地图(Occupancy Grid Map)
栅格地图是最直观的一种。把空间划分成一个个小格子,每个格子存一个概率值——表示这个格子被占用的可能性。
我在做毫米波雷达停车场建图时,就用的栅格地图。雷达打到墙上、柱子上,回波强,我就把对应格子的占用概率调高;打到空旷区域,回波弱,概率就调低。简单粗暴,但有效。
栅格地图的更新公式其实不复杂:
// 对数几率形式的贝叶斯更新
l_t(i,j) = l_{t-1}(i,j) + log( p(m_ij | z_t) / (1 - p(m_ij | z_t)) ) - l_0
// 其中 l_0 是先验对数几率
// p(m_ij | z_t) 是逆传感器模型
嗯,这里要注意。毫米波雷达的逆传感器模型和激光雷达不太一样。激光雷达的波束很窄,基本打到哪就是哪。但毫米波雷达有旁瓣、有多径反射,一个测量值可能对应多个格子。我踩过这个坑——一开始直接套用激光雷达的模型,结果建出来的图全是鬼影。
栅格地图的优点很明显:实现简单,能表达任意形状的环境,适合做路径规划。缺点也突出:分辨率高了内存爆炸,低了细节丢失。我一般用0.2米到0.5米的格子大小,具体看场景。
3.2 特征地图(Feature Map)
特征地图就不一样了。它不存格子,而是提取环境中的几何特征——点、线、面、角点、边缘等等。
我记得有一次做高速公路毫米波雷达定位,栅格地图搞了200MB,跑起来卡得要命。后来换成特征地图,只提取路沿、护栏、标志牌这些特征,地图大小压缩到5MB以内,定位精度反而更高了。
为什么会这样?因为特征地图抓住了环境的"骨架",去掉了冗余信息。
毫米波雷达常见的特征提取方法:
- 点特征: 角点检测、局部极值点。适合用ICP做匹配。
- 线特征: 用RANSAC或霍夫变换提取直线段。路沿、墙壁边缘很适用。
- 面特征: 地面、墙面等平面结构。用PCA分析点云法向量。
特征匹配的代码框架大概长这样:
// 特征匹配伪代码
for each feature_f in current_scan:
best_match = null
min_distance = INF
for each feature_m in map:
descriptor_dist = compute_descriptor_distance(feature_f, feature_m)
if descriptor_dist < threshold and descriptor_dist < min_distance:
min_distance = descriptor_dist
best_match = feature_m
if best_match is not null:
add_correspondence(feature_f, best_match)
特征地图的匹配速度比栅格地图快一个数量级。但有个前提——环境得有明显的几何特征。如果是在一片大草原上,或者漫天大雪的场景,特征提取就抓瞎了。
3.3 拓扑地图(Topological Map)
拓扑地图不关心精确的几何位置,它只关心"连通关系"。节点代表地点,边代表路径。
你想想看,人类认路从来不是靠精确的坐标。我们说"从A走到B,经过C路口右转",这就是拓扑地图的思维。
我在做园区物流机器人项目时,就用了拓扑地图做全局导航。机器人不需要知道每个点的精确经纬度,只需要知道"从充电桩到仓库,经过3号路口左转"就够了。
拓扑地图的构建流程:
- 用毫米波雷达做SLAM,先建一个栅格地图或特征地图作为底层
- 从底层地图中提取关键节点(路口、拐角、地标)
- 根据连通性构建节点之间的边
- 每条边附带一些约束信息(距离、方向、传感器特征)
拓扑地图最大的优势是轻量。一个10000平米的园区,拓扑地图可能只有几十个节点,几十KB就搞定了。而且做路径规划时,直接在拓扑图上跑A*算法,效率极高。
但拓扑地图也有短板——它没法做精确定位。你只能知道"我在哪个节点附近",但不知道"我具体在节点的哪个位置"。所以实际应用中,我通常把拓扑地图和特征地图结合起来用:拓扑地图做全局导航,特征地图做局部精确定位。
3.4 语义地图(Semantic Map)
语义地图是这几年最火的方向。它不只是存几何信息,还存"这个东西是什么"。
比如,一个栅格地图告诉你"坐标(10,5)处有障碍物"。语义地图告诉你"坐标(10,5)处有一辆白色轿车,车头朝北,正在静止等待"。信息量完全不在一个量级。
毫米波雷达做语义地图有个天然优势——多普勒信息。激光雷达只能测位置,但毫米波雷达能直接测速度。这意味着你可以区分"静止的汽车"和"运动的行人",甚至能判断物体的运动方向。
我去年做过一个项目,用毫米波雷达做路口语义建图。雷达扫到目标后,先聚类,然后提取特征:
- RCS(雷达散射截面积)——区分大小目标
- 多普勒速度——判断动静
- 微多普勒特征——识别行人步态
- 形状轮廓——区分车辆类型
把这些信息融合起来,就能给每个目标打上语义标签:
// 语义目标结构体
struct SemanticObject {
int id;
float x, y; // 位置
float vx, vy; // 速度
float rcs; // 雷达散射截面积
std::string type; // "car", "pedestrian", "cyclist", "unknown"
float confidence; // 置信度
float yaw; // 朝向角
};
语义地图的好处是,机器能真正"理解"环境。做决策时,不用再猜"前面那个东西是什么",直接就知道"前面有个人,我得减速避让"。
但说实话,语义地图的构建难度也最大。需要好的目标检测算法、分类器、跟踪器,还要处理时序一致性。我建议初学者先从栅格地图入手,等把SLAM的整个pipeline跑通了,再往语义方向延伸。
3.5 四种地图对比总结
| 地图类型 | 核心思想 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 栅格地图 | 离散网格表示占用 | 实现简单,表达完整 | 内存大,分辨率受限 | 室内、停车场、低速场景 |
| 特征地图 | 提取几何特征 | 轻量,匹配快 | 依赖环境特征丰富度 | 结构化道路、园区 |
| 拓扑地图 | 节点+边的连通关系 | 极轻量,导航高效 | 无法精确定位 | 大规模环境、全局导航 |
| 语义地图 | 目标识别+语义标签 | 信息丰富,支持决策 | 构建复杂,依赖算法 | 自动驾驶、人机交互 |
四种地图各有千秋。选哪种,取决于你的应用场景、计算资源、传感器配置。我个人觉得,做毫米波雷达SLAM,至少要掌握栅格地图和特征地图这两种。拓扑地图和语义地图,可以等基础打牢了再深入。
好了,地图表示方法就聊到这儿。下一章咱们进入实战环节——怎么用毫米波雷达数据,一步步构建出可用的地图。