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中定义了一个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