输入文件

./Examples/Monocular-Inertial/mono_inertial_euroc
./Vocabulary/ORBvoc.txt
./Examples/Monocular-Inertial/EuRoC.yaml 存储相机/imu等初始化参数
./Datasets/EuRoC/MH01
./Examples/Monocular-Inertial/EuRoC_TimeStamps/MH01.txt 存相机时间戳
dataset-MH01_monoi

imu0/data.csv中存储imu数据,时间戳,陀螺仪x y z,加速度x y z

#timestamp [ns],w_RS_S_x [rad s^-1],w_RS_S_y [rad s^-1],w_RS_S_z [rad s^-1],a_RS_S_x [m s^-2],a_RS_S_y [m s^-2],a_RS_S_z [m s^-2]
1403636579758555392,-0.099134701513277898,0.14730578886832138,0.02722713633111154,8.1476917083333333,-0.37592158333333331,-2.4026292499999999

cam0/data.csv中存储相机数据,时间戳,图片名字

#timestamp [ns],filename
1403636579763555584,1403636579763555584.png

两个相机的时间戳之间大概会有10个imu数据

入口函数/框架结构

【1】Examples/Monocular-Inertial/mono_inertial_euroc.cc

主要功能:
(1)读入数据,得到时间戳、所有帧、帧间imu数据
(2)新建System函数,执行TrackMonocular()

// Create SLAM system. It initializes all system threads and gets ready to process frames.
ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::IMU_MONOCULAR, true);////执行重点,输入图片帧,和对应图片帧的imu数据(10个左右),这两个数据在此文件中处理读出
SLAM.TrackMonocular(im,tframe,vImuMeas); // TODO change to monocular_inertial

【2】system.cc --- TrackMonocular()

主要功能:
(1)执行GrabImageMonocular()
(2)返回相机位姿

// 如果是单目+imu模式,把IMU数据存储到mlQueueImuData中if (mSensor == System::IMU_MONOCULAR)for(size_t i_imu = 0; i_imu < vImuMeas.size(); i_imu++)mpTracker->GrabImuData(vImuMeas[i_imu]);// 开始跟踪,返回相机位姿Sophus::SE3f Tcw = mpTracker->GrabImageMonocular(imToFeed,timestamp,filename);//mpTracker为三个主线程之一unique_lock<mutex> lock2(mMutexState);mTrackingState = mpTracker->mState;//记录跟踪状态mTrackedMapPoints = mpTracker->mCurrentFrame.mvpMapPoints;//当前帧的地图点mTrackedKeyPointsUn = mpTracker->mCurrentFrame.mvKeysUn;//当前帧的去畸变后关键点return Tcw;//返回世界坐标系到相机的位姿

【3】tracking.cc --- GrabImageMonocular()

主要功能:
(1)构建Frame表征当前帧,用特这点描述子来表示当前帧
(2)调用了Track()函数

//开始跟踪 单目
Sophus::SE3f Tracking::GrabImageMonocular(const cv::Mat &im, const double &timestamp, string filename)
{//将彩色图像转为灰度图像 mImGray//构造Frame,同时完成特征点的提取、计算词袋等操作,mCurrentFrame用图片帧里的特征点来表征一帧图像//imu模式的Frame构造函数  比纯视觉多了&mLastFrame,*mpImuCalib两项mCurrentFrame = Frame(mImGray,timestamp,mpIniORBextractor,mpORBVocabulary,mpCamera,mDistCoef,mbf,mThDepth,&mLastFrame,*mpImuCalib);mCurrentFrame.mNameFile = filename;mCurrentFrame.mnDataset = mnNumDataset;lastID = mCurrentFrame.mnId;Track();//最主要的函数return mCurrentFrame.GetPose();
}

【4】tracking.cc --- Track() 函数主体部分
下面为我认为的主体部分(还有纯定位部分没有考虑进去):
(1)imu预积分PreintegrateIMU()
(2)单目imu初始化MonocularInitialization();
(3)初始化完成进行跟踪,跟踪同步建图CheckReplacedInLastFrame(),两种跟踪模式【纯用关键帧TrackReferenceKeyFrame(),融合imu的跟踪TrackWithMotionModel()】;
(4)跟踪临时丢失用imu复原;
(5)跟踪完全丢失重置地图或新建地图;
(6)跟踪成功,TrackLocalMap()进行优化位姿,增加地图点

