Cartographer源码理解

embedded/2024/9/20 7:08:26/ 标签: slam, cartographer, 算法

一、前言

最近一个半月,利用空余时间对Cartographer源码进行了简单的阅读,在这里做了个简单梳理,和大家分享交流。

cartographer源码量其实是有点大的,逐行逐句去解释实在是有心无力了,而且已经有大佬做了类似的事情,后面链接中给大家分享出来,所以这里只表达我的理解和想法,如有理解偏差,感谢指正!

二、demo视频

老规矩,先看仿真视频。

三、源码梳理

面对这么大的项目工程,如何下手阅读也是让我这个小白所头疼的,毕竟我是做导航的,所以前两个星期基本都在梳理框架,先搞清楚数据是怎么流转的,核心对象是如何一步步构造的,在这个基础上再去看细节才会有全局思维。

为了方便,carto团队适配了ros的消息收发机制,这里我们也以ros_cartographer来理解,废话不多说,直接看下图,源码中的demo主函数在 node_main.cc 中,一上来就构造了核心的建图器 MapBuilder,这个建图器包含了前端(子图构建)和后端(闭环检测),然后用这个建图器(指针)构造了Carto的核心node,即 node.cc 文件中,在node构造的过程中,主要做了两件事情,第一件事情是声明了Sub、Pub、Serv等用于数据的传输;第二件事情是创建了MapBuilderBridge对象,顾名思义,它承担了ROS-Message到Carto-Message的消息转换(SensorBridge)及使用转换的数据构建地图(slam过程,即MapBuilder)。
到这,是不是思路清晰了。可以大致分成两条线索去深究,第一是SensorBridge如何实现消息转换,第二是MapBuilder如何工作。
在这里插入图片描述

在有了前面的基础上,我们进一步去探究,梳理下核心功能的调用实现。
在这里插入图片描述
在这里插入图片描述
看到这里,应该会对整个框架有系统性的了解,在此我惊叹carto框架的巧妙!


为了弄明白数据的流转,下面我解释几个地方:
1、demo中从 FLAGS_start_trajectory_with_default_topics接口进入(rosbag play 发布的传感器数据),而不是FLAGS_load_state_filename

2、demo中使用的是 ros::spin()被动的接收topic,或者说纯粹的接收topic,起到阻塞线程的作用,如果topic不接收或者不发布了,它会在自己的函数中死循环,直到主动结束程序或者有topic进来。还有一个是类似的函数是ros::spinOnce(),它可以根据自己的需求设置接收频率,一般配合while使用,会更加主动灵活。可以参考链接https://blog.csdn.net/weixin_40215443/article/details/103793316

3、node构造函数中创建了pub(通过定时器定时调用发布相关话题)、service等,在构造的过程中指定了定时运行的时间。

4、配置文件主要在 backpack_2d.lua 中,顺藤摸瓜include “map_builder.lua”、include “trajectory_builder.lua”

5、前端的核心函数是ScanMatch(local_trajectory_builder_2d.cc),里面主要做了两个核心的事情,
第一个是: scan_matching::RealTimeCorrelativeScanMatcher2D real_time_correlative_scan_matcher_;
主要为 ceres优化 提供更好的先验信息(此时的激光数据已经去畸变)
第二个是:scan_matching::CeresScanMatcher2D ceres_scan_matcher_; 使用Ceres库将扫描数据放置到地图中进行匹配,即图优化的过程。

这里我不做算法的详细推导:原因是还没有足够的时间理解底层核心,后面会继续探究再进行分享。

四、源码注释及好的文章

1、源码注释:https://github.com/lijun-mce/cartographer-detailed-comments
2、推荐文章:https://gaoyichao.com/Xiaotu/?book=Cartographer%E6%BA%90%E7%A0%81%E8%A7%A3%E8%AF%BB&title=index

五、配置仿真环境踩坑

刚开始用的是 ubuntu22.04 +ros2(humble) 环境,发现了ros2 bag 无法播放的问题(ros中是.bag格式,ros2中是.db3格式,开源包中的德意志博物馆是ros的.bag格式),网上有部分资料说可以进行转换,我折腾了很久很久,不行,放弃了,如果你们不信可以试试。
推荐这篇文章:https://blog.csdn.net/lgh1231/article/details/124939760,可以很快的配置cartographer,建议使用源码的方式进行编译安装。

