当前位置: 首页 > article >正文

FAST-LIO笔记

1.FAST-LIO

FAST-LIO 是一个计算效率高、鲁棒性强的激光-惯性里程计系统。该系统通过紧耦合的迭代扩展卡尔曼滤波器(IEKF)将激光雷达特征点与IMU数据进行融合,使其在快速运动、噪声较大或环境复杂、存在退化的情况下仍能实现稳定的导航。

1.1问题

1)LiDAR测量中提取的特征点通常是环境中的几何结构(如边缘和平面)。当无人机在特征不明显的复杂环境中运行时,LiDAR方案容易出现退化问题。该问题在视场角(FoV)较小的LiDAR中尤为明显; (特征稀缺的环境中或使用小FoV的LiDAR时,性能容易退化

2)由于在扫描方向上具有高分辨率,一帧LiDAR扫描通常包含大量特征点(例如几千个)。尽管这些特征点在退化场景中无法稳定估计位姿,但若将其与IMU测量进行紧耦合融合,将导致巨大的计算负担,而这对于无人机的机载计算机来说是不可承受的;(嵌入式平台对算力有要求

3)由于LiDAR使用少数激光发射/接收对逐点扫描,因此每个激光点的采样时间不同,这种时间差造成的运动畸变会显著降低点云配准的准确性。此外,无人机螺旋桨和电机的持续旋转还会对IMU测量引入显著噪声。(点云去畸变以及外部因素影响IMU测量

1.2解决方法

为使LiDAR导航适用于小型移动机器人(如无人机),提出了FAST-LIO——一个计算高效且鲁棒的LiDAR-IMU里程计算法。主要贡献如下:

1)为应对高速运动、有噪声或复杂环境中发生退化的情况,我们采用紧耦合的迭代卡尔曼滤波器,将LiDAR特征点与IMU测量数据融合。我们提出了正式的后向传播方法来补偿运动畸变

2)为减少大量LiDAR特征点带来的计算负担,我们提出了一种新的卡尔曼增益计算公式,并证明其与传统公式等价。新公式的计算复杂度取决于状态维度,而不是测量维度

3)我们将这些公式实现为一个快速且鲁棒的LiDAR-IMU里程计算软件包,系统可以运行在小型四旋翼的机载计算机上;

4)我们在多种室内和室外环境下,以及实际无人机飞行测试中,验证了系统在快速运动或强烈振动噪声条件下的鲁棒性。

