MSCKF+OpenVins梳理

reference
openvins学习中的问题https://zhuanlan.zhihu.com/p/355319559
OpenVins代码梳理https://www.zhihu.com/people/anson2004110/posts
OpenVINS能观一致性分析和FEJhttps://zhuanlan.zhihu.com/p/101478814
MSCKF那些事https://zhuanlan.zhihu.com/p/76894345
从MSCKF到OPENVINS https://zhuanlan.zhihu.com/p/56783450
官方文档中文翻译 https://blog.csdn.net/qq_39266065/article/details/128327291

整体框架

在这里插入图片描述

MSCKF

MSCKF核心思想

MSCKF的目标是解决EKF-SLAM的维数爆炸问题。传统EKF-SLAM将特征点加入到状态向量中与IMU状态一起估计,当环境很大时,特征点会非常多,状态向量维数会变得非常大。MSCKF不是将特征点加入到状态向量,而是将**不同时刻的相机位姿(位置 p和姿态四元数 q)**加入到状态向量,特征点会被多个相机看到,从而在多个相机状态(Multi-State)之间形成几何约束(Constraint),进而利用几何约束构建观测模型对EKF进行update。由于相机位姿的个数会远小于特征点的个数,MSCKF状态向量的维度相较EKF-SLAM大大降低,历史的相机状态会不断移除,只维持固定个数的的相机位姿(Sliding Window),从而对MSCKF后端的计算量进行限定。

IMU状态向量:

X I M U = [ q , b g , v , b a , p ] T X_{IMU}=[q,b_g,v,b_a,p]^T XIMU=[q,bg,v,ba,p]T

其中

  • q 为单位四元数,表示从世界系 ( G 系 ) 到 I M U 坐标系 ( I 系 ) 的 q为单位四元数,表示从世界系(G系)到IMU坐标系(I系)的 q为单位四元数,表示从世界系(G)IMU坐标系(I)旋转,长度为4
  • b a 为加速度计 a c c e l e r a t o r 的偏差 b i a s b_a为加速度计accelerator的偏差bias ba为加速度计accelerator的偏差bias
  • G v 为 I M U 在 G 系下的 G_v为IMU在G系下的 GvIMUG系下的速度
  • b g 为陀螺仪 g y r o s c o p e 的偏差 b i a s b_g为陀螺仪gyroscope的偏差bias bg为陀螺仪gyroscope的偏差bias
  • p I 为 I M U 在 G 系下的 p_I为IMU在G系下的 pIIMUG系下的位置

四元数q的维度为4,转化为李代数后的维度为3,所以状态向量 X I M U X_{IMU} XIMU的长度为16,而误差向量的长度为15。

将上述状态向量转化为李代数是为了方便优化求导和迭代。MSCKF的完整误差向量维度为15+6N

MSCKF状态向量:

X M S C K F = [ X I M U , p c 1 , q c 1 , p c 2 , p c 2 , … , p c N , q c N ] X_{MSCKF}=[X_{IMU},p_{c_1},q_{c_1},p_{c_2},p_{c_2},…,p_{c_N},q_{c_N}] XMSCKF=[XIMU,pc1,qc1,pc2,pc2,,pcN,qcN]

观测模型

视觉中,约束通常都是特征点到相机的重投影误差(空间中一个3D特征点根据相机的姿态和位置投影到相机平面,与实际观测的特征点之间的误差)

我们希望用这个重投影误差的约束等式来作为观测模型,但前提是需要知道特征点的3D坐标,而实际应用中特征点的3D坐标是未知的。

MSCKF的做法是根据历史相机位姿和观测来三角化计算特征点的3D坐标。这又带来了一个问题:如何确保三角化的精度呢?如果三角化误差太大,那么观测模型就会不准,最终会使得VIO精度太差。MSCKF做法是当特征点跟踪丢失后再进行三角化,特征点跟丢表示该特征的观测不会再继续增加了,这时利用所有的历史观测三角化。所以MSCKF中观测更新的时机是特征点跟丢

