ORB-SLAM源码保姆级解读(Map)

Map.h:

        Map类定义在Map.h中,包含了地图点头文件"MapPoint.h"和关键帧头文件"KeyFrame.h"

类成员组成表
成员 属性 作用
Map() public 构造函数
void AddKeyFrame(KeyFrame* pKF) public 向地图中添加关键帧pKF
void AddMapPoint(MapPoint* pMP) public 向地图中添加地图点pKF
void EraseMapPoint(MapPoint* pMP) public 从地图中擦除地图点pKF
void EraseKeyFrame(KeyFrame* pKF) public 向地图中擦除关键帧pKF
void SetReferenceMapPoints(const std::vector<MapPoint*> &vpMPs) public 设置当前帧参考地图点,这些点将用于DrawMapPoints函数画图(这里的vpMPs中v指的是vector,p指的是pointer,这个实体是一个存放地图点指针的容器)
int GetLastBigChangeIdx() public 用于获取最大的改变(此函数未被使用)
std::vector<MapPoint*> GetAllMapPoints() public 获取地图中所有地图点,返回地图点序列容器
std::vector<KeyFrame*> GetAllKeyFrames() public 获取地图中所有关键帧,返回关键帧序列容器
std::vector<MapPoint*> GetReferenceMapPoints() public 获取地图中所有参考地图点,返回地图点序列容器
long unsigned int MapPointsInMap() public 获得当前地图中的地图点个数(l返回long unsigned int)
long unsigned int KeyFramesInMap() public 获得当前地图中的关键帧个数(l返回long unsigned int)
long unsigned int GetMaxKFid() public 获取关键帧的最大id
void clear() public 清空地图
std::vector<KeyFrame*> mvKeyFrameOrigins public 存储最初始关键帧的成员变量(mv为成员变量容器)
std::mutex mMutexMapUpdate public 更新地图时的互斥量(回环检测中和局部BA后更新全局地图的时候会使用到)
std::mutex mMutexPointCreation public 为了避免地图点id冲突设计的互斥量
std::set<MapPoint*> mspMapPoints protected 存储所有地图点的集合成员
std::set<KeyFrame*> mspKeyFrames protected 存储所有关键帧的集合成员
std::vector<MapPoint*> mvpReferenceMapPoints protected 存储所有参考地图点的容器成员
long unsigned int mnMaxKFid protected 当前地图中具有最大id的关键帧
std:;mutex mMutexMap protected 类的成员函数在对类成员变量进行操作的时候,防止冲突的互斥量

Map.cc

        Map.cc中定义了一个namespace ORB_SLAM2{}来管理全局变量与函数,然后就是对Map.h中的类函数进行定义。其中构造函数的定义是:

Map::Map():mnMaxKFid(0){}

构造函数后面的冒号跟的是对成员变量的赋值,利用构造函数对mnMaxKFid(地图点中最大关键帧)赋值为0。

//在地图中插入关键帧 *pKF,同时更新关键帧的最大id
void Map::AddKeyFrame(KeyFrame *pKF)
{
    unique_lock<mutex> lock(mMutexMap);
    mspKeyFrames.insert(pKF);
    if(pKF->mnId > mnMaxKFid)
        mnMaxKFid = pKF->mnId;
}

        为了实现进程间的交流,需要用到互斥锁,以做到在多个进程同时对一个内存空间进行操作的时候,保证线程的安全。c++标准库中的mutex类是一种可锁定的对象,它被用来设计在关键代码段需要独占访问时发出信号,以防止具有相同保护的其他线程并行执行和访问相同的内存位置。

        上述提到的互斥锁使用很麻烦,因此可用unique_lock。unique_lock是一个模板类,它管理一个mutex对象。在构造的时候(或者通过移动赋值),对象获得一个互斥对象,对其进行lock操作unlock操作写在了它的析构函数中,所以这个类保证了销毁时的解锁状态(即使没有显式调用),并且不需要主动去对互斥锁进行解锁。因此,作为具有自动持续时间的对象,他特别有用,因为它保证了在抛出异常时正确解锁互斥对象。   

        在每一个线程运行过程中,首先会创建一个unique_lock类,并且自动加锁,这个类的生存周期是整个函数,当函数执行完毕时会释放、销毁该unique_lock类,在orb-slam2中,unique_lock使用的十分广泛。     

PS:c++多线程编程参考[c++11]多线程编程(一)——初识 - 简书 (jianshu.com)

        unique_lock参考:ORB-SLAM2多线程用法总结_heurobocon的博客-CSDN博客

//设置参考地图点用于绘图显示局部地图点(红色)
void Map::SetReferenceMapPoints(const vector<MapPoint *> &vpMPs)
{
    unique_lock<mutex> lock(mMutexMap);
    mvpReferenceMapPoints = vpMPs;
}
//获取地图中所有的关键帧
vector<KeyFrame*> Map::GetAllKeyFrames()
{
    unique_lock<mutex> lock(mMutexMap);
    return vector<KeyFrame*>(mspKeyFrames.begin(),mspKeyFrames.end());
}
//获取地图中所有的关键帧数目
vector<KeyFrame*> Map::GetAllKeyFrames()
{
    unique_lock<mutex> lock(mMutexMap);
    return mspKeyFrames.size();
}
//清除地图中的数据
void Map::clear()
{
    //将地图点集合与关键帧集合数据清空
    for(set<MapPoint*>::iterator sit=mspMapPoints.begin(),send=mspMapPoints.end();sit!=send;sit++)
    delete *sit;
    for(set<KeyFrame*>::iterator sit=mspKeyFrames.begin(),send=mspKeyFrames.end();sit!=send;sit++)
    delete *sit;
    //释放内存
    mspMapPoints.clear();
    mspKeyFrames.clear();
    mnMaxKFid=0;
    mvpReferenceMapPoints.clear();
    mvpKeyFrameOrigins.clear()
}

完毕over

上一篇:无人机视觉导航搜索资料


下一篇:视觉SLAM十四讲CH7课后习题5