1.3系统框架

  • LiDAR原始数据首先输入到特征提取模块,提取出平面特征和边缘特征。
  • 提取出的特征与IMU测量数据一同输入到状态估计模块中,以10Hz或50Hz的频率进行状态估计。IMU数据前向传播(粗略地位姿估计),后向传播(运动补偿去畸变
  • 估计得到的位姿用于将当前帧的特征点配准到全局坐标系中,并与当前已构建的特征点地图进行融合。更新后的地图将用于下一步中新点云的配准操作。

1.4系统描述        

关于流行的解释

流形(Manifold )是局部具有欧几里得空间性质的空间,是欧几里得空间中的曲线、曲面等概念的推广。参考文章中关于二维圆和三维球的例子解释的很好,二维空间中的圆就是一个一维流形,三维空间中的球面是一个二维流形

参考:https://www.cnblogs.com/icmzn/p/11082509.html

IMU运动模型

本质上是对P、V、Q的求导

离散模型

需要估计的状态量是个18维的量,包括位置、速度、姿态、偏置和加速度g .

数据预处理

由于原始LiDAR点是以非常高的频率(例如200kHz)采样的,因此通常无法在每接收到一个新点时立即处理它们。更实际的方法是将这些点积累一段时间,然后一次性处理它们。

在FAST-LIO中,最小的积累间隔设置为20毫秒,从而实现高达50Hz的全状态估计(即里程计输出)和地图更新。这种积累后的点集被称为一个扫描(scan),并且处理该扫描的时间为 tk。从原始点云中,我们提取具有较高局部平滑性的平面点和具有较低局部平滑性的边缘点。

1.5状态估计

使用迭代扩展卡尔曼滤波估计状态量X

前向传播 Forward Propagation

在 FAST-LIO 系统中,一旦接收到 IMU 输入,就会执行一次前向传播,用于预测系统当前的状态(积分得到粗略地位姿估计)。

后向传播与运动补偿 Backward Propagation and Motion Compensation

激光雷达一帧数据由很多点组成,这些点显然不是同一时间测量得到的,所以需要补偿时间差带来的运动误差。把一帧不同采样时间的点转换到最后的帧末时间(反向传播去运动畸变

残差计算和迭代状态更新

计算lidar里程计的残差,和LOAM、LIO-SAM一样,计算点面之间的距离作为残差。

利用迭代卡尔曼滤波估计位姿。

算法流程

1.6地图更新 MapUpdate

根据求解的状态量 X 把激光雷达点投影到世界坐标系的过程.

1.7初始化

为了获得系统状态(例如重力向量 Gg、偏差和噪声协方差)的良好初始估计,从而加速状态估计,需要进行初始化。在 FAST-LIO 中,初始化非常简单:保持 LiDAR 静止几秒钟(本文中的所有实验为 2 秒),然后将收集的数据用于初始化 IMU 偏差和重力向量。如果 LiDAR 支持非重复扫描(例如,Livox AVIA),保持静止还允许 LiDAR 捕捉一个初始的高分辨率地图,这对后续的导航非常有利。


 

2.代码相关

FAST-LIO 的代码是6e1fa94之前的commit的,之后的都是FAST-LIO2,注意区分。

代码有两个节点loam_feat_extract、loam_laserMapping。

2.1loam_feat_extract

1.支持四种激光雷达的点云:MID40、HORIZON、VELO16、OUST64,分别对应不同的回调函数

  • MID40:msg转为PCL点云,然后进行特征提取;
  • HORIZON(点云是livox自定义的类型)把每条线束scan的点看作一个点云,单帧点云把所有线束的点云放到容器vector中;会剔除一些重复性扫描到的点;

2.特征提取 give_feature

判断每个点类型是什么,如果是Edge_Jump或者Edge_Plane,加入到角点点云中;如果是Poss_Plane或者Real_Plane加入到面点点云中。最后将两个点云和单帧点云以话题形式发布。

2.2loam_laserMapping

1.订阅面点点云和IMU话题,把数据放到队列中,主函数中根据当前lidar的时间戳找到小于它时间戳的IMU数据 sync_packages()

2.对一组面点点云和IMU数据进行处理,计算状态量去除畸变后的面点点云 Process()

  • 第一次执行会进行初始化,利用开始的IMU帧的平均值初始化状态量x(初始化重力、陀螺仪偏差、加速度计和陀螺仪协方差)。只执行一次,执行完就退出了;
  • 后续帧会点云去畸变处理 UndistortPcl()

这个函数首先会把上一帧尾部的IMU数据添加到当前帧头部,遍历这些IMU数据,通过离散中值积分计算每两个IMU数据之间的状态量,更新协方差矩阵(对应论文公式7、8)

:关于误差卡尔曼ESKF的推导 建议参考高博的简明推导

然后将点云的每个点映射到采样结束时刻(后向传播,去畸变)。具体代码结合下面这张图更容易理解,参考[2]

假设某帧lidar采样开始时间是tb,采样结束时间是te,后向传播就是把单帧所有点的坐标映射到采样结束时刻te。

1.采样结束那一刻不一定有对应的IMU数据,因此先计算最后一个IMU数据到 te时刻的时间差 dli,以 dli 再做一次中值积分就得到了 te时刻系统的状态;

2.按时间从后往前遍历点云,假设当前点p对应的时刻为 tn,其所属的IMU区间时刻为[ tib , tie ](代码这部分设计的很巧妙),可以求得 tn 与 tib 的时间差 dt ,通过 dt 和 tib 时刻的位姿,便可求得 tn 时刻IMU的位姿。

3.上一步求得了 tn 时刻IMU的位姿,结合外参可以求出点p的世界坐标。

4.结合第一步te时刻IMU的位姿与第三步该点的世界坐标,可将该点世界坐标通过te时刻IMU位姿和外参反算回lidar系,就得到了该点在te时刻的lidar坐标系坐标。

总结:从 te 时刻至 tb 时刻,对每一个点完成上述操作,系统便完成了反向传播,即将一帧中所有点云都补偿到了这一帧结束的时刻。总之,通过向前与反向传播,得到了在点云最终时刻系统名义状态的先验值 x(计算了PVR,没有算bias) 误差状态的先验协方差 P运动补偿后的点云

3.局部地图动态管理,目的:为了始终维持lidar所在的世界坐标的位置在局部地图的中心,这样的匹配效果会更好  lasermap_fov_segment()

4.判断历史地图是否为空,若为空,用当前帧的点云降采样填充 featsFromMap;否则,对已有的 featsFromMap 再次降采样,如果降采样后点的个数大于5,会进入一个很大的if条件里。

  • 用当前帧点云与局部地图进行配准;

当前帧的每个点(lidar系)变换到世界坐标系(Pw = Twl * Pl = Twi * Til * Pl),然后找这个点在局部地图的五个近邻点,对这五个点拟合平面方程(Ax + By + Cz + D = 0),最小二乘求这个方程得到平面的法向量,计算该点到这个平面的距离作为残差。

  • 构建测量雅可比矩阵和观测值;

这部分主要是公式的推导,具体过程参考[3]的观测模型内容

  • 执行EKF状态更新;

这部分内容也是公式的推导,对当前状态进行更新以及卡尔曼增益的计算。其中卡尔曼增益的计算 用矩阵求逆定理推导了一种新的卡尔曼增益计算形式

  • 更新局部地图

根据求解的最优状态  把激光雷达点投影到世界坐标系.

5.话题的发布

发布去畸变后的点云、和局部地图匹配成功点的点云,发布里程计、路径。

总结

之前接触过的SLAM基本都是基于优化的后端方法,FAST-LIO算是我第一次接触基于滤波优化的方法,明显的区别在大量的公式推导。

参考

1.ESKF推导 https://zhuanlan.zhihu.com/p/441182819

2.Fast-Lio2代码及论文解析 https://zhuanlan.zhihu.com/p/616275334

3.观测模型的雅可比推导 https://zhuanlan.zhihu.com/p/561877392

相关文章:

FAST-LIO笔记

1.FAST-LIO FAST-LIO 是一个计算效率高、鲁棒性强的激光-惯性里程计系统。该系统通过紧耦合的迭代扩展卡尔曼滤波器(IEKF)将激光雷达特征点与IMU数据进行融合,使其在快速运动、噪声较大或环境复杂、存在退化的情况下仍能实现稳定的导航。 1…...

软考中级软件设计师——UML(统一建模语言)篇

UML的词汇表包含3种构造块:事物、关系和图。事物是对模型中最具有代表性的成分的抽象;关系把事物结合在一起;图聚集了相关的事物。 一、事物 UML 事物是模型中的基本元素,分为 结构事物、行为事物、分组事物、注释事物。 1. 结构事物 类(Class&#x…...

TSN网络与DIOS融合:破解煤矿井下电力系统越级跳闸难题

一、引言 1.1 研究背景与意义 在现代煤矿生产中,井下电力系统作为整个煤矿生产的动力核心,其重要性不言而喻。煤矿井下的各类机械设备,如采煤机、刮板输送机、通风机、排水泵等,都依赖稳定的电力供应才能正常运行。电力系统的稳定…...

python 实现文件批量重命名

以下是使用Python实现文件批量重命名的示例代码。该代码可以将指定目录下的文件按照一定规则进行重命名,这里以将文件重命名为带有编号的文件名为例: import osdef batch_rename(directory):if not os.path.isdir(directory):print(...

SierraNet协议分析使用指导[RDMA]| 如何设置 NVMe QP 端口以进行正确解码

在解码RoCEv2数据包(包括TCP RDMA和RoCE RDMA)时,若捕获的跟踪数据无法正确解码,通常需要执行特定的解码步骤。对于RoCE RDMA跟踪数据的处理,分析器主要采用两种方式获取必要信息以实现数据包解码: 首先&am…...

Nodejs核心机制

文章目录 前言 前言 结合 Node.js 的核心机制进行说明: 解释事件循环的各个阶段。 答案 Node.js 事件循环分为 6 个阶段,按顺序执行: Timers:执行 setTimeout 和 setInterval 的回调。 Pending I/O Callbacks:处理系…...

Win全兼容!五五 Excel Word 转 PDF 工具解决多场景转换难题

各位办公小能手们!今天给你们介绍一款超牛的工具——五五Excel Word批量转PDF工具V5.5版。这玩意儿专注搞批量格式转换,能把Excel(.xls/.xlsx)和Word(.doc/.docx)文档唰唰地变成PDF格式。 先说说它的核心功…...

【Bluedroid】HID DEVICE 连接的源码分析

本文分析Android Bluetooth协议栈中HID device设备连接流程的完整实现,从应用层接口到协议栈底层的交互细节。通过关键函数(如connect()、BTA_HdConnect()、HID_DevConnect()等)的代码解析,重点关注btif、bta、HID协议栈三层的协同机制,揭示BTA_HD_CONN_STATE_EVT事件传递…...

【AI大模型】SpringBoot整合Spring AI 核心组件使用详解

目录 一、前言 二、Spring AI介绍 2.1 Spring AI介绍 2.2 Spring AI主要特点 2.3 Spring AI核心组件 2.4 Spring AI应用场景 2.5 Spring AI优势 2.5.1 与 Spring 生态无缝集成 2.5.2 模块化设计 2.5.3 简化 AI 集成 2.5.4 支持云原生和分布式计算 2.5.5 安全性保障…...

Redis的操作以及Spring Cache框架

Redis是一种开源的内存数据结构存储,用作数据库、缓存和消息代理。它支持多种数据结构,如字符串、哈希、列表、集合、有序集合等。在Spring应用中,可以使用Spring Cache框架结合Redis来实现高效的缓存机制。本文将详细介绍Redis的基本操作以及…...

C#输出参数:使用、要求与新特性

在C#编程中,输出参数是一种强大的工具,用于从方法体内把数据传出到调用代码。它的行为与引用参数类似,但也有自己的特点。今天我们就来详细了解一下C#中的输出参数。 输出参数的基本要求 修饰符的使用 输出参数必须在声明和调用中都使用修…...

信号处理基础

一、目的 掌握信号处理的基本思想,理解采样信号的频谱特性,加强信号采样与重建的有关基本概念的理解,深入理解线性时不变系统输出与输入的关系,了解数字信号采样率转换前后信号频谱的特征。 二、内容与设计思想 1、给定序列,绘…...

小刚说C语言刷题—1058 - 求出100至999范围内的所有水仙花数

1.题目描述 2.参考代码(C语言版) #include <stdio.h> int main(void) { int i; int bai,shi,ge; for( i100;i<999;i) { baii/100; shii/10%10; gei%10; if((bai*bai*bai)(shi*shi*shi)(ge*ge*ge)i) printf("%d\n",i); } return 0; } 今天内容到此结束&…...

cat、more和less的区别

在 Linux 系统中&#xff0c;cat、more 和 less 都是用于查看文件内容的命令&#xff0c;但它们在功能和使用场景上有显著区别。以下是它们的详细对比&#xff1a; 1. cat 命令 功能&#xff1a; - 直接输出整个文件&#xff1a;一次性将文件内容全部显示在终端上&#xff…...

深入解析Docker:核心架构与最佳实践

文章目录 前言一、Docker 解决了什么问题&#xff1f;二、Docker 底层核心架构2.1 Docker 引擎的分层架构2.2 镜像的奥秘&#xff1a;联合文件系统&#xff08;UnionFS&#xff09;2.3 容器隔离的核心技术2.3.1 命名空间2.3.2 控制组&#xff08;Cgroups&#xff09;2.3.3 内核…...

HVV面试题汇总合集

应急响应的命令 Linux ps -aux 查看进程 netstat -antlp 查看端口 top查看 cpu使用情况 Windows tasklist 查看进程 netstat -an 查看端口struts2原理特征 原理: 045:默认的content-type解析器会把用户传来的数据直接当成代码执行&#xff0c;造成rce 特征:ognl表达式&…...

什么是深度神经网络

深度神经网络(DNN)详细介绍 1. 定义与核心原理 深度神经网络(Deep Neural Network, DNN)是一种具有多个隐藏层的人工神经网络模型,其核心在于通过层次化的非线性变换逐步提取输入数据的高层次抽象特征。与浅层神经网络相比,DNN的隐藏层数量通常超过三层,例如VGGNet、R…...

Node.js 24.0 正式发布:性能跃升与开发体验全面升级

Node.js v24.0.0 震撼发布&#xff01;V8 13.6、npm 11、权限模型稳定化等重磅更新 2025年5月6日 —— Node.js 社区迎来重大里程碑&#xff01;Node.js v24.0.0 正式发布&#xff0c;带来一系列激动人心的新特性、性能优化和 API 改进。本次更新涵盖 V8 JavaScript 引擎升级至…...

Linux/AndroidOS中进程间的通信线程间的同步 - 信号量

1 概述 本文将介绍 POSIX 信号量&#xff0c;它允许进程和线程同步对共享资源的访问。有两种类型的 POSIX 信号量&#xff1a; 命名信号量&#xff1a;这种信号量拥有一个名字。通过使用相同的名字调用 sem_open()&#xff0c;不相关的进程能够访问同一个信号量。未命名信号量…...

Python Cookbook-7.10 在 MySQL 数据库中储存 BLOB

任务 想把一个二进制的大对象(BLOB)存入MySQL数据库 解决方案 MySQLdb 模块并不支持完整的占位符,不过可以使用模块的escape_string 函数来解决: import MySQLdb,cPickle #连接到数据库,用你的本机来测试数据库,并获得游标 connection = MySQLdb.connect(db = "tes…...

Edge浏览器PDF字体显示错误

Edge浏览器PDF字体显示错误 软件版本信息 Edge Version: 136.0.3240.50 Word Version: Microsoft Office 专业增强版2021问题描述 在Word中使用多级列表自动编号, 并使用Word软件自带的导出为PDF文件功能, 在Word中显示正常的数字, 在Edge中查看PDF将会出现渲染错误的现象,…...

计算机网络与多线程同步机制详解

一、IP地址与子网划分 在互联网世界中&#xff0c;IP地址就像是每个设备的"门牌号"&#xff0c;它使得数据包能够准确送达目的地。IP地址的划分与管理就像城市的规划&#xff0c;通过合理的子网划分&#xff0c;能够高效地管理网络资源。 子网掩码的工作原理 子网…...

Python训练营打卡——DAY22(2025.5.11)

复习日 学习参考如何使用kaggle平台&#xff0c;写下使用注意点&#xff0c;并对下述比赛提交代码 泰坦尼克号——来自灾难的机器学习 数据来源&#xff1a; kaggle泰坦里克号人员生还预测 挑战 泰坦尼克号沉没是历史上最臭名昭著的海难之一。 1912年4月15日&#xff0c;在被普…...

实战项目4(05)

​目录 任务场景一 【sw1配置】 任务场景二 【sw1配置】 【sw2配置】 任务场景一 按照下图完成网络拓扑搭建和配置 任务要求&#xff1a; 1、在交换机SW1的E0/0/1端口进行设置&#xff0c;实现允许最多两个电脑可以正常进行通信。 2、在交换机SW1的E0/0/2端口进行设置&…...

快速上手Pytorch Lighting框架 | 深度学习入门

快速上手Pytorch Lighting框架 | 深度学习入门 前言参考官方文档 介绍快速上手基本流程常用接口LightningModule\_\_init\_\_ & setup()\*\_step()configure_callbacks()configure_optimizers()load_from_checkpoint Trainer常用参数 可选接口LoggersTensorBoard Logger Ca…...

C++学习之STL学习

在经过前面的简单的C入门语法的学习后&#xff0c;我们开始接触C最重要的组成部分之一&#xff1a;STL 目录 STL的介绍 什么是STL STL的历史 UTF-8编码原理&#xff08;了解&#xff09; UTF-8编码原理 核心编码规则 规则解析 编码步骤示例 1. 确定码点范围 2. 转换为…...

3. 仓颉 CEF 库封装

文章目录 1. capi 使用说明2. Cangjie CEF2. 1实现目标 3. 实现示例 1. capi 使用说明 根据上一节 https://blog.csdn.net/qq_51355375/article/details/147880718?spm1011.2415.3001.5331 所述&#xff0c; cefcapi 是libcef 共享库导出一个 C API, 而以源代码形式分发的 li…...

LabVIEW多通道并行数据存储系统

在工业自动化监测、航空航天测试、生物医学信号采集等领域&#xff0c;常常需要对多个传感器通道的数据进行同步采集&#xff0c;并根据后续分析需求以不同采样率保存特定通道组合。传统单线程数据存储方案难以满足实时性和资源利用效率的要求&#xff0c;因此设计一个高效的多…...

谷歌在即将举行的I/O大会之前,意外泄露了其全新设计语言“Material 3 Expressive”的细节

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

十三、基于大模型的在线搜索平台——整合function calling流程

基于大模型的在线搜索平台——整合function calling流程 一、function calling调用总结 上篇文章已经实现了信息抓取能力&#xff0c;并封装成了函数。现在最后一步将能力转换为大模型可以调用的能力&#xff0c;实现搜索功能就可以了。这篇主要实现大模型的function calling能…...