【代码】四元数、RPY、旋转矩阵、so3之间的转换

 需要使用Eigen库


using Vec3 = Eigen::Matrix<double, 3, 1>;
using Quat = Eigen::Matrix<double, 4, 1>;
using Mat3 = Eigen::Matrix<double, 3, 3>;



namespace MyMathTool{

enum class CoordinateAxis {X, Y, Z};

Mat3 CoordinateRotation(CoordinateAxis axis, double theta){
    
    double s = std::sin(theta);
    double c = std::cos(theta);

    Mat3 R;

    if (axis == MyMathTool::CoordinateAxis::X) {
        R << 1, 0, 0, 0, c, s, 0, -s, c;
    } 
    else if (axis == MyMathTool::CoordinateAxis::Y) {
        R << c, 0, -s, 0, 1, 0, s, 0, c;
    } 
    else if (axis == MyMathTool::CoordinateAxis::Z) {
        R << c, s, 0, -s, c, 0, 0, 0, 1;
    }

    return R;
}


double square(const double a){return a*a;}


Mat3 quaternionToRotationMatrix(const Quat& q){
      
  double e0 = q(0);
  double e1 = q(1);
  double e2 = q(2);
  double e3 = q(3);

  Mat3 R;

  R << 1 - 2 * (e2 * e2 + e3 * e3), 2 * (e1 * e2 - e0 * e3),
      2 * (e1 * e3 + e0 * e2), 2 * (e1 * e2 + e0 * e3),
      1 - 2 * (e1 * e1 + e3 * e3), 2 * (e2 * e3 - e0 * e1),
      2 * (e1 * e3 - e0 * e2), 2 * (e2 * e3 + e0 * e1),
      1 - 2 * (e1 * e1 + e2 * e2);
  R.transposeInPlace();
  return R;
}


Vec3 quatToRPY(const Quat& q){
        
    Vec3 rpy;
    double as = std::min(-2. * (q[1] * q[3] - q[0] * q[2]), .99999);
    rpy(2) =    std::atan2(2 * (q[1] * q[2] + q[0] * q[3]),
                square(q[0]) + square(q[1]) - square(q[2]) - square(q[3]));
    rpy(1) = std::asin(as);
    rpy(0) =
    std::atan2(2 * (q[2] * q[3] + q[0] * q[1]),
                square(q[0]) - square(q[1]) - square(q[2]) + square(q[3]));
    return rpy;
}



Vec3 quaternionToso3(const Quat quat){
      
    Vec3 so3;
    // Vec3 Zero;  Zero.setZero();
    so3[0] = quat[1];
    so3[1] = quat[2];
    so3[2] = quat[3];

    double theta =
    2.0 * asin(sqrt(so3[0] * so3[0] + so3[1] * so3[1] + so3[2] * so3[2]));

    if (fabs(theta) < 0.0000001) {
        so3.setZero();
        return so3;
    }
    so3 /= sin(theta / 2.0);
    so3 *= theta;

    return so3;
}

Quat so3ToQuat(const Vec3& so3){
     
    Quat quat;

    double theta = sqrt(so3[0] * so3[0] + so3[1] * so3[1] + so3[2] * so3[2]);

    if (fabs(theta) < 1.e-6) {
        quat.setZero();
        quat[0] = 1.;
        return quat;
    }
    quat[0] = cos(theta / 2.);
    quat[1] = so3[0] / theta * sin(theta / 2.);
    quat[2] = so3[1] / theta * sin(theta / 2.);
    quat[3] = so3[2] / theta * sin(theta / 2.);
    return quat;
}

Quat rpyToQuat(const Vec3& rpy){
        
    Mat3 R = rpyToRotMat(rpy);
    Quat Q = rotationMatrixToQuaternion(R);

    return Q;
}

Quat rotationMatrixToQuaternion(const Mat3& r1){
    
    Quat q;
    Mat3 r = r1.transpose();
    double tr = r.trace();

    if(tr > 0.0){
        double S = sqrt(tr + 1.0) * 2.0;
        q(0) = 0.25 * S;
        q(1) = (r(2, 1) - r(1, 2)) / S;
        q(2) = (r(0, 2) - r(2, 0)) / S;
        q(3) = (r(1, 0) - r(0, 1)) / S;       
    }
    else if ((r(0, 0) > r(1, 1)) && (r(0, 0) > r(2, 2))) {
        double S = sqrt(1.0 + r(0, 0) - r(1, 1) - r(2, 2)) * 2.0;
        q(0) = (r(2, 1) - r(1, 2)) / S;
        q(1) = 0.25 * S;
        q(2) = (r(0, 1) + r(1, 0)) / S;
        q(3) = (r(0, 2) + r(2, 0)) / S;
    } 
    else if (r(1, 1) > r(2, 2)) {
        double S = sqrt(1.0 + r(1, 1) - r(0, 0) - r(2, 2)) * 2.0;
        q(0) = (r(0, 2) - r(2, 0)) / S;
        q(1) = (r(0, 1) + r(1, 0)) / S;
        q(2) = 0.25 * S;
        q(3) = (r(1, 2) + r(2, 1)) / S;
    } else {
        double S = sqrt(1.0 + r(2, 2) - r(0, 0) - r(1, 1)) * 2.0;
        q(0) = (r(1, 0) - r(0, 1)) / S;
        q(1) = (r(0, 2) + r(2, 0)) / S;
        q(2) = (r(1, 2) + r(2, 1)) / S;
        q(3) = 0.25 * S;
    }

    return q;
}
   
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 欧拉角、四元数旋转矩阵和轴角都是表示三维旋的不同方式。 欧拉角是由三个轴角组成,按照顺序分别表示绕x轴旋的角度、绕y轴旋的角度、绕z轴旋的角度。 四元数是由四个实数组成,表示旋的方向和角度。 旋转矩阵是由3*3的实数组成的矩阵,表示旋的线性变换。 轴角就是由一个单位向量和一个角度组成,表示绕着该单位向量旋角度的意思。 它们之间可以相互转换。具体方法需要根据需要选择相应的公式进行转换. ### 回答2: 欧拉角、四元数旋转矩阵和轴角是用于表示物体在三维空间中旋的常见方法。它们可以相互之间进行转换。 首先,欧拉角是使用三个旋角度来描述物体的旋。通常使用的欧拉角包括俯仰角(pitch angle)、偏航角(yaw angle)和滚角(roll angle)。欧拉角的转换通常涉及将欧拉角转换旋转矩阵四元数,并且转换顺序也很重要。 其次,四元数是一种用于表示旋的数学工具,可以使用具有四个实数部分的向量进行表示。四元数转换通常涉及将四元数转换旋转矩阵或欧拉角,或者将旋转矩阵或欧拉角转换四元数旋转矩阵是一个3x3矩阵,用于表示物体的旋。它是通过将欧拉角或四元数转换矩阵来实现的,也可以将矩阵转换为欧拉角或四元数。 轴角是用于表示旋的方法之一。它由一个向量和一个表示旋角度的标量组成。轴角可以通过将轴角转换旋转矩阵来实现,也可以通过将旋转矩阵转换为轴角来实现。使用轴角进行旋时,常用的轴包括x轴、y轴和z轴。 总结起来,欧拉角、四元数旋转矩阵和轴角可以相互转换来表示物体的旋。这些转换过程在计算机图形学、机器人学和游戏开发等领域经常被使用。理解它们之间转换关系可以帮助我们更好地理解和应用旋的概念。 ### 回答3: 欧拉角、四元数旋转矩阵、轴角都是用于描述物体在三维空间中的旋变换的方法,它们之间可以相互转换。 欧拉角是指通过绕着三个坐标轴的旋来实现的旋变换。通常使用三个连续的旋角度来表示,在航空航天领域经常使用俯仰角、偏航角和滚角来描述。但欧拉角存在万向锁问题,即在某些情况下会导致旋变换不唯一。 四元数是一种四维复数,可以用一个实部和三个虚部来表示。它们可以直接表示旋变换,并且不存在万向锁问题。通过四元数的乘法运算可以实现旋变换的组合。同时,由于四元数是一个四维向量,所以它们的存储空间比旋转矩阵小。 旋转矩阵是一个3x3的矩阵,用于表示旋变换。在旋转矩阵中,每一列表示一个旋后的坐标轴方向。旋转矩阵可以通过将三个坐标轴绕着相应的角度进行旋得到。但旋转矩阵存在正交性约束,即必须是正交矩阵,并且行列式为1,不满足时需要进行正则化处理。 轴角表示旋轴和旋角度的方法。它将旋变换化为绕着一个轴旋一定角度的方式来描述。轴角与旋转矩阵之间转换比较直观,可以通过旋转矩阵的特征向量和特征值得到旋轴和旋角度。但轴角存在方向的不唯一性,即旋轴可以有两个相反的方向与同一个旋变换对应。 以上是欧拉角、四元数旋转矩阵、轴角之间转换方法及特点的简介。它们在三维空间中描述旋变换时各有优劣,可以根据具体需求选择合适的方法。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值