【干货】从LDSO中移植回环检测到VI-DSO

目的

给VI-DSO加入回环检测功能模块,从LDSO中移植。

好激动好期待,像是要给程序动手术一样

准备工作

首先,我大概解剖了一下LDSO是如何在DSO的基础上加入回环检测的。

  1. 在run_dso_tum_mono.cc主函数里,先把FullSystem类实例化:shared_ptr fullSystem(new FullSystem(voc));
  2. FullSystem类的构造函数里,实例化LoopClosing类(主角),回环检测线程mainLoop就存在于LoopClosing类的构造函数里。
  3. mainLoop = thread(&LoopClosing::Run, this); 看看这个Run()都做了哪些事吧~~
 void LoopClosing::Run() {
        finished = false;

        while (1) {
        //needFinish 初值为false
            if (needFinish) {
                LOG(INFO) << "find loop closing thread need finish flag!" << endl;
                break;
            }

            {
                // get the oldest one 如果关键帧queue是空的,等半秒再继续循环
                unique_lock<mutex> lock(mutexKFQueue);
                if (KFqueue.empty()) {
                    lock.unlock();
                    usleep(5000);
                    continue; //这里cotinue执行完,从头开始while循环
                }
                //把KFqueue中的第一个关键帧给currentKF
                currentKF = KFqueue.front();
                //移除KFqueue的第一个关键帧
                KFqueue.pop_front();
                //如果关键帧队列里超过20帧,就清空队列
                if (KFqueue.size() > 20)
                    KFqueue.clear(); 
                //把currentKFpush到allKF vector
                allKF.push_back(currentKF);
            }
            //感觉是计算的当前帧的orb特征词典  和voc没关系
            currentKF->ComputeBoW(voc);  
            //如果检测到了回环帧,poseGraphRunning初始是false,Idle()就是!poseGraphRunning就是true
            if (DetectLoop(currentKF)) {
                bool mapIdle = globalMap->Idle();  //mapIdle为true
                //如果修正了回环,并且mapIdle为true,就执行一次优化OptimizeALLKFs()
                if (CorrectLoop(Hcalib)) {
                    // start a pose graph optimization
                    if (mapIdle) {
                        LOG(INFO) << "call global pose graph!" << endl;
                        bool ret = globalMap->OptimizeALLKFs();
                        if (ret)
                            needPoseGraph = false;
                    } else {
                        LOG(INFO) << "still need pose graph optimization!" << endl;
                        needPoseGraph = true;
                    }
                }
            }

//如果还需要优化并且poseGraphRunning是false(没有在优化),再优化
            if (needPoseGraph && globalMap->Idle()) {
                LOG(INFO) << "run another pose graph!" << endl;
                if (globalMap->OptimizeALLKFs())
                    needPoseGraph = false;
            }

            usleep(5000);
        }

        finished = true; //回环结束
    }

总结一下,就是先去关键帧队列里取第一个关键帧(currentKF),其他的清空,计算currentKF的特征词典,和词典中比较出最相似的关键候选帧(candidateKF),如果candidateKF满足条件,就修正回环(CorrectLoop),并执行后端优化。

CorrectLoop(Hcalib)和OptimizeALLKFs()这俩函数我还没看,太长了…
除了这个loop主线程,在FullSystem.cc里还有一些关于LoopClosing的操作:

  1. 在makeKeyFrame()中, ======= add new Immature points & new residuals ===========添加一些record改动
  2. 在makeKeyFrame()中, ======== Marginalize Frames ============添加了将当前kf添加到地图中并检测loop的操作
  3. 还有一个地方,就是在FullSystem::~FullSystem()析构函数里,blockUntilMappingIsFinished()函数中加入了 loopClosing->SetFinish,如果globalMap->NumFrames() > 4,就进行最终的姿势图优化。并更新世界坐标系点UpdateAllWorldPoints()。

好了,涉及到LOOP的地方就是这么多,虽然有些粘连的地方没有去仔细看,但是我认为还是边移植边学边改

开始操作

首先,在VI-DSO中的FullSystem文件夹的FullSystem.cpp中的构造函数和析构函数改好。添加LoopClosing的头文件。

然后,把LDSO中的LoopClosing.cpp和LoopClosing.h暴力的复制到VI-DSO中的FullSystem文件夹。
then,顺着程序走,
未完待续

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值