ros2不行,然后我就安装 ubuntu18.04 +ros(melodic) 环境
推荐这篇文章:https://blog.csdn.net/weixin_44362628/article/details/122540297,可以很快进行配置,在编译的过程中碰到找不到lua库的问题,可能是由于ros版本的问题,可以试试这两个命令。
sudo apt-get install lua5.3-dev
sudo apt-get install lua5.3


争取早点和大家分享 ceres图优化的过程!


http://www.ppmy.cn/embedded/113304.html

相关文章

macOS Sequoia 正式版(24A335)黑苹果/Mac/虚拟机系统镜像

“ 以下内容来自于黑果魏叔官网” 镜像特点 完全由黑果魏叔官方制作,针对各种机型进行默认配置,让黑苹果安装不再困难。系统镜像设置为双引导分区,全面去除clover引导分区(如有需要,可以自行直接替换opencore分区文件为…

JVM 性能优化与调优-ZGC(Z Garbage Collector)

JVM 性能优化与调优——ZGC(Z Garbage Collector) 在 JVM 性能优化中,垃圾收集器的选择和调优至关重要。垃圾收集器(Garbage Collector, GC)负责回收不再使用的对象所占用的内存,以便应用程序可以高效使用…

算法入门-贪心1

第八部分:贪心 409.最长回文串(简单) 给定一个包含大写字母和小写字母的字符串 s ,返回通过这些字母构造成的最长的回文串 的长度。 在构造过程中,请注意 区分大小写 。比如 "Aa" 不能当做一个回文字符串…

docker_持久化存储

Docker Volumes 单机部署 要在 Docker 中使用 Volumes(卷) 来实现持久化存储,步骤非常简单。以下是具体的操作方法: 创建一个 Docker Volume 你可以通过 Docker CLI 来创建卷。执行以下命令创建一个名为 my_volume 的卷&#xf…

单片机中为什么要使用5v转3.3v,不直接使用3.3V电压

5V和3.3V是常见的电压水平,在技术上都有其特定的应用场景。为了保护电路、提升效能和确保系统的稳定运行,经常需要将5V转换为3.3V。 1.为什么要5V来供电 使用5V是因为部分传感器需要5V的供电,并且我们数据线一般都输出5V电压,而…

Web3入门指南:从基础概念到实际应用

Web3,即“去中心化的第三代互联网”,正在逐步改变我们对互联网的传统认知。从最初的静态网页(Web1.0)到互动平台和社交媒体为主的互联网(Web2.0),Web3的目标是让用户重新掌握对数据和数字资产的…

leetcode 四数相加||

1.题目要求: 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a;0 < i, j, k, l < n nums1[i] nums2[j] nums3[k] nums4[l] 0示例 1&#xff1a;输入&#xff1a;nums1 …

Hutool 使用详解

Hutool 是一个 Java 工具包&#xff0c;它为开发者提供了一系列实用的工具类和方法&#xff0c;帮助简化开发工作。本文将详细介绍 Hutool 的主要功能和使用方法&#xff0c;帮助开发者更好地利用这个强大的工具包。 目录 Hutool 简介Hutool 的安装与配置常用工具类介绍 字符…

【MySQL】MySQL中JDBC编程——MySQL驱动包安装——(超详解)

前言&#xff1a; &#x1f31f;&#x1f31f;本期讲解Java中JDBC编程&#xff0c;希望能帮到屏幕前的你。 &#x1f308;上期博客在这里&#xff1a;【MySQL】MySQL索引与事务的透析——&#xff08;超详解&#xff09;-CSDN博客 &#x1f308;感兴趣的小伙伴看一看小编主页&a…

Renesas R7FA8D1BH (Cortex®-M85)控制SHT20

目录 概述 1 硬件接口介绍 2 SHT20模块 2.1 SHT20简介 2.2 SHT-20模块电路 3 I2C接口实现 3.1 FSP配置I2C 3.2 I2C驱动程序实现 4 SHT20驱动程序 4.1 SHT20驱动代码结构 4.2 源代码文件 5 测试 5.1 测试功能介绍 5.2 测试代码实现 5.3 运行代码 概述 本文主要介…

安卓显示驱动

安卓显示驱动是用于在Android设备上提供图形和视频显示的底层软件组件。 显示驱动在Android系统中扮演着至关重要的角色&#xff0c;它们负责将图形和视频内容从系统内存传输到显示屏上。这些驱动程序确保了用户界面、图像、视频和游戏等视觉元素的正常显示。以下是关于安卓显…

详解QT插件机制

Qt插件机制允许将功能模块化为独立的插件,从而在运行时动态加载和卸载这些模块。这种机制对于扩展应用程序、插件架构和动态功能添加非常有用 插件机制 插件的基本概念 插件: 在Qt中,插件是实现特定接口的动态库(DLL或so文件),这些接口由Qt插件框架定义。插件可以被应用程序…

java,深拷贝和浅拷贝

在 Java 中&#xff0c;深拷贝&#xff08;Deep Copy&#xff09;和浅拷贝&#xff08;Shallow Copy&#xff09;是对象拷贝的两种方式&#xff0c;主要区别在于它们如何处理对象的内部引用。 目录 一、浅拷贝&#xff08;Shallow Copy&#xff09; 实现方式 二、深拷贝&…

【数据结构初阶】顺序结构二叉树(堆)接口实现超详解

文章目录 1.树1. 1 树的概念与结构1. 2 树的相关术语1. 3 树的表示1. 4 树形结构实际运用场景 2.二叉树2. 1 概念与结构2. 2 特殊的二叉树2. 2. 1 满二叉树2. 2. 2 完全二叉树 2. 3 二叉树存储结构2. 3. 1 顺序结构2. 3. 2 链式结构 3. 实现顺序结构二叉树&#xff08;小堆&…

Go语言并发编程:从理论到实践

并发是计算机科学领域中的一个核心概念&#xff0c;但对于不同的人来说&#xff0c;它可能意味着不同的东西。除了“并发”之外&#xff0c;你可能还听说过“异步”、“并行”或“多线程”等术语。一些人认为这些词是同义的&#xff0c;而另一些人则严格区分它们。如果我们要花…

CleanMyMac 5 for Mac 最新中文破解版下载 系统优化垃圾清理工具

今天给大家带来的是CleanMyMac最新款CleanMyMac 5&#xff0c;它是一个全面的Mac清理和维护工具&#xff0c;通过提供多项强大的功能&#xff0c;帮助用户简化日常维护任务&#xff0c;提升系统性能&#xff0c;同时保护个人隐私和安全。无论是新手还是经验丰富的Mac用户&#…

Next.js 14 如何在服务端页面中使用客户端渲染组件

在Next.js中&#xff0c;默认就是使用服务端渲染的&#xff0c;那如何在服务端页面中包含客户端组件呢&#xff0c;以下是试例&#xff1a; 在ArticlePage.js中&#xff1a; import DeleteButton from /components/DeleteBtnexport default async function ArticlePage(){retu…

构建“零工市场小程序”,服务灵活就业“大民生”

如今&#xff0c;灵活就业已成为现代劳动力市场的重要组成部分。然而&#xff0c;这一就业形态也面临着信息不对称、匹配效率低下等一系列挑战。为有效解决这些问题&#xff0c;构建一个高效、便捷的“零工市场小程序”显得尤为重要。 二、零工市场现状与挑战 市场规模与增长趋…

Makefile语法详解

目录 1 Makefile基本常识1.1 基本格式1.2 makefile规则1.3 伪目标1.4 变量的使用1.5 赋值方式1.6 常用函数 2 Makefile整体编译2.1 编译选项2.2三个.c整体编译2.3 静态库编译2.4 动态库编译 3 Makefile多文件调用 1 Makefile基本常识 1.1 基本格式 如下所示为Makefile的基本格…

【论文阅读】PERCEIVER-ACTOR: A Multi-Task Transformer for Robotic Manipulation

Abstract transformers凭借其对大型数据集的扩展能力&#xff0c;彻底改变了视觉和自然语言处理。但在机器人操作中&#xff0c;数据既有限又昂贵。通过正确的问题表述&#xff0c;操纵仍然可以从变形金刚中受益吗&#xff1f;我们使用peract来研究这个问题&#xff0c;peract…