• 重读ORB_SLAM之Tracking线程难点


    1. 初始化

    当获取第一帧图像与深度图后,首先设置第一帧位姿为4*4单位矩阵,然后为整个map添加关键帧与地图点。且更新地图点与关键帧的联系,例如地图点被哪个关键帧观测到,而此关键帧又包含哪些地图点。而且不得不为ORB的处理细节感动,每个地图点因为对应着不同关键帧的特征点,需要择优选取地图点最合适的描述子,pNewMP->ComputeDistinctiveDescriptors()。然后为localmapping线程添加关键帧,以及其他一些准备工作。

    2. 正常定位建图模式

    后续的定位工作,主要由四个函数完成,首先如果有速度信息,就会采取TrackWithMotionModel,没有速度信息或者重定位后的第一帧就会采用TrackReferenceKeyFrame(),当运动速度快,或者其他原因导致定位失败,会一直采用重定位方法。在跟踪当前帧成功后,还要在TrackLocalMap里继续对局部地图做跟踪以及优化位姿。这个localmap局部地图很有迷惑性,跟localMapping感觉很相似。但是两者有很大不同,localmap有两部分组成,一个是局部关键帧,一个是局部地图点。局部关键帧由与当前关键帧有共同观测点的其他关键帧组成,且包括其自身。如果localkeyframes不到80帧,则继续添加每个localkeyframes内的邻居关键帧,孩子与父关键帧。localMapping 则是根据传来的关键帧,经过计算,往整体的map中添加数据。localPoints就很容易理解了,把局部关键帧内所有的看到的地图点都添加进去。重定位函数Relocalization,就是在关键帧库里搜索能匹配上的关键帧,做相对位姿计算。

    3. 只定位不建图模式

    这种模式下,首先会进行重定位,然后根据mbVO 参数判断是进行正常的跟踪定位操作还是要结合重定位信息。mbVO为真表示当前图像和上一帧地图点匹配数目小于10,有可能是运动过快的原因。

    1. 假如上次定位显示,mbVO为0,则进行正常的定位跟踪,但是发现跟踪后mbVO在TrackWithMotionModel里被设置为1了,且定位是成功的,则进行正常的更新速度以及显示操作,如果mbVO仍然为0,则要先跟局部地图进行匹配跟踪,优化位姿,再进行后续操作。因为如果mbVO为1时,也就是跟上一帧地图点匹配较少时,可能得不到有效的局部地图信息。
    2. 在下次定位时,如果mbVO为1,则先进行TrackWithMotionModel跟踪,再进行重定位,为的是保证定位不会轻易丢失。但是如果运动速度仍然过快,mbVO 仍然为1,则下次任然重复步骤2。直到TrackWithMotionModel里设置mbVO为0,或者重定位成功把mbVO设置为0。

    4. 结尾处理

    此处有两个点比较难理解:

    1. 为什么会存在观测值小于1的地图点?
                 // Clean VO matches
                for(int i=0; i<mCurrentFrame.N; i++)
                {
                    MapPoint* pMP = mCurrentFrame.mvpMapPoints[i];
                    if(pMP)
                        if(pMP->Observations()<1)
                        {
                            mCurrentFrame.mvbOutlier[i] = false;
                            mCurrentFrame.mvpMapPoints[i]=static_cast<MapPoint*>(NULL);
                        }
                }
    

    梳理之后发现,在localMapping中,会对局部地图进行优化,会对地图点和关键帧的关系做出调整,有些地图点就会删掉某些observation。所以这里需要处理。

    1. 要删去一些临时地图点,这些点从哪里来的?
                // Delete temporal MapPoints
                for(list<MapPoint*>::iterator lit = mlpTemporalPoints.begin(), lend =  mlpTemporalPoints.end(); lit!=lend; lit++)
                {
                    MapPoint* pMP = *lit;
                    delete pMP;
                }
                mlpTemporalPoints.clear()
    

    在TrackWithMotionModel里有一个UpdateLastFFrame函数,在纯定位模式下,会根据深度图新增一些临时地图点,为的是增加匹配点数,使位姿更准确。所以后面要把这些临时的地图点删去。

  • 相关阅读:
    【设计模式】6.模板方法模式
    【设计模式】5.原型模式
    【设计模式】4.工厂模式
    【设计模式】3.代理模式
    zookeeper集群的搭建
    zookeeper实现分布式锁的原理和一个小例子
    zookeeper配置管理实现原理----监听事件watch
    zookeeper的javaAPI操作(基于Curator的CRUD)
    java.lang.IllegalArgumentException: A HostProvider may not be empty!
    Zookeeper的安装和基本操作
  • 原文地址:https://www.cnblogs.com/easonslam/p/9077001.html
Copyright © 2020-2023  润新知