四元数与欧拉角

四元数与欧拉角

RPY角与Z-Y-X欧拉角

坐标系 B {B} B 相对于坐标系 A {A} A 的姿态有两种方式。第一种绕自身坐标轴旋转;第二种绕固定坐标轴旋转


绕自身坐标轴旋转

坐标系 { B } \{B\} {B} 与 坐标系 { A } \{A\} {A} 重合:坐标系 { B } \{B\} {B} 先绕自身 x x x 轴旋转 α \alpha α;坐标系 { B } \{B\} {B} 再绕自身 y y y 轴旋转 β \beta β;最后坐标系 { B } \{B\} {B} 绕自身 z z z 轴旋转 γ \gamma γ。旋转的次序很重要,注意与矩阵的对于关系。旋转矩阵如下: ( c α = c o s ( α ) , s α = s i n ( α ) ) (c\alpha = cos(\alpha), s\alpha = sin(\alpha)) (cα=cos(α),sα=sin(α))

B A Euler ( γ , β , α ) = R o t ( z , γ ) R o t ( y , β ) R o t ( x , α ) = [ c α c β c α s β s γ − s α c γ c α s β c γ + s α s γ s α c β s α s β s γ + c α c γ s α s β c γ − c α s γ − s β c β s γ c β c γ ] _{B}^{A}\textrm{Euler}(\gamma, \beta, \alpha) = Rot(z, \gamma)Rot(y, \beta)Rot(x, \alpha) = \begin{bmatrix} c\alpha c\beta & c\alpha s\beta s\gamma - s\alpha c\gamma & c\alpha s\beta c\gamma + s\alpha s\gamma\\ s\alpha c\beta & s\alpha s\beta s\gamma + c\alpha c\gamma & s\alpha s\beta c\gamma - c\alpha s\gamma\\ -s\beta & c\beta s\gamma & c\beta c\gamma \end{bmatrix} BAEuler(γ,β,α)=Rot(z,γ)Rot(y,β)Rot(x,α)=cαcβsαcβsβcαsβsγsαcγsαsβsγ+cαcγcβsγcαsβcγ+sαsγsαsβcγcαsγcβcγ


绕固定坐标轴旋转

在这里插入图片描述

另一种常用的旋转集合是横滚(roll,绕 z z z 旋转)、俯仰(pitch,绕 y y y 旋转) 和 偏转(yaw, 绕 x x x 旋转)。旋转的顺序如下:先绕 x x x 轴旋转 α \alpha α;再绕 y y y 轴旋转 β \beta β;最后绕 z z z 轴旋转 γ \gamma γ。矩阵表示如下:

B A RPY ( γ , β , α ) = R o t ( z , γ ) R o t ( y , β ) R o t ( x , α ) = [ c α c β c α s β s γ − s α c γ c α s β c γ + s α s γ s α c β s α s β s γ + c α c γ s α s β c γ − c α s γ − s β c β s γ c β c γ ] _{B}^{A}\textrm{RPY}(\gamma, \beta, \alpha) = Rot(z, \gamma)Rot(y, \beta)Rot(x, \alpha) = \begin{bmatrix} c\alpha c\beta & c\alpha s\beta s\gamma - s\alpha c\gamma & c\alpha s\beta c\gamma + s\alpha s\gamma\\ s\alpha c\beta & s\alpha s\beta s\gamma + c\alpha c\gamma & s\alpha s\beta c\gamma - c\alpha s\gamma\\ -s\beta & c\beta s\gamma & c\beta c\gamma \end{bmatrix} BARPY(γ,β,α)=Rot(z,γ)Rot(y,β)Rot(x,α)=cαcβsαcβsβcαsβsγsαcγsαsβsγ+cαcγcβsγcαsβcγ+sαsγsαsβcγcαsγcβcγ

由上述式子可知,两种描述最终得到的旋转矩阵是一样的,只是描述的方式不一样。


Axis-Angle和四元数

绕坐标轴的多次旋转可以等效为绕某一转轴旋转一定的角度。假设该转轴的方向向量为 K ⃗ = [ k x , k y , k z ] T \vec{K} = [k_x, k_y, k_z]^T K =[kx,ky,kz]T,旋转角度为 θ \theta θ,用四元数表示为 q = ( x , y , z , w ) q = (x, y, z, w) q=(x,y,z,w),其中表达式如下:

x = k x ∗ s i n θ 2 y = k y ∗ s i n θ 2 z = k z ∗ s i n θ 2 w = c o s θ 2 ⃗ \vec{\begin{matrix} x = k_x * sin{\frac{\theta}{2}}\\ y = k_y * sin{\frac{\theta}{2}}\\ z = k_z * sin{\frac{\theta}{2}}\\ w = cos{\frac{\theta}{2}} \end{matrix}} x=kxsin2θy=kysin2θz=kzsin2θw=cos2θ


