李群、李代数在SLAM中的应用

2023-05-16

文章目录

  • 李群、李代数
    • 李群、李代书与坐标变换的对应关系
    • SE(3)上的李代数求导数
      • 左乘扰动、右乘扰动
      • 怎么选取用左or右扰动?
  • SLAM中的使用
  • 重投影误差
    • 误差项构建
    • 对应C++代码
    • 雅克比矩阵
      • frame_i的Ti2w从IMU坐标系变换到world坐标系
      • frame_j的Ti2w从IMU坐标系变换到world坐标系
      • Tc2i从camera坐标系变换到imu坐标系(相机外参)
      • frame_i中的逆深度inv_dep_i

李群、李代数

数学概念什么的不做介绍了,本人不是数学专业也解释不清楚。咱的目的是怎么即使不是很能理解还能够把这个东西理解下来,并且还能看懂和编程使用。就是像考试怎么不会还能把它做对!
反正下面是本人不知道对不对的理解方式。

  • 数学概念相关链接
  1. 视觉SLAM十四讲第四讲
  2. 等等

李群、李代书与坐标变换的对应关系

李群、李代数与坐标变化

SE(3)上的李代数求导数

首先需要补充一个运算符号^:将向量转换为反对称矩阵
反对称矩阵和向量转换运算

就是说对扰动求导数,SLAM中的主要应用就是这个其他的也不用很懂,记住下面的左乘、右乘的公式其实就行了,然后用公式推导3-4个雅克比矩阵基本上就会用了。但是《视觉SLAM十四讲》中只有左乘扰动的推导过程,其他的地方咱也没有搜到合适的右乘扰动的讲解。
扰动求导数

左乘扰动、右乘扰动

参考这个链接来吧,建议直接背公式套进去就行了。

怎么选取用左or右扰动?

大致就是说转换到world坐标系或者global坐标系这些固定不变的坐标系使用右乘扰动,其他的loacl坐标系下都是左乘扰动。
借鉴参考这个https://zhuanlan.zhihu.com/p/108478399

SLAM中的使用

这里以VINS_MONO中的重投影误差的约束为例解释使用。
projection_factor.cpp

重投影误差

误差项构建

重投影误差

对应C++代码

bool ProjectionFactor::Evaluate(double const *const *parameters, double *residuals, double **jacobians) 函数中

    TicToc tic_toc;
    Eigen::Vector3d Pi(parameters[0][0], parameters[0][1], parameters[0][2]); //共同观测的frame_i位姿
    Eigen::Quaterniond Qi(parameters[0][6], parameters[0][3], parameters[0][4], parameters[0][5]);

    Eigen::Vector3d Pj(parameters[1][0], parameters[1][1], parameters[1][2]); //共同观测的frame_j位姿
    Eigen::Quaterniond Qj(parameters[1][6], parameters[1][3], parameters[1][4], parameters[1][5]);

    Eigen::Vector3d tic(parameters[2][0], parameters[2][1], parameters[2][2]); //相机外参Tcamera2imu
    Eigen::Quaterniond qic(parameters[2][6], parameters[2][3], parameters[2][4], parameters[2][5]);

    double inv_dep_i = parameters[3][0]; //相机逆深度

    // 将frame_i下的3d点投影到frame_j坐标系下
    Eigen::Vector3d pts_camera_i = pts_i / inv_dep_i;                 //使用逆深度将frame_i的point归一化坐标恢复到真实3D坐标
    Eigen::Vector3d pts_imu_i = qic * pts_camera_i + tic;             //将frame_i的point转化到imu坐标系
    Eigen::Vector3d pts_w = Qi * pts_imu_i + Pi;                      //将frame_i的point转化到world坐标系
    Eigen::Vector3d pts_imu_j = Qj.inverse() * (pts_w - Pj);          //将frame_i的point转化到frame_j的imu坐标系下
    Eigen::Vector3d pts_camera_j = qic.inverse() * (pts_imu_j - tic); //将frame_i的point转化到frame_j的camera坐标系下
    Eigen::Map<Eigen::Vector2d> residual(residuals);

#ifdef UNIT_SPHERE_ERROR
    residual = tangent_base * (pts_camera_j.normalized() - pts_j.normalized());
#else
    double dep_j = pts_camera_j.z();                               //投影到frame_j坐标系下point的深度
    residual = (pts_camera_j / dep_j).head<2>() - pts_j.head<2>(); //归一化坐标的重投影误差
#endif

    residual = sqrt_info * residual; // sqrt_info = 焦距/1.5*I,信息矩阵,重投影误差的可靠性相等

雅克比矩阵

本质就是对误差项的各个变量求偏导数呗
咱也不知道为什么VINS_MONO的扰动都是右乘扰动。一开始拿《视觉SLAM14讲》的公式去推导怎么都不对QAQ

