SLAM-Eigen库

使用Eigen库的原因

开源线性代数库
矩阵运算,表达刚体旋转

三维空间中刚体的旋转表示

1.旋转矩阵

R和t组成齐次变换矩阵T,表达连续的欧式变换
R的逆矩阵表示相反的旋转

扩展:欧几里得坐标系(即欧式坐标)

定义了内积,角,距离。三维坐标系下的外积
内积:
在这里插入图片描述
几何概念,角:
在这里插入图片描述在这里插入图片描述
距离:
d(x,y)=||x-y||

三维坐标系下的外积:
齐次坐标下,向量a x b表示与a,b都垂直的向量

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

扩展:齐次坐标在欧式空间的好处

1.方便表达点在线上或平面上
直线 l 用ax + by + c = 0表示
在这里插入图片描述
p的齐次坐标(x,y,1)
在这里插入图片描述
面的原理同上
2.方便表达直线和交点
在齐次坐标下,可以用两个点 p, q 的齐次坐标叉乘结果来表达一条直线 l,也就是
l = p x q
也可以使用两条直线 l, m 的叉乘表示他们的交点 x
x = l x m
在这里插入图片描述3.方便区分点和向量
(1)从普通坐标转换成齐次坐标时,
如果(x,y,z)是个点,则变为(x,y,z,1);
另:如果是点(x,y,z,0)则表示无穷远处的点
如果(x,y,z)是个向量,则变为(x,y,z,0)

(2)从齐次坐标转换成普通坐标时 ,
如果是(x,y,z,1),则知道它是个点,变成(x,y,z);
如果是(x,y,z,0),则知道它是个向量,仍然变成(x,y,z)

4.更优美的表达欧式变换
将平移的加法变成矩阵相乘
当面对连续的旋转平移,就体现了优势,变成了连续的矩阵相乘

2.四元数

w+xi+yj+zk 即(w,x,y,z)

单位四元数才能描述旋转,使用前要归一化:q.normalize( )

Quaterniond (1, 0, 0, 0) Eigen里四元数赋值顺序是w,x,y,z,但实际内部存储顺序是x,y,z,w,输出格式也是x,y,z,w;

3.旋转向量

一个轴,一个角描述旋转,360度一圈,所以有奇异性
旋转向量到旋转矩阵有罗德里格斯公式,opencv和MATLAB有函数实现
旋转向量和旋转矩阵的转换对应于李代数和李群的映射

4.欧拉角

yaw,pitch,roll轴
俯仰角正负90度,一次和第三次旋转共轴,丢失一个自由度
三维旋转需要四个变量

Eigen库的安装与基础

安装:sudo apt-get install libeigen3-dev

1.Eigen库只有头文件,没有.so,.a等二进制库文件
在CMakeLists.txt里只需要添加头文件路径,不需要target_link_libraries将程序链接到库

#添加Eigen库
find_package(Eigen3)
#添加Eigen头文件
include_directories(${EIGEN3_INCLUDE_DIR})

2.转换图
在这里插入图片描述3.基本语法
Eigen库中的向量是特殊的矩阵,维度为1

Matrix3d H = Matrix3d::Zero(); //元素类型为double,大小为3*3
Vector3d b = Vector3d::Zero(); //默认为列向量

构造欧式变换矩阵:

Eigen::Isometry3d T = Eigen::Isometry3d::Identity();// 虽然称为3d,实际是4*4
T.matrix(): 1 0 0 0
            0 1 0 0
            0 0 1 0
            0 0 0 1
T.rotate ( rotation_vector );// 按照rotation_vector进行旋转
T.pretranslate ( Eigen::Vector3d ( 1,3,4 ) );// 把平移向量设成(1,3,4)

旋转矩阵转欧拉角

// 0,1,2代表roll,pitch,yaw
Eigen::Matrix3d rotation_matrix;
Eigen::Vector3d eulerAngle=rotation_matrix.eulerAngles(0,1,2);

四元数转欧拉角

  Eigen::Quaterniond quaternion_raw(
    msg.pose.pose.orientation.w, msg.pose.pose.orientation.x, msg.pose.pose.orientation.y,
    msg.pose.pose.orientation.z);
  Eigen::Vector3d eulerAngle = quaternion_raw.matrix().eulerAngles(0, 1, 2);
  改变yaw轴旋转方向
  double yaw;
  yaw = M_PI_2 - eulerAngle(2);
  while (yaw > M_PI) {
    yaw -= 2 * M_PI;
  }
  while (yaw < -M_PI) {
    yaw += 2 * M_PI;
  }

