从零入门激光SLAM(十三)——LeGo-LOAM源码超详细解析3

大家好呀,我是一个SLAM方向的在读博士,深知SLAM学习过程一路走来的坎坷,也十分感谢各位大佬的优质文章和源码。随着知识的越来越多,越来越细,我准备整理一个自己的激光SLAM学习笔记专栏,从0带大家快速上手激光SLAM,也方便想入门SLAM的同学和小白学习参考,相信看完会有一定的收获。如有不对的地方欢迎指出,欢迎各位大佬交流讨论,一起进步。博主创建了一个科研互助群Q:951026257,欢迎大家加入讨论。

Lego_Loam包括了Image projection、Feature association、MapOptmization、Transform Fusion四个部分,下面博主将按照算法的逻辑顺序对代码中的重要函数进行讲解。本节是解析Feature association文件中的特征匹配部分。
该专栏的其他章节链接如下
从零入门激光SLAM系列——总目录与更新情况_kiss icp-CSDN博客

一、Feature Extraction

经过上一节的点云特征提取,我们已经获得了稳健的角点和面点如下图所示,下面将介绍如何配准得到位姿Feature Association部分的源码解析

 1. Feature Extraction特征提取
// 1.1 点云运动补偿
        adjustDistortion();
// 1.2 计算平滑度
        calculateSmoothness();
// 1.3 标记遮挡点
        markOccludedPoints();
// 1.4 提取特征
        extractFeatures();
// 1.5 发布点云
        publishCloud();
2. Feature Association特征匹配
    if (!systemInitedLM) {
            // 2.1 检查系统初始化,点云投影到结束点
                checkSystemInitialization();
                return;}
// 2.2 更新初始猜测位置
        updateInitialGuess();
// 2.3 特征匹配,输出Transformation
        updateTransformation();
// 2.4 融合IMU坐标Transformation
        integrateTransformation();

二、函数解析

