VINS-MONO代码解读----vins_estimator(重点部分)

1.

代码目录如下,重点和难点是factor部分,是关于IMU部分的,有较多关于IMU预积分公式的推导。
在这里插入图片描述

1. 条件变量con.wait读取测量值:getMeasurements()

读取buf中IMU和IMG的数据,并进行align,最后的结果是这样:
在这里插入图片描述

2.读取到之后,对IMU数据进行预积分,

processIMU的实现需要结合公式弄明白。

3. 设置重定位帧

relo_buf:订阅pose graph node发布的回环帧数据,存到relo_buf队列中,供重定位使用
关于relo的部分需要搞清楚数据结构,何时pub?
为何要在process中执行estimator.setReloFrame,何时设置reloframe?

4. 重点函数estimator.processImage

视觉与IMU的初始化以及非线性优化的紧耦合

4.0 frame_count变量

int frame_count;// 最新帧在滑动窗口中的索引(0,1,2,... ,WINDOW_SIZE-1)WINDOW_SIZE=10,等frame_count==10时就该进行marg了,以保证window内只有10帧数据,该变量在window没满之前会自增,达到window_size之后就一直保持为window_size(10)

在这里插入图片描述

4.1 addFeatureCheckParallax中的条件判断

如下代码,其中进入compensatedParallax2函数的条件比较难理解,这里debug研究一下

for (auto &it_per_id : feature)
{
    // it_per_id.feature_per_frame.size()就是sliding window内该id的feature被tracking的次数,
    // 这两个判断条件意思是:要有至少3帧,且第3新帧和第2新帧之间要tracking上,保证有共视点来计算视差 TODO:可以debug看看,Done:已经debug过了,确实是这个意思
    // 这里img一定是it_per_id.feature_per_frame.size()>=1,即至少tracking了1次,即使在1st lost了但是在3rd和2nd时分别都tracking上了,那么3rd和2nd之间就有视差
    int condition_2 = it_per_id.start_frame + int(it_per_id.feature_per_frame.size()) - 1;
    if (it_per_id.start_frame <= frame_count - 2 &&
        it_per_id.start_frame + int(it_per_id.feature_per_frame.size()) - 1 >= frame_count - 1) //后一个判断条件是什么意思?
    {
        ROS_DEBUG("condition matched: condition_1: %d, condition_2: %d, frame_count: %d", it_per_id.start_frame, condition_2, frame_count);
        // 对于给定id的特征点,计算第2最新帧和第3最新帧之间该特征点的视差(当前帧frame_count是第1最新帧)
        //(需要使用IMU数据补偿由于旋转造成的视差)
        parallax_sum += compensatedParallax2(it_per_id, frame_count);
        parallax_num++;
    } else {
        ROS_WARN("condition not matched: condition_1: %d, condition_2: %d, frame_count: %d", it_per_id.start_frame, condition_2, frame_count);
    }
}

如下所示:
在这里插入图片描述
一个最极端的例子:
该feature在3rd时被extract出来,it_per_id.feature_per_frame.size()=1,
在2nd时被tracking上了,it_per_id.feature_per_frame.size()=2,
在1st时lost掉了,it_per_id.feature_per_frame.size()=2,start=0,frame_count=2
也是符合条件的:如下打印的0,1,2就是这种例子,start=0,size()=1+1=2,frame_count=2
而0,0,2则对应的是该feature目前只在[0]帧被extract出来一次,没有被tracking上
2,2,2则代表在3rd刚被extract出来,故在3rd和2nd之间不可能存在共视点,也就没有视差。

调试结果:
在这里插入图片描述

在这里插入图片描述

4.2 compensatedParallax2()

/**
 * 对于给定id的特征点
 * 计算第2最新帧和第3最新帧之间该特征点的视差(当前帧frame_count是第1最新帧)
 * (需要使用IMU数据补偿由于旋转造成的视差)
 */
