catographer框架分为前端和后端
前端包括雷达数据处理;位姿预测;扫描匹配和栅格地图更新。
后端包括后端:线程池任务与调度;向位姿图添加节点,计算节点的子图内约束和子图间约束(回环检测);多分辨率地图;基于分支定界算法的粗匹配,优化问题的构建与求解。
前端
雷达数据处理
local_trajectory_builder_2d.AddRangeData
点云数据处理,具体包括多传感器时间同步,点云数据去畸,以及体素滤波。
位姿预测
local_trajectory_builder_2d.AddAccumulatedRangeData.ExtrapolatePose
利用pose,以及传入的里程计,imu数据计算出线速度和角速度,不同的情况选择参与运算的传感器不同。利用线速度角速度乘以时间预测平移和姿态。
详见《》
扫描匹配
扫描匹配的目的是找到雷达点云在栅格地图中的位置与角度。
扫描匹配包括相关性扫描匹配RealTimeCorrelativeScanMatcher2D和ceres扫描匹配
将相关性扫描匹配的位姿作为ceres扫描匹配的初始值。
详见《Cartographer 基于ceres的扫描匹配-CSDN博客》
更新概率栅格地图
将雷达数据写入概率栅格地图
详见《Cartographer 栅格地图更新-CSDN博客》
后端
后端主要实现的是位姿图优化。向位姿图添加节点AddNode,计算节点的子图内约束和子图间约束(回环检测);多分辨率地图;基于分支定界算法的粗匹配,优化问题的构建与求解。
cartographer 中的节点共有两类---关键帧节点和子图节点。
关键帧指的是子图关键帧,而子图是由连续的若干个激光关键帧拼接到一起形成的子地图。
在carto中子图节点称为submap,关键帧节点称为node
构建约束是在这两类节点之间构建。
图中,三角表示子图,圆圈表示节点,由于传感器的一次扫描数据可能插入到多个不同的子图,所以同一个节点可能和多个子图之间存在一定的匹配关系。
子图内约束:
local 坐标系下,子图原点指向tracking_frame的坐标变换
node和insertion_submaps之间的约束,由于在前端是,一个node只插入到了两个submap中,所以个node最多只有两个约束为子图内约束。
子图间约束:
根据global坐标计算初值,然后通过分支丁界算法粗匹配与ceres的精匹配,获取校准后的位姿,最后计算local坐标系下,子图原点指向校准后的节点间的坐标变换。
使用分支定界算法之前需要先构建多分辨率地图。
构建优化问题,并求解:
- 确定2个节点在global坐标系下的相对位姿变换
- 通过其他方式再次获取这两个节点的相对位姿变换
- 对这2个先对位姿变换的差的最小二乘问题进行求解
- 进行求解之后会得到一个增量,将当前位姿加上这个增量后就得到了优化后的位姿
cartographer中通过ceres添加残差项构建优化问题求解。
详见《》