graph slam tutorial :从推导到应用3

2023-05-16

       为了更好地理解graph based slam的过程,本文以二维平面的激光SLAM为例子,先简单介绍如何根据传感器信息构建图,即图优化的前端(front-end)。然后再针对上篇博客的疑问,结合matlab程序,分析图优化的后端(back-end)。

       对于二维平面的激光SLAM,数据包括两部分,odometry和laser range data,所以构图过程如下:

  • 当机器人前进0.5m或者旋转超过0.5弧度时,将新的机器人位姿添加到图的顶点,并且记录相应的激光数据。
  • 当前激光数据和上一次的激光数据进行匹配,通过scan match获得两个相邻位姿之间的变换关系,将该变换关系加入到图的边。
  • 当机器人重新回到一个已知区域时,激光数据和以前的诺干组数据进行匹配进行闭环检测。如果匹配成功,在相应顶点之间加入一条边。

      对于3D的SLAM图优化的前端和上述过程基本差不多。

图优化后端

1.构建误差函数

      在构建好图以后,就得根据误差函数求雅克比矩阵,然后根据雅克比矩阵求b以及系统信息矩阵H了。对于2维SLAM,我们知道机器人某一时刻的位姿可以表示成。在各类论文中(主要是弗莱堡大学Grisetti派系的),把误差函数设定为如下形式:


其中函数t2v()表示将位姿矩阵转为向量,直接看代码。

% A =  cos -sin x
%      sin cos y
%      0    0   1
% v = (x,y,theta)
function v = t2v(A)
% T2V homogeneous transformation to vector
v(1:2,1) = A(1:2,3); % 第三列第1,2行,即x,y
v(3,1) = atan2(A(2,1), A(1,1));
end

并且上式中是位姿向量矩阵形式,使用一个v2t()的函数就行了。

function A = v2t(v)
% V2T vector to homogeneous transformation
c = cos(v(3));
s = sin(v(3));
A = [c, -s, v(1);
     s,  c, v(2);
     0   0  1];
end

误差函数表达式中要注意表示位姿j到位姿i之间的变换矩阵,也可以说是坐标j和坐标i之间的差异,至于为什么这里两个矩阵相乘就能表示它们的差异,这是由于它们是位姿矩阵,看下面的分析。

        先来一个简单版的推导:

        表示位姿i在世界坐标系w中的表示,也表示将坐标系i中的一点转换到世界坐标系w中的转换矩阵,同理表示坐标系j中的一点转换到世界坐标系w中的转换矩阵,也可以说是坐标系j在世界坐标系w中的表示。

        现在可以看看那两个矩阵相乘的含义了:,最后的结果是Xij,而它表示的就是坐标系j到坐标系i的转换矩阵。

        上面这个推导用下标推算简单说明了情况,背后的数学推导还是有必要看看的。现在开始严格一点的数学推导。我们先不分析分析和分析是一样的,所以直接分析,即为什么测量出的转换矩阵和理论计算的转换矩阵的误差err要这样计算?

预备知识:对于分块矩阵如何求逆。

                          

现在开始推导。不妨假设j到i变换的变换矩阵估计值为:

                 

注意,矩阵中的组成分别是旋转矩阵R和平移向量t。i,j之间变换的测量值变换矩阵为:

         

误差计算:


                                                      

                                                       

误差计算中最后一步是把上面的矩阵向量化。

      旋转矩阵表示逆时针旋转,表示顺时针旋转,两个旋转矩阵相乘再向量化的物理意义不就是两个旋转矩阵角度的差异嘛。表示两个位移向量的差异。因此,同理也表示位姿j到位姿i之间的变化。


2.计算雅克比矩阵

      误差函数有了,接下来最重要的一步是计算雅克比矩阵,先把误差函数由矩阵形式一步一步向量化,先把如下


将上面的矩阵再进一步转化为误差向量。


把上面的误差向量对机器人位姿i求偏导得到Aij。先对平移向量求偏导,再对角度求偏导得


同理,对位姿j求偏导得到Bij。


程序中对应的计算如下:

%compute the homoeneous transforms of the previous solutions
zt_ij = v2t(z_ij);%向量转化为矩阵
vt_i = v2t(v_i);
vt_j = v2t(v_j);

