【SLAM】VINS-MONO解析——初始化(理论部分)

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

6.初始化

第一个问题,为什么要初始化?
对于单目系统而言,
(1)视觉系统只能获得二维信息,损失了一维信息(深度),所以需要动一下,也就是三角化才能重新获得损失的深度信息;
(2)但是,这个三角化恢复的深度信息,是个“伪深度”,它的尺度是随机的,不是真实的,所以就需要IMU来标定这个尺度;
(3)要想让IMU标定这个尺度,IMU也需要动一下,得到PVQ的P;
(4)另外,IMU存在bias,视觉获得的旋转矩阵不存在bias,所以可以用视觉来标定IMU的旋转bias;
(5)需要获得世界坐标系这个先验信息,通过初始化能借助g来确定;

对于双目系统而言,
初始化的难度会低一些,因为双目可以一下确定深度,只需要通过g的方向(先验)来确定世界坐标系。

注意,这个初始化只进行一次就够了,或者是在系统重启时执行一次,大部分时候,系统都处于NON_LINEAR的状态。因为,初始化的时候,就能确定尺度scaler和bias初始值,scaler确定后,在初始化获得的这些路标点都是准的了,后续通过PnP或者BA得到的特征点都是真实尺度的了。而bias初始值确定以后,在后续的非线性优化过程中,会实时更新。

6.1 基础原理

初始化的逻辑图如下:
在这里插入图片描述

6.1.1 如果旋转外参数 qbc 未知, 则先估计旋转外参数
实际上讲,这部分并不是vins代码中初始化的内容,而是初始化之前就需要完成的判断和操作,见5.2-4。根据IMU和视觉部分的旋转关系,可以得到下面的关系式:
在这里插入图片描述 在这里插入图片描述在这里插入图片描述将多个帧之间的等式关系一起构建超定方程Ax=0。对A进行svd分解,其中最小奇异值对应的奇异向量便为需要求解的qbc。
虽然这里IMU的旋转部分并没有标定,得到的外参数可能不太准。但是问题不大,因为初始化所占用的总运行时间不长,而更长生命周期的后端会持续的优化这部分的值。

6.1.2 利用SfM确定各个pose和特征点的相对于c0帧的位置关系
这一部分和基于图像的三维重建比较像,可以用三角化和PnP把这一串的ck帧的位姿和特征点位置确定下来(特征点是伪深度),在加上外参数qbc和pbc,一系列bk帧的位姿也确定下来。注意,这里把c0帧作为基础帧,实际上,c0帧旋转一下使gc0和gw方向一致时获得的坐标系就是vins的世界坐标系,也就是先验。在vins代码中,这一部分篇幅很长,但是这一部分也是很重要的部分。
在这里插入图片描述
首先我们先推导论文式(14),所有帧的位姿(Rc0ck,qc0ck)表示相对于第一帧相机坐标系(·)c0。相机到IMU的外参为(Rbc,qbc),得到姿态从相机坐标系转换到IMU坐标系的关系。
在这里插入图片描述
将T展开有成R与p有:
在这里插入图片描述
左侧矩阵的两项写开:
在这里插入图片描述
在这里插入图片描述

6.1.3 利用相机旋转约束标定IMU角速度bias
求解的目标函数如下公式所示:

在这里插入图片描述
在SfM完成且外参数标定完之后,头两个值是已知的了,而且我们假设头两个值是准的。理想状态下,这三个数乘积应该是单位四元数,很可惜,第三个值是IMU预积分得到的,而预积分里面是有bias的。所以,通过最小化这个目标函数的,可以把旋转bias标定出来!
在IMU预积分部分,也就是4.1.1最后的那个公式,有:
在这里插入图片描述
带入到损失函数里,可以得到:
在这里插入图片描述
或者是:
在这里插入图片描述
带入bias的残差后,得到,
在这里插入图片描述
实部没有需要标定的量,所以只用考虑虚部,也就是:
在这里插入图片描述
两侧再乘以 ,可以构造出Ax=B的形式,在采用LDLT分解,就可以求出状态量:
在这里插入图片描述
其实这里不像那种用高斯牛顿法迭求解,而更像是用直接法,也就是矩阵运算的方式来求待优化的状态量,6.1.4也是一样的思路。代具体代码见:initial_aligment.cpp 函数 solveGyroscopeBias()。

接下来是代码解析,
(1)参数的传入和容器的定义

