草庐IT

欧拉角,旋转矩阵和四元数之间的转换关系

赵斌韬 2023-12-14 原文

引言

因为关于欧拉角、旋转矩阵、四元数之间的转换关系有网上有很多人在讲,但是都比较乱,我专门自己梳理了一下。

基本概念

两个坐标系之间的转换关系的表示方法分别为欧拉角、旋转矩阵和四元数。

欧拉角转旋转矩阵

假设参考坐标系 O − X r Y r Z r O-X_rY_rZ_r OXrYrZr,和本体坐标系 O − X b Y b Z b O-X_bY_bZ_b OXbYbZb,它们之间成一定角度,如果用欧拉角描述这个旋转关系的时候一定要说明旋转的顺序和旋转方式,旋转方式又分为外旋和内旋两种情况。
1.内旋:参考坐标系 O − X r Y r Z r O-X_rY_rZ_r OXrYrZr X r X_r Xr轴旋转 α \alpha α角度,然后再绕着新的 Y r Y_r Yr轴旋转 β \beta β角,最后再绕着新的 Z r Z_r Zr轴旋转 γ \gamma γ角度后与本体坐标系重合。
这三种旋转每次的旋转矩阵为分别为

那么参考坐标系到本体坐标系之间的转换矩阵为

本体坐标系到参考坐标系之间的转换矩阵是它的转置。
当然,如果你不按照这个顺序转动,比如,参考坐标系转动顺序为 Z r − Y r − X r Z_r-Y_r-X_r ZrYrXr时的参考坐标系到本体坐标系之间的转换矩阵就是:
实际上 Z r − Y r − X r Z_r-Y_r-X_r ZrYrXr的转动顺序更加常用,下变我们在介绍旋转矩阵转四元数和欧拉角时也使用这种转动顺序。
总之,在说欧拉角时候一定要指明旋转顺序,同样的欧拉角,旋转顺序不同,得到的旋转矩阵也不同。
2外旋:参考坐标系 O − X r Y r Z r O-X_rY_rZ_r OXrYrZr X r X_r Xr轴转动 α \alpha α角度,然后再绕着原来的 Y r Y_r Yr轴旋转 β \beta β角,最后绕着最初的 Z r Z_r Zr轴旋转 γ \gamma γ角度与本体坐标系重合。外旋与内旋的主要区别就是每次旋转围绕的轴是固定轴还是转动以后的新轴,在这种情况下三次旋转,每次的旋转矩阵分别为:

由于旋转方式不同,每次旋转的旋转矩阵也不同,这种旋转方式下参考坐标系到本体坐标系之间的转换矩阵为:

本体坐标系到参考坐标系之间的转换矩阵依然是它的转置:

注意几点:
一是内旋方式下按照某一顺序的旋转矩阵等于外旋方式下按照反着顺序来的旋转矩阵,比如说参考坐标系内旋顺序为 X r − Y r − Z r X_r-Y_r-Z_r XrYrZr时的旋转矩阵 C b r C^r_b Cbr等于参考坐标系外旋顺序为 Z r − Y r − X r Z_r-Y_r-X_r ZrYrXr时的旋转矩阵 C b r C^r_b Cbr
二是欧拉角转换旋转矩阵或者四元数的时候,一定要搞清楚旋转方式和旋转顺序。
三是姿态角和欧拉角的区别,其实我们可以理解为姿态角就是欧拉角的特殊情况,姿态角是描述运载体坐标系和地理坐标系之间的转换关系。 X X X轴为运载体的(纵)长轴,那么绕着 X X X轴转动的角度(横轴与水平面之间的夹角)就是横滚角 ϕ \phi ϕ Y Y Y轴为运载体的横轴,绕 Y Y Y轴转动的角度(纵轴与水平面的夹角)是俯仰角 θ \theta θ Z Z Z轴指向地面,绕Z轴转动的角度(纵轴与北向之间的夹角)就是航向角 ψ \psi ψ,姿态角默认情况下指的是按照内旋的方式地理坐标系按照 Z − Y − X Z-Y-X ZYX的旋转顺序分别旋转 ψ \psi ψ θ \theta θ ϕ \phi ϕ角以后就会与运载体坐标系重合。
四是很多场合我们说的欧拉角都使用的是 Z − Y − X Z-Y-X ZYX的内旋方式表示两个坐标系之间的转换关系,如果没有特殊说明的话就默认是这种方式。

旋转矩阵转欧拉角

对于一个旋转矩阵而言,不同的旋转顺序和旋转方式对应不同的欧拉角,旋转矩阵唯一,而欧拉角不唯一,这里给出最常用的一种转换关系。
参考坐标系为 O − X r Y r Z r O-X_rY_rZ_r OXrYrZr,本体坐标系为 O − X b Y b Z b O-X_bY_bZ_b OXbYbZb
如果已知参考坐标系到本体坐标系的旋转矩阵为

旋转矩阵转欧拉角的转换公式为:

