eigen——旋转向量、旋转矩阵、四元数、欧拉角的初始化及相互转化

//
// Created by iqr on 2019/11/6.
//

#include <iostream>
#include <cmath>
#include <Eigen/Core>
#include <Eigen/Dense>

using namespace std;
#define sqr_2 sqrt(2)

int main(int argc, char **argv)
{
    double theta = M_PI / 4;
    Eigen::AngleAxisd rotation_vec(theta, Eigen::Vector3d(0, 0, 1));     // 旋转向量
    Eigen::Matrix3d rotation_mat;
    rotation_mat<< sqr_2/2, sqr_2/(-2), 0,
                   sqr_2/2, sqr_2/2,    0,
                   0,       0,          1;    // 旋转矩阵
    Eigen::Quaterniond rotation_quat(cos(theta/2), 0, 0, sin(theta/2));  // 四元数
    Eigen::Vector3d rotation_eulerAngle(theta, 0, 0);    // 欧拉角

    Eigen::AngleAxisd vec;  // 旋转向量
    Eigen::Matrix3d mat;    // 旋转矩阵
    Eigen::Quaterniond quat;// 四元数
    Eigen::Vector3d euler;  // 欧拉角
    // 旋转向量转其他
    printf(">>> 旋转向量转其他形式:\n");
    mat = rotation_vec.matrix();
    cout << "旋转矩阵=\n" << mat << endl;
    quat = rotation_vec;
    cout << "四元数: (x, y, z, w)=(" << quat.x() << "," << quat.y() << "," << quat.z() << "," << quat.w() << ")" << endl;
    euler = rotation_vec.matrix().eulerAngles(2,1,0);
    cout << "欧拉角: (roll, pitch, yaw)=" << euler << endl << endl;

    // 旋转矩阵转其他
    printf(">>> 旋转矩阵转其他形式:\n");
    vec = rotation_mat;
    cout << "旋转向量: axis=" << vec.axis() << "\nangle=" << vec.angle() << endl;
    quat = rotation_mat;
    cout << "四元数: (x, y, z, w)=(" << quat.x() << "," << quat.y() << "," << quat.z() << "," << quat.w() << ")" << endl;
    euler = rotation_mat.eulerAngles(2,1,0);
    cout << "欧拉角: (roll, pitch, yaw)=" << euler << endl << endl;

    // 四元数转其他
    printf(">>> 四元数转其他形式:\n");
    vec = rotation_quat;
    cout << "旋转向量: axis=" << vec.axis() << "\nangle=" << vec.angle() << endl;
    mat = rotation_quat.toRotationMatrix();
    cout << "旋转矩阵=\n" << mat << endl;
    euler = mat.eulerAngles(2,1,0);
    cout << "欧拉角: (yaw, pitch, roll)=" << euler << endl << endl;

    // 欧拉角转其他
    printf(">>> 欧拉角转其他形式:\n");
    Eigen::AngleAxisd rollAngle(Eigen::AngleAxisd(rotation_eulerAngle(2),Eigen::Vector3d::UnitX()));
    Eigen::AngleAxisd pitchAngle(Eigen::AngleAxisd(rotation_eulerAngle(1),Eigen::Vector3d::UnitY()));
    Eigen::AngleAxisd yawAngle(Eigen::AngleAxisd(rotation_eulerAngle(0),Eigen::Vector3d::UnitZ()));
    vec = yawAngle * pitchAngle * rollAngle;
    cout << "旋转向量: axis=" << vec.axis() << "\nangle=" << vec.angle() << endl;
    mat = yawAngle * pitchAngle * rollAngle;
    cout << "旋转矩阵=\n" << mat << endl;
    quat = yawAngle * pitchAngle * rollAngle;
    cout << "四元数: (x, y, z, w)=(" << quat.x() << "," << quat.y() << "," << quat.z() << "," << quat.w() << ")" << endl << endl;

    // 欧式变换矩阵
    printf(">>> 旋转向量+平移向量=欧式变换矩阵");
    Eigen::Vector3d translation(1, 2, 3);
    Eigen::Isometry3d T = Eigen::Isometry3d::Identity();    // 虽然称为3d,实质上是4*4的矩阵 齐次坐标
    T.rotate (rotation_mat);                                // 按照rotation_vec进行旋转
    T.pretranslate (translation);     // 把平移向量设成(1,2,3)
    cout << "欧式变换矩阵=\n" << T.matrix() << endl << endl;

    // 欧式变换矩阵分解
    printf(">>> 欧式变换矩阵分解为:旋转向量+平移向量");
    mat = T.rotation();
    translation = T.translation();
    cout << "旋转矩阵=\n" << mat << endl;
    cout << "平移矩阵=\n" << translation << endl << endl;
}

 

### 欧拉角旋转矩阵四元数的关系 欧拉角旋转矩阵以及四元数都是用来描述三维空间中的旋转的不同方式。每种表示方法都有各自的优点,在不同的应用场景中有特定的选择。 #### 欧拉角旋转矩阵换 当给定一组按照一定顺序(比如Z-X-Z, X-Y'-X''等)定义的三个角度θx, θy 和 θz作为欧拉角时,可以构建相应的旋转矩阵R: \[ R = R_z(\theta_z) \cdot R_y(\theta_y) \cdot R_x(\theta_x)\] 其中\(R_x\), \(R_y\) 和 \(R_z\)分别代表绕着各自轴线的角度旋转变换[^2]。 对于具体的计算过程来说,如果已知某物体相对于固定参照系的姿态由这三个连续动组成,则可通过上述公式得到该姿态所对应的旋转矩阵形式。 #### 四元数旋转矩阵间的相互转化 四元数q=(w,x,y,z),这里w是实部而(x,y,z)构成虚部向量v;它同样能够表达一个刚体在三维空间内的定向状态。从四元数成标准3×3阶正交阵(即旋转矩阵): \[ R=\begin{bmatrix} 1-2(y^{2}+z^{2}) & 2(xy-wz) & 2(xz+wy) \\ 2(xy+wz) & 1-2(x^{2}+z^{2})& 2(yz-wx)\\ 2(xz-wy) & 2(yz+wx) & 1-2(x^{2}+y^{2}) \end{bmatrix} \] 反之亦然,可以从任意有效的旋转矩阵推导出唯一的单位长度四元数来表示相同的旋转操作[^4]。 #### 使用Eigen库实现换 以C++编程环境为例,利用流行的线性代数模板库——Eigen,可以直接调用内置函数完成这些变换工作。例如要将四元数对象`Quaterniond q(w,x,y,z)`转化旋转矩阵: ```cpp #include <iostream> #include <Eigen/Dense> using namespace Eigen; int main(){ Quaterniond q(0.7071, 0, 0.7071, 0); // 定义一个四元数 Matrix3d m; m=q.toRotationMatrix(); // 将其换为旋转矩阵m } ``` 以上就是关于如何理解并处理这三种常用的空间旋转表述之间联系的主要内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值