Sophus教程

Sophus详细教程

Sophus 是一个用于处理李群(Lie Groups)和李代数(Lie Algebras)的 C++ 库,特别适用于机器人学、计算机视觉、图形学等领域中的位姿估计和优化问题。它基于高效的 Eigen 库,提供了对旋转和平移操作的高效实现,支持如 SO(2)、SO(3)、SE(2)、SE(3) 等常见的李群及其对应的李代数操作。

一、安装 Sophus

  1. 克隆仓库

    git clone https://github.com/strasdat/Sophus.git
    cd Sophus
    git checkout a621ff  # 选择一个稳定的版本
    
  2. 编译安装

    mkdir build
    cd build
    cmake ..
    make
    sudo make install  # 可选,将库安装到系统目录
    
  3. 配置环境变量(如果未执行 sudo make install):

    • .bashrc.zshrc 文件中添加 Sophus 的头文件目录和库文件目录:
      export CPLUS_INCLUDE_PATH=/path/to/Sophus:$CPLUS_INCLUDE_PATH
      export LD_LIBRARY_PATH=/path/to/Sophus/build:$LD_LIBRARY_PATH
      

二、基本使用

1. 包含头文件
#include <iostream>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include "sophus/so3.h"
#include "sophus/se3.hpp"
2. SO(3) 操作(三维旋转)
  • 构造函数

    // 从旋转矩阵构造
    Eigen::Matrix3d R = Eigen::AngleAxisd(M_PI / 2, Eigen::Vector3d(0, 0, 1)).toRotationMatrix();
    Sophus::SO3d SO3_R(R);
    
    // 从四元数构造
    Eigen::Quaterniond q(R);
    Sophus::SO3d SO3_q(q);
    
    // 从旋转向量(轴角)构造(注意:不是直接使用旋转向量的三个坐标值)
    // 正确的做法是通过指数映射
    Eigen::Vector3d so3 = Sophus::SO3d::log(SO3_R);  // 获取李代数(旋转向量)
    Sophus::SO3d SO3_exp = Sophus::SO3d::exp(so3);    // 通过指数映射构造 SO(3)
    
  • 输出

    std::cout << "SO(3) from matrix: " << SO3_R.log().transpose() << std::endl;
    std::cout << "SO(3) from quaternion: " << SO3_q.log().transpose() << std::endl;
    
  • 李代数与李群的转换

    // 李群到李代数(对数映射)
    Eigen::Vector3d so3 = SO3_R.log();
    
    // 李代数到李群(指数映射)
    Sophus::SO3d SO3_exp = Sophus::SO3d::exp(so3);
    
3. SE(3) 操作(三维刚体变换)
  • 构造函数

    // 从旋转矩阵和平移向量构造
    Eigen::Vector3d t(1, 0, 0);  // 平移向量
    Sophus::SE3d SE3_Rt(R, t);
    
    // 从四元数和平移向量构造
    Sophus::SE3d SE3_qt(q, t);
    
    // 从 4x4 变换矩阵构造
    Eigen::Matrix4d T = Eigen::Matrix4d::Identity();
    T.block<3, 3>(0, 0) = R;
    T.block<3, 1>(0, 3) = t;
    Sophus::SE3d SE3_T(T);
    
  • 输出

    std::cout << "SE(3) from matrix and translation: " << SE3_Rt.log().transpose() << std::endl;
    std::cout << "SE(3) from quaternion and translation: " << SE3_qt.log().transpose() << std::endl;
    
  • 李代数与李群的转换

    // 李群到李代数(对数映射)
    Eigen::Matrix<double, 6, 1> se3 = SE3_Rt.log();
    
    // 李代数到李群(指数映射)
    Sophus::SE3d SE3_exp = Sophus::SE3d::exp(se3);
    

三、高级功能

1. 位姿插值
  • SO(3) 插值(Slerp)

    double t = 0.5;  // 插值比例
    Sophus::SO3d SO3_interp = Sophus::SO3d::slerp(t, SO3_R, SO3_q);
    
  • SE(3) 插值(旋转用 Slerp,平移用 Lerp)

    Sophus::SE3d SE3_interp = Sophus::SE3d::lerp(t, SE3_Rt, SE3_qt);
    
2. 增量扰动模型
// SO(3) 增量扰动
Eigen::Vector3d update_so3(1e-4, 0, 0);  // 扰动量
Sophus::SO3d SO3_updated = Sophus::SO3d::exp(update_so3) * SO3_R;

// SE(3) 增量扰动
Eigen::Matrix<double, 6, 1> update_se3;
update_se3.setZero();
update_se3(1, 0) = 1e-4;  // 对平移的第二维增加扰动
Sophus::SE3d SE3_updated = Sophus::SE3d::exp(update_se3) * SE3_Rt;

四、实际应用示例

1. 使用 Sophus 进行 Bundle Adjustment(光束法平差)

在 Bundle Adjustment 中,需要优化相机位姿(SE(3))和三维点坐标。Sophus 可以方便地表示相机位姿,并通过李代数进行增量更新。

2. SLAM 中的位姿图优化

在 SLAM 中,位姿图优化是一个关键步骤。Sophus 可以用于表示位姿节点,并通过李代数进行误差计算和优化。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老黄编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值