lio-sam中雅克比推导

2023-05-16

lio-sam做的是scan-map,点变到世界系下,优化本帧在是世界系下的位姿,和loam有所不同。
符号:
本帧特征点云(相对机体系) P s c a n l i d a r P_{scan}^{lidar} Pscanlidar , 本帧点云变换至世界系 P s c a n P_{scan} Pscan,局部地图中匹配的点云 P m a p P_{map} Pmap(世界系),位姿 X = { R , T } X=\{R,T\} X={R,T},点到对应线、面的距离残差 f ( X ) f(X) f(X),围绕机体 x x x轴旋转的角度为 r x rx rx s i n ( r x ) 、 c o s ( r x ) sin(rx)、cos(rx) sin(rx)cos(rx)记作 s x 、 c x s_x、c_x sxcx,其他轴同理。

坐标变换关系:
在这里插入图片描述
待优化的误差函数:
其实没有 P m a p P_{map} Pmap这个点,误差函数是点到线、面的距离,这里认为 P m a p P_{map} Pmap是线、面上垂直 P s c a n P_{scan} Pscan的点(后面和 P m a p P_{map} Pmap没有关系)。
(打错了,是 f = d i s t ( P s c a n , P m a p ) f=dist(P_{scan},P_{map}) f=dist(Pscan,Pmap)
在这里插入图片描述
误差函数的雅可比 J J J
在这里插入图片描述
1、分步求导第一项:
在这里插入图片描述
即为特征点到对应线面的距离的单位向量 [ l a , l b , l c ] [la,lb,lc] [la,lb,lc](行向量),在求误差 f f f时,便已经得到,存放在coeff.xyz中。
2、分步求导第二项:
(应该是 [ r x , r y , r z , x , y , z ] [rx,ry,rz,x,y,z] [rx,ry,rz,x,y,z],下面写法括号里的 T T T不该带转置的)
在这里插入图片描述

R R R是机体在世界系下的位姿,先围绕 z z z轴旋转的角度为 r z rz rz,后围绕 x x x轴旋转的角度为 r x rx rx,最后围绕 y y y轴旋转的角度为 r y ry ry R = R y R x R z R=RyRxRz R=RyRxRz, 表示为(推导过程可以见附录中wiki截图):
在这里插入图片描述
2.1 我们先只看对 r x rx rx的求导部分:
在这里插入图片描述
其中, P s c a n P_{scan} Pscan即点的坐标,存储在pointOri.xyz,这一块的雅可比为:
在这里插入图片描述

对应代码中的:

float arx = (crx*sry*srz*pointOri.x + crx * crz*sry*pointOri.y - srx * sry*pointOri.z) * coeff.x
    + (-srx * srz*pointOri.x - crz * srx*pointOri.y - crx * pointOri.z) * coeff.y
    + (crx*cry*srz*pointOri.x + crx * cry*crz*pointOri.y - cry * srx*pointOri.z) * coeff.z;

2.2 r y , r z ry,rz ry,rz略过,对 T T T的求导部分为:
在这里插入图片描述
这一块的雅可比为:
在这里插入图片描述
对应代码中的:

matA(i, 3) = coeff.x;
matA(i, 4) = coeff.y;
matA(i, 5) = coeff.z;

3、最后把3个旋转,和T(x,y,z)的雅可比拼凑起来,就得到该特征点对应到1X6的雅可比矩阵:
在这里插入图片描述
附录:
参考1 2 3;
和参考123有些差异的地方,其中的 R R R如下,为啥差着负号,还没搞懂,没看过loam源码,估计是优化的R和计算误差时用的R是逆的关系,优化用 R t − 1 t R_{t-1}^t Rt1t,误差函数是当前帧点变到上一帧 R t t − 1 R_{t}^{t-1} Rtt1,但最后优化结果直接加在 R t − 1 w o r l d R_{t-1}^{world} Rt1world上了(也就是 R t t − 1 R_{t}^{t-1} Rtt1)?不知道不知道…
在这里插入图片描述

这里附上wiki中的公式:
在这里插入图片描述
在这里插入图片描述
标量对列向量求导(参考1中有误):
在这里插入图片描述

代码:

// 求roll、pitch、yaw对应的sin和cos
float srx = _transformTobeMapped.rot_x.sin();
float crx = _transformTobeMapped.rot_x.cos();
float sry = _transformTobeMapped.rot_y.sin();
float cry = _transformTobeMapped.rot_y.cos();
float srz = _transformTobeMapped.rot_z.sin();
float crz = _transformTobeMapped.rot_z.cos();

Eigen::Matrix<float, Eigen::Dynamic, 6> matA(laserCloudSelNum, 6);	// J
Eigen::Matrix<float, 6, Eigen::Dynamic> matAt(6, laserCloudSelNum);	// JT
Eigen::Matrix<float, 6, 6> matAtA;									// JT*J
Eigen::VectorXf matB(laserCloudSelNum);								// f
Eigen::VectorXf matAtB;												// JT*f
Eigen::VectorXf matX;													// delta

// 对每个点依次构建雅克比
for (int i = 0; i < laserCloudSelNum; i++)
{
    // scan中每个特征点的坐标(当前雷达系下)
    pointOri = _laserCloudOri.points[i];
    // scan中特征点到map中对应点的距离的方向单位向量(即误差在xyz方向上的单位分量)
    coeff = _coeffSel.points[i];
    // 雅克比中对roll求导部分
    float arx = (crx*sry*srz*pointOri.x + crx * crz*sry*pointOri.y - srx * sry*pointOri.z) * coeff.x
    + (-srx * srz*pointOri.x - crz * srx*pointOri.y - crx * pointOri.z) * coeff.y
    + (crx*cry*srz*pointOri.x + crx * cry*crz*pointOri.y - cry * srx*pointOri.z) * coeff.z;
    // 雅克比中对pitch求导部分
    float ary = ((cry*srx*srz - crz * sry)*pointOri.x
                + (sry*srz + cry * crz*srx)*pointOri.y + crx * cry*pointOri.z) * coeff.x
    + ((-cry * crz - srx * sry*srz)*pointOri.x
        + (cry*srz - crz * srx*sry)*pointOri.y - crx * sry*pointOri.z) * coeff.z;
    // 雅克比中对yaw求导部分
    float arz = ((crz*srx*sry - cry * srz)*pointOri.x + (-cry * crz - srx * sry*srz)*pointOri.y)*coeff.x
    + (crx*crz*pointOri.x - crx * srz*pointOri.y) * coeff.y
    + ((sry*srz + cry * crz*srx)*pointOri.x + (crz*sry - cry * srx*srz)*pointOri.y)*coeff.z;

    // 雅克比中对roll,pitch,yaw求导部分值
    matA(i, 0) = arx;
    matA(i, 1) = ary;
    matA(i, 2) = arz;
    //雅克比中对x,y,z求导部分值
    matA(i, 3) = coeff.x;
    matA(i, 4) = coeff.y;
    matA(i, 5) = coeff.z;
    // 残差f
    matB(i, 0) = -coeff.intensity;
}

matAt = matA.transpose();
matAtA = matAt * matA;
matAtB = matAt * matB;

// LM求解:JT*J*x=-JT*f (solve: A * X = B, 求解X)
matX = matAtA.colPivHouseholderQr().solve(matAtB);

// 更新状态量: X = X + δX
_transformTobeMapped.rot_x += matX(0, 0);
_transformTobeMapped.rot_y += matX(1, 0);
_transformTobeMapped.rot_z += matX(2, 0);
_transformTobeMapped.pos.x() += matX(3, 0);
_transformTobeMapped.pos.y() += matX(4, 0);
_transformTobeMapped.pos.z() += matX(5, 0);

// 更新小于阈值,则判断收敛;或达到指定次数,则退出
float deltaR = sqrt(pow(rad2deg(matX(0, 0)), 2) +
                    pow(rad2deg(matX(1, 0)), 2) +
                    pow(rad2deg(matX(2, 0)), 2));
float deltaT = sqrt(pow(matX(3, 0) * 100, 2) +
                    pow(matX(4, 0) * 100, 2) +
                    pow(matX(5, 0) * 100, 2));

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

lio-sam中雅克比推导 的相关文章

  • 用rs_lidar雷达跑lio_sam

    1 准备工作 imu绑定串口有线连接雷达并能用rviz显示雷达点云用两个imu标定包标定imu在完成第二步必要的工作后 xff0c 配置LIO SAM config 下的params yaml参数 xff0c 更改之前建议备份在旁边复制粘贴
  • LIO-SAM-自采数据运行踩坑

    一直觉得LIO SAM还是一个比较不错的激光雷达惯性里程计框架 xff0c 最近在使用自己的数据进行测试过程中出现了很多坑 xff0c 花费了一周多的时间才填平 xff0c 在此记录一下 前言 Ouster 128激光雷达数据Ouster内
  • LIO-SAM ouster

    1 ROS tested with Melodic sudo apt span class token operator span get install span class token operator span y ros span
  • lvi-sam的深度匹配策略

    在lvi sam中 xff0c 作者通过视觉处理的时候 xff0c 利用lidar的深度信息 xff0c 得到了更稳定的估计 那在代码里是怎么实现的呢 xff1f 一起来看看看呗 1 在lvi sam的feature tracker nod
  • SAM-Segment Anything Model进行单张图片的检测记录

    一 代码和模型下载 下载链接 GitHub facebookresearch segment anything 将代码下载并解压到一个没有中文的路径下 页面往下滑找到需要下载的模型 nbsp 这里提供了三个模型 vit b的大小是358m
  • FAST-LIO, ikd-Tree, FAST-LIO2, FASTER-LIO论文总结

    目录 一 FAST LIO 本文的三个创新点 xff1a FAST LIO框架 二 ikd Tree 三 FAST LIO2 四 FASTER LIO 一 FAST LIO FAST LIO三个创新点 xff1a 将IMU和雷达点特征点紧耦
  • LVI-SAM论文翻译

    摘要 我们提出了一个通过smoothing and mapping的紧耦合的雷达视觉惯性里程计框架 xff0c LVI SAM xff0c 能够实时状态估计和建图 xff0c 且具有很高的精度和鲁棒性 LVI SAM基于因子图构建 xff0
  • LIO-SAM论文翻译

    摘要 我们提出了一个通过smoothing and mapping实现的紧耦合激光惯性里程计框架 xff0c LIO SAM xff0c 能够取得高精度 实时的移动机器人的轨迹估计和地图构建 LIO SAM基于因子图构建 xff0c 把多个
  • FAST-LIO论文翻译

    摘要 本文提出了一个计算效率较高和鲁棒的激光 惯性里程计框架 我们使用基于紧耦合的迭代扩展卡尔曼滤波器将LiDAR特征点与IMU数据融合在一起 xff0c 以便在发生退化的快速运动 xff0c 嘈杂或杂乱环境中实现稳健的导航 为了在存在大量
  • Ubuntu20.04部署编译LVI-SAM

    该动图来自LVI SAM开源地址 xff08 https github com TixiaoShan LVI SAM xff09 1 写在开头 1 1 为何诞生此文 近期在学习SLAM相关知识 xff0c 拜读了此篇经典论文LVI SAM
  • ROS-3DSLAM(二)lvi-sam项目认识

    2021SC 64 SDUSC xff08 二 xff09 lvi sam项目认识 一 SLAM简介 SLAM是Simultaneous Localization and Mapping xff08 同时定位 43 建图 xff09 独立的
  • 运行LIO-SAM,[lio_sam_imuPreintegration-2] process has died,[lio_sam_mapOptmization-5] process has died

    报错图例 解决办法 span class token builtin class name cd span usr local lib span class token function sudo span span class token
  • 用rs_lidar雷达跑lio_sam

    1 准备工作 imu绑定串口有线连接雷达并能用rviz显示雷达点云用两个imu标定包标定imu在完成第二步必要的工作后 xff0c 配置LIO SAM config 下的params yaml参数 xff0c 更改之前建议备份在旁边复制粘贴
  • 【SLAM】LVI-SAM解析——综述

    LVI SAM可以认为是LIO SAM和VINS MONO的合体 xff0c 在此基础上的修改不大 github xff1a https github com TixiaoShan LVI SAM paper LVI SAM Tightly
  • 万物分割SAM使用教程

    文章目录 安装 使用 全图分割 点 框 完整代码 原理篇 安装 创建虚拟环境 conda create n sam python 3 8 激活环境 conda activate sam 下载代码 git clone git github c
  • Segment Anything开源项目学习记录

    一 什么是Segment Anything开源项目 Introduction We introduce the Segment Anything SA project a new task model and dataset for ima
  • RNA-seq——三、使用Hisat2进行序列比对

    步骤 1 下载对应的index 2 序列比对 3 samtools 将sam文件转为bam文件 4 将bam文件载入IGV 为什么要比对 https www jianshu com p 681e02e7f9af Jimmy老师主要演示了四种
  • 利用SAM实现自动标注

    利用SAM实现自动标注 目录 利用SAM实现自动标注 一 下载安装 1 1 下载SAM Tool和SAM 1 2 下载SAM模型文件 1 3 安装SAM 二 配置项目 三 提取信息 四 获得SAM onnx文件 五 标注 六 格式转换 6
  • 多功能 SAM 模板的推荐项目结构

    我有一个新项目 需要相对少量的服务 可能是 10 个或更少 因此将每个服务放在单独的项目存储库中并不经济 每项服务都将通过 SAM 模板定义为 AWS Serverless Function 我的问题是 组织或构建这样一个项目的推荐方法是什
  • Sam 在 intellij 中构建:错误:JavaMavenWorkflow:MavenBuild - 'utf-8' 编解码器无法解码位置 150889 中的字节 0xbb:无效的起始字节

    我正在使用带有 Spring Boot 应用程序的 aws 无服务器架构 当我在 intellij 中使用 sam build 构建项目时 出现以下错误 Building codeuri runtime java11 metadata fu

随机推荐

  • 匿名飞控openmv寻色块解读

    作者 xff1a 不会写代码的菜鸟 时间 xff1a 2019 7 26 源码 xff1a 匿名TI板飞控源码 43 openmvH4 说明 xff1a 限于本人水平有限 xff0c 并不能写的很详细 xff0c 还望各位能够补充
  • 校验和的计算方法

    实验要求 编写一个计算机程序用来计算一个文件的16位效验和 最快速的方法是用一个32位的整数来存放这个和 记住要处理进位 xff08 例如 xff0c 超过16位的那些位 xff09 xff0c 把它们加到效验和中 要求 xff1a 1 x
  • MT7621路由器芯片/处理器参数介绍

    MT7621路由器芯片包括一个880 MHz MIPS 1004Kc CPU双核 xff0c 一个5端口10 100 1000交换机 PHY和一个RGMII 嵌入式高性能cpu可以很容易地处理高级应用程序 如路由 安全和VoIP等 MT76
  • 谈谈你对事件的传递链和响应链的理解

    一 xff1a 响应者链 UIResponser包括了各种Touch message 的处理 xff0c 比如开始 xff0c 移动 xff0c 停止等等 常见的 UIResponser 有 UIView及子类 xff0c UIViCont
  • CMake 引入第三方库

    CMake 引入第三方库 在 CMake 中 xff0c 如何引入第三方库是一个常见的问题 在本文中 xff0c 我们将介绍 CMake 中引入第三方库的不同方法 xff0c 以及它们的优缺点 1 使用 find package 命令 在
  • u-boot的启动模式(面试常考)

    交互模式 uboot启动之后 xff0c 在倒计时减到0之前按任意键 xff0c uboot会进入到交互模式 xff0c 此时可以输入各种uboot命令 和uboot进行交互 自启动模式 uboot启动之后 xff0c 在倒计时减到0之前不
  • vins-fusion代码理解

    代码通读了一遍做些总结 xff0c 肯定有很多理解错了的地方 xff0c 清晰起见详细程序都放到引用链接里 从rosNodeTest cpp开始 main函数 ros span class token operator span span
  • vins博客的一部分1

    文章目录 imu callbackimg callback imu callback 从话题中读入各个数据的t x y z g y r xff0c 存放到acc和gry中 span class token comment 从话题读入 spa
  • vins博客的一部分2

    sync process 对两个imgBuf里的图像进行双目时间匹配 xff08 通过判断双目图像时间之差 lt 3ms xff09 xff0c 扔掉匹配不到的老帧 span class token keyword double span
  • vins博客的一部分3

    FeatureTracker trackImage 包含了 xff1a 帧间光流法 区域mask 检测特征点 左右目光流法匹配 计算像素速度 画图 跟踪上一帧的特征点 如果已经有特征点 xff0c 就直接进行LK追踪 xff0c 新的特征点
  • vins博客的一部分4

    processMeasurements 取出数据 将 featureBuf中 xff0c 最早帧的feature取出 xff1a feature 61 featureBuf front 节点的接收IMU的消息再imu callback中被放
  • vins博客的一部分5

    目录 initFirstIMUPose xff08 xff09 processIMU propagate initFirstIMUPose xff08 xff09 得到IUM的Z与重力对齐的旋转矩阵 xff1a IMU开始很大可能不是水平放
  • vins博客的一部分6

    processImage 输入是本帧的特征点 id cam id xyz uv vxvy 包含了检测关键帧 估计外部参数 初始化 状态估计 划窗等等 检测关键帧 选择margin帧 addFeatureCheckParallax 检测和上一
  • vins博客的一部分7

    目录 initFramePoseByPnP frame count Ps Rs tic ric triangulate frame count Ps Rs tic ric initFramePoseByPnP frame count Ps
  • vins博客的一部分8

    目录 optimization slideWindow optimization 优化先验残差 重投影残差 预积分残差 xff08 即要拟合的目标是 xff0c 之前边缘化后的先验值 xff0c 前后帧之间的IMU的预积分值 xff0c 每
  • 以下为WindowsNT下32位 C++程序,请计算sizeof的值

    转帖地址 xff1a http hi baidu com hikeba blog item 68ad9f10a7dd8003213f2ecf html char str 61 34 hello 34 char p1 61 str int n
  • vins博客的一部分9

    目录 IMUFactor xff08 imu约束 xff09 ProjectionTwoFrameOneCamFactor xff08 视觉约束 xff09 marginalize 边缘化约束 IMUFactor xff08 imu约束 x
  • fiesta论文翻译和代码

    论文 体素信息结构 VIS Namemean符号position体素坐标posoccupancy占用概率occESDF到最近障碍物的欧几里得距离disClosest Obstacle Coordinate最近障碍物的体素坐标cocobser
  • ROS中四元数、欧拉角、旋转矩阵等格式转换

    未完 ROS接收到odometry格式消息 xff1a nav msgs span class token operator span Odometry pos msg 具有 xff1a pos msg span class token p
  • lio-sam中雅克比推导

    lio sam做的是scan map xff0c 点变到世界系下 xff0c 优化本帧在是世界系下的位姿 xff0c 和loam有所不同 符号 xff1a 本帧特征点云 xff08 相对机体系 xff09 P s c a