算法流程

  1. IMU积分:先利用IMU加速度和角速度对状态向量中的IMU状态进行预测,一般会处理多帧IMU观测数据。
  2. 相机状态扩增:每来一张图片后,计算当前相机状态并加入到状态向量中, 同时扩充状态协方差.
  3. 特征点三角化:然后根据历史相机状态三角化估计3D特征点
  4. 特征更新:再利用特征点对多个历史相机状态的约束,来更新状态向量。注意:这里不只修正历史相机状态,因为历史相机状态和IMU状态直接也存在关系(相机与IMU的外参),所以也会同时修正IMU状态。
  5. 历史相机状态移除:如果相机状态个数超过N,则剔除最老或最近的相机状态以及对应的协方差.

图中 X X X表示状态向量, P P P表示对应的协方差矩阵,红色部分为当前步骤改变的量。

OPENVINS

OpenVINS维护的协方差中包括15维的Q,P,V,Ba,Bg,1维的IMU和相机间的时间差dt,6维的左相机的位姿LCP,8维的左相机的LC相机内参,6维的右相机的位姿RCP,8维的右相机的RC相机内参,共计44维。

每一次位姿增广后(augment_clone),当前IMU位姿作为相机位姿(6维)加入到协方差中。例如在原程序中滑动窗口的长度为11,那么增广一个后就变成12,总维度为72。当滑窗个数超过11时会处理掉一帧IMU位姿(marginalize_old_clone),则又会变回11,总维度为66。另外,长期维护的特征点上限为50个(一个点x,y,z是三维),总计150维。

OpenVins流程:

  • state propagator
  • state initialize
  • MSCKF updater
  • SLAM updater
  • zero velocity updates

IMU Propagation

利用两帧图像之间的所有IMU观测数据(加速度 a m a_m am和角速度 w m w_m wm),对MSCKF的状态向量和协方差进行迭代预测。它相当于EKF中的预测过程。

Propagator::predict_and_compute

预测IMU积分值,根据IMU积分更新状态量雅可比矩阵F和噪声雅可比矩阵Qd

状态向量预测(IMU积分)
  • predict_mean_rk4()https://docs.openvins.com/propagation_analytical.html 根据IMU内参进行4阶Runge-Kutta积分,常用的三种数值积分:Euler积分、Mid-Point积分、Runge-Kutta积分(4阶)。它们的精度依次从低到高、计算量依次从小到大。令 k 2 k_2 k2的权重为1,其他为0,RK4就退化为Mid-Point法;令 k 1 k_1 k1的权重为1,其他为0,RK4就退化为Euler积分。
  • predict_mean_discrete()https://docs.openvins.com/propagation_discrete.html根据离散的平均量进行积分

更新误差状态系数矩阵

构建离散噪声协方差矩阵

First-Estimate-Jacobian滑窗问题的解决(FEJ)

滑动窗口中的问题

滑动窗口算法中,对于同一个变量,不同残差对其计算雅克比矩阵时线性化点可能不一致,导致信息矩阵可以分成两部分,相当于在信息矩阵中多加了一些信息,使得其零空间出现了变化

解决办法: First Estimated Jacobian

FEJ 算法:不同残差对同一个状态求雅克比时,线性化点必须一致。这样就能避免零空间退化而使得不可观变量变得可观。

将计算出来的IMU状态量送进FEJ

state->_imu->set_fej(imu_x);

EKF Propagation

augment_clone

marginalize_slam


propagation time 0.0018s 0.0016s 0.0015s

feats_lost, feats_marg, feats_slam三步筛选:

  1. 如果lost点在别的相机可以观测到则保留,否则剔除掉
  2. 剔除lost中存在于feats_marg的点
  3. 如果跟踪到的点feats_marg数量达到max length 将超出的点设置为SLAM features候选

Append a new SLAM feature

如果数量没超过max 则将slamfeature候选全部加入设置为SLAM feature

遍历SLAM feature 确定marg点

对当前状态量marginalize_slam,将没有在当前帧中追踪到的边缘化掉

将SLAM feature分为update和delayed

将所有feature加入MSCKF,并根据track length进行排序

将最老的观测feature删掉

将协方差矩阵中对应的特征x_m删掉

// Generic covariance has this form for x_1, x_m, x_2. If we want to remove x_m:
//
//  P_(x_1,x_1) P(x_1,x_m) P(x_1,x_2)
//  P_(x_m,x_1) P(x_m,x_m) P(x_m,x_2)
//  P_(x_2,x_1) P(x_2,x_m) P(x_2,x_2)
//
//  to
//
//  P_(x_1,x_1) P(x_1,x_2)
//  P_(x_2,x_1) P(x_2,x_2)
//
// i.e. x_1 goes from 0 to marg_id, x_2 goes from marg_id+marg_size to Cov.rows() in the original covariance

