OKVIS 代码框架
1. okvis_app_synchronous.cpp
在此文件中 okvis 对象为 okvis_estimator,是类 okvis::ThreadedKFVio 的实例化对象。
数据输入接口是 ThreadedKFVio::addImuMeasurement 和 ThreadedKFVio::addImage。
整个数据输入的代码,在 for(...; i < numCameras; ...) 内,可支持多个相机的影像。
此文件是为 EuRoC 数据集写的入口,所以 IMU 只有 1 个,也没有为多个 IMU 提供便利。
输入 IMU 数据的代码如下,其中 deltaT 为 0,而 start 是第一张影像的时间。此 if 判断,将输入的 IMU 时间控制在,[start - 1, +inf],IMU 需要在影像 1s 前启动初始化。
if (t_imu - start + okvis::Duration(1.0) > deltaT) {
okvis_estimator.addImuMeasurement(t_imu, acc, gyr);
}
2. ThreadedKFVio::addImuMeasurement 和 ThreadedKFVio::addImage
IMU 数据与相机数据在这两个函数中进行封装(okvis::ImuMeasurement 和 okvis::CameraMeasurement),随后 push 到队列的尾部,等待其他线程进行处理。
这两个队列实例是 imuMeasurementReceived_ 和 cameraMeasurementReceived_。对应的类是 okvis::threadsafe::ThreadSafeQueue,嗯,这个类可以仔细看看,对小白来说很有价值。对数据的处理有两种方式,blocking 和 non blocking,控制对列繁忙的时候是不是要把数据丢弃。
3. ThreadedKFVio 中的线程
okvis 开了一些线程进行不同部分的计算,可以在 Threaded::startThreads 中看到这些进程的启动。这个函数中启动了一些现在没有用的线程,如 position, gps, manetometer, differential 数据处理的线程,这些数据当前都没有支持。
主要关注的线程函数有,frameConsumerLoop 和 imuConsumerLoop 数据预处理,matchingLoop 影像匹配,optimizationLoop 后端优化,publisherLoop publish 最终位姿计算结果。
3.1 ThreadedKFVio::imuConsumerLoop
从 imuMeasurementReceived_ 中 pop 出 imu 数据,push 到 imuMeasurements_ 这个 std::deque 中去。随后在 frameConsumerLoop 中调用函数 ThreadedKFVio::getImuMeasurements,将其取出进行处理。
最后 imuFrameSynchronizer_.gotImuData(data.timeStamp) 向其他等待的线程申明已经把该时刻之前的 imu 数据放入 imuMeasurements_ 中。
如果设置中设定了要 publish imu 积分结果,就进行一次 imu 积分,frontend_.propagation,积分的结果存放在 optimizationResults_ 中。在 ThreadedKFVio.cpp 中搜一下 optimizationResults_ 的出现场景,实际上对其中数据的输入、输出只另外出现在了 optimizationLoop 输入和 publisherLoop 输出。
3.2 ThreadedKFVio::frameConsumerLoop
这个函数有 numCameras_ 个,之间用函数参数 cameraIndex 区别。作用是提取每一张影像上的 brisk 特征点,并计算描述子。
先从 cameraMeasurementsReceived_ 中 pop 出 camera 数据 frame,使用 frameSynchronizer_.addNewFrame(frame) 中得到一个 okvis::MultiFrame,MultiFrame 是同一时刻所有相机拍摄到影像的集合(当然也不是完全绝对的同一时刻,总是有点偏差,具体细节看 Frame:Synchronizer::addNewFrame)。
现在,multiFrame 代表了这一张影像。因为特征点需要绝对的方向进行描述,所以现在需要使用 imu 数据积分算当前影像的姿态。若是第一帧,imu 没有启动,使用 okvis::Estimator::initPoseFromImu 进行启动。如果不是第一帧,则使用 okvis::ceres::ImuError::propagation 积分得到当前的姿态。而这个积分的起点是 lastOptimized_T_WS_,是 optimizationLoop 得到的上一帧影像优化结果(publish 出去的最终姿态)。
得到当前影像位姿(中间结果,未优化),进行特征点处理。
frontend.detectAndDescribe(frame->sensorId, multiFrame, T_WC, nullptr);
bool push = false;之后的部分,就是一些后续的结尾工作。
frameSynchronizer_.detectionEndedForMultiFrame(multiFrame->id());
为当前 multiFrame 的处理计数 +1,当该计数为 numCameras_ 时,说明这个 multiFrame 处理完成了,下面这个 if 语句为真。
if (frameSynchronizer_.detectionCompletedForAllCameras(multiFrame->id())) {
push = true;
}
push 为真,西面就可以把当前 multiFrame push 到 keypointMeasurements_ 中,matchingLoop 会从 keypointMeasurements_ 中取数据。
3.3 ThreadedKFVio::matchingLoop
fontend_.dataAssociationAndInitialization(estimator_, T_WS, parameters_, map_, frame, &asKeyframe);
与上一个关键帧进行匹配,当前帧不同影像之间进行 Stereo Matching。
if (estimator_.addStates(frame, imuData, asKeyframe)) {
...
}
estimator_ 是后端优化的实例,这里又将当前帧与上一帧(上一次 matchingLoop 处理的帧)之间的 imu 提取出存储在 imuData 中,加入到后端中。
3.4 ThreadedKFVio::optimizationLoop
真正的后端处理在这个函数中。分为三个部分:optimization, marginalization, afterOptimization 三个部分。
OKVIS 代码框架的更多相关文章
- x01.CodeBuilder: 生成代码框架
根据 Assembly 生成代码框架. 这是学习 AvalonEdit 的一个副产品.学习时,照着源代码新建文件夹,新建文件,添加方法与属性,虽然只是个框架,也要花费大量时间.为什么不让它自动生成呢? ...
- twemproxy代码框架概述——剖析twemproxy代码前编
本篇将去探索twemproxy源码的主干流程,想来对于想要开始啃这份优秀源码生肉的童鞋会有不小的帮助.这里我们首先要找到 twemproxy正确的打开方式--twemproxy的文件结构,接着介绍tw ...
- [C++]Linux之多进程运行代码框架
声明:如需引用或者摘抄本博文源码或者其文章的,请在显著处注明,来源于本博文/作者,以示尊重劳动成果,助力开源精神.也欢迎大家一起探讨,交流,以共同进步- 0.0 多进程代码框架示例 /* @url: ...
- python爬取网页的通用代码框架
python爬取网页的通用代码框架: def getHTMLText(url):#参数code缺省值为‘utf-8’(编码方式) try: r=requests.get(url,timeout=30) ...
- DSO 代码框架
从数据流的角度讲一遍 DSO 代码框架. DSO 的入口是 FullSystem::addActiveFrame,输入的影像生成 FrameHessian 和 FrameShell 的 Object, ...
- 深入浅出etcd系列Part 1 – etcd架构和代码框架
1.绪论 etcd作为华为云PaaS的核心部件,实现了PaaS大多数组件的数据持久化.集群选举.状态同步等功能.如此重要的一个部件,我们只有深入地理解其架构设计和内部工作机制,才能更好地学习华为云Ku ...
- 自适应大邻域搜索代码系列之(1) - 使用ALNS代码框架求解TSP问题
前言 上次出了邻域搜索的各种概念科普,尤其是LNS和ALNS的具体过程更是描述得一清二楚.不知道你萌都懂了吗?小编相信大家早就get到啦.不过有个别不愿意透露姓名的热心网友表示上次没有代码,遂不过瘾啊 ...
- 使用EA生成多层次的代码框架
最近工作期间发现了一个非常棒的UML软件[Enterprise Architect UML 建模工具]简称EA,在该软件上绘制框架层面的类之间关系后,可以自动生成相关语言的代码. EA上目前支持的语言 ...
- Onvif开发之代码框架生成篇
看了前一篇的ONVIF的简单介绍应该对它的基本使用都有了一些基本的了解了吧!下面我讲一步分解向大家介绍下如何通过gsoap生成需要的代码,以及代码中需要注意的问题[基于Linux平台 C开发] 生成O ...
随机推荐
- Django-website 程序案例系列-2 字典操作
设置一个全局字段: USER_DICT = { 'k1': 'root1', 'k2': 'root2', 'k3': 'root3', } def index(request): return re ...
- BZOJ2002[Hnoi2010]弹飞绵羊——LCT
题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系 ...
- BZOJ1195[HNOI2006]最短母串——AC自动机+BFS+状态压缩
题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字符串的 ...
- MT【59】一道迭代函数作图
[Read a good book, that is conversation with many a noble man.]---勒内·笛卡尔(1596-1650) 解答: 评:也可以把f(f(x) ...
- CQOI2009叶子的染色
叶子的染色 题目描述 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到每个叶子的简单路径上都至少包含一 ...
- luogu2024 食物链 (并查集)
把一个点拆成三个,分别对应它的同类.它的猎物和它的天敌,这样的话(以下的相等都是并查集意义上的): 如果令a,b同类,那么a的猎物不能是b的同类,a的天敌不能是b的同类 如果令a吃b,那么a的同类不能 ...
- CF986C AND Graph
半年前做的一道题现在还是不会 x&y=0 意味着,x的补集的子集都是和x直接相连的 不妨令图中的点数就是2^n 那么可以直接从x^((1<<n)-1)开始记忆化爆搜,路上遇到的都是 ...
- A1080. Graduate Admission
It is said that in 2013, there were about 100 graduate schools ready to proceed over 40,000 applicat ...
- 如何在通用权限管理系统中集成log4net日志功能
开发人员都知道,在系统运行中要记录各种日志,自己写一个日志功能,无论是在效率还是功能扩展上来说都不是很好,目前大多用的是第三方的日志系统,其中一个非常有名,用的最多的就是log4net.下面是关于这个 ...
- .NET中26个优化性能方法
1. 数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接池( ...