frame_i的Ti2w从IMU坐标系变换到world坐标系

  • 公式推导
    jacobians[0]- 对应C++代码
        if (jacobians[0]) //共同观测的frame_i位姿
        {
            Eigen::Map<Eigen::Matrix<double, 2, 7, Eigen::RowMajor>> jacobian_pose_i(jacobians[0]);

            Eigen::Matrix<double, 3, 6> jaco_i;
            jaco_i.leftCols<3>() = ric.transpose() * Rj.transpose();
            jaco_i.rightCols<3>() = ric.transpose() * Rj.transpose() * Ri * -Utility::skewSymmetric(pts_imu_i);

            jacobian_pose_i.leftCols<6>() = reduce * jaco_i;
            jacobian_pose_i.rightCols<1>().setZero();
        }

frame_j的Ti2w从IMU坐标系变换到world坐标系

  • 公式推导
    jacobians[1]
  • 对应C++代码
        if (jacobians[1]) //共同观测的frame_j位姿
        {
            Eigen::Map<Eigen::Matrix<double, 2, 7, Eigen::RowMajor>> jacobian_pose_j(jacobians[1]);

            Eigen::Matrix<double, 3, 6> jaco_j;
            jaco_j.leftCols<3>() = ric.transpose() * -Rj.transpose();
            jaco_j.rightCols<3>() = ric.transpose() * Utility::skewSymmetric(pts_imu_j);

            jacobian_pose_j.leftCols<6>() = reduce * jaco_j;
            jacobian_pose_j.rightCols<1>().setZero();
        }

Tc2i从camera坐标系变换到imu坐标系(相机外参)

这个太多了,不想写了,搜索参考崔华坤《VINS论文推导及代码解析》很详细了。注意扰动的二阶项近似为0就是了。

  • 对应C++代码
        if (jacobians[2]) //相机外参Tcamera2imu
        {
            Eigen::Map<Eigen::Matrix<double, 2, 7, Eigen::RowMajor>> jacobian_ex_pose(jacobians[2]);
            Eigen::Matrix<double, 3, 6> jaco_ex;
            jaco_ex.leftCols<3>() = ric.transpose() * (Rj.transpose() * Ri - Eigen::Matrix3d::Identity());
            Eigen::Matrix3d tmp_r = ric.transpose() * Rj.transpose() * Ri * ric;
            jaco_ex.rightCols<3>() = -tmp_r * Utility::skewSymmetric(pts_camera_i) + Utility::skewSymmetric(tmp_r * pts_camera_i) +
                                     Utility::skewSymmetric(ric.transpose() * (Rj.transpose() * (Ri * tic + Pi - Pj) - tic));
            jacobian_ex_pose.leftCols<6>() = reduce * jaco_ex;
            jacobian_ex_pose.rightCols<1>().setZero();
        }

frame_i中的逆深度inv_dep_i

  • 公式推导
    不涉及李群、李代数,即1/inv_dep_i的导数为1/(inv_dep_i*inv_dep_i)
  • 对应C++代码
        if (jacobians[3]) //相机逆深度
        {
            Eigen::Map<Eigen::Vector2d> jacobian_feature(jacobians[3]);
#if 1
            jacobian_feature = reduce * ric.transpose() * Rj.transpose() * Ri * ric * pts_i * -1.0 / (inv_dep_i * inv_dep_i);
#else
            jacobian_feature = reduce * ric.transpose() * Rj.transpose() * Ri * ric * pts_i;
#endif
        }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

李群、李代数在SLAM中的应用 的相关文章