更新MSCKF updaterMSCKF->update(state, featsup_MSCKF);

msckf time 0.021299s 0.012962s 0.007s

更新SLAMupdaterSLAM->update(state, featsup_TEMP);

SLAM time 0.032213s 0.013258s 0.0035106s


**delay_init time ** 0.014931s 0.0149179s 0.007424s


retriangulate_active_tracks

// Finally marginalize the oldest clone if needed

StateHelper::marginalize_old_clone(state);

re&marg time 0.022846s 0.021955s 0.02066s

根据相机观测计算雅可比矩阵

在这里插入图片描述

re&marg

retriangulate_active_tracks(message)

添加SLAM feature后重新对所有feature进行三角化和状态更新

  1. 对当前帧除了slam pts进行三角化,将3D点加入到active_tracks_posinG
  2. 对SLAMfeature 遍历进行三角化加入到active_tracks_posinG
  3. 将active_tracks_posinG中的3D点投影到当前帧中,保存uvd

对slam pts进行三角化

updaterSLAM->change_anchors(state);

StateHelper::marginalize_old_clone(state);

p_FinG feature in ground axis

  1. 取出当前帧的观测添加到每一个相机中,记录在cam0中的uv位置,跳过SLAM点
  2. 根据相机内参去畸变获得归一化平面坐标,将向量转化为反对称矩阵后添加到线性空间中。
  3. SVD分解求三角化
  4. 处理SLAM feature,将SLAMfeature投影到当前帧中

向量的零空间:

线性方程组Ax=0的所有解x的集合

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣labuladong一刷day54天前缀树

力扣labuladong一刷day54天前缀树 文章目录 力扣labuladong一刷day54天前缀树一、208. 实现 Trie (前缀树)二、648. 单词替换三、211. 添加与搜索单词 - 数据结构设计四、1804. 实现 Trie (前缀树) II五、677. 键值映射 一、208. 实现 Trie (前缀树) 题…

一键了解获取网页requests方式

目录 一、爬虫原理: 二、安装: 测试: 三、文件的操作 方式一 方式二: 方式三 四、认识User-Agent 4.1、为什么用User-Agent: 步骤: 五、请求方式 5.1、get 5.2、post 六、爬出有中国关键字页面案例 一、爬…

win10下vscode+cmake编译C代码操作详解

0 工具准备 1.Visual Studio Code 1.85.1 2.cmake 3.24.01 前言 当我们只有一个.c文件时直接使用vscodeCode Runner插件即可完成编译,如果我们的工程很复杂包含多个.c文件时建议使用cmake来生成对应的make,指导编译器完成编译,否则会提示各…

强化学习的数学原理学习笔记 - 基于模型(Model-based)

