关于欧拉角你需要知道几个点

news2024/9/17 7:14:24

基础理解,参照:https://www.cnblogs.com/Estranged-Tech/p/16903025.html

欧拉角、万向节死锁(锁死)理解

一、欧拉角理解

举例讲解

欧拉角用三次独立的绕确定的轴旋转角度来表示姿态。如下图所示
在这里插入图片描述
经过三次旋转,旋转角度分别为𝛼、𝛽和 𝛾,由初始的𝑥𝑦𝑧坐标系得到了最终的𝑥‴𝑦‴𝑧‴
坐标系。这就是欧拉角来表示姿态的方法。
如图所示为航空航天中常用的欧拉角,图中的𝜓、𝜃和𝜙
对应于上图中的𝛼、𝛽和 𝛾。
在这里插入图片描述

顺规、内旋与外旋

上面所举的例子中,旋转的顺序是按照 𝑧−𝑦−𝑥 的顺序来进行旋转的,并且每一次旋转都是绕自身轴(运动轴)进行的, 这只是欧拉角的一种表示方式。欧拉角共有12种表示方式。

  • 顺规
    顺规即欧拉角三次转动的顺序规定,欧拉角一共有12种顺规
三个轴只用两个的:Proper Euler angles (z−x−z, x−y−x, y−z−y, z−y−z, x−z−x, y−x−y)
三个轴全都用的:Tait-Bryan angles (x−y−z, y−z−x, z−x−y, x−z−y, z−y−x, y−x−z)

上文举例所用的 𝑧−𝑦−𝑥是三个轴都用的一种顺规,即 先绕𝑧轴旋转,再绕𝑦轴旋转,最后绕𝑥轴旋转。

  • 内旋与外旋
    根据绕旋转轴的不同,可以分为内旋和外旋。
内旋 Intrinsic rotations:绕运动轴
外旋 Extrinsic rotations:绕固定轴

上文所举的例子每次旋转都是绕上一次旋转所新产生的坐标轴旋转的(这句话有点绕),比如第二次旋转绕的是𝑦″而不是固定的坐标轴𝑦。所以是绕运动轴,即内旋。

如下图所示,每一次旋转都是绕蓝色的固定轴旋转
在这里插入图片描述
在这里插入图片描述

如下图所示,每一次旋转都是绕红色(第一张图)、绿色(第二张图)、紫色(第三张图)的运动轴旋转:
在这里插入图片描述
在这里插入图片描述
在绕轴旋转的时候,顺规有12种,内外旋有2种,但是一般情况下,欧拉角都是说的绕自身轴(运动轴)旋转,即 内旋 。所以欧拉角共有 1×12=12种表示方式。

小结

  • 首先说一个很有意思却很不直观的结论:三次绕固定轴旋转的最终姿态和以相反顺序三次绕运动轴旋转的最终姿态相同。

  • 一般情况下,每一个领域有自己默认的欧拉角定义,也就是24种的其中之一。比如经典力学中使用𝑧𝑥𝑧,量子力学使用的是𝑧𝑦𝑧,航空航天使用𝑧𝑦𝑥或𝑧𝑥𝑦。所以在跨行业或者跨模块协作的时候,一定要问清楚对方是哪一种欧拉角。

二、数学公式

在这里插入图片描述

三、万向节死锁理解

  • 说明
    欧拉角表示姿态的时候,会出现万向节死锁的情况,当我使用传感器(维特智能WT901c-485)读取角度的时候,在𝑍𝑌𝑋的顺规下,当pitch角度为90或-90的时候,roll和yaw角度会乱飘,这就是遇到了万向节的死锁。不同的顺规死锁的情况不一样,本文仅以𝑍𝑌𝑋说明死锁的情况。
  • 形象表示
    我们以手机为例,说明一下万向节死锁的情况
    注意,欧拉角表示姿态时,只能旋转三次,这是理解死锁的前提!
    首先这是一个手机,我们对其建立坐标系,平行于手机长边是 𝑋轴,平行于手机短边是 𝑌轴,垂直于桌面是 𝑍轴。我们按照 𝑍-𝑌-𝑋的顺规,对手机进行旋转:
    在这里插入图片描述
    1.首先,先绕 𝑍轴旋转得到 𝑋′𝑌′𝑍′坐标系,如图中绿色所示:
    在这里插入图片描述
    2.然后对 𝑋′𝑌′𝑍′ 绕 𝑌′轴旋转-90°,得到 𝑋″𝑌″𝑍″ ,如图中蓝色所示(此时旋转后的 𝑋″ 轴轴与旋转之前的 𝑍′轴重合)
    在这里插入图片描述
    3.最后将 𝑋″𝑌″𝑍″ 绕 𝑋″轴旋转得到 𝑋‴𝑌‴𝑍‴ 坐标系,如图中黄色所示。
    在这里插入图片描述
  • 这时候重点来了!!!

我们发现,这样旋转过后,手机的长边是与桌面(地面)垂直的,手机的短边是与桌面(地面)平行的。并且,无论第一步转 𝑍轴转了多少度,第三步转 𝑋 轴转了多少度,手机长边与短边都是这个状态。
这就是欧拉角表示角度时的“万向节死锁”现象,按理说欧拉角可以表示三个自由度,即三个方向的旋转。但是在这种情况下,只要𝛽=±90°,无论 𝛼与𝛾怎么取值,手机最终的长边都会与地面垂直,这就好像少了一个自由度,只有2个自由度,所以称之为“万向节死锁”。
在这里插入图片描述

  • 那么为什么会出现这种情况呢?

一种感性的理解是这样:我们在第二步旋转的时候,将旋转后的 𝑋″ 轴与旋转之前的 𝑍′ 轴重合(这个我在上面旋转演示的时候加粗说明了)。而第一步旋转是绕 𝑍′ 轴旋转的,第三步旋转是绕 𝑋″轴旋转的,所以两轴重合意味着两次旋转绕的是同一个轴,所以说,三个自由度变为了两个自由度。

  • 数学解释:
    在这里插入图片描述

欧拉角与旋转矩阵转换中的相关问题:

  • 先出结论:
# ea(人为给定的)转rotmat 再转ea后两个ea的值存在不一致,且含义不一致(主要出现在y角度在一定范围时时),但两个不同的ea可以得到相同的旋转矩阵。
# rotmat转ea再转rotmat(前后rotmat一致)再转ea 前后ea含义是一致的,说明相同的rotmat可以获得一致的ea
# rotmat转ea再转rotmat 前后rotmat是一致的,

# 以上说明rotmat到ea是多射,但使用函数进行rotmat转换ea时可以获得一致的ea结果;ea到rotmat是单射。以上说明虽存在多设情况但不影响我们场景的使用。(再验证下)
import torch
import math


def euler_to_rotation_matrix(euler_angles):
    """
    将欧拉角转为旋转矩阵。欧拉角采用 Z-Y-X顺序 的内旋旋转(与X-Y-Z 的外旋一致)
    参数:
        euler_angles:欧拉角,形状为 (batch_size, 3)
    返回:
        rotation_matrix:旋转矩阵,形状为 (batch_size, 3, 3)
    """
    # 将欧拉角转为弧度
    x, y, z = euler_angles[:, 0], euler_angles[:, 1], euler_angles[:, 2]
    x, y, z = x * torch.pi / 180, y * torch.pi / 180, z * torch.pi / 180
    # 计算旋转矩阵
    c_x, s_x = torch.cos(x), torch.sin(x)
    c_y, s_y = torch.cos(y), torch.sin(y)
    c_z, s_z = torch.cos(z), torch.sin(z)
    rotation_matrix_x = torch.stack([torch.ones_like(c_x), torch.zeros_like(c_x), torch.zeros_like(c_x),
                                     torch.zeros_like(c_x), c_x, -s_x,
                                     torch.zeros_like(c_x), s_x, c_x], dim=1).reshape(-1, 3, 3)
    rotation_matrix_y = torch.stack([c_y, torch.zeros_like(c_y), s_y,
                                     torch.zeros_like(c_y), torch.ones_like(c_y), torch.zeros_like(c_y),
                                     -s_y, torch.zeros_like(c_y), c_y], dim=1).reshape(-1, 3, 3)
    rotation_matrix_z = torch.stack([c_z, -s_z, torch.zeros_like(c_z),
                                     s_z, c_z, torch.zeros_like(c_z),
                                     torch.zeros_like(c_z), torch.zeros_like(c_z), torch.ones_like(c_z)], dim=1).reshape(-1, 3, 3)
    rotation_matrix = rotation_matrix_z @ rotation_matrix_y @ rotation_matrix_x
    return rotation_matrix


def rotation_matrix_to_euler(rotation_matrix):
    """
    将旋转矩阵转为欧拉角, 欧拉角采用 Z-Y-X顺序 的内旋旋转(与X-Y-Z 的外旋一致)
    参数:
        rotation_matrix:旋转矩阵,形状为 (batch_size, 3, 3)
    返回:
        euler_angles:欧拉角,形状为 (batch_size, 3)
    """
    # 计算欧拉角
    sy = torch.sqrt(rotation_matrix[:, 0, 0] ** 2 + rotation_matrix[:, 1, 0] ** 2)
    x = torch.atan2(rotation_matrix[:, 2, 1], rotation_matrix[:, 2, 2])
    y = torch.atan2(-rotation_matrix[:, 2, 0], sy)
    z = torch.atan2(rotation_matrix[:, 1, 0], rotation_matrix[:, 0, 0])
    # 将弧度转为角度
    x, y, z = x * 180 / torch.pi, y * 180 / torch.pi, z * 180 / torch.pi
    # 组合
    ea = torch.stack((x, y, z), dim=1)
    return ea