且有: x 2 + y 2 + z 2 + w 2 = 1 x^2 + y^2 + z^2 + w^2 = 1 x2+y2+z2+w2=1


即四元数存储了旋转轴和旋转角的信息,它能方便的描述刚体绕任意轴的旋转。

用四元数表示旋转矩阵

R = [ 1 − 2 y 2 − 2 x 2 2 ( x y − z w ) 2 ( x z + y w ) 2 ( x y + z w ) 1 − 2 x 2 − 2 z 2 2 ( y z − x w ) 2 ( x z − y w ) 2 ( y z + x w ) 1 − 2 x 2 − 2 y 2 ] R = \begin{bmatrix} 1-2y^2-2x^2 & 2(xy - zw) & 2(xz + yw)\\ 2(xy + zw) & 1-2x^2-2z^2 & 2(yz-xw)\\ 2(xz-yw) & 2(yz+xw) & 1-2x^2-2y^2 \end{bmatrix} R=12y22x22(xy+zw)2(xzyw)2(xyzw)12x22z22(yz+xw)2(xz+yw)2(yzxw)12x22y2


用旋转矩阵表示四元数

R = [ r 11 r 12 r 13 r 21 r 22 r 23 r 31 r 32 r 33 ] R = \begin{bmatrix} r_{11} & r_{12} & r_{13} \\ r_{21} & r_{22} & r_{23} \\ r_{31} & r_{32} & r_{33} \end{bmatrix} R=r11r21r31r12r22r32r13r23r33


则对应的四元数为:
x = r 32 − r 23 4 w y = r 13 − r 31 4 w z = r 21 − r 12 4 w w = 1 2 1 + r 11 + r 22 + r 33 \begin{matrix} x = \frac{r_{32} - r_{23}}{4w}\\ y = \frac{r_{13} - r_{31}}{4w}\\ z = \frac{r_{21} - r_{12}}{4w}\\ w = \frac{1}{2}\sqrt{1 + r_{11}+r_{22}+r_{33}} \end{matrix} x=4wr32r23y=4wr13r31z=4wr21r12w=211+r11+r22+r33


四元数的操作

定义两个四元数:
q = a + u ⃗ = a + b i + c j + d k ; p = y + v ⃗ = t + x i + y j + z k \begin{matrix} q = a + \vec{u} = a + bi + cj + dk;\\ p = y + \vec{v} = t + xi + yj + zk \end{matrix} q=a+u =a+bi+cj+dk;p=y+v =t+xi+yj+zk


四元数相加

跟复数、向量和矩阵一样,两个四元数之和需要将不同的元素加起来。

p + q = a + t + u ⃗ + v ⃗ = ( a + t ) + ( b + x ) i + ( c + y ) j + ( d + z ) k p + q = a + t + \vec{u} + \vec{v} = (a+t) + (b+x)i + (c+y)j + (d+z)k p+q=a+t+u +v =(a+t)+(b+x)i+(c+y)j+(d+z)k


四元数相乘

四元数的乘法的意义类似于矩阵的乘法,可以表示旋转的合成。当有多次旋转操作时,使用四元数可以获得更高的计算效率。
p q = a t − u ⃗ ⋅ v ⃗ + a v ⃗ + t u ⃗ + u ⃗ × v ⃗ p q = ( a t − b x − c y − d z ) + ( a x + b t + c z − d y ) i + ( a y − b z + c t + d x ) j + ( a z + d t − c x + b y ) k \begin{matrix} pq = at - \vec{u} \cdot \vec{v}+a\vec{v}+t\vec{u}+\vec{u} \times \vec{v}\\ pq = (at-bx-cy-dz)+(ax+bt+cz-dy)i+(ay-bz+ct+dx)j+(az+dt-cx+by)k \end{matrix} pq=atu v +av +tu +u ×v pq=(atbxcydz)+(ax+bt+czdy)i+(aybz+ct+dx)j+(az+dtcx+by)k


由于四元数乘法的非可换性,pq并不等于qp,qp乘积的向量部分是:

q p = a t − u ⃗ ⋅ v ⃗ + a v ⃗ + t u ⃗ − u ⃗ × v ⃗ qp = at - \vec{u} \cdot \vec{v} + a\vec{v} + t\vec{u} - \vec{u} \times \vec{v} qp=atu v +av +tu u ×v


编程

四元数、欧拉数和旋转矩阵代码如下:

#pragma GCC diagnostic error "-std=c++11"
#include <iostream>
#include <Eigen/Eigen>
#include <stdlib.h>
#include <Eigen/Geometry>
#include <Eigen/Core>
#include <vector>
#include <math.h>
 
using namespace std;
using namespace Eigen;
 
