vins-fusion代码解读[四] 图像回环检测loop_fusion主体

2023-05-16

SLAM新手,欢迎讨论。

这篇主要讲loop_fusion包的程序结构,loop_fusion主要作用:利用词袋模型进行图像的回环检测。在vinsmono中,该程序包处于pose_graph包内。vins_fusion与vins_mono一个差别在于,回环检测的点云数据在mono中有回调供给VIO进行非线性优化,而在fusion中,VIO估计完全独立于回环检测的结果。即回环检测的全局估计会受到VIO的影响,但是VIO不受全局估计的影响。

程序入口:loop_fusion的pose_graph_node.cpp

pose_graph_node

(1)定义了全局变量。最重要的是定义了全局姿态类:Posegraph posegraph。在定义了这个变量的过程中,由于posegraph的初始化,因此开启了一个持续不断的新线程:
optimize4DoF,即全局优化一个4自由度的过程。
该过程由于IMU的存在,使得位姿6自由度的问题一下子降了两维。并且线程每结束一次优化的过程,线程就会睡眠2秒钟,再继续。optimize4DoF优化的前提条件:optimize_buf不等于空。添加optimize_buf的内容只有两个地方,一个是addKeyFrame()函数,一个是loadKeyFrame()函数。
loadKeyFrame()函数:只要在LOAD_PREVIOUS_POSE_GRAPH有,即我们有原来的地图信息,加载的时候,才会发生。
addKeyFrame()函数:外部调用类pose_graph的第一个函数。即通过findConnection()函数判断是否有检测到回环,检测到后满足一定条件就把回环帧的序号添加optimize_buf内部。

main()函数

  • 读取配置文件,通过fsSetting进行相应的参数配置
    比较重要的是读入了vocabulary_file,即在support_files里面的brief_k10L6.bin。以及BRIEF_PATTERN_FILE。通过posegraph.loadVocabulary为posegraph的类成员 BriefDatabase db设置属性以及BriefVocabulary voc赋值。以及为BRIEF_PATTERN_FILE赋值。为后期keyframe的构建创造一个基础。
  • 根据LOAD_PREVIOUS_POSE_GRAPH,即是否要加载原有的地图信息,如果加载了之前的信息,则posegraph.loadPoseGraph,之前所有的关键帧的序号sequence都设置为0,base_sequence也是0。不过不加载之前的信息,base_sequence=1。
  • 订阅话题,发布话题
  • 开启一个新线程:process()
    程序主要的执行内容。
  • 开启一个控制台键盘控制线程:command()
    键盘控制输入,有提供两种选择,在控制台上写入:
    ‘s’:把当前Posegraph存储起来,并且把整个loop_fusion包的进程关掉。
    ‘n’:图像更新序列,new_sequence()