ea1=torch.tensor([[   0.,   75.,   90.],
        [   0.,   78.,   90.],
        [   0.,  105.,   90.],
        [   0.,  102.,   90.],
        [   0.,  -75.,   90.],
        [   0., -105.,   90.],
        [   0.,  -65.,   90.],
        [   0., -125.,   90.]])
rm1=euler_to_rotation_matrix(ea1)


ea2=rotation_matrix_to_euler(rm1)

print("有false")
print(ea1==ea2) # 有false

rm2=euler_to_rotation_matrix(ea2)
print("全true")
print(rm1-rm2 <0.0001) # q全true

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/358424.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

原创不易,坚持更难

早上CSDN发消息&#xff0c;今天是创作满三年的纪念日&#xff0c;邀请写一篇博文&#xff0c;谈谈感受 开博原因 2020年是一个特殊的年份&#xff0c;疫情刚爆发第一年&#xff0c;也是第一次居家办公&#xff0c;从过完年就一直居家办公&#xff0c;一直居家了38天。2020年…

宗教生活污水处理项目的设计原则

我国的历史源远流长&#xff0c;许多传统文化都延续了上千年以上。同时&#xff0c;我国也是宗教信仰自由的国家&#xff0c;儒释道文化相互影响&#xff0c;交相辉映。游人穿过山间小道&#xff0c;走到寺院庄严礼拜&#xff0c;游客和信众的增多&#xff0c;使教堂、寺庙等宗…

机器学习笔记之谱聚类(一)k-Means聚类算法介绍

机器学习笔记之谱聚类——K-Means聚类算法介绍引言回顾&#xff1a;高斯混合模型聚类任务基本介绍距离计算k-Means\text{k-Means}k-Means算法介绍k-Means\text{k-Means}k-Means算法示例k-Means\text{k-Means}k-Means算法与高斯混合模型的关系k-Means\text{k-Means}k-Means算法的…

CTFer成长之路之CTF中的SQL注入

CTF中的SQL注入CTF SQL注入 SQL注入-1 题目描述: 暂无 docker-compose.yml version: 3.2services:web:image: registry.cn-hangzhou.aliyuncs.com/n1book/web-sql-1:latestports:- 80:80启动方式 docker-compose up -d 题目Flag n1book{union_select_is_so_cool} Wri…

PyQt5数据库开发1 4.3 QSqlTableModel 之 相关槽函数的实现(多图长文详解)

目录 一、打开数据库表 1. 写打开数据库的槽函数 2. 运行后发现数据库可以打开了 3. ODBC配通了&#xff0c;数据库还是打不开 4. 写在tableView上显示数据库表的函数 5. 运行后发现表可以显示了 6. 代码分析 7. 添加列名称 8. 根据内容调整列宽 9. 备注&#xff1a;…

Kaggle系列之CIFAR-10图像识别分类(残差网络模型ResNet-18)

CIFAR-10数据集在计算机视觉领域是一个很重要的数据集&#xff0c;很有必要去熟悉它&#xff0c;我们来到Kaggle站点&#xff0c;进入到比赛页面&#xff1a;https://www.kaggle.com/competitions/cifar-10CIFAR-10是8000万小图像数据集的一个子集&#xff0c;由60000张32x32彩…

spring cloud gateway集成sentinel并扩展支持restful api进行url粒度的流量治理

sentinel集成网关支持restful接口进行url粒度的流量治理前言使用网关进行总体流量治理&#xff08;sentinel版本&#xff1a;1.8.6&#xff09;1、cloud gateway添加依赖:2、sentinel配置3、网关类型项目配置4、通过zk事件监听刷新上报api分组信息1、非网关项目上报api分组信息…

I.MX6ULL_Linux_系统篇(16) uboot分析-启动流程

原文链接&#xff1a;I.MX6ULL_系统篇(16) uboot分析-启动流程 – WSY Personal Blog (cpolar.cn) 前面我们详细的分析了 uboot 的顶层 Makefile&#xff0c;了解了 uboot 的编译流程。本章我们来详细的分析一下 uboot 的启动流程&#xff0c;理清 uboot 是如何启动的。通过对 …

虹科资讯| 虹科AR荣获汽车后市场“20佳”维修工具评委会提名奖!