();//imu模式下进行imu预积分
if(mState==NOT_INITIALIZED){MonocularInitialization();//
}else{//已经初始化完成,正常定位模式if(mState==OK){CheckReplacedInLastFrame();//检查上一帧被替换的地图点,将地图点替换成新的地图点//如果运动模型是空且imu未初始化 || 刚刚完成重定位if((!mbVelocity && !pCurrentMap->isImuInitialized()) || mCurrentFrame.mnId<mnLastRelocFrameId+2)bOK = TrackReferenceKeyFrame(); //跟踪参考关键帧  估计参考关键帧和当前帧之间的位姿,都没有IMU的参与 elsebOK = TrackWithMotionModel(); //否则用恒速模型进行跟踪,IMU,失败则再次跟踪参考关键帧if(!bOK)bOK = TrackReferenceKeyFrame();if (!bOK)//如果跟踪失败,bOK==false      mState = LOST;mState = RECENTLY_LOST;//地图中关键帧的数量>10}else if(mState == RECENTLY_LOST){PredictStateIMU();//利用IMU计算位姿//有两种情况会用到此函数:(a)视觉跟丢时用imu预测位姿;(b)imu模式下,恒速模型跟踪时提供位姿初始值//imu进行跟踪,最多跟5s,还失败就设置为LOST}else if(mState == LOST){mpSystem->ResetActiveMap();//如果关键帧数量小于10,则重置地图CreateMapInAtlas();//否则新建地图}
}
TrackLocalMap();//优化当前帧的位姿(跟踪成功,则更新局部地图,寻找更多的匹配)

【5】tracking.cc --- TrackLocalMap() 主体部分
这个函数主要是利用局部窗口的关键帧和地图点,为当前帧找到更多的匹配地图点,再进行位姿优化,使得位姿更加准确。
以下三个优化函数都在optimizer.cc中

UpdateLocalMap();//更新局部地图,共视关键帧,共视地图点
SearchLocalPoints();
//imu没有初始化,或者刚刚重定位
PoseOptimization(&mCurrentFrame);
//地图未更新时(与上一帧距离近、误差小)用PoseInertialOptimizationLastFrame()
PoseInertialOptimizationLastFrame(&mCurrentFrame);
//地图更新时用(关键帧优化了,和上一阵相比误差更小)PoseInertialOptimizationLastKeyFrame()
PoseInertialOptimizationLastKeyFrame(&mCurrentFrame);

【6】tracking.cc --- PreintegrateIMU()
IMU预积分,主要实现在IMUType.cc中,IntegrateNewMeasurement(acc,angVel,tstep)
??目前不明白IntegrateNewMeasurement的具体操作,好像只积分了一个imu数据,怎么就能表示到上一关键帧的呢??