process()

  • image_buf,pose_buf,point_buf三个buff都不为空的时候,才进行运行,否则程序就休息5毫秒,继续监测。
    (1)image_buf,存放image_callback()图像回调函数的信息,接收相机话题的原始图片。并且当两张图片的时间戳相差1秒,或者说当图像的时间戳小于上一帧的时间戳,可以认为图像出现新序列,因此new_sequence()
    (2)point_buf,存放point_callback()关键帧的三维特征点信息的回调。并且在这个回调函数中,同时利用point_cloud标准数据结构发布特征点三维点云以供可视化操作。发布的话题为:point_cloud_loop_rect。注意,此时的点云信息不是单纯vio得到的点云信息,而是在pose_graph参考坐标系下,关键帧点云的位置。因为vio自己有一个参考坐标系,而pose_graph求解出来的位姿图也有自己的坐标系,这两个坐标系有一个变换关系,写在了pose_graph.r_drift,pose_graph.t_drift里面。
    (3)pose_buf,存放pose_callback()回调函数的信息。订阅的是关键帧的vio得到的关键帧的位姿信息。
    从上面订阅的信息我们可以看出,只有当相机有关键帧的时候(vins_estimator中有对应的规则判断该帧是不是关键帧),才会进行进一步处理,整个loop_fusion处理的信息不是原始图像,而是一帧帧关键帧
  • 接着程序开始找一帧keyframe 对应的image_buf,point_buf,pose_buf三者的数据。即point_buf和pose_buf这个存储的点云和位姿是对应(image_buf里面的)哪一帧关键帧。最终的结果
    (1)image_msg存放关键帧的图像原始信息
    (2)point_msg存放了该关键帧里面的3D点云信息,由VIO以及pose_graph.r_drift, pose_graph.t_drift 解算得到。
    (3)pose_msg存放了该关键帧的位姿信息。
  • 根据上面得到的三个信息,来构造关键帧!!用数据结构KeyFrame来表示,这里用了十个变量的KeyFrame构造函数来构造这个关键帧,十个变量的KeyFrame来构造函数默认没有brief_descriptor,因为我们VIO前端提取的并不需要特征点的描述子。在构造关键帧的时候,函数同时又增加了阈值大于20的FAST角点,来增加关键帧特征点的数量,同时,对这些特征点用相应的描述子来进行表述。构造出一个向量容器,用来存放所有特征点的描述子,即KeyFrame类成员vector<BRIEF::bitset> brief_descriptor
    注意点:只有当两个关键帧之间的位移量(T-last_t)>阈值SKIP_DIS时候,才会构造新的关键帧。但是程序默认的SKIP_DIS为0。就是除非T和last_t完全相等,否则就会进入构造函数。
  • 构造好的keyframe,通过posegraph.addKeyFrame(keyframe,1),加入到全局姿态图当中去,第二个参数代表是需要回环检测detect_loop,这里直接默认设置需要。

PoseGraph类

先简单介绍下loop_fusion整个程序里面最重量级的类:PoseGraph类。整个程序都是维护这个main函数里面定义的全局变量PoseGraph posegraph来进行的。通过PoseGraph 的类函数,addKeyFrame来进行关键帧的添加。重要的成员变量:
list<KeyFrame*>keyframelist 最重要的类成员,整个回环检测的过程就是用来维护这个关键帧链表list,当检测到回环的时候,更新这个链表的数据,即关键帧的位姿。
BriefDatabase db 图像数据库信息,通过不断更新这个数据库,可以用来查询,即回环检测有没有回到之前曾经来过的地方。

addKeyFrame()

  • 检查该关键帧的序号是否有跳变,整个loop_fusion里面,每当出现new_sequence()时候,关键帧的sequence会自增1,为什么一直需要关心一个关键帧的sequence呢?因为这里一个关键帧的位姿的参考系是建立在某一个sequence下面的,不同的sequence对应了不同w_t_vio,w_r_vio,就是该sequence 和base_sequence之间坐标系的转换关系。
    -posegraph坐标系是以world frame作为坐标系的,world frame为base sequence(载入原来的图像数据库)或者(没有载入图像数据库的话)用sequence=1的序列作为坐标系。PoesGraph里面的两个类成员 w_t_vio,w_r_vio描述的就是当前序列的第一帧,与世界坐标系之间的转换关系。
  • 通过detectLoop(),查找到一个最合适得分最高的闭环候选帧(如果没找到,loop_index=-1),此时本质是通过bag of word中的db.query()来进行查找的。并且无论有没有查找到,都用db.add()把当前关键帧的描述子添加到图像的数据库db中去。
  • 若detectLoop()能够找到相似的一帧,此时,通过findConnection() 判断新旧两帧关联,匹配点大于25对,相对的偏航角位移小于30度并且相对位移少于20m,则返回true,其余情况均返回false。在true的条件下,更新参考系转化的变量。并且把当前帧的序号加入到optimize_buf中去。
  • 最终,把该帧keyframe 添加到keyframelist中去。从此,keyframelist又增添了一个关键帧元素。

optimize4DoF()

