每日浅读SLAM论文——简析Cartographer

news2024/12/23 8:30:52

文章目录

      • 二维激光SLAM
      • 简单框架
      • 前端
        • scan matching
        • Submaps构建
      • 后端
        • 分支定界优化csm(CorrelativeScanMatch)
      • 代码实现框架

Cartographer(论文名:Real-Time Loop Closure in 2D LIDAR SLAM)是目前二维激光SLAM中应用最广泛的,尤其在工业界,堪称工业神器。Cartographer由谷歌工程师所写,框架十分复杂,想要详细了解Cartographer框架和代码实现细节,我强烈推荐 无处不在的小土的Blog。
这里我只是帮助大家快速理解一下Cartographer的核心,我并不会按照论文顺序来讲,我的blog风格就是 浅显易懂,因此我对 理解框架最为看重。

二维激光SLAM

看这篇文章你至少应该之前就对二维激光SLAM有所了解(默认了解基础概念,前端/后端,滤波器/图优化)。其实二维SLAM一般来说就了解一下四个算法(gmapping,hector,karto,cartographer)。

  • Gmapping是基于粒子滤波的算法,我会拿另一篇文章去讲,Gmapping之前都是基于滤波器的算法(EKF-SLAM,FastSLAM等),但是几乎可以这么说,基于滤波器的后端算法在二维激光SLAM中已经被淘汰了,有人这么说“Gmapping不是最好的SLAM算法,但他是特定时代下最优美的解决方法”,我觉得很有道理。
  • Hector的核心就是使用了scan to map来进行前端的扫描匹配,简单而言就是用当前激光和累计出来的地图进行匹配,通过将激光投影到栅格上进行打分,然后使用高斯牛顿法求最优的位姿。
  • karto主要贡献是引入了后端图优化,使用submap代替全局地图进行匹配和优化,但是表现不如cartographer(好像有人说karto其实效果也很好,只是代码实现不如carto,总是没谁用)。
  • 简而言之,掌握cartographer约等于掌握了二维激光SLAM

简单框架

cartographer论文根本没有给出框架图,你可以这么理解,carto的作者并不认为自己的文章提出了什么新的框架,它只是整合了一些内容。因此,你可以简单地认为carto的框架其实就是前端+后端。前端使用了的基本和hector一样,就是scan to map(submap)。它的主要工作在后端,使用分支定界优化了CSM算法,然后构建了位姿和submap之间的约束图,使用SPA(一种利用图稀疏性来加速优化,这可以说是真正将图优化投入实际使用的算法,学习到一定深度了可以再去学习,总之是一种快速进行图优化的算法)进行优化。

前端

scan matching

就是前端,核心就是优化这个函数, ξ i \xi_i ξi就是当前扫到第i个点的局部坐标, S i ( ξ ) S_i(\xi) Si(ξ)就是把这个点映射到全局坐标系下。 M ( . ) M(.) M(.)就代表地图,如果被占据概率为1,那扫到1-1=0,自然不算残差,我们也就是希望每个激光点都扫到障碍物上。整个算法用高斯牛顿法优化,具体如何求导的可以去看hector,里面有详细写(其实就是图像求导)。
在这里插入图片描述

Submaps构建

就是使用静态二值贝叶斯滤波器进行的地图更新,推导大家可以自己去找(比如看概率机器人),小土写的很好。简单来说就是在得到位姿之后,利用射出去的激光来更新地图。
在这里插入图片描述
当submap中插入数据到一定量时候,这张submap就算完成了,传入后端不再更新,开启一张新的submap开始建图。核心是它当作短期内构建的submap是准确的。

后端

后端核心就是构建一张位姿约图,下面圆代表一个个位姿,上面三角代表一张张submap,每个位姿态可能观测到很多张submap,那么之间就可以构建一个约束。之前前端使用简单的scan matching方法构建的约束精度不够,后端使用csm进行像素级别的匹配。
在这里插入图片描述

分支定界优化csm(CorrelativeScanMatch)

其实csm就是一个暴力搜索,二维位姿其实就是 { x , y , θ } \{x,y,\theta\} {x,y,θ}三个变量,我们在初值附近套三重循环暴力搜索,给每个组合算一个分数,取最高的。csm还可以同时处理回环,某帧激光和很久之前一张submap匹配分数非常高的时候,就是找到回环了,也增加约束。