%compute the displacement between x_i and x_j
f_ij=(inv(vt_i) * vt_j);% Xi的逆乘以Xj

%this below is too long to explain, to understand it derive it by hand
theta_i = v_i(3);
ti = v_i(1:2,1);
tj = v_j(1:2,1);
dt_ij = tj-ti;

si = sin(theta_i);
ci = cos(theta_i);

% 这里的A,B是还没有乘以Rz转置的
A= [-ci, -si, [-si, ci]*dt_ij; si, -ci, [-ci, -si]*dt_ij; 0, 0, -1 ];
B =[  ci, si, 0           ; -si, ci, 0            ; 0, 0, 1 ];

ztinv = inv(zt_ij);
e = t2v(ztinv * f_ij); % 误差向量
ztinv(1:2,3) = 0;% 偏导A,B计算公式中只用了z的旋转矩阵R,所以把平移向量强制清0
A = ztinv*A; % 乘以Z的转置,即Z的逆,这是由于旋转矩阵的关系
B = ztinv*B;
有了雅克比矩阵以后,只要将计算的b,H累加起来就行了

对应代码如下:

    %compute the blocks of H^k
    b_i = -A' * omega * e;
    b_j = -B' * omega * e;
    H_ii=  A' * omega * A;
    H_ij=  A' * omega * B;
    H_jj=  B' * omega * B;
    
    %accumulate the blocks in H and b
    H((id_i-1)*3+1:id_i*3,(id_i-1)*3+1:id_i*3) = ...
        H((id_i-1)*3+1:id_i*3,(id_i-1)*3+1:id_i*3)+ H_ii;
    H((id_j-1)*3+1:id_j*3,(id_j-1)*3+1:id_j*3) = ...
        H((id_j-1)*3+1:id_j*3,(id_j-1)*3+1:id_j*3) + H_jj;
    H((id_i-1)*3+1:id_i*3,(id_j-1)*3+1:id_j*3) = ...
        H((id_i-1)*3+1:id_i*3,(id_j-1)*3+1:id_j*3) + H_ij;
    H((id_j-1)*3+1:id_j*3,(id_i-1)*3+1:id_i*3) = ...
        H((id_j-1)*3+1:id_j*3,(id_i-1)*3+1:id_i*3) + H_ij';
    b((id_i-1)*3+1:id_i*3,1) = ...
        b((id_i-1)*3+1:id_i*3,1) + b_i;
    b((id_j-1)*3+1:id_j*3,1) = ...
        b((id_j-1)*3+1:id_j*3,1) + b_j;
       所有部分计算完毕以后,就是计算增量,迭代直到收敛。
下面是matlab代码中,图优化前和优化后的机器人轨迹对比:

  

整个代码是grisetti课程里面代码改成的matlab版。我不生产代码,只是github的搬运工,O(∩_∩)O 下载地址戳这里。在看代码前,建议看看关于图顶点和边的数据说明。

图的数据格式       

       最后讲一下图优化前端处理以后产生的顶点和边的数据格式,这是写程序时特别关注的,也是众多优化包如g2o的数据格式。

       顶点vertex2: id,pose.x,pose.y,pose.theta 其中id表示位姿的序号,后面三个是位姿参数

       边EDGE2: idFrom idTo mean.x mean.y mean.theta inf.xx inf.xy inf.xt inf.yy inf.yt  inf.tt 其中idfrom,idTo表示连接边的两个位姿顶点序号,mean.xytheta表示测量的位姿变换矩阵。inf表示边的信息矩阵即权重。


       到目前为止,基本已经了解了graph based slam是咋回事。在实际编程中,弗莱堡大学的牛人们开发了g2o优化包帮大家解决图优化的后端(back-end)问题。因此写写图优化前端的程序(match,icp求位姿矩阵,loop closure),构建图,然后再用g2o库就能够完成一个图优化SLAM程序,是不是感觉思路很清晰,很容易。关于g2o库的使用,Grisetti写了一个教程,g2o也自带很多例子,但是不自己动动手,永远给人感觉像是雾里看花,水中望月,不踏实。在下一篇博客中,我们将拿一个数据集练练手,操练操练g2o库的使用,祝好运。