double FeatureManager::compensatedParallax2(const FeaturePerId &it_per_id, int frame_count)
{
    //check the second last frame is keyframe or not
    //parallax betwwen seconde last frame and third last frame
    //计算3rd和2nd在it_per_id.feature_per_frame下的index,size是该id的feature已经被tracking的次数,
    // 如frame_count=4时,从第0帧开始被tracking,start_frame=0,则3rd和2nd时,it_per_id.feature_per_frame.size()分别为3[index=2],4[index=3],则他们的index分别为4-2-0=2,4-1-0=3
    // start_frame=1时,size()=2[index=1],3[index=2], index分别为4-2-1=1,4-1-1=2,图示见博客4.2节:https://blog.csdn.net/qq_37746927/article/details/134436475
    int third_lst_idx = frame_count - 2 - it_per_id.start_frame;
    int second_lst_idx = frame_count - 1 - it_per_id.start_frame;
    //这里的window size是10
    ROS_INFO("======here1: frame_count: %d, third_lst_idx: %d, second_lst_idx: %d", frame_count, third_lst_idx, second_lst_idx);
    const FeaturePerFrame &frame_i = it_per_id.feature_per_frame[third_lst_idx];//third last frame
    const FeaturePerFrame &frame_j = it_per_id.feature_per_frame[second_lst_idx];//seconde last frame

    double ans = 0;
    Vector3d p_j = frame_j.point;

    double u_j = p_j(0);
    double v_j = p_j(1);

    Vector3d p_i = frame_i.point;
    Vector3d p_i_comp;

    //int r_i = frame_count - 2;
    //int r_j = frame_count - 1;
    //p_i_comp = ric[camera_id_j].transpose() * Rs[r_j].transpose() * Rs[r_i] * ric[camera_id_i] * p_i;
    p_i_comp = p_i;
    double dep_i = p_i(2);//深度
    double u_i = p_i(0) / dep_i;
    double v_i = p_i(1) / dep_i;
    double du = u_i - u_j, dv = v_i - v_j;//计算i,j帧间的视差

    double dep_i_comp = p_i_comp(2);
    double u_i_comp = p_i_comp(0) / dep_i_comp;
    double v_i_comp = p_i_comp(1) / dep_i_comp;
    double du_comp = u_i_comp - u_j, dv_comp = v_i_comp - v_j;
    //这俩货不一样??
    ans = max(ans, sqrt(min(du * du + dv * dv, du_comp * du_comp + dv_comp * dv_comp)));

    return ans;
}

3rd和2nd的index计算图示
在这里插入图片描述
调试结果符合预期:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/183800.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux-Ubuntu环境下搭建SVN服务器

Linux-Ubuntu环境下搭建SVN服务器 一、背景二、前置工作2.1确定IP地址保持不变2.2关闭防火墙 三、安装SVN服务器四、修改SVN服务器版本库目录五、调整SVN配置5.1查看需要修改的配置文件5.2修改svnserve.conf文件5.3修改passwd文件&#xff0c;添加账号和密码&#xff08;window…

【Unity】 UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用

1. 什么是PhysicsRaycaster组件&#xff1f; PhysicsRaycaster是Unity UGUI中的一个组件&#xff0c;用于在UI元素上进行物理射线检测。它可以检测鼠标或触摸事件是否发生在UI元素上&#xff0c;并将事件传递给相应的UI元素。 2. PhysicsRaycaster的工作原理 PhysicsRaycast…

Java零基础——Linux篇

1.【熟悉】认识Linux 1.1 什么是操作系统 1.2 现实生活中的操作系统 1.2.1 Win10 1.2.2 Mac 1.2.3 Android(Linux) 1.2.4 iOS(Unix) 1.3 操作系统的发展史 1.3.1 Unix 1965年之前的时候&#xff0c;电脑并不像现在一样普遍&#xff0c;它可不是一般人能碰的起的&#xff0c…

11月24日星期五今日早报简报微语报早读

11月24日星期五&#xff0c;农历十月十二&#xff0c;早报微语早读。 1、第十批在韩中国人民志愿军烈士遗骸迎回仪式在沈阳举行&#xff1b; 2、港媒&#xff1a;乱港分子林卓廷等7人被裁定暴动罪表证成立&#xff1b; 3、深圳&#xff1a;欠缴路边临停车费不再纳入个人征信…

智能医疗越发周到!新的机器人系统评估中风后的活动能力

原创 | 文 BFT机器人 中风是在医疗界上最难的解决的病例之一&#xff0c;全球每年有超过1500万人中风&#xff0c;四分之三的中风患者的手臂和手部会出现损伤、虚弱和瘫痪。 许多中风患者日常生活是依靠他们强壮的手臂来完成的&#xff0c;从拿一些小东西到梳头&#xff0c;即…

提供开箱即用的一站式数据库云平台,「 沃趣科技」完成数千万B+轮战略融资

近日&#xff0c;36氪获悉&#xff0c;国内数据库基础设施厂商沃趣科技完成数千万B轮战略融资&#xff0c;本轮融资由翌马投资&#xff08;恒生电子产业基金&#xff09;领投&#xff0c;金蚂投资跟投&#xff0c;融资金额将用于研发投入及市场拓展。 沃趣科技成立于2012年&am…

vulnhub4

靶机地址: https://download.vulnhub.com/admx/AdmX_new.7z 信息收集 fscan 扫一下 ┌──(kali㉿kali)-[~/Desktop/Tools/fscan] └─$ ./fscan_amd64 -h 192.168.120.138 ___ _ / _ \ ___ ___ _ __ __ _ ___| | __ / /_\/____/ __|/ …