void solveGyroscopeBias(map<double, ImageFrame> &all_image_frame, Vector3d* Bgs)
{
   
   
    Matrix3d A;
    Vector3d b;
    Vector3d delta_bg;
    A.setZero();
    b.setZero();
    map<double, ImageFrame>::iterator frame_i;
    map<double, ImageFrame>::iterator frame_j;
    

上式中,A和b对应的是Ax=b。注意,传入的参数是all_image_frame,不仅仅是滑窗内的帧。frame_i和frame_j分别读取all_image_frame中的相邻两帧。

(2)套本小节的最后一个公式,构造Ax=b等式

    for (frame_i = all_image_frame.begin(); next(frame_i) != all_image_frame.end(); frame_i++)
    {
   
   
        frame_j = next(frame_i);
        MatrixXd tmp_A(3, 3);
        tmp_A.setZero();
        VectorXd tmp_b(3);
        tmp_b.setZero();
        Eigen::Quaterniond q_ij(frame_i->second.R.transpose() * frame_j->second.R);
        tmp_A = frame_j->second.pre_integration->jacobian.template block<3, 3>(O_R, O_BG);
        tmp_b = 2 * (frame_j->second.pre_integration->delta_q.inverse() * q_ij).vec();
        A += tmp_A.transpose() * tmp_A;
        b += tmp_A.transpose() * tmp_b;
    }


注意到本小节的第一个公式了吗,那里有求和,所以需要遍历all_image_frame,然后叠加A和b。

(3)ldlt分解

    delta_bg = A.ldlt().solve(b);

(4)给滑窗内的IMU预积分加入角速度bias

    for (int i = 0; i <= WINDOW_SIZE; i++)
        Bgs[i] += delta_bg;

(5)重新计算所有帧的IMU积分(重要!)

    for (frame_i = all_image_frame.begin(); next(frame_i) != all_image_frame.end( ); frame_i++)
    {
   
   
        frame_j = next(frame_i);
        frame_j->second.pre_integration->repropagate(Vector3d::Zero(), Bgs[0]);
    }
}

repropagate()部分内容见4.3.2.。

6.1.4 利用IMU的平移估计重力/各bk帧速度/尺度scaler
首先要明确需要优化的状态量是什么,是各帧在bk坐标系下的速度,c0帧下的g和SfM的尺度scaler:
在这里插入图片描述
这块有个遗留问题,就是为什么要优化速度呢?
在IMU预积分部分,已经有如下的公式:
在这里插入图片描述
但是w坐标系我们不知道,只知道c0坐标系,所以需要把上面的公式转到c0坐标系上:
在这里插入图片描述
上式中,等号左边减去等号右边就是残差,理想状态下,这个残差是0,那么带入上式得:
在这里插入图片描述
把这个 XX = 0的等式也转为 A x = b这种线性方程组的形式,如下式:

SLAMVINS-MONO解析——vins_estimator流程 5.vins_estimator 基本上VINS里面绝大部分功能都在这个package下面,包括IMU数据的处理(前端)初始化(我觉得可能属于是前端),滑动窗口(后端),非线性优化(后端),关键帧的选取(部分内容)(前端)。我第一次看的时候,总是抱有一个疑问,就是为什么把这么多内容全都放在这一个node里面。为了回答这个问题,那么首先先搞清楚vins_estimator里面分别具体都是什么,为什... 阅读详情

相关推荐

VINS-mono初始化的原理解析

初始化大致流程 如果IMU和相机之间的外参未知,则需要在线标定求解旋转量qbc。 利用求解出来的qbc,结合相机间的约束,求解IMU角速度的bias。 利用IMU的运动估计重力,速度以及尺度。 利用重力的模长矫正重力,之后再矫正每个参数。 1.估计外参qbc 根据相机和IMU的坐标相对关系可得 整理得: 将多个帧之间的等式关系一起构建超定方程Ax=0,如下: 对A进行svd分解,其中最小奇异值对应的奇异向量便为需要求解的qbc。 其中 由于旋转矩阵和欧拉角..

半不闲居士的博客 2865

VINS-Mono 代码解析二、初始化 第1部分

一、前言 VINS的状态估计器模块(estimator),主要在代码中/vins_estimator节点的相关部分实现。 这个模块可以说是VINS的最核心模块,从论文的内容上来说,里面的内容包括了VINS的估计器初始化、基于滑动窗口的非线性优化实现紧耦合。此外还包括了关键帧的选择内容。该模块的代码放在文件夹vins_estimator中,可以看到,除了上述内容外,还包括有外参标定、可视化等其他功能的实现,内容实在是太多了! 本人主要按照程序的运行步骤来讲解,理论和代码 结合的方式,可能有点多,后面可能会

