orb_slam整体编程思路及代码解析(1)

来源:互联网 发布:js两个对象数组合并 编辑:程序博客网 时间:2024/06/05 01:53

都说,看别人写的代码就是根据别人的排泄物,来分析他的早餐是什么,这个工作既困难由恶心。

这里不贴详细的代码注释,只是根据个人的理解,揣测了一番大佬们的心思,尽量做到详细,难免有错误,欢迎交流。

PAGE1:mono_?_ccp

这个page中主要完成的是LoadImages,创建System(SLAM),配合时间戳循环地把图像传给mpTracker,最后统计跟踪所花费的时间的中间值和平均值。

LoadImages的目的主要是把数据库进行解析,变成了图像向量,和时间戳向量。

SLAM.TrackMonocular(im,tframe)在传送图像时,我们注意到用chrono来计时传送的时间,并计算出两个图像捕获时间的差,如果传送时间小的话则usleep等待下个图像捕获,如果超过一个捕获周期的话,则传送下下个图像,超过两个,则传送下下个图像,以此类推,当然了,这样的话就失帧了。(?这个时间主要花在什么地方),这部分要注意的是数据集的时间戳是以秒为单位的,而usleep的单位是微秒,所以要乘以10^6。

当把所有的图像都传送进去后,就终止所有的线程。并把相机的轨迹保存成文件格式。

PAGE2:System.ccp
在这里完成对整个项目的资源配置

FUCTION1:System

System构造函数完成了对整个项目的资源配置,包括

1.读入配置文件,

2.读取orb词袋(用于定位和特征匹配)(判断传入的参数中有没有".txt"或者".bin",这是对应的orb字典的两种格式),

3.创建关键帧数据库(用于定位和闭环检测)

4.创建地图对象(用于储存KeyFrames 和 MapPoints的指针)

5.创建用于Viewer的mpFrameDrawer(图像窗口)和mpMapDrawer(轨迹窗口)对象

6.新建Tracking对象,他是主线程,即调用该构造函数的线程为主线程

注意,当创建的线程加载的是类方法时,我们需要同时传递类对象

7.新建mpLocalMapper对象(通过BA来管理本地地图),新建线程,线程运行ORB_SLAM2::LocalMapping::Run函数,

8.新建LoopClosing对象(寻找闭环,当找到闭环时优化位姿,并执行全局BA优化),新建线程,线程运行ORB_SLAM2::LoopClosing::Run函数,

9.新建Viewer对象(做图),新建线程,线程运行Viewer::Run函数,

10.指定各个线程中的指针关系,说明各个线程的所访问的数据之间的关系

(mSensor、mpVocabulary、mpKeyFrameDatabase、mpMap、mpTracker、mpLocalMapper、mpLoopCloser、mpViewer)(mpFrameDrawer、mpMapDrawer)

FUCTION2:TrackMonocular

该函数是system.cc里的,所以这是在主线程里的函数,相当于跟踪线程的入口。这个函数里有3个互斥量控制着三个过程:

1.首先利用模式状态量mbActivateLocalizationMode和mbDeactivateLocalizationMode来控制是否执行局部地图功能,局部地图关闭以后,只进行追踪的线程,只计算相机的位姿,没有对局部地图进行更新,设置mbOnlyTracking为真,这里的互斥量是mMutexMode;

2.用互斥量mMutexReset来保护对重置跟踪线程的操作;接下来的部分才是最重要的部分,获取数据,对各个线程的数据进行更新, 对地图重新进行计算;

3.用互斥量mMutexState来保护更新跟踪中的状态量的过程,其中包括mTrackingState,mTrackedMapPoints,mTrackedKeyPointsUn三个状态量,并返回位姿。

FUCTION3:SaveKeyFrameTrajectoryTUM

这个函数用于保存地图中相机的姿态,其中时间戳保存小数点后六位,位姿为小数点后七位的精确度。

这个函数就相当于完成了跟踪的视觉里程计部分,主线程就结束了。


原创粉丝点击