【SLAM】LVI-SAM解析——综述

2023-11-22 07:40
文章标签 解析 slam 综述 sam lvi

本文主要是介绍【SLAM】LVI-SAM解析——综述,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

LVI-SAM可以认为是LIO-SAM和VINS-MONO的合体,在此基础上的修改不大。

github: https://github.com/TixiaoShan/LVI-SAM

paper: LVI-SAM: Tightly-coupled Lidar-Visual-Inertial Odometry via Smoothing and Mapping

有一个注释版的代码:https://github.com/electech6/LVI-SAM_detailed_comments

这个注释版代码中一些关于坐标系的注释我认为是有错误的,大家擦亮眼睛。LIO-SAM和VINS-MONO我也分别写过比较详细的代码解析,详情见链接。

1. 综述

 这个是论文里的流程图,很贴心的介绍了LVI-SAM改了哪些地方:

1.VINS-MONO的初始化由LIO-SAM的imuPreintefration提供;

2.VINS-MONO的feature_tracker同时和来自LIO-SAM的imageProjection的lidar进行了深度关联,就不用自己进行三角化;

3.LIO-SAM的imageProjection订阅的里程计来自VINS-MONO的estimator的imucallback提供的高频里程计;

4.VINS只进行回环检测,不做重定位,回环检测的结果提供给LIO-SAM的mapOptimization进行icp匹配+全局图优化。

代码流程图如下:

在代码里,论文中指出的来自vio的between factor并没有加上:

2.注意事项

2.1 官方数据集的坐标系统

代码里坐标系系统比较混乱,官方数据集的坐标系是这样的:

红色是相机坐标系,蓝色是lidar坐标系,绿色是LVI-SAM的坐标系,橙色是VINS的坐标系,也就是IMU坐标系。官方配置文件中params_camera.yaml里的lidar_to_cam_XX外参指蓝色和绿色之间的外参,并不是蓝色和红色之间的外参。

此外,Feature_tracker_node的get_depth()中给特征点赋予lidar深度时,忽略了cam和lidar之间的平移,即image特征的单位球和点云的单位球球心不统一,分别是cam和IMU,rotation是统一的,都是为lidar的R。

3. LVI-SAM主要改了哪些地方

3.1. image feature的数据关联

在一个位于相机中心的单位球体上投影视觉特征和激光雷达深度点,借助球面2D kdtree找到球体上最近的三个深度点。特征深度是由视觉特征和照相机中心Oc形成的线的长度,它与笛卡尔空间中由三个深度点形成的平面相交。

考虑到每帧image都会对应积攒了一段时间的lidar点云,持续被追踪的特征点可能会投影上不同的深度值。所以他们会检查一个特征点附近的深度值差判断是否采用该深度值。

lidar点云的积攒:visual_odometry/visual_feature/feature_tracker_node.cpp:lidar_callback()

深度关联:visual_odometry/visual_feature/feature_tracker.h:get_depth()

3.2 VINS的初始化

整个系统最开始初始化的地方是LIO-SAM的mapOptimization的updateInitialGuess()这里,第一帧会使用9轴IMU的pitch,roll信息确定R,首帧lidarpose确定之后提供给IMUPreintegration联合imu预积分量进行图优化,然后再发布高频的imuPose被vins-estimator-node订阅,用它计算得到的PQV+bias对VINS系统进行初始化。

获取LIO-SAM的数据: visual_odometry/visual_estimator/initial/initial_alignment.h:Class odometryRegister

VINS初始化:visual_odometry/visual_estimator/estimator.cpp: initialStructure()

3.3 其它

还有就是VINS给LIO-SAM提供pose初值,还有回环检测,这些内容都比较简单,就不贴地址了。

这篇关于【SLAM】LVI-SAM解析——综述的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/408581

相关文章

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Python利用ElementTree实现快速解析XML文件

《Python利用ElementTree实现快速解析XML文件》ElementTree是Python标准库的一部分,而且是Python标准库中用于解析和操作XML数据的模块,下面小编就来和大家详细讲讲... 目录一、XML文件解析到底有多重要二、ElementTree快速入门1. 加载XML的两种方式2.

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

java解析jwt中的payload的用法

《java解析jwt中的payload的用法》:本文主要介绍java解析jwt中的payload的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java解析jwt中的payload1. 使用 jjwt 库步骤 1:添加依赖步骤 2:解析 JWT2. 使用 N

Python中__init__方法使用的深度解析

《Python中__init__方法使用的深度解析》在Python的面向对象编程(OOP)体系中,__init__方法如同建造房屋时的奠基仪式——它定义了对象诞生时的初始状态,下面我们就来深入了解下_... 目录一、__init__的基因图谱二、初始化过程的魔法时刻继承链中的初始化顺序self参数的奥秘默认

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三