//在IMUType.cc中有Preintegrated构造函数
IMU::Preintegrated* pImuPreintegratedFromLastFrame = new IMU::Preintegrated(mLastFrame.mImuBias,mCurrentFrame.mImuCalib);
//对于n个imu数据,要进行n-1次计算得到两帧之间的预积分量
for(int i=0; i<n; i++){//开始计算预积分 IntegrateNewMeasurement()mpImuPreintegratedFromLastKF->IntegrateNewMeasurement(acc,angVel,tstep);//上一关键帧到当前帧的预积分mpImuPreintegratedFromLastKFpImuPreintegratedFromLastFrame->IntegrateNewMeasurement(acc,angVel,tstep);//上一帧到当前帧的预积分pImuPreintegratedFromLastFrame}
//计算结果加入当前帧
mCurrentFrame.mpImuPreintegratedFrame = pImuPreintegratedFromLastFrame;
mCurrentFrame.mpImuPreintegrated = mpImuPreintegratedFromLastKF;
mCurrentFrame.mpLastKeyFrame = mpLastKeyFrame;

ORB-SLAM3:单目+imu 详细代码解读相关推荐

  1. HTML5 form表单 调查问卷制作(内含超详细代码解读)

    HTML 表单技术练习:制作调查问卷(内含超详细代码解读) 这一篇来记录HTML5表单API的学习,以制作调查问卷为例,效果如图: 注:完整代码见文章末尾处. 一.表单标签form 1.常用属性 常用 ...

  2. mask rcnn 超详细代码解读(一)

    mask r-cnn 代码解读(一) 文章目录 1 代码架构 2 model.py 的结构 3 train过程代码解析 3.1 Resnet Graph 3.2 Region Proposal Net ...

  3. 单片机c语言全程图文教程,单片机C语言,从小白到菜鸟进阶教程(超详细代码解读)...

    首先要认识单片机是啥?单片机语言是啥?单片机是一种可存储可读写可编程可运行的芯片,你写啥它就运行啥,运行出错,那你程序写错了.单片机语言,嗯!确定要学C啊!有哪一种语言能够抗衡C的强大地位?没有!哪一 ...

  4. [从零手写VIO|第五节]——后端优化实践——单目BA求解代码解析

    长篇警告⚠⚠⚠ 目录 solver 全流程回顾 Solver三要素 Solver求解中的疑问 核心问题 代码解析 1. TestMonoBA.cpp 2. 后端部分: 2.1 顶点 2.2 边(残差) ...

  5. 如何用 Python 爬取网易云音乐的 10w+ 评论?附详细代码解读

    在简单学习了Python爬虫之后,我的下一个目标就是网易云音乐.因为本人平时就是用它听的歌,也喜欢看歌里的评论,所以本文就来爬一爬网易云音乐的评论吧! 正式进入主题 首先是找到目标网页并分析网页结构, ...

  6. 你们要的代码来了!爬了菊姐的两万条评论——详细代码解读篇

    点击上方"程序人生",选择"置顶公众号" 第一时间关注程序猿(媛)身边的故事 作者 张俊红 如需转载,请联系原作者授权. 前言 上一篇文章爬了菊姐的两万条评论, ...

  7. orb slam3之BA部分源码解读

    提前透露一下,用的是g2o库 Optimizer::GlobalBundleAdjustemnt(mpAtlas->GetCurrentMap(),20); 迭代次数是20 然后进入Bundle ...

  8. 一文详解单目VINS论文与代码解读目录

    本文旨在对前一阶段学习vins-mono开源框架的总结.结合暑假秋招之前报名的深蓝学院的<从零开始手写VIO>课程,本文从VIO原理以及开源代码分析两部分进行详细介绍.PS:提升代码能力最 ...

  9. 手把手教你用Pytorch代码实现Transformer模型(超详细的代码解读)

    手把手教你用Pytorch代码实现Transformer模型(超详细代码解读)

最新文章

  1. 当定时任务遇上随机数
  2. 他们隔空协作,打造出懂医学、知开源的智能机器人
  3. MySQL5.7登陆数据库管理控制平台问题 ERROR 1045(28000)
  4. ege函数库_基于c++ ege图形库实现五子棋游戏
  5. 对于如何删除redis中geo存入的坐标
  6. python2.7更新_centos系统python2.7更新到3.5
  7. Android源码编译到/data/app方法
  8. 固定再计算机主机箱,一种计算机主机放置箱架的制作方法
  9. ble连接过程建立_BLE蓝牙协议 — BLE连接建立过程梳理
  10. Android studio 数据库可视化操作
  11. 【Windows优秀软件推荐】:唧唧down——视频和弹幕全清晰度下载
  12. 服务器snb芯片组,认识6系列主板芯片组
  13. 3S基础知识:MapInfo教程--二次开发入门
  14. 软件测试的六大测试质量标准
  15. matlab向量的模
  16. 进一步限塑!洲际酒店集团与联合利华达成合作,旗下酒店将提供大瓶装洗护用品替换一次性小包装 | 美通社头条...
  17. 7-4 身份证号码最后一位 (100分)
  18. linux 删除模块命令,Linux系统中的Modprobe命令:添加和删除Linux内核模块的方法
  19. Spring Security + JWT实现权限管理
  20. 本主题的评论还有不足之处,还望海涵

热门文章

  1. 9V充3.7V锂电池,12V充3.7V单节锂电池充电芯片和电路图
  2. Java的基本学习(五)——高级UI设计与异常处理
  3. 51单片机实例学习四 128X64 液晶显示器、PS/2与单片机通信、密码锁
  4. 1.通过PADS Logic创建原件类型和逻辑封装
  5. 以小25倍参数量媲美GPT-3的检索增强自回归语言模型:RETRO
  6. Android iOS APPUI设计规范实例(详细的UI设计方法)
  7. “云时代”大势当前,专有云成企业上云首选
  8. 推荐一部美国电影---‘’决胜21点‘’O(∩_∩)O
  9. 入职宇宙条之后,我知道了这些
  10. soj 3172 Fisherman (01背包的装满)