(转载请注明作者和出处:http://blog.csdn.net/heyijia0327 未经允许请勿用于商业用途)


reference:

1. Grisetti的课程,有课件下载,点这里

2. Grisetti. 《A Tutorial on Graph-Based SLAM》

3. Grisetti. 课件 《SLAM Back-end》(可以直接搜到)





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

graph slam tutorial :从推导到应用3 的相关文章

  • Bellman-Ford 算法检测什么?负重还是负循环?

    如果给定一个图 现在我们要从源头计算最短路径 现在 如果一条边具有负权重 但在到达目的地时有边到后边返回到该边 我的意思是如果没有循环 那么我们就没有负循环 但是here http en wikipedia org wiki Bellman
  • 在无向图中查找强连通分量

    我想在无向图中找到强连接的组件 即如果我从节点开始A然后我会回到节点A并且每条边都被恰好访问一次 对于有向图可以使用Tarjan算法来寻找强连通分量 但是对于无向图怎么办 我认为您错过了强连通分量的含义 强连接组件 如果所有顶点对之间都存在
  • 用于带有嵌套子图的图的 r 包? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个用于图形 网络的 r 包 它可以处理嵌套子图 Graphviz 做到了这一点 但只提供可
  • Flash 图表和图形的最佳解决方案是什么? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我知道融合图表 http www fusioncharts com 还有其他好的解决方案或 API 用
  • 使用 PHP 创建图表并导出为 PDF

    我正在寻找有关使用 PHP 创建图表的建议 我还希望能够将这些图表导出到 PDF 文档 我目前正在使用谷歌图表 但我不喜欢将我的所有信息发送到谷歌的想法 我更喜欢自己的托管解决方案 我见过很多 Flash 解决方案 但我不知道有什么方法可以
  • 为什么图的 C++ 数据结构隐藏连续的整数索引?

    有向图和无向图的数据结构至关重要 众所周知且广泛使用的实现 例如Boost图库 http www boost org doc libs 1 56 0 libs graph doc table of contents html and Lem
  • 更改 3D 图形颜色 (matplotlib)

    我使用以下代码在 matplotlib 中绘制了 3D 图形 Previously defines lists of data to plot fig plt figure ax fig add subplot 111 projection
  • 使用 Java 进行树可视化 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个库来生成图形或树 例如组织图表 该库应该能够从该图中生成纯图像 有谁知道一个好的 希望开源
  • 您将如何显示/布局企业应用程序之间的数据流?

    我的雇主是一家大型瑞士电信公司 我们有许多系统用于为不同任务传输数据 例如性能管理 故障管理 配置管理等 为了向 管理 尖头等 解释这些系统如何交互 我将有关数据流 格式 协议的信息收集到 数据库 逗号分隔的说服者 中 然后为 Graphv
  • 为什么我的 Python 散点图不起作用?

    我使用 pylab 创建了一个非常简单的散点图 pylab scatter engineSize fuelMile pylab show 该程序的其余部分不值得发布 因为正是该行给我带来了问题 当我将 散点 更改为 绘图 时 它会绘制数据图
  • 如何将条形图的 XtickLabels 向左移动?

    我目前正在尝试创建频率直方图 为此 我必须创建一个条形图 条形图之间没有空格 然而 这集中于XTickLabels在酒吧的中间 由于它是一个直方图 我希望数值位于每个条形之间的线上 以便它可以直观地指示间隔 本质上 我需要将所有刻度标签移至
  • 用于图形操作的 Javascript 库

    有没有建议的 javascript 替代 pythonpygraph http code google com p python graph or NetworkX http networkx lanl gov 应该注意的是 可视化不是必需
  • 在skiena的书中给出的关于应用dfs在图中查找循环的代码中存在错误

    这是dfs的代码 bool processed MAXV 1 which vertices have been processed bool discovered MAXV 1 which vertices have been found
  • 如何使用 Julia 查找矩阵中的连通分量

    假设我有以下矩阵 此处用 Julia 语言定义 mat 1 1 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 1 1 将一组值为 1 的相邻元素视为一个 分量 如何识别该矩阵有 2 个分量以及每个分量由哪些顶点组成 对于矩
  • 计算 Adamic-Adar 的快速算法

    我正在研究图形分析 我想计算一个 N N 相似度矩阵 其中包含每两个顶点之间的 Adamic Adar 相似度 为了概述 Adamic Adar 让我从以下介绍开始 给定邻接矩阵A无向图的G CN是两个顶点的所有公共邻居的集合x y 两个顶
  • 如何在 Twitter 中获取性别和年龄图表?

    我必须在 Twitter 上显示性别和年龄图表 就像 Facebook 人口统计图一样 附上这个 是否可以根据关注者数量使用 oauth 或 api 从 Twitter 获取性别和年龄数据 提前致谢 根据 Twitter 员工 episod
  • 绘制点之间的所有线

    我有以下 R 代码 x lt c 0 01848598 0 08052353 0 06741172 0 11652034 y lt c 0 4177541 0 4042247 0 3964025 0 4074685 d lt data fr
  • 贝尔曼福特算法可以有任意的边顺序吗?

    我刚刚开始学习新算法 但当我阅读 极客为极客而写的贝尔曼福特算法 时 我陷入了困境 http www geeksforgeeks org dynamic programming set 23 bellman ford algorithm h
  • 我如何能够以两行显示标题,并且每行的字体大小不同?

    我正在使用 Google Chart API 创建时间线图 并希望将图的标题修改为两行 问题 我如何能够显示具有不同字体大小的两线图表标题 电流输出 理想输出 相关研究 我唯一能找到的是有人试图用饼图来做到这一点 但我尝试了但无法使其发挥作
  • 添加边后更新最大流量

    考虑我们有一个网络流量 并使用 Edmond Karp 算法 我们已经拥有网络上的最大流量 现在 如果我们向网络添加任意边 具有一定容量 更新最大流量的最佳方法是什么 我正在考虑更新关于新边缘的残差网络 并再次寻找增强路径 直到找到新的最大

随机推荐

  • 物联网安全系列 - 非对称加密算法 ECDH

    非对称加密算法 ECDH 背景 之前的章节讲到了对称加密算法AES xff0c 发送方和接收方需要使用相同的密钥进行通讯 xff0c 但是发送方怎么将密钥安全的发送给接收方 xff1f 这是一个问题 密钥分配问题 对称加密算法中 xff0c
  • 【开源】一款PyQT+Pyserial开发的串口调试工具

    开源 PyQT 43 Pyserial开发的串口调试工具 串口调试工具是我们做嵌入式开发常用的工具 xff0c 市面上已经有很多串口调试工具了 xff0c 博主写这款串口调试工具一方面是为了学习Python PyQT Pyserial 相关
  • 【Matter】解密Matter协议(一)--- 什么是Matter协议?

    1 什么是Matter协议 xff1f 目前的智能家居行业使用解决方案众多 xff0c 相互之间隔离严重 xff0c 有WiFi 蓝牙 ZigBee 蜂窝或者有线等等不同通讯协议的设备 不仅不同协议之间的设备不能互通 xff0c 而且连相同
  • 【蓝牙系列】蓝牙5.4到底更新了什么?(1)--- PAwR

    蓝牙系列 蓝牙5 4到底更新了什么 xff08 1 xff09 PAwR 一 背景 蓝牙技术联盟最近发布了蓝牙5 4的核心规范 xff0c 蓝牙5 4规范的主要改进之一就是实现了单个接入点与数千个终端节点进行双向无连接通信 xff0c 这一
  • UP Squared Board,工业级创新开发板,为您的物联网应用注入升级能量

    研扬科技自推出UP Board xff08 世界首创 Intel 平台信用卡大小开发板 xff09 以来 xff0c 便成功于业界打开名号 xff0c 后续 xff0c 研扬持续开发 UP 系列产品 xff0c 至今 xff0c 除了 UP
  • 【蓝牙系列】蓝牙5.4到底更新了什么(2)

    蓝牙系列 蓝牙5 4到底更新了什么 xff08 2 xff09 一 背景 上一篇文章讲了蓝牙5 4的PAwR特征 xff0c 非常适合应用在电子货架标签 xff08 ESL xff09 领域 xff0c 但是实际应用场景中看 xff0c 只
  • 【转载】【Nordic博文分享系列】详解Zephyr设备树(DeviceTree)与驱动模型

    详解Zephyr设备树 xff08 DeviceTree xff09 与驱动模型 转载自nordic半导体微信公众号 1 前言 Nordic最新的开发包NCS xff08 nRF Connect SDK xff09 相对于原来的nRF5 S
  • 感受一下SPL06气压计+APM三阶互补的高度融合

    不得不说 xff0c spl06气压计很强 xff0c 原始数据也比较干净 xff0c 短时间可以保持在30cm内浮动 xff0c 滤波后在10cm内浮动 就是这么夸张 使用APM的三阶互补滤波融合出 高度 xff0c 速度 xff0c 效
  • 6种串口协议的实现

    串口协议开发 以下解析范式都是采用数据队列的形似来存储 xff0c 并且根据设备运行速度差异 xff0c 还需增加数据包队列来存储解析完毕的数据包 1 范式一 固定长度 无校验 0x6B 20字节 0xB6 上面数据中有一个帧头0x6B x
  • html页面实时刷新显示服务器数据

    在上一篇中我说到浏览器和服务器交互数据 xff0c 是实现了服务器发数据给浏览器 xff0c 并在页面上显示 xff0c 但是是通过按钮点击刷新的 xff0c 而且数据是和html页面一起发过来的 xff0c 在这里我是数据放到页面数组里
  • 平衡小车之家客服真差

    我同事送了我一台直流电机平衡车 xff0c 然后同事又买了一台步进电机平衡车 都是在平衡小车之家买的 xff0c 好好看看下面的图片 最近在研究同事的步进平衡小车 xff0c 然后跑去问一下客服步进电机的参数 xff0c 一看我说 xff0
  • C++编译流程

    C 43 43 编译流程 C C 43 43 是编译型高级语言 xff0c 程序要执行 xff0c 必须要有编译器和链接器 编译过程分为四步 xff1a 预处理 编译 汇编 链接 1 预处理 读取源代码并对其中的以 开头的指令和特殊符号进行
  • 卡尔曼滤波 -- 从推导到应用(一)

    前言 卡尔曼滤波器是在估计线性系统状态的过程中 xff0c 以 最小均方误差为目的而推导出的几个递推数学等式 也可以从贝叶斯推断的角度来推导 本文将分为两部分 xff1a 第一部分 xff0c 结合例子 xff0c 从最小均方误差的角度 x
  • 卡尔曼滤波 -- 从推导到应用(二)

    该文是自我总结性文章 xff0c 有纰漏 xff0c 请指出 xff0c 谢谢 白巧克力 这部分主要是通过对第一部分中提到的匀加速小车模型进行位移预测 先来看看状态方程能建立准确的时候 xff0c 状态方程见第一部分分割线以后内容 xff0
  • LQR 的直观推导及简单应用

    本文主要介绍LQR的直观推导 xff0c 说明LQR目标函数J选择的直观含义以及简单介绍矩阵Q R的选取 xff0c 最后总结LQR控制器的设计步奏 xff0c 并将其应用在一个简单的倒立摆例子上 假设有一个线性系统能用状态向量的形式表示成
  • STM32学习路线-长图

    最近好好整理了一下学习STM32的路程 xff0c 做成了一个长图 xff1a STM32学习路线 xff0c 供初学者们参考一下
  • ROS 教程之 vision: 摄像头标定camera calibration

    在上一个ROS教程视觉文章中 xff0c 我们使用usb cam包读入并发布了图像消息 xff0c 但是图像没有被标定 xff0c 因此存在畸变 ROS官方提供了用于单目或者双目标定的camera calibration包 这个包是使用op
  • ROS 基础: 在同一个节点里订阅和发布消息

    在一些应用中 xff0c 可能有的人需要在同一个节点中实现订阅一个消息 xff0c 然后在该消息的回调函数中处理一下这些数据后再发布到另一个topic上 ROS answers中也有人有相同的疑问 xff0c 这里贴出Martin Peri
  • ROS : 修改ROS源代码(overlaying package)

    ROS官方或者其他个人提供了很多package供大家使用 xff0c 但是随着学习的深入 xff0c 很多人可能想去修改这些package的源代码 xff0c ROS提供了一种称之为overlaying的机制 它允许 ROS原有安装的pac
  • graph slam tutorial :从推导到应用3

    为了更好地理解graph based slam的过程 xff0c 本文以二维平面的激光SLAM为例子 xff0c 先简单介绍如何根据传感器信息构建图 xff0c 即图优化的前端 xff08 front end xff09 然后再针对上篇博客