努力努力努力 4444

vins-mono中的初始化详解(1)

本文详细介绍vins-mono初始化阶段完成的任务,以及如何使用ceres进行优化问题的求解。

weixin_44587828的博客 1896

读懂VINS-Mono——初始化

估计器初始化 初始化的原因是单目惯性紧耦合系统是一个非线性程度很高的系统,首先单目是无法获得空间中的绝对尺度,而IMU又必然存在偏置,在后面进行求解的时候还需要用到重力加速度(包括大小和方向),对于速度比较敏感的条件下,比如说无人机,又要精确的速度信息,因此,如何有效的在紧耦合系统处理之前计算出这些量,对整个紧耦合系统的鲁棒性有着重大的意义 初始化要做的事其实说起来很简单,就是计算出绝对尺度s、...

xiaohu的博客 5367

VINS-Mono初始化流程

目录滑动窗口内的纯视觉SfM视觉惯性对齐小结 单目紧耦合的VIO是一个非线性系统,需要有一个精确的初始值。VINS-Mono初始化采用松耦合的方式将纯视觉SfM和IMU预积分对齐,获得状态估计器的初始值。该部分对应源代码的bool Estimator::initialStructure()函数。 滑动窗口内的纯视觉SfM 为了维持有限的计算复杂度,VINS-Mono采用了滑动窗口优化的方法,只对滑动窗口内的相机位姿和路标点位置进行优化。当图像帧数量累积到足够窗口大小时,系统开始初始化。在进行纯视觉SfM之

weixin_43296222的博客 1873

SLAMVINS-MONO解析——对vins-mono的一点小改动

vins-mono刷了三遍,手写vio刷了两遍,从一开始完全看不懂是啥,再到自己写总结写攻略,真的有很多感慨。学习开源代码的目的其实就是是为了自己能够去开发一个vio,一个slam系统。 slam最难的就是工程化了,公式很多人推导了一遍又一遍,道理大家都懂,但是转化为c++项目就是另一码事了。 vins系列真的是神作,对沈老师和对秦神真的是佩服。在这里我对vins-mono进行了一下小小的提升和修...

iwanderu的博客 7051

SLAMVINS-MONO解析——综述

目前网上有很多分析文章,但是都只是一些比较基础的原理分析,而且很多量,虽然有推倒,但是往往没有讲清楚这些量是什么,为什么要有这些量,这些量是从哪来的,也没有刷通整个代码,或者太简练了,对新手不友好。这一次我计划从原理/代码一步步刷通整个VINS,并且说清楚代码中遇到的每一个数据结构对应的作用是什么。 github官方上开源了VINS-monoVINS-Fusion和VINS-mobile,还有另...

iwanderu的博客 6万+

SLAMVINS-MONO解析——基于vins-mono的双目slam系统开发

这个系统是基于香港科技大学飞行机器人组的开源框架VINS-Mono开发的,原开源框架是针对单目SLAM。本双目SLAM系统是在原单目开源框架基础上的二次深度开发,外部接口与原框架一致。这个项目是我的研究课题项目,非商业用途,感谢HKUST的沈老师课题组提供的开源框架。该项目的github地址请点击这里。 1.需要的基本配置 Ubuntu 16.04 ROS Kinetic Ceres Solver...

iwanderu的博客 4331

港科大VINS-MONO入门(一):框架入门及源码解析

