zoukankan      html  css  js  c++  java
  • 重读ORB_SLAM之LocalMapping线程难点

    1. 认清几个锁与布尔参数

    线程的通信与相互影响在ORB比较复杂,需要好好缕清思路。
    1.1 mbStopRequested,由RequestStop函数设定,主要是在回环线程里,在运行全局优化时,以及检测后,调整Loop时,localMapping需要暂停。
    1.2 mbStopped:由stop()函数设定。mbNotStop: 由SetNotStop()设定。 这两个真是把人搞得头大。在Tracking线程,如果mapping线程被要求暂停,也就是mpLocalMapper->isStopped() || mpLocalMapper->stopRequested() 为真,则停止往里添加关键帧。如果可以添加关键帧,则Tracking线程添加关键帧时,必须保证LocaMapping不能被终止,则mbNotStop需要为真。

       if(!mpLocalMapper->SetNotStop(true))
            return;
    

    这个判断要为真。

    1.3 mpLocalMapper->Release(); 此函数在全局优化以及调整Loop后使用,目的是使mbStopped,mbStopRequested都置为false。且清空 mlNewKeyFrames。
    1.4 mMutexStop锁,主要是在设置以上两个参数时使用,防止同时更改。
    1.5 mMutexAccept锁,也是防止在设置mbAcceptKeyFrames时保持异步。mMutexNewKFs也是同样的原理。

    2 整体流程

    void LocalMapping::Run()
    {
    
        mbFinished = false;
    
        while(1)
        {
            // Tracking will see that Local Mapping is busy
            SetAcceptKeyFrames(false);
    
            // Check if there are keyframes in the queue
            if(CheckNewKeyFrames())
            {
                // BoW conversion and insertion in Map
                /* 1. 首先计算BOW
                   2. 对于Tracking 线程匹配到的mappoint做一些处理,比如为mappoint增加观测,更新描述子
                   3. 更新当前帧与其邻居帧的关系
                   4. 最后把关键帧加入到map里 */
    
                ProcessNewKeyFrame();
    
                // Check recent MapPoints
                /*
                    这里主要处理刚加入的地图点。刚加入的地图点一般由上一次CreateNewMapPoints产生。在这里做删减。但是这里不知道mlpRecentAddedMapPoints有什么作用。好像哪里都没有用到,而且list里erase这些mappoint指针并不会对map里的mappoint指针有影响。
                */
                MapPointCulling();
    
                // Triangulate new MapPoints
                /*
                  这里生成新的地图点,与Tracking线程里不太一样,那里是直接利用深度信息产生地图点。这里是根据当前帧的邻居帧,进行再次匹配,利用三角化生成地图点。这样就增大了SLAM的可视距离
                */
                CreateNewMapPoints();
    
                if(!CheckNewKeyFrames())
                {
                    // Find more matches in neighbor keyframes and fuse point duplications
                    SearchInNeighbors();
                }
    
                mbAbortBA = false;
    
                if(!CheckNewKeyFrames() && !stopRequested())
                {
                    // Local BA
                    if(mpMap->KeyFramesInMap()>2)
                        Optimizer::LocalBundleAdjustment(mpCurrentKeyFrame,&mbAbortBA, mpMap);
    
                    // Check redundant local Keyframes
                    /*
                    如果当前局部地图里有这样的关键帧:其所看到的90%的地图点,也至少被其他三个关键帧看到,则应删除此关键帧。
                    */
                    KeyFrameCulling();
                }
    
                mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame);
            }
            else if(Stop())
            {
                // Safe area to stop
                while(isStopped() && !CheckFinish())
                {
                    usleep(3000);
                }
                if(CheckFinish())
                    break;
            }
    
            ResetIfRequested();
    
            // Tracking will see that Local Mapping is busy
            SetAcceptKeyFrames(true);
    
            if(CheckFinish())
                break;
    
            usleep(3000);
        }
    
        SetFinish();
    }
    
  • 相关阅读:
    IE浏览器cookie存放在本地什么目录
    C# clickonce 部署自定义文件
    [C#.Net]C#连接Oracle数据库的方法
    Eclipse 插件一览
    登录名 '***' 拥有一个或多个数据库。在删除该登录名之前,请更改相应数据库的所有者。 (Microsoft SQL Server,错误: 15174)
    SqlServer_表结构查询_查询当前用户所有表名
    sqlserver怎么删除有外键关联的数据?
    springboot logback控制台中文输出乱码
    控制台运行JAVA的jar文件时乱码 / Gradle编译设置编码格式
    Python 算法之一
  • 原文地址:https://www.cnblogs.com/easonslam/p/9089112.html
Copyright © 2011-2022 走看看