当前位置:   article > 正文

持之以恒(一)位姿转换:姿态 / 四元数 / 旋转矩阵 / 欧拉角 及 位姿矩阵_相机位姿旋转向量转欧拉角

相机位姿旋转向量转欧拉角

1. 简介

1.1 位姿的几种表示形式

姿态的几种表示形式,姿态角四元数欧拉角旋转矩阵位姿矩阵

姿态说明表示形式Eigen
姿态角指的是机体坐标系与地理坐标系的夹角,即旋转向量rx,ry,rzEigen::Vector3f(Degrees)
四元数四元素不存在万向节死锁问题、利用球面插值可以获得均匀的转速w,x,y,zEigen::Quaternionf
欧拉角绕机体坐标系三个轴旋转的角度
经典欧拉角ZXZ系列 :ZXZ, XYX, YZY, ZYZ, XZX, YXY
泰特布莱恩角ZYX系列:XYZ, YZX, ZXY, XZY, ZYX, YXZ
ex,ey,ez,sequence
RPY欧拉角的变种,滚转角、俯仰角、偏航角
与ZYX系列对应为  :YPR,RYP,PRY,PYR,RPY,YRP
ex,ey,ez,sequence
旋转矩阵3×3Eigen::Matrix3f
位姿矩阵4×4Eigen::Matrix4f

注意:坐标系的定义与旋转矩阵是配套的,禁止混用。Eigen 内部的计算均为弧度值。

1.2 姿态转换在线工具

  1. 3D Rotation Converter:https://www.andre-gaschler.com/rotationconverter/
  2. Rotation Conversion Tool: https://danceswithcode.net/engineeringnotes/quaternions/conversion_tool.html
  3. 四元数在线可视化转换网站: https://quaternions.online/

2. 位姿转换接口

欧拉角分类

