一build.sh
二build结构
├── build 生成的build文件
├── build_ros.sh
├── build.sh build的脚本,上文提到
├── CMakeLists.txt
├── cmake_modules
├── Dependencies.md
├── Examples 实际入口文件都在此
├── include
├── KeyFrameTrajectory.txt
├── lib
├── src
├── Thirdparty
├── Vocabulary 词袋
三代码入口
1)入口
2)校准
3)回环
1. 入口 Mono_kitti.cc
一)main
1) 参数判断,略过不谈
2) LoadImages 根据路径和时间戳加载图片,填充两个vector:string类型filename double类型timestamp
3)ORB_SLAM2::System SLAM 创建SLAM对象(system.cc) ,二)部分详述
这里new了三个thread: tracking ,mapping , loopclosing, 负责追踪,建图,闭环,三个非常重要的环节
i) mpTracker =new Tracking(this, mpVocabulary, mpFrameDrawer, mpMapDrawer, mpMap, mpKeyFrameDatabase, strSettingsFile, mSensor);
ii)
iii)
4)Main loop 循环读取数据
i)从文件读取img cv::imread
ii)将图片传给SLAM system SLAM.TrackMonocular(im,tframe);
5)SLAM Shutdown
这里关闭了三个thread
6)保存轨迹路线
SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt");
二)ORB_SLAM2::System
1)new ORBVocabulary() 创建词袋,根据参数后缀决定是bin文件还是txt,前者会比较小一些,加载快速一些
2)new KeyFrameDatabase 创建关键帧数据库
3)new Map 创建地图
4)new FrameDrawer
new MapDrawer
创建显示窗口,一个是每张图片的显示,一个是地图
初始化view thread mptViewer = new thread(&Viewer::Run, mpViewer);
5) 初始化Tracking ,Mapping,Loop closing
new Tracking 初始化Tracking对象
new LocalMapping 初始化LocalMapping
new thread 初始化LocalMapping thread
new LoopClosing 初始化LoopClosing
new thread 初始化LoopClosing thread
new Viewer
new thread
SetViewer
通过一下三段:
SetLocalMapper SetLoopClosing
SetTracker SetLoopCloser
SetTracker SetLocalMapper
使得Tracker LoopCloser LocalMapper三者互相可以访问
const bool bUseViewer = true
注: System(const string &strVocFile, const string &strSettingsFile, const eSensor sensor, const bool bUseViewer = true, bool is_save_map_=false);倒数第二个参数如果为false,没有处理,需要修改:
bool System::GetShutdown()
if(mpViewer)
{
return mpViewer->isFinished();
}
else
return false;
mptViewer = new thread(&Viewer::Run, mpViewer);
三)Tracking 每一帧图像进行跟踪计算
main函数里,主循环里调用 SLAM.TrackMonocular(im,tframe);作为Tracking的入口)
这一部分主要工作是:
(1)从图像中提取ORB特征,
(2)根据上一帧进行姿态估计,或者进行通过全局重定位初始化位姿,
(3)然后跟踪已经重建的局部地图,优化位姿,
(4)再根据一些规则确定新的关键帧。
四)Mapping 地图构建
这一部分主要工作是:
(1)加入关键帧,更新图,
(2)验证最近加入的地图点,去除outlier
(3)生成新的地图点
(4)局部bundle 调整(去除outlier)
(5)验证关键帧(去除重复帧)
void LocalMapping::Run() //LocalMapping.cc { 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 ProcessNewKeyFrame(); // Check recent MapPoints MapPointCulling(); // Triangulate new MapPoints 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 KeyFrameCulling(); } mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame); } else if(Stop()) { // Safe area to stop while(isStopped() && !CheckFinish()) { std::this_thread::sleep_for(std::chrono::microseconds(3000)); } if(CheckFinish()) break; } ResetIfRequested(); // Tracking will see that Local Mapping is busy SetAcceptKeyFrames(true); if(CheckFinish()) break; std::this_thread::sleep_for(std::chrono::microseconds(3000)); } SetFinish(); }
LocalMapping::Run() //LocalMapping.cc { 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 ProcessNewKeyFrame(); // Check recent MapPoints MapPointCulling(); // Triangulate new MapPoints 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 KeyFrameCulling(); } mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame); } else if(Stop()) { // Safe area to stop while(isStopped() && !CheckFinish()) { std::this_thread::sleep_for(std::chrono::microseconds(3000)); } if(CheckFinish()) break; } ResetIfRequested(); // Tracking will see that Local Mapping is busy SetAcceptKeyFrames(true); if(CheckFinish()) break; std::this_thread::sleep_for(std::chrono::microseconds(3000)); } SetFinish(); }
五)LoopClosing
闭环检测
这一部分主要工作是:
(1)选取相似帧
(2)检测闭环,RANSAC计算内点数
(3)融合三维点,更新图
(4)图优化,传导变换矩阵,更新地图点