万向锁(Gimbal lock)问题的理解及解决

2023-12-28 19:08

本文主要是介绍万向锁(Gimbal lock)问题的理解及解决,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

万向锁(Gimbal lock)问题的理解及解决

万向锁(Gimbal lock): 一旦选择±90°作为pitch角,就会导致第一次旋转和第三次旋转等价,整个旋转表示系统被限制在只能绕竖直轴旋转,丢失了一个表示维度。

对于万向锁的问题,只有在动态欧拉角中出现,而静态欧拉角不存在万向锁的问题!!!

  • 静态: 即绕世界坐标系三个轴的旋转,由于物体旋转过程中坐标轴保持静止,所以称为静态,此时各个变换顺序的旋转矩阵是左乘的

  • 动态: 即绕物体坐标系三个轴的旋转,由于物体旋转过程中坐标轴随着物体做相同的转动,所以称为动态,此时各个变换顺序的旋转矩阵是右乘的

  • 内旋Intrinsic rotations:绕运动轴

  • 外旋 Extrinsic rotations: 绕固定轴
    在这里插入图片描述

不管采用哪种欧拉角,只要中间的变换旋转90°就会发生Gimbal lock问题!!!

案例1:
一个典型的万向锁问题可以表述如下:先heading45°再pitch90°,这与先pitch90°再bank45°是等价的。事实上,一旦选择±90°作为pitch角,就会导致第一次旋转和第三次旋转等价,整个旋转表示系统被限制在只能绕竖直轴旋转,丢失了一个表示维度。这种角度为±90°的第二次旋转使得第一次和第三次旋转的旋转轴相同的现象,称作万向锁。

在这里插入图片描述
在这里插入图片描述

案例2:

首先确定手机的物体坐标系朝向,假设z轴与手机屏幕垂直(手机平放于桌面)指向上方,手机较短的一条边为x轴,较长的一条边为y轴(方向由手机尾部指向头部),物体坐标系的原点是手机左下角的顶点。(注意旋转顺序为zyx)

绕z轴旋转任意角度(注意x和y轴也跟着一起旋转),再绕y轴旋转90°,再绕x轴旋转任意角度。通过多次尝试,会发现一个共同点:z轴永远是水平的, 通俗的说,手机永远也不会立起来(旋转形成的三维空间是固定的)!本来以为手机会指向任何方向,但实际上手机好像是被锁在桌面上,只能指向水平的某个方向,这个现象就称为万向锁。

而如果绕y轴旋转不等于90°(1°也好89°也好),只要选择适当的绕x和z的角度,就可以让手机指向三维空间中的任何一个方向,手机是自由的(旋转产生的三维空间不会完全重叠),也就不会遇到万向锁现象。

2. 解决方案

(1)使用四元数来解决

将欧拉角转换为四元数,对四元数进行slerp插值,再将这一系列四元数转换为对应的欧拉角,而后作用于目标。

缺点是耗费一定的内存,但目标可以任意旋转,灵活度高。

(2)为什么要使用四元数

一是由于万向锁的问题,二是插值的时候直接对RPY插值可能导致不平滑,插值结果可能有跳跃;

而且四元数表示旋转,计算次数更少,最关键的一点是它非常非常非常适合插值!!!

最常用的是球面线性插值~

但要注意:使用四元数插值时,插值结果需要进行归一化(有些地方也叫规范化或者规格化),否则单位长度会发生变化!!!

3. 欧拉角与四元数的对应

欧拉角(pitch yaw roll)←→四元数(第一个值是实部,后面三个是虚部)
0.0, 0.0, 0.0←→1.000000, 0.000000, 0.000000, 0.000000
90.0, 0.0, 0.0←→0.707107, 0.707107, 0.000000, 0.000000
0.0, 90.0, 0.0←→0.707107, 0.000000, 0.707107, 0.000000
0.0, 0.0, 90.0←→0.707107, 0.000000, 0.000000, 0.707107

4. 使用四元数时的注意事项

注意不要将一个绕RPY的旋转使用三个四元数来描述,旋转完再转换回去发现卵用没有,仍会出现Gimbal Lock问题!!!

正确的姿势应该将RPY这个绕三轴的三次变换,当成一次变换,使用四元数来描述!!!