2.1 publishCloudsLast

  • 作用:将当前帧点云投影到结束点并发布,作为下一帧匹配的对象,(匹配之前需要有一个匹配对象点云)
  • 输入:
     cornerPointsSharp角特征  
     cornerPointsLessSharp缓角特征  
     surfPointsFlat面特征  
     surfPointsLessFlat缓面特征 
     adjustCloud修正点云              
    
  • 输出:
     /laser_cloud_corner_last
     /laser_cloud_surf_last
     /outlier_cloud_last
     /laser_odom_to_init
    
  • 代码:
    void publishCloudsLast(){
    //把特征点云投影到每帧的结尾时刻
    updateImuRollPitchYawStartSinCos();
    int cornerPointsLessSharpNum = cornerPointsLessSharp->points.size();
    for (int i = 0; i < cornerPointsLessSharpNum; i++) {
      TransformToEnd(&cornerPointsLessSharp->points[i], &cornerPointsLessSharp->points[i]); }
      int surfPointsLessFlatNum = surfPointsLessFlat->points.size();
    for (int i = 0; i < surfPointsLessFlatNum; i++) {
      TransformToEnd(&surfPointsLessFlat->points[i], &surfPointsLessFlat->points[i]);}
    //用KD树存储当前帧点云,为后续匹配做准备
    pcl::PointCloud<PointType>::Ptr laserCloudTemp = cornerPointsLessSharp;
    cornerPointsLessSharp = laserCloudCornerLast;
    laserCloudCornerLast = laserCloudTemp;
    laserCloudTemp = surfPointsLessFlat;
    surfPointsLessFlat = laserCloudSurfLast;
    laserCloudSurfLast = laserCloudTemp;
    laserCloudCornerLastNum = laserCloudCornerLast->points.size();
    laserCloudSurfLastNum = laserCloudSurfLast->points.size();
    if (frameCount >= skipFrameNum + 1) {
              frameCount = 0;
    //发布上一帧outlier
    pubOutlierCloudLast.publish(outlierCloudLast2);
    //发布上一帧线特征
    pubLaserCloudCornerLast.publish(laserCloudCornerLast2);
    //发布上一帧面特征
    pubLaserCloudSurfLast.publish(laserCloudSurfLast2);}
    
    下图中红色为前一帧,绿色为当前帧

    2.2 updateInitialGuess

  • 作用:把当前IMU数值作为位姿先验
  • 输入:IMU数值
  • 输出:transformCur位姿矩阵
    // 如果IMU有旋转,则更新变换矩阵以反映新的旋
    void updateInitialGuess(){
    if (imuAngularFromStartX != 0 || imuAngularFromStartY != 0 || imuAngularFromStartZ != 0){transformCur[0] = - imuAngularFromStartY;  // 根据Y轴旋转更新变换矩阵的第一个元素
    transformCur[1] = - imuAngularFromStartZ;  // 根据Z轴旋转更新变换矩阵的第二个元素
    transformCur[2] = - imuAngularFromStartX;  // 根据X轴旋转更新变换矩阵的第三个元素}
    // 如果IMU有移动,则更新变换矩阵以反映新的平移
    if (imuVeloFromStartX != 0 || imuVeloFromStartY != 0 || imuVeloFromStartZ != 0)
    {transformCur[3] -= imuVeloFromStartX * scanPeriod;  // 根据X轴移动更新变换矩阵的第四个元素
    transformCur[4] -= imuVeloFromStartY * scanPeriod;  // 根据Y轴移动更新变换矩阵的第五个元素
    transformCur[5] -= imuVeloFromStartZ * scanPeriod;  // 根据Z轴移动更新变换矩阵的第六个元素 }   }
    

    2.3 updateTransformation

  • 作用:匹配角和面特征点,计算位姿
  • 输入:
     laserCloudSurfLast
     surfPointsFlat
     laserCloudCornerLast
     cornerPointsSharp
    
  • 输出:transformCur位姿矩阵
  • 代码

    void updateTransformation(){
         //检查特征点
         if (laserCloudCornerLastNum < 10 || laserCloudSurfLastNum < 100)
             return;
    //  面特征匹配
         for (int iterCount1 = 0; iterCount1 < 25; iterCount1++) {
             laserCloudOri->clear(); 
             coeffSel->clear(); 
             findCorrespondingSurfFeatures(iterCount1); 
          if (laserCloudOri->points.size() < 10)
                 continue;
             // 通过面特征的匹配,计算变换矩阵
             if (calculateTransformationSurf(iterCount1) == false)
                 break;
         }
    // 线特征匹配
         for (int iterCount2 = 0; iterCount2 < 25; iterCount2++) {
    
             laserCloudOri->clear();
             coeffSel->clear();
    
             findCorrespondingCornerFeatures(iterCount2); 
             if (laserCloudOri->points.size() < 10)
                 continue;
             if (calculateTransformationCorner(iterCount2) == false) 
                 break;
         }
     }

详情请见...
从零入门激光SLAM(十三)——LeGo-LOAM源码超详细解析3 - 古月居 (guyuehome.com)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python3极简教程(一小时学完)上

开始 Python 之旅 本教程基于 Python for you and me 教程翻译制作&#xff0c;其中参考了 Python tutorial 和 _The Python Standard Library_&#xff0c;并对原教程的内容进行了改进与补充。 相关链接地址如下&#xff1a; _Python tutorial_&#xff1a;Python 入门指南…

通过颜色传感器控制机械臂抓物体

目录 1 绪论 2整体设计方案 2.1 系统的介绍 2.2 抓取模块 2.2.1 机械臂的定义 2.2.2 机械臂的分类 2.2.3 机械臂的选用 2.3 颜色识别模块 2.3.1 颜色传感器识别原理 2.3.2 TCS3200简介 2.4 整体控制方案 3 颜色识别抓取系统的硬件设计 3.1 单片机选型及参数 3.2 系…

13.爬虫---PyMongo安装与使用

13.PyMongo安装与使用 1.安装 PyMongo2.使用PyMongo2.1连接数据库和集合2.2增加数据2.3修改数据2.4查询数据2.5删除数据 3.总结 MongoDB 安装可以看这篇文章MongoDB安装配置教程&#xff08;详细版&#xff09; 1.安装 PyMongo PyMongo 是Python中用于连接MongoDB数据库的库&a…

适用于 Windows 11 的 5 大数据恢复软件 [免费和付费]

为什么我们需要Windows 11数据恢复软件&#xff1f; 计算机用户经常遇到的一件事就是数据丢失&#xff0c;这种情况随时可能发生。错误地删除重要文件和文件夹可能会非常令人担忧&#xff0c;但幸运的是&#xff0c;有一种方法可以恢复 PC 上丢失的数据。本文将向您展示可用于…

AI引领创意潮流:高效生成图片,参考图助力,一键保存到指定文件夹

在这个数字与创意交融的时代&#xff0c;我们迎来了AI绘画的新纪元。借助先进的AI技术&#xff0c;我们不仅能够高效生成图片&#xff0c;还能在参考图的启发下&#xff0c;激发无限创意&#xff0c;让您的想象力在数字世界中自由翱翔。 首助编辑高手软件中的魔法智能绘图板块&…

路径规划算法--DFS

文章目录 一、DFS二、DFS伪代码三、DFS做全覆盖路径 一、DFS DFS&#xff08;Depth First Search&#xff09;为深度优先搜索&#xff0c;是一种用于遍历或搜索树或图的搜索算法。DFS是从当前点出发&#xff0c;沿着一个方向一直搜索&#xff0c;如果搜索完成且未搜索到目标点…

C++系列-String(三)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” assign 这个接口的目的是用一个新的值代替之前的那个值 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string> #include<list> #include&l…

HTTP协议中的各种请求头、请求类型的作用以及用途

目录 一、http协议介绍二、http协议的请求头三、http协议的请求类型四、http协议中的各种请求头、请求类型的作用以及用途 一、http协议介绍 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一种用于分布式、协作式和超媒体信息系统的应…

计算机组成原理 | CPU子系统(3)MIPS32指令架构

MIPS32架构指令格式 MIPS32架构寻址方式 指令的编码与功能

突破内存限制:Jamba模型的高效文本处理能力

在当今信息爆炸的时代&#xff0c;处理和理解海量文本数据的需求日益增长。自然语言处理&#xff08;NLP&#xff09;领域的研究者们一直在探索如何构建更高效、更强大且更灵活的语言模型来应对这一挑战。然而&#xff0c;现有的大型语言模型&#xff0c;尤其是基于Transformer…

昇思25天学习打卡营第8天|保存与加载

一、简介&#xff1a; 上一章节主要介绍了如何调整超参数&#xff0c;并进行网络模型训练。在训练网络模型的过程中&#xff0c;实际上我们希望保存中间和最后的结果&#xff0c;用于微调&#xff08;fine-tune&#xff09;和后续的模型推理与部署&#xff0c;本章节我们将介绍…

关于Vite+Vue+Ts WebStorm路径别名的问题

一、准备一个项目 二、在 vite.config.js 中添加 resolve: {alias: {: /src}} 三、tsconfig.app.json中添加代码 //添加代码"baseUrl": ".","paths": {"/*": ["src/*"]}把src的一个文件修改路径为开头 四、安装插件 npm i …

【嵌入式Linux】i.MX6ULL GPIO 中断服务函数注册与编写

文章目录 1 外部中断初始化与中断服务函数1.2 外部中断初始化函数 exti_init1.2.1 GPIO引脚配置1.2.2 中断使能与注册1.2.3 GIC_EnableIRQ()函数的分析 1.3 中断服务函数 gpio1_io20_irqhandler1.3.1 消抖处理1.3.2 中断事件处理1.3.3 清除中断标志 2 BUG处理2.1 问题描述2.2 解…

打破数据分析壁垒:SPSS复习必备(九)

有序定性资料统计推断 1.分类 单向有序行列表 双向有序属性相同行列表 双向有序属性不同行列表 2.单向有序行列表 秩和检验 ① 两组单向有序分类资料 ②多组单向有序定性资料 步骤&#xff1a; 1.建立检验假设和确定检验水准 2.编秩 3.求秩和 4.确定检验统计量 5…

Sora:探索AI视频模型的无限可能

随着人工智能技术的飞速发展&#xff0c;AI在视频处理和生成领域的应用正变得越来越广泛。Sora&#xff0c;作为新一代AI视频模型&#xff0c;展示了前所未有的潜力和创新能力。本文将深入探讨Sora的功能、应用场景以及它所带来的革命性变化。 一、Sora的核心功能 1.1 视频生…

一年Java|16K|同程艺龙面经

面经哥只做互联网社招面试经历分享&#xff0c;关注我&#xff0c;每日推送精选面经&#xff0c;面试前&#xff0c;先找面经哥 背景 公司&#xff1a;同程艺龙成都BU,现场部门老大面 之前的同程艺龙电话一面过了&#xff0c;然后通知到同程艺龙成都办公地点现场进行部门老大…

宠物空气净化器热卖爆款,希喂、小米、352猫用空气净化器真实PK

相信大漫天多数养猫家庭都会有一个烦恼&#xff1a;猫咪们的猫实在是太多了&#xff0c;无法忍受家里面漫天飞舞的浮毛和难闻的猫猫便臭。作为养猫多年的过来人我尝试过很多种方法清理这些猫浮毛和异味&#xff0c;但都以失败告终。 直到后面看到一个宠物博主推荐的宠物空气净…

【干货】【全网最全】【全网最详细】 javaWeb关于Thymeleaf+SpringBoot 的学习教程,看这一篇就够了。

大家好&#xff0c;我是DX3906 第一部分&#xff1a;介绍 Thymeleaf 简介 1.什么是Thymeleaf Thymeleaf是一个用于Java和Java EE平台的服务器端模板引擎&#xff0c;它可以用来在服务端生成HTML、XML、JavaScript、CSS甚至纯文本的输出。Thymeleaf适用于需要快速开发和维护Web…

React+TS前台项目实战(十六)-- 全局常用组件Pagination封装

文章目录 前言Pagination组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 [PC端&手机端] 总结 前言 在上篇文章中&#xff0c;我们封装了表格组件Table&#xff0c;本文则继续封装配套使用的分页器组件。想看Table表格组件的&#xff0c;可自行查看全局常用组件Tab…

【渗透测试】小程序反编译

前言 在渗透测试时&#xff0c;除了常规的Web渗透&#xff0c;小程序也是我们需要重点关注的地方&#xff0c;微信小程序反编译后&#xff0c;可以借助微信小程序开发者工具进行调试&#xff0c;搜索敏感关键字&#xff0c;或许能够发现泄露的AccessKey等敏感信息及数据 工具…