一、VINS介绍 VINS-Mono是HKUST的Shen Shaojie团队开源的一套Visual-Inertial融合定位算法. 介绍见(https://github.com/HKUST-Aerial-Robotics/VINS-Mono), 论文里面也有. 此外,他们还开源了ios版本(https://github.com/HKUST-Aerial-Robotics/VINS-Mobil...

wbzhang233的博客 2万+

SLAMVINS-MONO解析——前端

3. feature_tracker feature_tracker是vins的前端,它的目录在src/ feature_tracker下,功能主要是获取摄像头的图像帧,并按照事先设定的频率,把cur帧上满足要求的特征点以sensor_msg::PointCloudPtr的格式发布出去,以便RVIZ和vins——estimator接收。 这个package下面主要包括4个功能: feature_t...

iwanderu的博客 2万+

多种视觉SLAM方案对比

SLAM研究中,我们通常需要在各数据集上测试各个方案的性能情况。如下主要对表1中6个视觉SLAM方案进行相关测试,测试其在不同场景、要求下的精度和鲁棒性,并给出最终方案选型。 【由于时间、场地等原因,多次引用大神们测试结果,谢谢前人的分享!】 ** 开源SLAM方案选型: ** ** 数据集: ** 一、ORB-SLAM2 检测流程:Kinect生成地图【地图主要可见的有关键帧(包括相机的p...

hly453的博客 2万+

SLAMVINS-MONO解析——初始化(代码部分)

6.2 代码解析部分代码在estimator::processImage()最后面。初始化部分的代码虽然生命周期比较短,但是,代码量巨大!主要分成2部分,第一部分是纯视觉SfM优化滑窗内的位姿,然后在融合IMU信息,按照理论部分优化各个状态量。 if (solver_flag == INITIAL)//进行初始化 { if (frame_count == WIN...

iwanderu的博客 9696

SLAMVINS-MONO解析——IMU预积分

4.IMU预积分 IMU预积分主要干了2件事,第一个是IMU预积分获得α、β、γ值,另一个是误差传递函数的获取。本部分的流程图如下图所示。 4.1 IMU预积分 4.1.1 连续形式 第一个问题,为什么要IMU积分? IMU获取的是加速度和角速度,通过对IMU测量量的积分操作,能够获得机器人的位姿信息。 IMU测量值包括加速度计得到的线加速度和陀螺仪得到的角速度。 其中 t下标表示在IMU坐标...

iwanderu的博客 2万+

VINS-MONO概述

VINS-Mono是HKUST的Shen Shaojie团队开源的一套Visual-Inertial融合定位算法,https://github.com/HKUST-Aerial-Robotics/VINS-Mono,是用紧耦合方法实现的,通过单目+IMU恢复出尺度,效果很好,接下来对会该算法框架逐步解析,以便二次开发。 那么为什么要进行视觉与IMU的融合呢,自己总结的主要有以下几点: 视觉与IMU的融合可以借助IMU较高的采样频率,进而提高系统的输出频率。 视觉与IMU的融合可以提高视觉的鲁棒性,如视觉S

xiaojinger_123的博客 1万+

VINS技术路线与代码详解

VINS技术路线 写在前面:本文整和自己的思路,希望对学习VINS或者VIO的同学有所帮助,如果你觉得文章写的对你的理解有一点帮助,可以推荐给周围的小伙伴们,当然,如果你有任何问题想要交流,欢迎随时探讨。话不多说,下面上正文。 VINS代码地址:https://github.com/HKUST-Aerial-Robotics/VINS-Mono 参考文档:1.VINS-Mono A R...

wangshuailpp的博客 7万+

SLAMVINS-MONO解析——回环检测和重定位

部分内容涉及到的代码大部分在pose_graph文件夹下,少部分vins_estimator里。这部分最主要的作用就是求出漂移位姿矫正矩阵r_drift和t_drift。这么大一个工程,这么多行代码,保存这么多帧特征点和描述子,就是为了找出这6个自由度的变量。

iwanderu的博客 1万+

超详细:VINS-Mono论文中文记录

VINS-Mono论文笔记题目0. 摘要1. 背景简介2.相关工作介绍2.1 融合方式2.2 摄像头数据处理2.3 imu数据处理2.4 初始化2.5里程计3. VINS-Mono系统总览4 视觉和IMU测量的预处理步骤4.1 视觉部分4.2 imu部分4.3 偏置纠正5 鲁棒的初始化过程5.1 视觉重构5.2 视觉惯性联合6 紧耦合的单目VIO系统6.1 公式6.2 imu残差6.3 视觉残差6.4 边缘化残差6.5 针对相机实时帧率的纯运动视觉惯性状态估计器6.6 imu向前传播以得到imu频率的状态估

hu_hao的博客 1万+

VINS-Mono论文学习与代码解读——目录与参考

港科大的VINS-Mono作为目前state of the art的开源VIO项目,是研究视觉与IMU融合的必读算法。本人将在学习之余逐步整理自己对算法的论文和实现的相关解读,欢迎大家一起讨论。

Manii 5万+

VINS-mono详细解读与实现

VINS-mono详细解读 VINS-mono详细解读 前言 Vins-mono是香港科技大学开源的一个VIO算法,https://github.com/HKUST-Aerial-Robotics/VINS-Mono,是用紧耦合方法实现的,通过单目+IMU恢复出尺度,效果非常棒。 感谢他们开源,我从中学到了非常多的知识。源码总共有15000多行,我在通读完程序之后,结合参考文献,把程序背后...

格物致知 2万+
上一篇: 【SLAM】VINS-MONO解析——vins_estimator流程
下一篇: 【SLAM】VINS-MONO解析——初始化(代码部分)
iwander。
博客等级 码龄7年 1430粉丝 67原创
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值