2021SC@SDUSC
orb-slam3有一个主要功能就是利用atlas来解决不限数量的子地图融合问题。altas有不限数量的子地图关键帧的词袋数据库,保证了地图场景重识别的效率。
其中多地图的操作算法:新地图生成、在混合地图中重定位和地图融合以及在有差的相机位姿的时候评价跟踪失败的方法。这样可以有效避免在闭环的过程中由于高度不确定的位姿导致的位姿图优化误差过大。
Atlas.cc引用Atlas.h, Viewer.h, GeometricCamera.h, Pinhole.h, KannalaBrandt8.h头文件。
Atlas.h中创建了类Viewer;
类Atlas中public声明中定义了创建新地图方法CreateNewMap();protected声明中set<Maps> mspMaps存放所有的地图。
public声明:
public:
Atlas();
Atlas(int initKFid); // When its initialization the first map is created
~Atlas();
// 创建新地图
void CreateNewMap();
void ChangeMap(Map* pMap);
unsigned long int GetLastInitKFid();
void SetViewer(Viewer* pViewer);
// Method for change components in the current map
void AddKeyFrame(KeyFrame* pKF);
void AddMapPoint(MapPoint* pMP);
void AddCamera(GeometricCamera* pCam);
/* All methods without Map pointer work on current map */
void SetReferenceMapPoints(const std::vector<MapPoint*> &vpMPs);
void InformNewBigChange();
int GetLastBigChangeIdx();
long unsigned int MapPointsInMap();
long unsigned KeyFramesInMap();
// Method for get data in current map
std::vector<KeyFrame*> GetAllKeyFrames();
std::vector<MapPoint*> GetAllMapPoints();
std::vector<MapPoint*> GetReferenceMapPoints();
vector<Map*> GetAllMaps();
int CountMaps();
void clearMap();
void clearAtlas();
Map* GetCurrentMap();
void SetMapBad(Map* pMap);
void RemoveBadMaps();
bool isInertial();
void SetInertialSensor();
void SetImuInitialized();
bool isImuInitialized();
void SetKeyFrameDababase(KeyFrameDatabase* pKFDB);
KeyFrameDatabase* GetKeyFrameDatabase();
void SetORBVocabulary(ORBVocabulary* pORBVoc);
ORBVocabulary* GetORBVocabulary();
long unsigned int GetNumLivedKF();
long unsigned int GetNumLivedMP();
protected声明:
std::set<Map*> mspMaps; //存放所有的地图
std::set<Map*> mspBadMaps;
Map* mpCurrentMap;
std::vector<GeometricCamera*> mvpCameras;
std::vector<KannalaBrandt8*> mvpBackupCamKan;
std::vector<Pinhole*> mvpBackupCamPin;
std::mutex mMutexAtlas;
unsigned long int mnLastInitKFidMap;
Viewer* mpViewer;
bool mHasViewer;
// Class references for the map reconstruction from the save file
KeyFrameDatabase* mpKeyFrameDB;
ORBVocabulary* mpORBVocabulary;
Atlas.cc中CreatenNewMap();创建新地图,如果当前活跃地图有效,先存储当前地图为不活跃地图,然后新建地图,否则直接新建地图。
void Atlas::CreateNewMap()
{
// 锁住地图集
unique_lock<mutex> lock(mMutexAtlas);
cout << "Creation of new map with id: " << Map::nNextId << endl;
// 如果当前活跃地图有效,先存储当前地图为不活跃地图后退出
if(mpCurrentMap){
cout << "Exits current map " << endl;
// mnLastInitKFidMap为当前地图创建时第1个关键帧的id,它是在上一个地图最大关键帧id的基础上增加1
if(!mspMaps.empty() && mnLastInitKFidMap < mpCurrentMap->GetMaxKFid())
mnLastInitKFidMap = mpCurrentMap->GetMaxKFid()+1; //The init KF is the next of current maximum
// 将当前地图储存起来,其实就是把mIsInUse标记为false
mpCurrentMap->SetStoredMap();
cout << "Saved map with ID: " << mpCurrentMap->GetId() << endl;
//if(mHasViewer)
// mpViewer->AddMapToCreateThumbnail(mpCurrentMap);
}
cout << "Creation of new map with last KF id: " << mnLastInitKFidMap << endl;
mpCurrentMap = new Map(mnLastInitKFidMap); //新建地图
mpCurrentMap->SetCurrentMap(); //设置为活跃地图
mspMaps.insert(mpCurrentMap); //插入地图集
}