随机推荐

  • 程序设计思维与实践 Week12 作业B - 必做题 - 2

    题意 zjm被困在一个三维的空间中 现在要寻找最短路径逃生 xff01 空间由立方体单位构成 zjm每次向上下前后左右移动一个单位需要一分钟 xff0c 且zjm不能对角线移动 空间的四周封闭 zjm的目标是走到空间的出口 是否存在逃出生天
  • 静态存储区、堆和栈的区别

    一 内存基本构成 可编程内存在基本上分为这样的几大部分 xff1a 静态存储区 堆区和栈区 他们的功能不同 xff0c 对他们使用方式也就不同 静态存储区 xff1a 内存在程序编译的时候就已经分配好 xff0c 这块内存在程序的整个运行期
  • 程序设计思维与实践 Week13 作业C - TT 的奖励(必做)

    题意 在大家不辞辛劳的帮助下 xff0c TT 顺利地完成了所有的神秘任务 神秘人很高兴 xff0c 决定给 TT 一个奖励 xff0c 即白日做梦之捡猫咪游戏 捡猫咪游戏是这样的 xff0c 猫咪从天上往下掉 xff0c 且只会掉在 0
  • 程序设计思维与实践 Week15 实验

    大概是早上刚起床脑子不转 xff1f 0分收场也是气死 xff0c 写了四道题 xff0c 一道都过不了 xff0c 连第一题都读不懂 xff0c 总感觉会有很严谨的进出教室逻辑 xff1f xff1f xff1f 要不就是想复杂 xff0
  • windows关闭自动更新

    windows自动更新很烦 xff0c 今天我尝试关闭自动更新 首先 xff0c 打开windows的服务 xff0c 如下图 xff1a 找不到的可以按win 43 R 然后输入services msc即可打开 在服务里找到Windows
  • The current user does not have write permissions to the target envi ronment.

    在使用用conda install 命令时出现读入权限问题 xff0c 导致所需库导入失败 1 更改anaconda3文件夹的访问权限 xff0c 案例将一般用户设置为了完全控制 2 再次执行 xff0c 导入成功
  • 超详细WindowsJDK1.8与JDK11版本切换教程

    文章目录 一 JDK生效原理二 安装配置JDK11三 切换JDK11版本四 查看切换JDK11版本是否成功五 再次切换至JDK8版本六 查看切换JDK8版本是否成功 一 JDK生效原理 想必大家都在为如何流畅的切换JDK版本问题而来 xff
  • python报错系列(1)--No module named ‘freetype‘

    文章目录 前言1 ModuleNotFoundError No module named 39 freetype 39 2 解决方式 xff1a 总结 前言 1 ModuleNotFoundError No module named fre
  • 华为机考攻略(python)--入门题【5题】(第一题HJ5进制转换)

    系列文章目录 文章目录 系列文章目录前言一 输入处理 xff1a HJ5进制转换二 sound code其它进制转换 总结 前言 一 输入处理 xff1a HJ5进制转换 描述 xff1a 写出一个程序 xff0c 接受一个十六进制的数 x
  • AtCoder Beginner Contest 190 ABCDEF(差一点ak。。。E超出了我的水平qwq)

    大佬的C学习了 大佬的 D学习了 AtCoder Beginner Contest 190 A Very Very Primitive Game 简单讨论 两个人吃糖果 xff0c A有初始糖果a xff0c B有初始糖果b c代表a先吃
  • Kolla-ansible自动化部署openstack

    Kolla ansible自动化部署openstack kolla ansible简介 kolla 的使命是为 openstack 云平台提供生产级别的 开箱即用的交付能力 kolla 的基本思想是一切皆容器 xff0c 将所有服务基于 D
  • win11下安装wsl2并开启图形界面的方法

    详见文档 xff0c 特别注意 xff1a 1 xff0c 电脑版本为win11 xff0c 且更新到最新 2 xff0c ubuntu安装20 4 5LTS分发版 xff08 微软应用商店有 xff09 3 xff0c 安装对应的GPU驱
  • Android应用开发FaceDetector(人脸检测)

    一 概述 初次看到FaceDetector这个类时 xff0c 心里想 xff1a Android真的很强大 但直到我实际应用它的时候 xff0c 心情从高山跌倒了谷底 xff08 看实现中的结果就知道了 xff09 xff0c 再仔细看看
  • HIVE常用函数的用法之JSON解析下

    HIVE常用函数之JSON TUPLE 如果JSON为空或者为非法的JSON格式 xff0c 返回NULL 如果键Key为空或者不合法 xff08 JSON中不存在 xff09 返回NULL 如果JSON合法 xff0c 键Key也存在 x
  • 时间机器无法存入备份之外的文件的解决方法

    在macOS Big Sur 11 0之后 xff0c APFS 或 APFS 加密磁盘已经替代Mac OS 扩展格式 xff08 日志式 xff09 格式 xff0c 成为时间机器备份磁盘的首选格式 但是Mac将整个APFS宗卷作为时间机
  • ROS安装与报错记录

    ubuntu18 04 安装ros melodic的踩最全的坑的记录 目录 ubuntu18 04 安装ros melodic的踩最全的坑的记录ubuntu 18 04 ros melodic安装记录 ubuntu20 04 ROS noe
  • Eigen3安装、卸载与重装(包含一键卸载安装指令)

    目录 ubuntu中一键卸载安装的 96 sh 96 文件下载链接一 卸载1 查看当前版本2 删除 96 eigen3 96 相关文件二 安装需要的版本1 官网 https gitlab com libeigen eigen release
  • c++调用python

    这里写目录标题 c 43 43 调用python头文件包含初始化python调用具体的函数调用链接CMakeLists txtExamplec 43 43 python的数据类型转化图像数据格式cv Mat传递numpy数据格式转化 一些奇
  • 在ubuntu安装使用miniconda

    目录 miniconda安装使用安装下载更好channel开启虚拟环境 使用一些库安装 miniconda安装使用 安装 下载 span class token function wget span https mirrors tuna t
  • 李群、李代数在SLAM中的应用

    文章目录 李群 李代数李群 李代书与坐标变换的对应关系SE 3 上的李代数求导数左乘扰动 右乘扰动怎么选取用左or右扰动 xff1f SLAM中的使用重投影误差误差项构建对应C 43 43 代码雅克比矩阵frame i的Ti2w从IMU坐标