简单说下这个函数,optimize_buf一有东西,意味着该帧已经被检测出回环了,因此就开始优化,优化的对象就是keyframelist中每个关键帧的四个自由度,包括x,y,z,yaw。同样是ceres问题求解

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vins-fusion代码解读[四] 图像回环检测loop_fusion主体 的相关文章

  • 迅雷笔试题2014校园招聘 武汉

  • C#中的readonly与const区别

    xfeff xfeff const 的概念就是一个包含不能修改的值的变量 常数表达式是在编译时可被完全计算的表达式 因此不能从一个变量中提取的值来初始化常量 如果 const int a 61 b 43 1 b是一个变量 xff0c 显然不
  • 改变无线连接、有线连接的优先级

    有线和无线连的是同一个网络 xff0c 当笔记本打开时 xff0c 总是优先使用无线连接 xff0c 如何转变优先级为有线连接呢 xff1f 1 打开网络和共享中心 2 更改适配器设置 xff0c 打开网络连接窗口 3 单击此窗口的高级菜单
  • 杂感一

    从2014年7月工作至今已有快2年了 xff0c csdn的博客从毕业后就很少上了 工作中有很多收获 技术上 也在不断积累和成长中 不管做什么事情 xff0c 要坚持下去 xff0c 方得初心 xff0c 把坚持养成习惯 xff0c 学习如
  • MFC隐藏主窗口的方法

    隐藏基于对话框的MFC应用程序窗口的方法 推荐这个方法 xff0c 非常好用 很多人可能会将窗口创建出来 然后用一个 ShowWindow SW HIDE 的方法去隐藏窗口 当然这是可以做到隐藏的功能 但是有一点不足的地方就是窗口在隐藏之前
  • JSP 通过Servlet将excel数据导入SQL

    1 gt 在网上下载jxl jar 这个JAR包用于Java操作excel 下载后 xff0c 将这个包复制到工程Webroot下的WEB INF下的lib中 xff0c 或是在工程中导入jxl jar包 2 gt 准备excel文件 如图
  • 1=5,2=15,3=215,4=2145,那么5=?

    如题 xff0c 1 61 5 xff0c 2 61 15 xff0c 3 61 215 xff0c 4 61 2145 xff0c 那么5 61 xff1f 答案 xff1a 5 61 1 哎 xff0c 这个题出的 xff0c 没反应过
  • 数值分析上机题Matlab--东南大学出版社(牛顿迭代/逐次超松弛迭代/3次样条插值/复合梯形SimpsonRomberg/四阶经典Runge-Kutta/幂法求特征向量)

    第二章上机题 Newton迭代法 function x err 61 Newton f x0 epsilon 用例 xff1a x err 61 Newton 39 x 3 3 x 39 0 7 0 005 Input f 字符串公式 39
  • 村子里有50个人,每人有一条狗,在这50条狗中有病狗(这种病不传染),于是人们要找出病狗。

    xff29 xff22 xff2d 公司向来以高素质人才作为企业持续竞争力的保证 进入 xff29 xff22 xff2d 公司是差不多每个 xff29 xff34 人的梦想 下面这条 xff29 xff22 xff2d 公司的面试题 xf
  • 删除单向链表中的某一个节点

    已知一个单向链表的表头head xff0c 写出一个删除某一个节点的算法 xff0c 要求先找到此节点 xff0c 然后删除 include lt iostream gt using namespace std typedef struct
  • 多段图的最短路径问题-----动态规划法

    对多段图 xff0c 求最短路径 xff0c 如图 xff1a 对其使用动态规划法 xff1a 阶段 xff1a 将图中的顶点划分5个阶段 xff0c k 状态 xff1a 每个阶段有几种供选择的点s 决策 xff1a 当前状态应在前一个状
  • Ceres-Solver学习笔记(6)

    溯洄从之 xff0c 道阻且长 建模最小化二乘问题 Ceres有两个组成部分 xff0c 一个是建模API xff0c 它提供了一组丰富的工具 xff0c 可以在一段时间内构造一个优化问题 xff0c 另一个是求解程序API xff0c 控
  • hualinux2.1 环境搭建:源码、二进制、yum/apt安装区别

    一 linux软件常用的安装方式 linux软件常见的安装方式一般分以下几种 xff1a 1 源码安装 xff1a 直接通过源代码安装 一般用make或cmake安装 2 二进制安装 xff1a 别人已经帮编译好了 xff0c 拿过来就可以
  • 百度试题---开发测试工程师

    一 问答题 说出常用的几种希哈函数 xff0c 其作用是什么 xff1f 描述OSI 的七层网络结构 xff0c HTTP 工作在哪一层 xff1f 描述一段C 语言代码程序能运行起来的代码要求和执行过程 二 算法设计 有一车苹果 xff0
  • ((硬件spi+dma)+模拟spi)驱动LCD5110

    span class hljs preprocessor ifndef spi dma h span span class hljs preprocessor define spi dma h span span class hljs pr
  • 《Python深度学习》第五章-2(Cats_vs_Dogs)读书笔记

    5 2 在小型数据集上从头开始训练一个卷积神经网络 当数据不够时 xff0c 有以下方法进行处理 xff0c 本节主要是介绍数据增强 5 2 1 深度学习与小数据问题的相关性 深度学习的一个基本特性就是能够独立地在训练数据中找到有趣的特征
  • 无人机原理图、pcb图下载地址

    原理图 pcb图下载地址 无人机pcb电路图原理图 智能家居文档类资源 CSDN文库
  • Win 10 系统下搭建 Python 编程环境,有手就行

    前言 想把一门编程语言学好 xff0c 会搭建编程环境无疑是有必要的 xff0c 纵然有线上集成的编程环境 xff0c 但那高度依赖于网络条件以及诸多情况 xff0c 这使得我们在编程的时候难以存储自己的资料 学习和使用 python 一年
  • Latex小白学习方法和实践

    1 了解简单语法 xff0c 读懂latex解决的问题 xff0c 和其核心方法论 知道latex其实不是万金油 xff0c 只是在熟悉的情况下 xff0c 让你更完美的排版 xff0c 省去可视化下不精确的问题 xff0c 其不会很快的完
  • PADS版本历史

    从加载文件的速度 xff0c 生成的文件大小 xff0c 画图的速度 xff0c 渲染的速度等多方面来说 xff0c 个人认为 PDAS 算是非常不错的一款软件 xff0c 值得学习和使用 大概把其光辉历史罗列一下 xff0c 作为一个回忆