SpringBoot整合SpringSecurity+jwt+knife4生成api接口(从零开始简单易懂)

一、准备工作 ①&#xff1a;创建一个新项目 1.事先创建好一些包 ②&#xff1a;引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency>&…

Whatweb简单使用

目录 简介 安装 debian/ubtuntu redhat/centos 特性 使用 常用参数如下&#xff1a; whatweb -v whatweb --version whatweb -i 1.txt whatweb -v www.baidu.com 扫描等级 whatweb -a 4 www.baidu.com 扫描网段 whatweb --no-errors -t 255 192.168.71.0/24 导出…

Word怎么看字数?简单教程分享!

“我在写文章时&#xff0c;总是想看看写了多少字。但是我发现我的Word无法看到字数。在Word中应该怎么查看字数呢&#xff1f;请帮帮我&#xff01;” Word是一个广泛使用的文档编辑工具。在我们编辑文章时&#xff0c;如果想查看写了多少字&#xff0c;也是可以轻松完成的。 …

黑马点评笔记 redis实现优惠卷秒杀

文章目录 难题全局唯一IDRedis实现全局唯一Id 超卖问题问题解决方案乐观锁问题 一人一单 难题 要解决优惠卷秒杀的问题我们要考虑到三个个问题&#xff0c;全局唯一ID&#xff0c;超卖问题&#xff0c;一人一单。 全局唯一ID 用户抢购时&#xff0c;就会生成订单并保存到同一…

LeetCode.283移动零(双指针)

LeetCode.283移动零 1.问题描述2.解题思路3.代码 1.问题描述 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1…

便携式水污染物监测设备的招标参数有哪些

便携式多参数水质检测仪参数特点&#xff1a; 便携式多参数水质检测仪参数特点&#xff1a; 便携式多参数水质快速测定仪&#xff0c;根据国家检测标准&#xff08;G B &#xff09; 及环境部检测标准(H J &#xff09;研发生产&#xff0c;本仪器具有检测快速、操作简单、测试…

PHP预约上门回收废品系统的代码披露

PHP预约上门回收废品系统的代码披露 <?phpnamespace app\admin\controller;class Code {public function getTopDomainhuo(){error_reporting(0);$host $_SERVER["HTTP_HOST"];$matchstr "[^\\.]\\.(?:(" . $host . ")|\\w{2}|((" . $ho…

解决LocalDateTime传输前端为时间的数组

问题出现如下&#xff1a; 问题出现原因&#xff1a; 默认序列化情况下会使用SerializationFeature.WRITE_DATES_AS_TIMESTAMPS。使用这个解析时就会打印出数组。 解决方法&#xff1a; 我在全文搜索处理方法总结如下&#xff1a; 1.前端自定义函数来书写 ,cols: [[ //表头{…

【黑马甄选离线数仓day03_数仓设计和维度域开发】

1. 数仓基本概念 1- 什么是数据仓库呢? 存储数据的仓库, 主要用于存储过去历史发生过的数据,面向主题, 对数据进行统计分析的操作, 从而能够对未来提供决策支持 2- 数据仓库最大的特点是什么呢? 数据仓库既不生产数据, 也不消耗数据, 数据来源于各个数据源 3- 数据仓库的四…

知行之桥EDI系统HTTP签名验证

本文简要概述如何在知行之桥EDI系统中使用 HTTP 签名身份验证&#xff0c;并将使用 CyberSource 作为该集成的示例。 API 概述 首字母缩略词 API 代表“应用程序编程接口”。这听起来可能很复杂&#xff0c;但真正归结为 API 是一种允许两个不同实体相互通信的软件。自开发以…

Android WorldWind加载shapefile格式文件形成三维效果

目录 1 前言2 实现思路3 绘制Polygons4 读取shapefile文件5 加载立体模型6 问题1 前言 在项目中有时会加载shapefile格式的数据,要形成三维立体效果。但是查看worldwind NASA官网,在worldwind android的使用教程中并没用加载shapefile格式的教程,然后源码中也没有开发加载s…

Grails 启动

Grails系列 Grails项目启动 文章目录 Grails系列Grails一、项目创建二、可能的问题1.依赖下载2.项目导入到idea失败3.项目导入到idea后运行报错 Grails Grails是一款基于Groovy语言的Web应用程序框架&#xff0c;它使用了许多流行的开源技术&#xff0c;如Spring Framework、…

synchronized的轻量级锁居然不会自旋?

《Java并发编程的艺术》中说到「如果失败&#xff0c;表示其他线程竞争锁&#xff0c;当前线程便尝试使用自旋来获取锁」&#xff0c;并且下文所配的流程图中明确表示自旋失败后才会升级为重量级锁&#xff0c;但《深入理解Java虚拟机》又说「如果出现两条以上的线程争用同一个…