Eigen::Quaterniond euler2Quaternion(const double roll, const double pitch, const double yaw)
{
    Eigen::AngleAxisd rollAngle(roll, Eigen::Vector3d::UnitZ());
    Eigen::AngleAxisd pitchAngle(pitch, Eigen::Vector3d::UnitY());
    Eigen::AngleAxisd yawAngle(yaw, Eigen::Vector3d::UnitZ());
 
    Eigen::Quaterniond q = rollAngle * pitchAngle * yawAngle;
    
    cout << "Euler2Quaternion result is:" <<endl;
    cout << "x = " << q.x() <<endl;
    cout << "y = " << q.y() <<endl;
    cout << "z = " << q.z() <<endl;
    cout << "w = " << q.w() <<endl<<endl;
    
    return q;
}

Eigen::Vector3d Quaterniond2Euler(const double x,const double y,const double z,const double w)
{
    Eigen::Quaterniond q;
    q.x() = x;
    q.y() = y;
    q.z() = z;
    q.w() = w;
    
    Eigen::Vector3d euler = q.toRotationMatrix().eulerAngles(2, 1, 0);
    
    cout << "Quaterniond2Euler result is:" <<endl;
    cout << "x = "<< euler[2] << endl ;
    cout << "y = "<< euler[1] << endl ;
    cout << "z = "<< euler[0] << endl << endl;
    
    return euler;
}

Eigen::Matrix3d Quaternion2RotationMatrix(const double x,const double y,const double z,const double w)
{
    Eigen::Quaterniond q;
    q.x() = x;
    q.y() = y;
    q.z() = z;
    q.w() = w;
    
    Eigen::Matrix3d R = q.normalized().toRotationMatrix();
    
    cout << "Quaternion2RotationMatrix result is:" <<endl;
    cout << "R = " << endl << R << endl<< endl;
    
    return R;
}

Eigen::Quaterniond rotationMatrix2Quaterniond(Eigen::Matrix3d R)
{
    Eigen::Quaterniond q = Eigen::Quaterniond(R);
    q.normalize();
    
    cout << "RotationMatrix2Quaterniond result is:" <<endl;
    cout << "x = " << q.x() <<endl;
    cout << "y = " << q.y() <<endl;
    cout << "z = " << q.z() <<endl;
    cout << "w = " << q.w() <<endl<<endl;
    
    return q;
}

Eigen::Matrix3d euler2RotationMatrix(const double roll, const double pitch, const double yaw)
{
    Eigen::AngleAxisd rollAngle(roll, Eigen::Vector3d::UnitZ());
    Eigen::AngleAxisd yawAngle(yaw, Eigen::Vector3d::UnitX());
    Eigen::AngleAxisd pitchAngle(pitch, Eigen::Vector3d::UnitY());
    
    Eigen::Quaterniond q = rollAngle * pitchAngle * yawAngle;
    Eigen::Matrix3d R = q.matrix();
    
    cout << "Euler2RotationMatrix result is:" <<endl;
    cout << "R = " << endl << R << endl<<endl;
    
    return R;
}

Eigen::Vector3d RotationMatrix2euler(Eigen::Matrix3d R)
{
    Eigen::Matrix3d m;
    m = R;
    Eigen::Vector3d euler = m.eulerAngles(0, 1, 2);
    
    cout << "RotationMatrix2euler result is:" << endl;
    cout << "x = "<< euler[2] << endl ;
    cout << "y = "<< euler[1] << endl ;
    cout << "z = "<< euler[0] << endl << endl;
    
    return euler;
}

int main(int argc, char **argv)
{
   euler2Quaternion(0,0,0);
  
   Quaterniond2Euler(0,0,0,1);

   Quaternion2RotationMatrix(0,0,0,1);

   Eigen::Vector3d x_axiz,y_axiz,z_axiz;
   x_axiz << 1,0,0;
   y_axiz << 0,1,0;
   z_axiz << 0,0,1;
   Eigen::Matrix3d R;
   R << x_axiz,y_axiz,z_axiz;
   rotationMatrix2Quaterniond(R);
	
   euler2RotationMatrix(0,0,0);
	
   RotationMatrix2euler(R);
   
   cout << "All transform is done!" << endl;
}

输入如下指令:`g++ -std=c++11 test.cpp -o test -I /usr/include/eigen3/`
结果如下: ``` Euler2Quaternion result is: x = 0 y = 0 z = 0 w = 1

Quaterniond2Euler result is:
x = 0
y = -0
z = 0

Quaternion2RotationMatrix result is:
R =
1 0 0
0 1 0
0 0 1

RotationMatrix2Quaterniond result is:
x = 0
y = 0
z = 0
w = 1

Euler2RotationMatrix result is:
R =
1 0 0
0 1 0
0 0 1

RotationMatrix2euler result is:
x = -0
y = 0
z = -0

All transform is done!

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值