显然,这种算法复杂度很高。其实我们很容易想到一种简单的算法(我瞎想的,便于理解),假设一开始x搜索范围之[-10,10],步长为1,搜一百次,取分数最高的10次,这10次分数都在[-1,1]之间,那我改步长为0.1搜索新的区间。这样肯定比[-10,10]直接以0.1为步长搜索快。

在这个问题中,作者使用了不同分辨率的地图进行匹配(其实和我瞎想的是一个意思),并证明了粗分辨率找到的最优得分是细节分辨率的上界。因为有了这个条件,我们可以使用分枝定界来优化搜索过程,其实就是剪枝的思想,你在粗分辨率的情况下找到的位姿还不如之前细分辨率得到的结果,那没必要在这个位姿下搜索更细的分辨率了。
在这里插入图片描述

代码实现框架

众所周知,SLAM论文只包含了全部内容的20%,剩下80%要在代码中找到答案。下面这张图才是算法在实现时候的真实框架。

首先最左边是输入,Range Data(激光数据),Odometry(里程计),IMU(惯导),Fixed Frame Pose(GPS一类全局定位)。
Range Data首先会经过Voxel filter(体素滤波,用于点云降采样),而IMU和Odom会先经过一个PoseExtraplator(主要用于IMU位姿解算,推导很复杂,PoseExtraplator同时接受Scan Matching的数据,因为传感器是增量式的,应该在之前更新完的位姿上再跟新目前位姿)。过完滤波的Range Data利用PoseEstimate(传感器估计的位姿) 作为初值计算和上一帧相对运动。后面不产生运动的匹配被drop了,可以理解为关键帧吧。一段连续帧被构建成submap,当这个submap完成后被送入后端,即Global SLAM。

后端就是使用分支定界优化的csm计算位姿和submaps之间的约束关系(包含回环,因为位姿和之前的submap很近的时候也会被拿去扫描匹配),构建约束图,然后如果有全局传感器也加入约束图,一起使用SPA优化,最后得到准确的位姿和图。
在这里插入图片描述

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

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

相关文章

postman不能进行并发测试

1.按照网上文档的配置 2.在登录接口里睡眠5s,如果是并发的话,所有的请求都会一起睡眠5s 3.测试结果:请求是每隔5s串行执行的

Linux定时任务-定时执行Shell脚本

主要是使用Linux的crontab工具来实现的,有两个方法,一个放在contab 列表里面,另一个是放在contab文件里面(其实原理是一致的)。 crontab 列表 cd /tmp # 创建一个shell脚本 vim hello.sh #!/bin/bash echo "hel…

钳形表校准装置单匝法校准钳形电流表

交流大电流源输出标准电流信号到直径为1 m的单匝半圆铜环,电流输出铜环分为大小铜环,适配于校准不同钳口大小的钳形电流表。 方案优势:完全符合《JJF 1075-2015 钳形电流表校准规范》中主要推荐的单匝法校准钳形电流表的要求,操控…

全景感知—让视图上云更便捷,存储更安全

6月15日,由腾讯云主办的“数实共进产业行浙江站”在杭州圆满开展,活动中腾讯云存储高级产品经理张泽南进行了“全景感知,让视图上云更便捷,存储更安全”主题演讲,与行业伙伴深度交流新一代视图计算解决方案&#xff0c…

Redis中的介绍和安装教程(配置文件)

1.Redis简单的介绍 redis是一种键值对的NoSql数据库,这里有两个关键字: 键值对 Nosql 其中键值型,是指Redis中存储的数据都是以key.value对的形式多种多样,可以实字符串、数值、甚至json,可以参考HashMap 然后NoSq…

TiDB(5):TiDB-读取历史数据

接下来介绍 TiDB 如何读取历史版本数据,包括具体的操作流程以及历史数据的保存策略。 1 功能说明 TiDB 实现了通过标准 SQL 接口读取历史数据功能,无需特殊的 client 或者 driver。当数据被更新、删除后,依然可以通过 SQL 接口将更新/删除前…

MySQL容器无法输入或显示中文异常解决

如果使用docker创建了MySQL容器,但是进入容器后发现无法输入中文,也就是在插入数据的时候中文直接显示为空,数据表里的中文也显示为空,解决方法是: 1,临时方法 该方法只在每一次进入容器的命令上添加参数&a…

Web服务器群集:使用Haproxy搭建Web集群