欧拉角转四元数并归一化

  Eigen::AngleAxisd rollAngle(Eigen::AngleAxisd(eulerAngle(0), Eigen::Vector3d::UnitX()));
  Eigen::AngleAxisd pitchAngle(Eigen::AngleAxisd(eulerAngle(1), Eigen::Vector3d::UnitY()));
  Eigen::AngleAxisd yawAngle(Eigen::AngleAxisd(yaw, Eigen::Vector3d::UnitZ()));
  Eigen::Quaterniond quaternion_cal;
  quaternion_cal = (yawAngle * pitchAngle * rollAngle).normalized();

计算示例

  Eigen::Quaterniond q_l_t_n;
  q_l_t_n.x() = -0.0021053214176469;
  q_l_t_n.y() = -0.000315898914674642;
  q_l_t_n.z() = -0.419858669107839;
  q_l_t_n.w() = 0.907587001782528;
  Eigen::Vector3d t_l_t_n =
    Eigen::Vector3d(336479.74262972595, 3446927.073586678, 10.751341438890508);

  Eigen::Quaterniond q_l = q_l_t_n.inverse() * quaternion_cal;
  Eigen::Vector3d t_l =
    q_l_t_n.inverse().toRotationMatrix() *
    (Eigen::Vector3d(msg.pose.pose.position.x, msg.pose.pose.position.y, msg.pose.pose.position.z) -
     t_l_t_n);

更多转换:
https://www.cnblogs.com/long5683/p/14373627.html#23-%E6%97%8B%E8%BD%AC%E7%9F%A9%E9%98%B5%E8%BD%AC%E6%AC%A7%E6%8B%89%E8%A7%92xyz%EF%BC%8C%E5%8D%B3rpy

### 关于 ORB-SLAM2 和 Eigen 的配置 #### 安装依赖项 为了使 ORB-SLAM2 正常工作,Eigen 是必需的之一。通常情况下,在安装 ORB-SLAM2 前会先通过包管理器来获取所需的各种依赖关系,包括 Eigen 。 对于 Ubuntu 系统而言,可以通过如下命令安装必要的软件包: ```bash sudo apt-get update && sudo apt-get install -y \ cmake \ g++ \ git \ libeigen3-dev \ # 安装 Eigen ... ``` 这一步骤确保了开发环境中已经包含了最新版本的 Eigen 开发文件[^1]。 #### 修改 CMakeLists.txt 文件 在完成上述准备工作之后,需要编辑 `CMakeLists.txt` 来指定如何链接到本地已有的 Eigen 版本。具体来说就是在该文件顶部添加以下几行代码以便找到并引入 Eigen 头文件的位置: ```cmake find_package(Eigen3 REQUIRED) include_directories(${EIGEN3_INCLUDE_DIR}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEIGEN_USE_NEW_STDVECTOR -msse2") add_definitions(-D_EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT) ``` 这段设置不仅指定了 Eigen 的头文件位置还定义了一些预处理器宏用于优化性能以及防止潜在错误的发生[^2]。 #### 编译过程中的注意事项 当一切准备就绪后就可以尝试编译项目了。如果遇到任何与 Eigen 相关的问题,则可以考虑以下几个方面来进行排查: - **确认 Eigen 已正确安装**:检查 `/usr/include/eigen3/Eigen/Dense` 是否存在;如果没有则说明 Eigen 并未被正确安装。 - **验证环境变量 PATH 设置无误**:有时即使安装好了也可能因为路径问题找不到对应的文件。此时可通过打印 `$ echo $PATH` 查看当前系统的查找路径列表,并适当调整使其能够覆盖到 Eigen 所处目录。 - **查看日志信息定位确切原因**:大多数时候编译失败都会给出详细的报错提示,仔细阅读这些消息往往能帮助快速锁定问题所在之处。 #### 解决方案实例展示 针对某些特定场景下的问题,比如无法识别 Eigen 类型或是函数调用不匹配等问题,可采取下面的方法处理: 假设遇到了类似这样的警告:“warning: ‘void* memset(void*, int, size_t)’ clearing an object of non-trivial type...”,这是因为 Eigen 中部分数据结构并非 trivially copyable 导致标准内存操作可能引发异常行为。对此可以在源码里加入 `-fno-elide-constructors` 参数强制禁用对象复制省略机制从而规避此风险[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值