注意:这里说的是动态欧拉角

使用四元数变换完记得要对改变后的四元数进行Normalize(规范化)!!!

仔细理解该文中的例子:传送门


参考文献:

  • https://blog.csdn.net/hangl_ciom/article/details/98170231
  • https://blog.csdn.net/lmonkey000/article/details/51001753
  • https://baike.baidu.com/item/%E4%B8%87%E5%90%91%E9%94%81/15817326?fr=aladdin
  • https://www.cnblogs.com/psklf/p/5656938.html
  • https://www.cnblogs.com/psklf/p/5667593.html
  • https://www.qiujiawei.com/quaternion3/
  • https://www.qiujiawei.com/quaternion4/
  • https://www.cnblogs.com/ymd12103410/p/9985063.html

这篇关于万向锁(Gimbal lock)问题的理解及解决的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/546969

相关文章

Oracle登录时忘记用户名或密码该如何解决

《Oracle登录时忘记用户名或密码该如何解决》:本文主要介绍如何在Oracle12c中忘记用户名和密码时找回或重置用户账户信息,文中通过代码介绍的非常详细,对同样遇到这个问题的同学具有一定的参... 目录一、忘记账户:二、忘记密码:三、详细情况情况 1:1.1. 登录到数据库1.2. 查看当前用户信息1.

springboot3.4和mybatis plus的版本问题的解决

《springboot3.4和mybatisplus的版本问题的解决》本文主要介绍了springboot3.4和mybatisplus的版本问题的解决,主要由于SpringBoot3.4与MyBat... 报错1:spring-boot-starter/3.4.0/spring-boot-starter-

在 Spring Boot 中使用异步线程时的 HttpServletRequest 复用问题记录

《在SpringBoot中使用异步线程时的HttpServletRequest复用问题记录》文章讨论了在SpringBoot中使用异步线程时,由于HttpServletRequest复用导致... 目录一、问题描述:异步线程操作导致请求复用时 Cookie 解析失败1. 场景背景2. 问题根源二、问题详细分

解读为什么@Autowired在属性上被警告,在setter方法上不被警告问题

《解读为什么@Autowired在属性上被警告,在setter方法上不被警告问题》在Spring开发中,@Autowired注解常用于实现依赖注入,它可以应用于类的属性、构造器或setter方法上,然... 目录1. 为什么 @Autowired 在属性上被警告?1.1 隐式依赖注入1.2 IDE 的警告:

解决java.lang.NullPointerException问题(空指针异常)

《解决java.lang.NullPointerException问题(空指针异常)》本文详细介绍了Java中的NullPointerException异常及其常见原因,包括对象引用为null、数组元... 目录Java.lang.NullPointerException(空指针异常)NullPointer

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

关于Nginx跨域问题及解决方案(CORS)

《关于Nginx跨域问题及解决方案(CORS)》文章主要介绍了跨域资源共享(CORS)机制及其在现代Web开发中的重要性,通过Nginx,可以简单地解决跨域问题,适合新手学习和应用,文章详细讲解了CO... 目录一、概述二、什么是 CORS?三、常见的跨域场景四、Nginx 如何解决 CORS 问题?五、基

python安装whl包并解决依赖关系的实现

《python安装whl包并解决依赖关系的实现》本文主要介绍了python安装whl包并解决依赖关系的实现,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录一、什么是whl文件?二、我们为什么需要使用whl文件来安装python库?三、我们应该去哪儿下

MySQL安装时initializing database失败的问题解决

《MySQL安装时initializingdatabase失败的问题解决》本文主要介绍了MySQL安装时initializingdatabase失败的问题解决,文中通过图文介绍的非常详细,对大家的学... 目录问题页面:解决方法:问题页面:解决方法:1.勾选红框中的选项:2.将下图红框中全部改为英

Nginx启动失败:端口80被占用问题的解决方案

《Nginx启动失败:端口80被占用问题的解决方案》在Linux服务器上部署Nginx时,可能会遇到Nginx启动失败的情况,尤其是错误提示bind()to0.0.0.0:80failed,这种问题通... 目录引言问题描述问题分析解决方案1. 检查占用端口 80 的进程使用 netstat 命令使用 ss