
ORB-SLAM3 LocalMapping类源码分析(一)
2021SC@SDUSC
2021SC@SDUSC
localmapping主要是对keyframe进行操作
这里主要说明一下LocalMapping的线程入口Run()方法
Run()方法利用while循环主要执行五种操作:
1、关键帧(KeyFrame)的插入
2、地图点(Map point)的删除
3、新地图点(Map point)的插入
4、局部地图点Map point的融合
5、局部关键帧(KeyFrame)的删除
下面介绍while循环一次执行的操作:
1,设置LocalMaping类的成员mbAcceptKeyFrames为false,表示不接受Tracking线程创建新关键帧
2,检查成员mlNewKeyFrames中是否有新关键帧。mlNewKeyFrames保存所有Tracking线程创建新关键帧。
3,如果mlNewKeyFrames为空,则检查是否有外部操作要求终止该线程,有的话终止,没有的话休眠3毫秒后进行下一次循环。
4,如果mlNewKeyFrames不为空,则在本次循环中处理一帧新关键帧并进行一系列相关操作,再执行3,退出或进入下一次循环。
如何处理mlNewKeyFrames中的一新关键帧是非常重要的操作,下面进行详细的介绍
1、关键帧的插入(利用ProcessNewKeyFrame()函数)
在Tracking线程挑选出 keyframe了之后,Local Mapping的线程就要把该关键帧插入到Local Map中去。在代码中,它利用一个List来管理所有的keyframes,那么Local Mapping线程会先通过CheckNewKeyFrames()函数检查这个队列是不是为空,如果队列不为空有keyframes,则调用ProcessNewKeyFrame()来完成关键帧的插入。
当要插入的当前的keyframe帧为mpCurrentKeyframe,(这是一个keyframe的指针变量)最开始就把这一帧加入keyframes的队列里面,然后计算mpCurrentKeyframe的BOW,然后找出地图点同时也在mpCurrentKeyframe中的,给这些地图点添加一些约束的关系。最后再给这一帧找到它的共视帧,并且加入到map中去
void LocalMapping::ProcessNewKeyFrame()
{
{
unique_lock<mutex> lock(mMutexNewKFs);
//这一帧加入keyframes的队列里面
mpCurrentKeyFrame = mlNewKeyFrames.front();
mlNewKeyFrames.pop_front();
}
// 计算mpCurrentKeyframe的BOW
mpCurrentKeyFrame->ComputeBoW();
// 找出地图点同时也在mpCurrentKeyframe中的,给这些地图点添加约束关系
const vector<MapPoint*> vpMapPointMatches = mpCurrentKeyFrame->GetMapPointMatches();
//根据mpCurrentKeyFrame->mvpMapPoints更新mpCurrentKeyFrame的
mConnectedKeyFrameWeights、mvpOrderedConnectedKeyFrames、mvOrderedWeights、mpParen
for(size_t i=0; i<vpMapPointMatches.size(); i++)
{
MapPoint* pMP = vpMapPointMatches[i];
if(pMP)
{
if(!pMP->isBad())
{
if(!pMP->IsInKeyFrame(mpCurrentKeyFrame))
{
pMP->AddObservation(mpCurrentKeyFrame, i);
pMP->UpdateNormalAndDepth();
pMP->ComputeDistinctiveDescriptors();
}
else // this can only happen for new stereo points inserted by the Tracking
{
mlpRecentAddedMapPoints.push_back(pMP);
}
}
}
}
// Update links in the Covisibility Graph
mpCurrentKeyFrame->UpdateConnections();
// 给这一帧找到共视帧,并且加入到map中去
mpAtlas->AddKeyFrame(mpCurrentKeyFrame);
}
更多推荐