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 ...
随机推荐
- BZOJ2803[Poi2012]Prefixuffix——hash
题目描述 对于两个串S1.S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同.例如串ababba和串abbaab是循环相同的.给出一个长度为n的串S,求满足下面条件的最大的L: ...
- JavaScript实现表单的全选,反选,获取值
构思 通过for循环和for in循环来实现,界面效果如下 步骤 全选: 循环给所有的表单设置checked 反选: 循环内判断checked是否为true,如果为true则改为false否则改为tr ...
- QT 5 安装 vs2017 后,出现找不到 rc.exe 问题
QT 5 安装 vs2017 后,出现找不到 rc.exe 问题 qt 5 cannot run 'rc.exe' 出现这种错误,是因为,rc.exe 未找到,也就是 SKD 路径不对. 找到相应的 ...
- HTML DOM setAttribute()、与createAttribute()
setAttribute().与createAttribute() 都可以动态的为DOM 添加属性:但是用法却不一样: 1.setAttribute() setAttribute() 直接在DOM节点 ...
- Leetcode 344.反转字符串 By Python
请编写一个函数,其功能是将输入的字符串反转过来. 示例: 输入:s = "hello" 返回:"olleh" 思路 Python里面的切片用来解决这个问题就很快 ...
- NOIP2012题解
NOIP2012题解 Day1 Vigenère 密码 vigenere 直接模拟就好了,对于那张表找找规律就很短了. #include<iostream> #include<cst ...
- Centos7下安装python3
1. 安装依赖环境 # yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline- ...
- HDU 1029 Ignatius and the Princess IV / HYSBZ(BZOJ) 2456 mode(思维题,~~排序?~~)
HDU 1029 Ignatius and the Princess IV (思维题,排序?) Description "OK, you are not too bad, em... But ...
- 11:SSM框架下各个层的解释说明
具体见网址:http://blog.csdn.net/lutianfeiml/article/details/51864160
- checkBox全选全不选及数据提交后台
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...