万向锁(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

相关文章

Java循环创建对象内存溢出的解决方法

《Java循环创建对象内存溢出的解决方法》在Java中,如果在循环中不当地创建大量对象而不及时释放内存,很容易导致内存溢出(OutOfMemoryError),所以本文给大家介绍了Java循环创建对象... 目录问题1. 解决方案2. 示例代码2.1 原始版本(可能导致内存溢出)2.2 修改后的版本问题在

大数据小内存排序问题如何巧妙解决

《大数据小内存排序问题如何巧妙解决》文章介绍了大数据小内存排序的三种方法:数据库排序、分治法和位图法,数据库排序简单但速度慢,对设备要求高;分治法高效但实现复杂;位图法可读性差,但存储空间受限... 目录三种方法:方法概要数据库排序(http://www.chinasem.cn对数据库设备要求较高)分治法(常

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

linux报错INFO:task xxxxxx:634 blocked for more than 120 seconds.三种解决方式

《linux报错INFO:taskxxxxxx:634blockedformorethan120seconds.三种解决方式》文章描述了一个Linux最小系统运行时出现的“hung_ta... 目录1.问题描述2.解决办法2.1 缩小文件系统缓存大小2.2 修改系统IO调度策略2.3 取消120秒时间限制3

关于@MapperScan和@ComponentScan的使用问题

《关于@MapperScan和@ComponentScan的使用问题》文章介绍了在使用`@MapperScan`和`@ComponentScan`时可能会遇到的包扫描冲突问题,并提供了解决方法,同时,... 目录@MapperScan和@ComponentScan的使用问题报错如下原因解决办法课外拓展总结@

MybatisGenerator文件生成不出对应文件的问题

《MybatisGenerator文件生成不出对应文件的问题》本文介绍了使用MybatisGenerator生成文件时遇到的问题及解决方法,主要步骤包括检查目标表是否存在、是否能连接到数据库、配置生成... 目录MyBATisGenerator 文件生成不出对应文件先在项目结构里引入“targetProje

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

numpy求解线性代数相关问题

《numpy求解线性代数相关问题》本文主要介绍了numpy求解线性代数相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 在numpy中有numpy.array类型和numpy.mat类型,前者是数组类型,后者是矩阵类型。数组

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas