《LIO-SAM阅读笔记》1.IMU预积分模块

news2024/9/27 5:24:42

前言:

        LIO-SAM是一个多传感器融合的紧耦合SLAM框架,融合的传感器类型有雷达、IMU和GPS,其中雷达和IMU在LIO-SAM框架中必须使用的。LIO-SAM的优化策略采用了GTSAM库,GTSAM库采用了因子图的优化方法,其提供了一些列C++的外部接口,以便用户方便传入参数等进行优化。特别的是GTSAM库专门单独设计关于IMU计算与优化的接口。

        IMU预积分模块在LIO-SAM源码中写在了imuPreintegration.cpp文件中,其中预积分模块的功能使用class IMUPreintegration来实现,IMUPreintegration类中构造函数中最主要的两个部分分别是imu的回调函数imuHandler和odom的回调函数odometryHandler。

1.IMU回调函数imuHandler

在imuHandler中主要分为了3个部分,分别是将imu数据放入缓存队列,计算imu里程计,发布imu里程计。

1.1 将imu数据放入缓存队列

在回调函数中,首先将接受到的imu原始数据存放进两个队列中,第一个队列用来预积分与优化,第二个队列用来更新imu状态量(进行优化后的位姿传播),这两个队列都是在odom的回调函数odometryHandler中使用。

1.2 计算imu里程计

       此部分是将2.3部分联系在一起的,利用最近一次的odom里程计作为起点利用imu预积分来计算每一帧imu数据时刻的位姿。

        2.3小节只是将当前帧的odom里程计作为起点加入到imu预积分器中,在此小节中是加入每帧imu信息到预积分器,以及预积分器的推理。

1.3 发布imu里程计

imu里程计位姿转到lidar系,发布里程计。

2.odom回调函数odometryHandler

在odometryHandler回调函数中主要进行了imu数据和lidar的里程计数据联合进行因子图优化的操作。

2.1 odometryHandler中进行的主要操作
  • Step 0. 系统初始化,第一帧
  • Step 1. 计算前一帧与当前帧之间的imu预积分量,用前一帧状态施加预积分量得到当前帧初始状态估计,添加来自mapOptimization的当前帧位姿,进行因子图优化,更新当前帧状态
  • Step 2. 优化之后,执行重传播;优化更新了imu的偏置,用最新的偏置重新计算当前激光里程计时刻之后的imu预积分,这个预积分用于计算每时刻位姿。
  • Step 3. 每隔100帧激光里程计,重置ISAM2优化器,保证优化效率
2.2 因子图优化的步骤
  • 1.添加imu预积分因子
// 上面imu预积分的结果
const gtsam::PreintegratedImuMeasurements &preint_imu = dynamic_cast<const gtsam::PreintegratedImuMeasurements &>(*imuIntegratorOpt_);
// 参数:前一帧位姿,前一帧速度,当前帧位姿,当前帧速度,前一帧偏置,预计分量   //?:此处的当前帧位姿和当前帧速度是哪里得到的?此处是否是待求量?
gtsam::ImuFactor imu_factor(X(key - 1), V(key - 1), X(key), V(key), B(key - 1), preint_imu);
graphFactors.add(imu_factor);
  • 2.添加imu偏置因子,前一帧偏置,当前帧偏置,观测值,噪声协方差;deltaTij()是积分段的时间
graphFactors.add(gtsam::BetweenFactor<gtsam::imuBias::ConstantBias>(B(key - 1), B(key), gtsam::imuBias::ConstantBias(),
                                                                            gtsam::noiseModel::Diagonal::Sigmas(sqrt(imuIntegratorOpt_->deltaTij()) * noiseModelBetweenBias)));
  • 3.添加位姿因子
gtsam::Pose3 curPose = lidarPose.compose(lidar2Imu);
gtsam::PriorFactor<gtsam::Pose3> pose_factor(X(key), curPose, degenerate ? correctionNoise2 : correctionNoise);
graphFactors.add(pose_factor);
// 用前一帧的状态、偏置,施加imu预计分量,得到当前帧的状态  // note: 前一帧的状态是经过上一次优化后的结果
gtsam::NavState propState_ = imuIntegratorOpt_->predict(prevState_, prevBias_);
  • 4.变量节点赋初值
graphValues.insert(X(key), propState_.pose());
graphValues.insert(V(key), propState_.v());
graphValues.insert(B(key), prevBias_);
  • 5.优化
optimizer.update(graphFactors, graphValues);
optimizer.update();
graphFactors.resize(0);
graphValues.clear();
// 优化结果
gtsam::Values result = optimizer.calculateEstimate();

注意: 每优化完成一次后,就会清空因子图和变量,优化器是每100帧重置一次。因此每次向优化器内添加的因子图和变量是一一对应的。

  • 6.利用优化结果更新状态量
// 更新当前帧位姿、速度
prevPose_ = result.at<gtsam::Pose3>(X(key));
prevVel_ = result.at<gtsam::Vector3>(V(key));
// 更新当前帧状态
prevState_ = gtsam::NavState(prevPose_, prevVel_);
// 更新当前帧imu偏置
prevBias_ = result.at<gtsam::imuBias::ConstantBias>(B(key));
  • 7.重置预积分器,设置新的偏置,这样下一帧激光里程计进来的时候,预积分量就是两帧之间的增量
imuIntegratorOpt_->resetIntegrationAndSetBias(prevBias_);
2.3 因子图优化之后的重传播步骤

        这里用一张示意图来表达,这一部操作最主要的原因是:imu接受数据的频率大于odom里程计的数据,因此每来一个odom数据,队列中已经有多个imu数据,而因子图优化的频率是按照odom里程计的频率来进行的,因此如果想要得到每一个imu数据时刻的位姿估计就要以最近的odom时刻的位姿为初始值,通过每个imu数据时刻的预积分进行位姿的传播。

效果展示:此处一小段粉红色的轨迹就是通过经过因子图优化后的重传播(IMU预积分)预测出的轨迹,前面蓝色的轨迹是因子图优化得到的轨迹。

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

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

相关文章

CRS-4995: The command ‘start resource’ is invalid in crsctl.

ntp时间调整后&#xff0c;节点1&#xff0c;advm 和acfs offline 处理办法&#xff1a; /u01/app/12.2.0.1/grid/bin/crsctl stop crs /u01/app/12.2.0.1/grid/bin/crsctl start crs 曾经尝试如下命令不起作用 /u01/app/12.2.0.1/grid/bin/acfsload start /u01/app/12.2…

2023_Spark_实验三十三:配置Standalone模式Spark3.4.2集群

实验目的&#xff1a;掌握Spark Standalone部署模式 实验方法&#xff1a;基于centos7部署Spark standalone模式集群 实验步骤&#xff1a; 一、下载spark软件 下载的时候下载与自己idea里对应版本的spark News | Apache Spark 选择任意一个下载即可 - spark 3.4.1 - spark …

Mybatis缓存机制详解与实例分析

前言&#xff1a; 本篇文章主要讲解Mybatis缓存机制的知识。该专栏比较适合刚入坑Java的小白以及准备秋招的大佬阅读。 如果文章有什么需要改进的地方欢迎大佬提出&#xff0c;对大佬有帮助希望可以支持下哦~ 小威在此先感谢各位小伙伴儿了&#x1f601; 以下正文开始 Mybat…

AI时代下,如何看待“算法利维坦”?程序员客栈程序员客栈​

ChatGPT的浪潮从2022年袭来后&#xff0c;至今热度不减&#xff0c;呈现出蓬勃发展的趋势。AI家居、医疗、教育、金融、公益、农业、艺术......AI真的已经走进了生活的方方面面&#xff0c;我们仿佛已经进入了AI时代&#xff0c;势不可挡。人工智能水平如此之高&#xff0c;不禁…

Dijkstra(迪杰斯特拉)算法总结

知识概览 Dijkstra算法适用于解决所有边权都是正数的最短路问题。Dijkstra算法分为朴素的Dijkstra算法和堆优化版的Dijkstra算法。朴素的Dijkstra算法时间复杂度为&#xff0c;适用于稠密图。堆优化版的Dijkstra算法时间复杂度为&#xff0c;适用于稀疏图。稠密图的边数m和是一…

ansible-playbook实操之一键搭建lnmp+wordpress

目录 1、架构和准备&#xff1a; 2、配置nginx角色&#xff1a; 3、配置mariadb角色&#xff1a; 4、配置php角色&#xff1a; 5、配置完之后&#xff0c;写脚本调用roles 6、配置完之后浏览器搭建wordpress&#xff1a; 1、架构和准备&#xff1a; 操控节点&#xff1a;…

2022第十二届PostgreSQL中国技术大会-核心PPT资料下载

一、峰会简介 本次大会以“突破•进化•共赢 —— 安全可靠&#xff0c;共建与机遇”为主题&#xff0c;助力中国数据库基础软件可掌控、可研究、可发展、可生产&#xff0c;并推动数据库生态的繁荣与发展。大会为数据库从业者、数据库相关企业、数据库行业及整个IT产业带来崭…

C# 类型和成员

C# 教程 - 类型及其成员 - C# | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/tour-of-csharp/types 目录 类和对象 类型参数 基类 结构 接口 枚举 可为 null 的类型 元组 作为面向对象的语言&#xff0c;C# 支持封装、继承和多态性这些概念。 类可…

