讲解关于slam一系列文章汇总链接:史上最全slam从零开始,针对于本栏目讲解(02)Cartographer源码无死角解析-链接如下:
(02)Cartographer源码无死角解析- (00)目录_最新无死角讲解:https://blog.csdn.net/weixin_43013761/article/details/127350885
文
末
正
下
方
中
心
提
供
了
本
人
联
系
方
式
,
点
击
本
人
照
片
即
可
显
示
W
X
→
官
方
认
证
{\color{blue}{文末正下方中心}提供了本人 \color{red} 联系方式,\color{blue}点击本人照片即可显示WX→官方认证}
文末正下方中心提供了本人联系方式,点击本人照片即可显示WX→官方认证
一、前言
关于 LocalTrajectoryBuilder2D 有关于点云数据处理得部分已经讲解完成了,但是比较杂,比较乱,因为很多地方可能都是跳着讲解得。为了方便大家的理解,这里把相关的总要环节都复盘一下。首相再重述一下之前已经讲解过的数据系统构建过程。
(
1
)
\color{blue}(1)
(1) 已经知道每新建一条轨迹就会创建一个 CreateGlobalTrajectoryBuilder2D或者 CreateGlobalTrajectoryBuilder3D对象,该对象的实例化位于 MapBuilder::AddTrajectoryBuilder() 函数中。实例化 CreateGlobalTrajectoryBuilder 对象时,会传入一个回调函数 local_slam_result_callback,该函数为 MapBuilderBridge::AddTrajectory 中的表达式:
// lambda表达式 local_slam_result_callback_
[this](const int trajectory_id,
const ::cartographer::common::Time time,
const Rigid3d local_pose,
::cartographer::sensor::RangeData range_data_in_local,
const std::unique_ptr<
const ::cartographer::mapping::TrajectoryBuilderInterface::
InsertionResult>) {
// 保存local slam 的结果数据 5个参数实际只用了4个
OnLocalSlamResult(trajectory_id, time, local_pose, range_data_in_local);
}
暂且先放一下,只需要知道其核心时调用 OnLocalSlamResult() 函数即可。
(
2
)
\color{blue}(2)
(2) CreateGlobalTrajectoryBuilder(2D或3D) 对象中包含着一个 LocalTrajectoryBuilder(2D或3D)对象。CreateGlobalTrajectoryBuilder 在把雷达数据分发给 LocalTrajectoryBuilder 之前,会通过阻塞的方式对所有数据按时间进行排序(fix与Landmar可以通过参数配置取消)。
阻塞排序分发数据最重要的就是 cartographer::sensor::Collator 这个类,因为 Collator 中存在变量 OrderedMultiQueue queue_; 该变量中的核心函数 OrderedMultiQueue::Dispatch() 起到了按时间分发数据的主要作用,这里的时间同步,与后续激光雷达点云数据的时间同步时不一样的,回顾之前的内容如下:
(0, scan): { 4, }
(0, imu): {1, 3, 5, }
(0, odom): { 2, 6,}
这里的时间同步,是针对于所有传感器的数据,按时间戳分发数据。而激光雷达数据的时间同步,是把多个激光雷达数据进行混合,之前的分析图如下:
( 3 ) \color{blue}(3) (3) CreateGlobalTrajectoryBuilder 接收到数据之后,就会转发至 LocalTrajectoryBuilder2D 或者 LocalTrajectoryBuilder3D 如果是激光雷达数据,则是调用到 LocalTrajectoryBuilder2D(3D)::AddRangeData() 函数。
二、激光雷达点云数据处理
这里主要以 LocalTrajectoryBuilder2D 处理点云数据为例,经过 CreateGlobalTrajectoryBuilder 转发到 LocalTrajectoryBuilder2D 的数据,即调用 LocalTrajectoryBuilder2D::AddRangeData() 函数进行处理。
已经是按时间分发的了,但是多个激光雷达的点云数据是仙湖