2022 虹科荣获20佳维修工具 评委会提名奖 特大喜讯&#xff0c;在2月16日《汽车维修与保养》杂志主办的第十八届汽车后市场“20佳”评选活动中&#xff0c;虹科的产品“M400智能AR眼镜”凭借在AR领域的专业实力&#xff0c;通过层层筛选&#xff0c;在102款入围产品中脱颖而出…

GIT:【基础三】Git工作核心原理

目录 一、Git本地四个工作区域 二、Git提交文件流程 一、Git本地四个工作区域 工作目录(Working Directory)&#xff1a;电脑上存放开发代码的地方。暂存区(Stage/Index)&#xff1a;用于l临时存放改动的文件&#xff0c;本质上只是一个文件&#xff0c;保存即将提交到文件列…

[ 对比学习篇 ] 经典网络模型 —— Contrastive Learning

&#x1f935; Author &#xff1a;Horizon Max ✨ 编程技巧篇&#xff1a;各种操作小结 &#x1f3c6; 神经网络篇&#xff1a;经典网络模型 &#x1f4bb; 算法篇&#xff1a;再忙也别忘了 LeetCode [ 对比学习篇 ] 经典网络模型 —— Contrastive Learning&#x1f680; …

MongoDB介绍及使用教程

文章目录一、MongoDB介绍1. 什么是MongoDB2. 为什么要用MongoDB3. MongoDB的应用场景4. MongoDB基本概念二、MongoDB使用教程1.下载安装&#xff08;Windows&#xff09;2.MongoDB Conpass简单使用&#xff08;选学&#xff09;3.使用navicat连接MongoDB4.JAVA项目中使用MongoD…

JVM11 垃圾回收

1.1GC分类与性能指标 垃圾收集器没有在规范中进行过多的规定&#xff0c;可以由不同的厂商、不同版本的JVM来实现。 从不同角度分析垃圾收集器&#xff0c;可以将GC分为不同的类型。 Java不同版本新特性 语法层面&#xff1a;Lambda表达式、switch、自动拆箱装箱、enumAPI层面…

AI稳定生成图工业链路打造

前沿这篇文章会以比较轻松的方式&#xff0c;跟大家交流下如何控制文本生成图片的质量。要知道如何控制文本生成质量&#xff0c;那么我们首先需要知道我们有哪些可以控制的参数和模块。要知道我们有哪些控制的参数和模块&#xff0c;我们就得知道我们文本生成图片的这架机器或…

新手福利——x64逆向基础

一、x64程序的内存和通用寄存器 随着游戏行业的发展&#xff0c;x32位的程序已经很难满足一些新兴游戏的需求了&#xff0c;因为32位内存的最大值为0xFFFFFFFF&#xff0c;这个值看似足够&#xff0c;但是当游戏对资源需求非常大&#xff0c;那么真正可以分配的内存就显得捉襟…

测试人员如何运用好OKR

在软件测试工作中是不是还不知道OKR是什么?又或者每次都很害怕写OKR?或者总觉得很迷茫&#xff0c;不知道目标是什么? OKR 与 KPI 的区别 去年公司从KPI换OKR之后&#xff0c;我也有一段抓瞎的过程&#xff0c;然后自己找了两本书看&#xff0c;一本是《OKR工作法》&#xf…

WPF_ObservableCollection基本使用及其注意项

文章目录一、引言二、ObservableCollection三、结语一、引言 在GUI编程中经常会用到条目控件&#xff0c;常见的如ComboBox&#xff08;下拉列表框&#xff09;&#xff0c;它内部往往有多个项。 在使用一些图形框架&#xff08;Qt、WinForm&#xff09;上进行原始开发时&…

安卓mvvm

AndroidX的意思是android extension libraries, 也就是安卓扩展包 AndroidX其实是Jetpack类库的命名空间 (190条消息) AndroidX初识_Neda Wang的博客-CSDN博客https://blog.csdn.net/weixin_38261570/article/details/111500044 viewmodel ViewModel类旨在以注重生命周期的方…

【机器学习】决策树-C4.5算法

1.C4.5算法 C4.5算法与ID3相似&#xff0c;在ID3的基础上进行了改进&#xff0c;采用信息增益比来选择属性。ID3选择属性用的是子树的信息增益&#xff0c;ID3使用的是熵&#xff08;entropy&#xff0c; 熵是一种不纯度度量准则&#xff09;&#xff0c;也就是熵的变化值&…

回溯算法理论基础及组合问题

文章目录回溯算法理论基础什么是回溯法回溯法的效率回溯法解决的问题如何理解回溯法回溯法模板组合问题回溯算法理论基础 什么是回溯法 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。 回溯是递归的副产品&#xff0c;只要有递归就会有回溯。 所以以下讲解中&…