随机推荐

  • 简述Z-Stack的基本工作原理与流程(OSAL操作系统)

    首先上图 xff0c 跟着图中的函数顺序来感受Z Stack的工作流程 xff1a Z Stack协议栈总的来说做了两件事 xff0c 系统的初始化和启动OSAL操作系统 系统初始化 xff1a 从main函数看 xff0c 首先是调用了o
  • 使用MaixPy IDE开发K210

    使用MaixPy IDE快速开发K210 距离我第一次使用MaixPy将近40天了 xff0c 大概花了26天 xff0c 完成了我的毕业设计并且进行了优化 后面我会花时间去和大家分享我的毕设 xff0c 也希望能得到各位码友的意见和建议
  • K210实现人脸识别(附代码解读)

    基于K210的人脸识别门禁 xff08 一 xff09 进入官网 xff08 首次登陆需要注册 xff09 获取人脸识别源码 https wiki sipeed com soft maixpy zh course ai image face
  • K210人脸识别+人脸信息存储

    在我的上一篇博客中已经介绍了如何使用K210实现基本的人脸识别功能 https blog csdn net HuangChen666 article details 113995079 spm 61 1001 2014 3001 5501
  • 旅行商问题--蚁群优化算法求解(matlab实现)

    今天给大家分享一下matlab实现蚁群优化算法 xff0c 解决旅行商问题 在上一篇博客中对蚁群优化算法做了较为详细的介绍 xff0c 有需要的小伙伴可以看一下 https blog csdn net HuangChen666 articl
  • 粒子群优化算法及MATLAB实现

    上一篇博客是关于蚁群优化算法的 xff0c 有兴趣的可以看下 https blog csdn net HuangChen666 article details 115913181 1 粒子群优化算法概述 2 粒子群优化算法求解 2 1 连续
  • A星(A*、A Star)路径规划算法详解(附MATLAB代码)

    首先看看运行效果 xff0c 分别有三种模式 xff0c 代码运行前需要通过鼠标点击设置起点和终点 第一种模式直接输出最短路径 第二种模式输出最短路径的生成过程 第三种模式输出最短路径的生成过程和详细探索的过程 代码获取 gitee链接 x
  • Ubuntu20.04+MAVROS+PX4+Gazebo保姆级安装教程

    Ubuntu20 04 43 MAVROS 43 PX4 43 Gazebo 安装PX4步骤安装MAVROS安装QGCPX4仿真 安装PX4步骤 从github上clone源码 span class token function git s
  • PX4+Offboard模式+代码控制无人机起飞(Gazebo)

    参考PX4自动驾驶用户指南 https docs px4 io main zh ros mavros offboard cpp html 我的另一篇博客写了 键盘控制PX4无人机飞行 PX4无人机 键盘控制飞行代码 可以先借鉴本篇博客 xf
  • 基于ESP32的小型四轴无人机

    粗糙版试飞成功 xff01 陀螺仪部分直接飞线飞了一个模块 xff0c 懒得焊了 不是很水平 xff0c 稳定性不是很好 因为滤波算法中加入的元素太少了 xff0c 目前也就MPU6050的输出数据加入了计算 xff0c 所以很多自稳定性飞
  • PX4无人机 - 键盘控制飞行代码

    PX4无人机 键盘控制飞行代码 仿真效果 实机效果 由于图片限制5M以内 xff0c 只能上传一小段了 xff0c 整段视频请点击链接 Pixhawk 6c 无人机 键盘控制无人机 Offboard模式 核心 xff1a 发布 mavros
  • 【FreeRTOS学习 - 消息队列学习】

    跟着韦东山老师FreeRTOS教学资料的学习记录 FreeRTOS全部项目代码链接 xff08 更新中 xff09 https gitee com chenshao777 free rtos study 本文章一共分为一下几个部分 1 创建
  • 【Linux多线程编程-自学记录】08.Linux多线程互斥量

    Linux多线程编程学习代码 xff08 代码已上传gitee xff0c 还请各位兄弟点个Star哦 xff01 xff09 https gitee com chenshao777 linux thread git 笔记 xff1a 1
  • 【Linux多线程编程-自学记录】09.Linux多线程之读写锁

    Linux多线程编程学习代码 xff08 代码已上传gitee xff0c 还请各位兄弟点个Star哦 xff01 xff09 https gitee com chenshao777 linux thread git 笔记 xff1a 1
  • 【Linux多线程编程-自学记录】10.条件变量

    Linux多线程编程学习代码 xff08 代码已上传gitee xff0c 还请各位兄弟点个Star哦 xff01 xff09 https gitee com chenshao777 linux thread git 笔记 xff1a 1
  • 树莓派4B安装Ros 2 Foxy踩坑记录

    1 通过树莓派官方提供的写卡工具raspberry pi imager选择Ubuntu 20 04 5 xff08 64 bit xff09 xff0c 因为我打算用一个8G的存储卡安装ros 2 xff0c Ubuntu 22 04的比较
  • 港科大vins-fusion初探

    SLAM新手 xff0c 欢迎讨论 关于vins fusion的博客 xff1a 1 初探 xff1a https blog csdn net huanghaihui 123 article details 86518880 2 vio主体
  • vins-fusion代码解读[一] vio主体

    SLAM新手 xff0c 欢迎讨论 港科大vins fusion代码解读 一 vins fusion与vins mono代码结构有很大相似性 这次先看看vins estimator节点内的内容 1 程序入口 xff1a 1 vins est
  • vins-fusion代码解读[二] 惯性视觉里程结果与GPS松耦合

    感谢 slam萌新 xff0c 本篇博客部分参考 xff1a https blog csdn net weixin 41843971 article details 86748719 欢迎讨论 惯性视觉里程结果与GPS松耦合 xff1a g
  • vins-fusion代码解读[四] 图像回环检测loop_fusion主体

    SLAM新手 xff0c 欢迎讨论 这篇主要讲loop fusion包的程序结构 xff0c loop fusion主要作用 xff1a 利用词袋模型进行图像的回环检测 在vinsmono中 xff0c 该程序包处于pose graph包内