ORB-SLAM2的局部建图线程LocalMapping分为5个步骤,非常简单。当得到缓冲队列里的关键帧,第一步处理当前关键帧的地图点关系等;第二步判断地图点是否为新创建,如果是那就进入测试,测试地图点的好坏,如果不好的地图点就舍弃;第三步创建新地图点,这里创建的是局部地图(真正会被注册到环境变量的里面的局部地图),trakcing的局部地图只用来跟踪使用;第四步进行局部的BA优化;第五步删除掉冗余的关键帧。
在ORB-SLAM2中创建的局部地图点这些都是从头开始创建的,根本没有利用到tracking线程里面的局部地图点局部关键帧的信息,这个操作在使用上感觉是作者的疏漏。其实LocalMapping管理全部的地图或者在Map对象里面管理全部的地图,Tracking线程就查找LocalMapping创建的变量这样是最好的选择,不然它创建的局部地图没有参与其中,局部地图创建了两遍设计的不是很好。
文章目录
- 一、局部建图线程的成员函数/变量
- 二、局部建图主函数: Run()

一、局部建图线程的成员函数/变量
Tracking线程向LocalMapping线程插入关键帧的缓冲队列,这两个线程之间通过关键帧进行交互信息传递的,所以有一个缓冲队列。
成员函数/变量 | 访问控制 | 意义 |
---|---|---|
std::list<KeyFrame*> mlNewKeyFrames | protected | Tracking线程向LocalMapping线程插入关键帧的缓冲队列 |
void InsertKeyFrame(KeyFrame* pKF) | public | 向缓冲队列mlNewKeyFrames内插入关键帧 |
bool CheckNewKeyFrames() | protected | 查看缓冲队列mlNewKeyFrames内是否有待处理的新关键帧 |
int KeyframesInQueue() | public | 查询缓冲队列mlNewKeyFrames内关键帧个数 |
bool mbAcceptKeyFrames | protected | LocalMapping线程是否愿意接收Tracking线程传来的新关键帧 |
bool AcceptKeyFrames() | public | mbAcceptKeyFrames的get方法 |
void SetAcceptKeyFrames(bool flag) | public | mbAcceptKeyFrames的set方法 |
LocalMapping线程局部关键帧太多处理不过来,所以把mbAcceptKeyFrames变量
设置为false
,通知Tracking线程停止输入,实际上mbAcceptKeyFrames变量
在系统非常需要关键帧的时候,无论这个mbAcceptKeyFrames变量
的取值,Tracking线程依然会输入,这个mbAcceptKeyFrames变量
表示接受关键帧意愿
成员函数mbAcceptKeyFrames表示当前LocalMapping线程是否愿意接收关键帧,这会被Tracking线程函数Tracking::NeedNewKeyFrame()
用作是否生产关键帧的参考因素之一;但即使mbAcceptKeyFrames
为false
,在系统很需要关键帧的情况下Tracking线程函数Tracking::NeedNewKeyFrame()
也会决定生成关键帧。
二、局部建图主函数: Run()
主函数就是一个无限循环,每次循环检查当前环境队列里面有无关键帧,如果当前队列没有传来关键帧,当前线程暂停3毫秒开启下一轮查询;如果当前环境队列有当前帧,就处理队列的关键帧剔除坏点、创建新点、将局部地图关键帧与地图点融合、局部BA优化、剔除冗余关键帧和将当前关键帧加入闭环检测中。
void LocalMapping::Run() {
while (1) {
SetAcceptKeyFrames(false); // 设置当前LocalMapping线程处于建图状态,不愿意接受Tracking线程传来的关键帧
// step1. 检查缓冲队列内的关键帧
if (CheckNewKeyFrames()) {
// step2. 处理缓冲队列中第一个关键帧
ProcessNewKeyFrame();
// step3. 剔除劣质地图点
MapPointCulling();
// step4. 创建新地图点
CreateNewMapPoints();
if (!CheckNewKeyFrames()) {
// step5. 将当前关键帧与其共视关键帧地图点融合
SearchInNeighbors();
// step6. 局部BA优化: 优化局部地图
mbAbortBA = false;
Optimizer::LocalBundleAdjustment(mpCurrentKeyFrame, &mbAbortBA, mpMap);
// step7. 剔除冗余关键帧
KeyFrameCulling();
}
// step8. 将当前关键帧加入闭环检测中
mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame);
}
SetAcceptKeyFrames(true); // 设置当前LocalMapping线程处于空闲状态,愿意接受Tracking线程传来的关键帧
// 线程暂停3毫秒再开启下一轮查询
std::this_thread::sleep_for(std::chrono::milliseconds(3));
}
}