此时计算出来的欧拉角 γ , β , α \gamma,\beta,\alpha γ,β,α的含义就是参考坐标系以内旋的方式按照 Z r − Y r − X r Z_r-Y_r-X_r ZrYrXr的顺序分别旋转 γ , β , α \gamma,\beta,\alpha γ,β,α角,这是旋转矩阵和欧拉角的对应关系,这个对应关系很重要,比如,如果说计算的时候使用的旋转矩阵是 C b r C^r_b Cbr而不是 C r b C^b_r Crb,那再使用这个转换公式计算出来的欧拉角就不是这个含义了,这一点值得注意。

旋转矩阵转四元数

参考坐标系为 O − X r Y r Z r O-X_rY_rZ_r OXrYrZr,本体坐标系为 O − X b Y b Z b O-X_bY_bZ_b OXbYbZb
四元数 q r b q^b_r qrb为参考坐标系到本体坐标系的四元数。
四元数 q b r q^r_b qbr为本体坐标系到参考坐标系的四元数。
q r b q^b_r qrb q b r q^r_b qbr之间是共轭关系。
如果我们已知旋转矩阵 C r b C^b_r Crb

那么可以根据计算以下公式计算四元数 q r b q^b_r qrb q r b = q 0 + q 1 i + q 2 j + q 3 k q^b_r=q_0+q_1i+q_2j+q_3k qrb=q0+q1i+q2j+q3k

四元数转旋转矩阵

如果我们已知四元数 q r b q^b_r qrb,旋转矩阵 C r b C^b_r Crb的计算公式如下:

四元数转欧拉角

参考坐标系为 O − X r Y r Z r O-X_rY_rZ_r OXrYrZr,本体坐标系为 O − X b Y b Z b O-X_bY_bZ_b OXbYbZb
四元数 q r b q^b_r qrb为参考坐标系到本体坐标系的四元数,
q r b = q 0 + q 1 i + q 2 j + q 3 k q^b_r=q_0+q_1i+q_2j+q_3k qrb=q0+q1i+q2j+q3k
使用以下公式得到的欧拉角的含义为:参考坐标系以内旋的方式按照 Z r − Y r − X r Z_r-Y_r-X_r ZrYrXr的顺序分别旋转 γ , β , α \gamma,\beta,\alpha γ,β,α角。

欧拉角转四元数

参考坐标系为 O − X r Y r Z r O-X_rY_rZ_r OXrYrZr,本体坐标系为 O − X b Y b Z b O-X_bY_bZ_b OXbYbZb
已知欧拉角的含义为参考坐标系以内旋的方式按照 Z r − Y r − X r Z_r-Y_r-X_r ZrYrXr的顺序分别旋转 γ , β , α \gamma,\beta,\alpha γ,β,α角,那么可以计算得到参考坐标系到本体坐标系的四元数 q r b q^b_r qrb,其中 q r b = q 0 + q 1 i + q 2 j + q 3 k q^b_r=q_0+q_1i+q_2j+q_3k qrb=q0+q1i+q2j+q3k
计算公式为

总结

在转化的时候一定要搞清楚旋转方式和旋转顺序。

有关欧拉角,旋转矩阵和四元数之间的转换关系的更多相关文章

  1. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  2. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  3. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  4. ruby - Rails 关联 - 同一个类的多个 has_one 关系 - 2

    我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下

  5. 旋转矩阵的几何意义 - 2

    点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度;     在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。

  6. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  7. [工业相机] 分辨率、精度和公差之间的关系 - 2

    📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年

  8. ruby - 无法理解 `puts{}.class` 和 `puts({}.class)` 之间的区别 - 2

    由于匿名block和散列block看起来大致相同。我正在玩它。我做了一些严肃的观察,如下所示:{}.class#=>Hash好的,这很酷。空block被视为Hash。print{}.class#=>NilClassputs{}.class#=>NilClass为什么上面的代码和NilClass一样,下面的代码又显示了Hash?puts({}.class)#Hash#=>nilprint({}.class)#Hash=>nil谁能帮我理解上面发生了什么?我完全不同意@Lindydancer的观点你如何解释下面几行:print{}.class#NilClassprint[].class#A

  9. ruby - 在模块/类之间共享全局记录器 - 2

    在许多ruby​​类之间共享记录器实例的最佳(正确)方法是什么?现在我只是将记录器创建为全局$logger=Logger.new变量,但我觉得有更好的方法可以在不使用全局变量的情况下执行此操作。如果我有以下内容:moduleFooclassAclassBclassC...classZend在所有类之间共享记录器实例的最佳方式是什么?我是以某种方式在Foo模块中声明/创建记录器还是只是使用全局$logger没问题? 最佳答案 在模块中添加常量:moduleFooLogger=Logger.newclassAclassBclassC..

  10. ruby - Rails 组合多个 activerecord 关系 - 2

    我想合并多个事件记录关系例如,apple_companies=Company.where("namelike?","%apple%")banana_companies=Company.where("namelike?","%banana%")我想结合这两个关系。不是合并,合并是apple_companies.merge(banana_companies)=>Company.where("namelike?andnamelike?","%apple%","%banana%")我要Company.where("名字像?还是名字像?","%apple%","%banana%")之后,我会写代

随机推荐