文章目录 概览:RL方法分类基于模型(Model-Based)值迭代(Value Iteration)🟦策略迭代(Policy Iteration)🟡截断策略迭代(Truncated Policy Iteration&#xff…

YOLOv5改进 | 损失函数篇 | EIoU、SIoU、WIoU、DIoU、FocusIoU等二十余种损失函数

一、本文介绍 这篇文章介绍了YOLOv5的重大改进,特别是在损失函数方面的创新。它不仅包括了多种IoU损失函数的改进和变体,如SIoU、WIoU、GIoU、DIoU、EIOU、CIoU,还融合了“Focus”思想,创造了一系列新的损失函数。这些组合形式的损失函数超过了二十余种,每种都针对特定的…

K8S--安装MySQL8(单机)

原文网址:K8S--安装MySQL8(单机)-CSDN博客 简介 本文介绍K8S部署MySQL8(单机)的方法。 本文的目标 1.通过PV和PVC(hostPath方式)存储MySQL的数据 2.通过Deployment、Service部署MySQL8&…

Java异常机制:从混乱到控制的错误管理艺术

👑专栏内容:Java⛪个人主页:子夜的星的主页💕座右铭:前路未远,步履不停 目录 一、异常的体系结构1、异常的体系结构2、异常的分类 二、异常的处理1、异常的抛出2、异常的捕获2.1、异常声明throws2.2、try-c…

leaflet:加载本地shp文件,并在地图上显示出来 (138)

第138个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载本地shp文件,利用shapefile读取shp数据,转换为json,利用L.geoJSON()在地图上显示图形。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果 文章目录 示例效果安装加载shapefile.j…

Docker使用扩展

日升时奋斗,日落时自省 目录 1、容器 1.1、容器的生命周期 1.1.1、容器OOM 1.1.2、容器异常退出 1.1.3、容器暂停 1.2、容器命令 1.2.1、创建容器 1.2.2、启动容器 1.2.3、容器日志 1.2.4、容器交互 1.2.5、容器停止 1.2.6、扩展 1.3、综合演示 2、存…

ChatGPT | 模型架构 | 应用 | 思考

介绍 ChatGPT 3.5 是 OpenAI 推出的语言模型的一个版本,是 GPT(生成式预训练模型)系列的一部分。在自然语言理解和生成方面具有强大的能力,可以应用于问答系统、文本生成、翻译和对话系统等多个领域。 模型架构 GPT-3.5&#x…

【代码】Keras3.0:实现残差连接

简介 残差连接是一种非常重要的网络结构创新,最早被广泛应用于ResNet(Residual Neural Network)模型中,由何凯明等人在2015年的论文"Deep Residual Learning for Image Recognition"中提出。 核心思想 通过引入“short…

Linux stm32串口下载程序

一、工具 使用stm32flash进行串口下载 二、stm32flash安装 sudo apt-get install stm32flash 三、查看串口设备名称 先拔掉串口运行下面指令,获得所有设备名称,插上串口再运行一次,新增的就是串口设备名称,记住串口设备名称,以…

【Hadoop】说下HDFS读文件和写文件的底层原理?

文件读取文件的写入 文件读取 客户端调用 FileSystem 对象的 open()函数,打开想要读取的文件。其中FileSystem 是 DistributeFileSystem 的一个实例;DistributedFileSystem 通过使用 RPC(远程过程调用) 访N…

Unity 了解Input Manage下默认的输入轴

在Unity菜单Edit->Project Settings->Input Manager->Axes下有一些默认的输入轴,如 这些输入轴代表不同类型的输入,其中: Horizontal:水平移动输入轴。通常与键盘的左右箭头键、A和D键、游戏手柄的左摇杆水平轴等相关联…

【AI视野·今日CV 计算机视觉论文速览 第282期】Wed, 3 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Wed, 3 Jan 2024 Totally 70 papers 👉上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Street Gaussians for Modeling Dynamic Urban Scenes Authors Yunzhi Yan, Haotong Lin, Chenxu Zhou, Weijie Wang, Haiya…

nvm安装教程,实现node的多版本管理(图文界面)

目录 前言1. 安装配置2. 使用方式 前言 由于前端项目不同的node版本,导致重复的卸载安装会比较麻烦,对此需要nvm来管理 类似python版本的差异,可以使用虚拟环境管理(anconda),在我原先的文章也有讲解过 …

从法律和经济学角度看工业数据共享

文章目录 前言一、工业数据利用现状二、工业数据的新特点三、数据再利用和储备的现状(一)防止先行者通过数据进行垄断(二)数据储备情况以及数据成本、数量和价值四、工业数据共享的法律经济学模型分析情形一:在没有数据共享政策的情况下,尝试给出如下命题。情形二:有数据…

LeetCode-加一(66)

题目描述: 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外,这个整数不会以零开头。 思路: 这里主要分…

《路由与交换技术》---简答题

1、什么是STP?解决什么问题? STP代表生成树协议(Spanning Tree Protocol)。它是用于在计算机网络中解决环路问题的一种协议。 STP的主要目标是消除环路,保持网络的稳定性和可靠性,同时提供冗余路径以实现网…

快速实现产品智能:用 AI 武装你的 API | 开源日报 No.138

openchatai/OpenCopilot Stars: 3.8k License: MIT OpenCopilot 是一个允许你拥有自己产品的 AI 副驾驶员的项目。它集成了产品底层 API,并可以在需要时执行 API 调用。它使用 LLMs 来确定用户请求是否需要调用 API 端点,然后决定调用哪个端点并根据给定…