enum EulerAngleSequence{
    //经典欧拉角ZXZ系列
    ZXZ, XYX, YZY, ZYZ, XZX, YXY,
    //泰特布莱恩角ZYX系列
    XYZ, YZX, ZXY, XZY, ZYX, YXZ,
    //固定角
    YPR, RYP, PRY, PYR, RPY, YRP
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.1 旋转向量与四元数`

旋转向量 转 四元数

  • 旋转向量转四元数公式
/* rx,ry,rz 分别转化为弧度值
 * w_abs = sqrt(rx^2 + ry^2 + rz^2);
 * qw = cos(w_abs / 2)
 * qx = sin(w_abs / 2) * rx / w_abs
 * qy = sin(w_abs / 2) * ry / w_abs
 * qz = sin(w_abs / 2) * rz / w_abs
 */ 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

法1:使用Eigen库

Eigen::Quaternionf RotateVectortoQuaternionf(const Eigen::Vector3f& rotateVec) {
    Eigen::Vector3f vecfDegree = Eigen::Vector3f(rotateVec[0] * PI / 180, 
    											 rotateVec[1] * PI / 180, 
    											 rotateVec[2] * PI / 180);
    float w_abs = sqrt(vecfDegree[0] * vecfDegree[0] + 
    				   vecfDegree[1] * vecfDegree[1] + 
    				   vecfDegree[2] * vecfDegree[2]);
    return Eigen::Quaternionf(cos(w_abs / 2),
                      		  sin(w_abs / 2) * vecfDegree[0] / w_abs,
                       	      sin(w_abs / 2) * vecfDegree[1] / w_abs,
                              sin(w_abs / 2) * vecfDegree[2] / w_abs);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

法2:使用公式

Eigen::Quaternionf RotateVectortoQuaternionf(const float rx, const float ry, const float rz) {
    float rxx = rx * PI / 180;
    float ryy = ry * PI / 180;
    float rzz = rz * PI / 180;

    float w_abs = sqrt(rxx * rxx + ryy * ryy + rzz * rzz);
    return Eigen::Quaternionf(cos(w_abs / 2),
                       	      sin(w_abs / 2) * rxx / w_abs,
                              sin(w_abs / 2) * ryy / w_abs,
                              sin(w_abs / 2) * rzz / w_abs);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

四元数 转 旋转向量

  • 四元数转旋转向量公式
/* qx,qy,qz,qw 
 * angle = acos(qw) * 2
 * rx = qx / sin(angle /2) * angle * 180 / PI
 * ry = qy / sin(angle /2) * angle * 180 / PI
 * rz = qz / sin(angle /2) * angle * 180 / PI
 */ 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

法1:使用Eigen库

Eigen::Vector3f QuaterniontoRotateVector(const Eigen::Quaternionf&  quaternion) {
    float angle = acos(quaternion.w()) * 2;
    float x = quaternion.x() / sin(angle / 2);
    float y = quaternion.y() / sin(angle / 2);
    float z = quaternion.z() / sin(angle / 2);
    return Eigen::Vector3f(angle * x * 180 / M_PI,
                           angle * y * 180 / M_PI,
                           angle * z * 180 / M_PI);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

法2:使用公式

Eigen::Vector3f QuaterniontoRotateVector(const float qx, const float qy, 
                                         const float qz, const float qw) {
    float angle = acos(qw) * 2;
    float x = qx / sin(angle / 2);
    float y = qy / sin(angle / 2);
    float z = qz / sin(angle / 2);
    return Eigen::Vector3f(angle * x * 180 / M_PI,
                           angle * y * 180 / M_PI,
                           angle * z * 180 / M_PI);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.2 旋转矩阵与四元数

旋转矩阵 转 四元数

法1:使用Eigen库

Eigen::Quaternionf RotateMattoQuaternion(const Eigen::Matrix3f& rotateMat) {
    return Eigen::Quaternionf(rotateMat);
}
  • 1
  • 2
  • 3

四元数 转 旋转矩阵

2.3 欧拉角与旋转矩阵

欧拉角 转 旋转矩阵

法1:使用Eigen库

Eigen::Matrix3f EulerAngletoRotateMat(const Eigen::Vector3f& eulerAngle,
                                      EulerAngleSequence sequence) {
    Eigen::AngleAxis<float> Rx = Eigen::AngleAxisf(eulerAngle[0], Eigen::Vector3f::UnitX());
    Eigen::AngleAxis<float> Ry = Eigen::AngleAxisf(eulerAngle[1], Eigen::Vector3f::UnitY());
    Eigen::AngleAxis<float> Rz = Eigen::AngleAxisf(eulerAngle[2], Eigen::Vector3f::UnitZ());
    Eigen::Matrix3f rotate_mat = Eigen::Matrix3f::Zero();
    switch (sequence) {
    default:
    case XYZ:
    case YPR:
        rotate_mat = Eigen::Matrix3f(Rx * Ry * Rz);
        break;
    case YZX:
    case RYP:
        rotate_mat = Eigen::Matrix3f(Ry * Rz * Rx);
        break;
    case ZXY:
    case PRY:
        rotate_mat = Eigen::Matrix3f(Rz * Rx * Ry);
        break;
    case ZXY:
    case PRY:
        rotate_mat = Eigen::Matrix3f(Rz * Rx * Ry);
        break;
    case XZY:
    case PYR:
        rotate_mat = Eigen::Matrix3f(Rx * Rz * Ry);
        break;
    case ZYX:
    case RPY:
        rotate_mat = Eigen::Matrix3f(Rz * Ry * Rx);
        break;    
    case YXZ:
    case YRP:
        rotate_mat = Eigen::Matrix3f(Ry * Rx * Rz);
        break;
    case YZY:
        rotate_mat = Eigen::Matrix3f(
            Eigen::AngleAxisf(eulerAngle[0], Eigen::Vector3f::UnitY()) *
            Eigen::AngleAxisf(eulerAngle[1], Eigen::Vector3f::UnitZ()) *
            Eigen::AngleAxisf(eulerAngle[2], Eigen::Vector3f::UnitY()));
        break;      
    case ZYZ:
        rotate_mat = Eigen::Matrix3f(
            Eigen::AngleAxisf(eulerAngle[0], Eigen::Vector3f::UnitZ()) *
            Eigen::AngleAxisf(eulerAngle[1], Eigen::Vector3f::UnitY()) *
            Eigen::AngleAxisf(eulerAngle[2], Eigen::Vector3f::UnitZ()));
        break; 
     case XZX:
        rotate_mat = Eigen::Matrix3f(
            Eigen::AngleAxisf(eulerAngle[0], Eigen::Vector3f::UnitX()) *
            Eigen::AngleAxisf(eulerAngle[1], Eigen::Vector3f::UnitZ()) *
            Eigen::AngleAxisf(eulerAngle[2], Eigen::Vector3f::UnitX()));
        break;  
    case ZXZ:
        rotate_mat = Eigen::Matrix3f(
            Eigen::AngleAxisf(eulerAngle[0], Eigen::Vector3f::UnitZ()) *
            Eigen::AngleAxisf(eulerAngle[1], Eigen::Vector3f::UnitX()) *
            Eigen::AngleAxisf(eulerAngle[2], Eigen::Vector3f::UnitZ()));
        break;
		case XYX:
        rotate_mat = Eigen::Matrix3f(
            Eigen::AngleAxisf(eulerAngle[0], Eigen::Vector3f::UnitX()) *
            Eigen::AngleAxisf(eulerAngle[1], Eigen::Vector3f::UnitY()) *
            Eigen::AngleAxisf(eulerAngle[2], Eigen::Vector3f::UnitX()));
        break;
		case YXY:
        rotate_mat = Eigen::Matrix3f(
            Eigen::AngleAxisf(eulerAngle[0], Eigen::Vector3f::UnitY()) *
            Eigen::AngleAxisf(eulerAngle[1], Eigen::Vector3f::UnitX()) *
            Eigen::AngleAxisf(eulerAngle[2], Eigen::Vector3f::UnitY()));
        break;
		}
    return Eigen::Quaternionf(rotate_mat);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

2.4 欧拉角与四元数

欧拉角 转 四元数

法1:使用Eigen库

Eigen::Quaternionf EulerAngletoRotateMat(const Eigen::Vector3f& eulerAngle,
                                         EulerAngleSequence sequence) {
    Eigen::Matrix3f rotate_mat = EulerAngletoQuaternion(eulerAngle, sequence);
    return Eigen::Quaternionf(rotate_mat);
}
  • 1
  • 2
  • 3
  • 4
  • 5

参考文献:

  1. 三维旋转之欧拉角: https://zhuanlan.zhihu.com/p/626258420
  2. 欧拉角(Euler Angle): https://blog.csdn.net/thefist11cc/article/details/126595776

3. 工业机器人应用

3.1 不同厂家协作机器人的位姿表示形式

厂家位姿形式Eigen
ABB四元数Eigen::Quaternionf
FANUC欧拉角 ZYXEigen::Matrix3f(Eigen::AngleAxisf(rx, Eigen::Vector3f::UnitX()),
        Eigen::AngleAxisf(ry, Eigen::Vector3f::UnitY()),
        Eigen::AngleAxisf(rz, Eigen::Vector3f::UnitZ()))
UR欧拉角 ZYXEigen::Vector3f(Degrees)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/646205
推荐阅读
相关标签
  

闽ICP备14008679号