图像质量评估方法——结构相似性指数(SSIM)

结构相似性指数&#xff08;SSIM&#xff09;是一种全参考图像质量评估方法&#xff0c;用于比较两幅图像的相似性。 SSIM的计算涉及到亮度&#xff08;Luminance&#xff09;、对比度&#xff08;Contrast&#xff09;和结构&#xff08;Structure&#xff09;三个方面的相似性…

Goland配置leetcode

1. 安装 首先在goland的setting界面上找到Plugins&#xff0c;然后搜索关键字leetcode&#xff0c;找到LeetCode Editor&#xff0c;安装它。 在安装后&#xff0c;第一次需要对其进行配置&#xff0c;在Tools中找到LeetCode Plugins&#xff0c;如下图所示进行配置。首先国内…

Pytorch,16个超强转换函数全总结!!

哈喽&#xff0c;这些天无论是社群还是私信&#xff0c;很多人希望看到更多关于深度学习基础内容&#xff0c;这篇文章想要分享的是关于pytorch的转换函数。 建议大家一定要好好看看这部分&#xff0c;在平常的使用中&#xff0c;既多又重要&#xff01;&#xff01; 当然在 P…

正式官宣!谈思AutoSec 8周年年会暨中国汽车网络安全及数据安全合规峰会将于明年4月在沪召开

随着智能互联网时代的到来&#xff0c;智能汽车的安全形势变得更加严峻和复杂&#xff0c;网络资产的暴露和安全边界继续扩大。与传统的汽车车身安全问题相比&#xff0c;网络安全、数据安全、用户隐私等安全问题交织叠加&#xff0c;并加速了黑客对智能汽车领域的渗透&#xf…

在别人发来的文章上修改时,出现红色且带下划线的情况

这是因为一些比较严谨的机构将模板发过来在你修改的时候会出现特殊标记&#xff08;比如律师行业&#xff09; 这里想要直接在他的文档上进行修改&#xff0c;需要取消掉原来的修订配置 再次输入格式消失

我们一起动手学大模型应用开发

大模型正逐步成为信息世界的新革命力量&#xff0c;其通过强大的自然语言理解、自然语言生成能力&#xff0c;为开发者提供了新的、更强大的应用开发选择。 随着国内外井喷式的大模型 API 服务开放&#xff0c;如何基于大模型 API 快速、便捷地开发具备更强能力、集成大模型的…

three.js使用精灵模型Sprite渲染森林

效果&#xff1a; 源码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div><div class"box-right&quo…

nginx反向代理服务器及负载均衡服务配置

一、正向代理与反向代理 正向代理&#xff1a;是一个位于客户端和原始服务器(oricin server)之间的服务器&#xff0c;为了从原始服务器取得内容&#xff0c;客户端向代理发送一个请求并指定目标(原始服务器)&#xff0c;然后代理向原始服务器转交请求并将获得的内容返回给客户…

一文道破Java中的深拷贝,浅拷贝,零拷贝

前言 在Java编写代码中&#xff0c;对象的拷贝是一个常见的操作。根据拷贝的层次和方式不同&#xff0c;可以分为深拷贝、浅拷贝和零拷贝。本篇文章我们将详细介绍这三种拷贝方式的概念、实现方法以及使用场景&#xff0c;方便大佬学习及面试。 深拷贝 深拷贝是一种创建对象副…

晶振等效电路工作原理和特性详细解读

晶振等效电路对于理解电子设备的工作原理和故障排除具有重要意义&#xff0c;晶振工作时内部是真实的存在“振动”的&#xff0c;是机械振动。振动的同时两端会输出对应频率的振动电压&#xff0c;这个电压非常精确且稳定&#xff0c;所以我们经常用作时钟信号。 一、等效电路…

【AI】使用阿里云免费服务器搭建Langchain-Chatchat本地知识库

书接上文&#xff0c;由于家境贫寒的原因&#xff0c;导致我本地的GPU资源无法满足搭建Langchain-Chatchat本地知识库的需求&#xff0c;具体可以看一下这篇文章&#xff0c;于是我只能另辟蹊径&#xff0c;考虑一下能不能白嫖一下云服务器资源&#xff0c;于是去找网上找&…

阿里云服务器本地localhost换成本地的IP地址后不能访问的原因

阿里云服务器本地localhost换成本地的IP地址后不能访问的原因 问题在安装以及配置都没有问题的情况下我使用localhost:5001&#xff08;127.0.0.1:5001&#xff09;都可以正常使用&#xff0c;但是我是用本机Ip地址的时候发现无法打开网页以上这个问题出现在我阿里云的服务器上…