目录 一、理论 1.Haproxy集群 2.常见的web集群调度器 3.三种web集群调度器的区别 4.下载安装 二、部署Haproxy集群 1.部署 2.重新定义Haproxy集群的日志 三、实验 1.部署Haproxy集群 四、问题 1.nginx编译安装与yum安装的网页配置路径 五、总结 一、理论 1.Hapro…

【2022吴恩达机器学习课程视频翻译笔记】3.1线性回归模型-part-1

3.1线性回归模型-part-1 In this video, we’ll look at what the overall process of supervised learning is like. Specifically, you see the first model of this course, Linear Regression Model. That just means fitting a straight line to your data. It’s probab…

Github-提交PR指南

1. Fork你将要提交PR的repo 2. 将你fork下来的repo克隆到你的本地 git clone your_repo.git Cloning into ultralytics... remote: Enumerating objects: 8834, done. remote: Counting objects: 100% (177/177), done. remote: Compressing objects: 100% (112/112), done. …

交易所行情基础相关知识

目录 一、行情基本概念 二、简单交易模型 三、行情系统结构 四、各种行情协议 1.FIX 2.STEP 3.FAST 4.Binary 一、行情基本概念 行情是描述市场繁荣状态的数据,比较笼统,例如买卖交易量。准确一些的描述是,揭示交易所标的交易与买卖…

http升级https图文,免费证书ssl下载安装

1.先登录阿里云(搜索ssl证书) 2.点击免费SSL证书概述 3.搜索安装PFX格式证书(搜索ssl证书) 4.下载SSL证书 5. 在tomcat服务器安装证书 6. 验证SSL证书是否安装成功 7.阿里云连接 ***注意 **** 1.先登录阿里云官网 2.再访问该网址…

Python Websocket 控制大屏显示

场景描述: 在做大屏展示时,有这样一个需求:在不刷新页面的情况下,动态改变大屏展示内容,如:执行某个函数,把相关数据醒目展示,轮换数据显示顺序等等。比如有领导参观时,马…

技术分享| 融合通讯的架构介绍

在融合通讯中,我们经常听到如下一些术语:MCU服务,SFU架构,MESH架构,星形网络等等。很多客户听到这些数据都是一脸雾水,经常说我们就是要一个可以把多种设备拉到同一个会议中,怎么搞这么复杂。今…

《动手学深度学习》(PyTorch版)-第一章

TOC 第一章 1.1、一般编程要解决的问题 例如,如果我们要为一台微波炉编写一个用户界面 假设我们要编写一个电子邮件客户端。 1.2、深度学习要解决的问题 例如,假设我们想要编写一个判定一张图像中有没有猫的程序。这件事听起来好像很简单&#xff0…

PSI算法极简概述

什么是隐私求交PSI 隐私求交是多方安全计算中的密码学技术,它允许数据持有方通过比较加密集合计算得到交集,且任何一方都不会获得其他信息。PSI还存在一种变体,即CS场景。客户端可以获取其与服务器的交集但是服务器无法学习到该集合。如果在…

【Linux】gcc 的使用 | 动静态库 | make Makefile

程序翻译的过程 程序翻译的过程就是将C语言转换成二进制指令的过程。 预编译(完成 去注释、宏替换、头文件展开、条件编译等工作):gcc -E test.c -o test.i 编译(将C文本替换成汇编语言):gcc -S test.i -…

Excel实用技巧 如何将EXCEL中在同个单元格中的汉字和数字分开

右边字符串,左边数字 RIGHT(A1,LENB(A1)-LEN(A1)) LEFT(A1,2*LEN(A1)-LENB(A1)) 左边字符串,右边数字 LEFT(A1,LENB(A1)-LEN(A1)) RIGHT(A1,2*LEN(A1)-LENB(A1))

在Ubuntu环境下安装anaconda(很简单!!!!!)

前言:想要使用tensorflow-compression,但是这个在windows下不支持。那我只好去Ubuntu环境下的安装anaconda。但是!!!!!找了半天,都没找到好的安装教程,浪费了一下午,心态…

每天一点Python——day49

#第四十九天 # #元组的创建方式: #如图: #①直接小括号 a(python,world,98) print(a) print(type(a)) #也可以省略不写 a1python,world,98 print(a1) print(type(a1)) #为什么可以省略省略小括号呢 a3(python) print(type(a3)) #会发现是字符串类型 #因为…