旋转矩阵-数学理论

news2024/12/28 19:26:30

目录

概述       

一、固定旋转(Fix Angles)

二、欧拉旋转(Euler Angle)

 三、旋转矩阵小结

四、参考


概述       

 旋转矩阵是姿态的一种数学表达方式,或者笼统说变换矩阵是一种抽象的数学变量。其抽象在于当你看到数据,根本无法断定其正确性;往往只有转换为较为直观的欧拉角,然后大概目测估算(总不能拿着量角器去测量精度吧)。我们知道,姿态的数学形式有旋转矩阵(满足RTR=E)、欧拉角、旋转向量(角轴)、四元数(norm(x y z w) = 1)等。今天这里要讨论的是旋转矩阵相关理论基础。

       旋转矩阵常用于以下三种场景:

  • 描述一个frame(坐标系)相对于另一个frame间的位姿;(如:描述相邻两帧间的相机运动)
  • 描述一个point从一个frame变换到另一个frame;(其实点没动,只是在两个frame观测时,坐标不一样而已;如:;路标点点P在不同相机坐标系下坐标值不同,但在世界坐标系下是固定的)
  • 描述一个point在同一个frame中的运动;(这里的点是运动了的,在VSLAM中应用较少)

 绕三个轴的旋转矩阵请按以下形式进行记忆,可能有些地方是下面的转置形式。

 (本博客和大多数论文资料一样,都是左乘原则)

一、固定旋转(Fix Angles)

       所谓固定旋转,就是按照物体外部固定轴旋转。这种旋转在工程中很常见,用的相对多一些(相对于下面的欧拉旋转),例如:旋转次序为X-Y-Z,那么旋转矩阵的形式为:RZRYRX。如下图,其实没什么好说。

      已知旋转矩阵,怎么求解欧拉角呢?下图便是一种比较好的求解办法。我们知道,顺时针旋转180°和逆时针旋转180°是等效的(让机械臂旋转190°其实是走远路,因为旋转170°似乎更快),所以求解出来的欧拉角其取值范围最好是:[0°,180°] or [0°,-180°] 或者[-90°,90°],这里采用的后者。下面代码中的atan2是matlab中的api,我们在这里简单验证下其与tan的区别:可以看到,当一个点在第三象限,如(-1, -1),在欧拉角中,其角度为:-135°,但是atan(-1/-1)算出来是45°,显然是错的。

>> atan(1) * 180 / pi

ans =

    45

>> atan2(1, 1) * 180 / pi

ans =

    45

>> atan2(-1, -1) * 180 / pi

ans =

  -135

>>

顺在在这里用Eigen验证下:(相关头文件(如Pose.h)去这个链接中查找: 基于Eigen的位姿转换-CSDN博客 )不去下载,下面C++代码你都跑不了

#include"Pose.h"
#include<iostream>
using namespace std;

int main()
{
    Eigen::Matrix3d R1;
    R1 << 0.866, 0.433, 0.25, 0., 0.5, -0.866, -0.5, 0.75, 0.433;

    Pose pose1(R1);
    cout << "旋转矩阵 = " << endl; cout << pose1.rotation() << endl;
    cout << "欧拉角 = " << endl;   cout << pose1.euler_angle().transpose()*(180 / M_PI) << endl;
    cout << "四元数 = " << endl;   cout << pose1.quaternion().coeffs().transpose() << endl;
    cout << "角轴 = " << endl;
    cout << pose1.angle_axis().angle()* (180 / M_PI) << " " << pose1.angle_axis().axis().transpose() << endl;
    cout << "-----------------------------" << endl;
    return 1;
}

  打印结果:

旋转矩阵 =  0.866  0.433   0.25
            0    0.5 -0.866
            -0.5   0.75  0.433
欧拉角 =   63.4349  14.4779 -26.5651
四元数 =   0.482959  0.224145 -0.129407  0.836511
角轴 =     66.4519 0.881411 0.409071 -0.23617

可以看到Eigen的欧拉角结果和上述PPT中Matlab计算的结果不一样,但是他们旋转矩阵具体是一样的,这个是正常的,下面还会碰到。其实就是利用欧式旋转矩阵求解。欧拉角的解并不唯一,这个问题在手眼标定中验证过。 

二、欧拉旋转(Euler Angle)

        固定旋转与欧拉旋转的关系,例如:固定旋转次序为:XYZ,写成旋转矩阵则为:Rz*Ry*Rx;其等效的欧拉旋转次序为:ZYX,写成旋转矩阵则为:Rz*Ry*Rx,最后的映射矩阵是一样的,但是过程不一样,殊途同归。)例如下面例子:

ZYZ的欧拉旋转次序,这个我是实际“体验过”,那是在自研机械臂上示教器是数据。欧拉旋转的方式如下图:

 形如固定旋转,我这里也给出:已经ZYZ类型欧拉旋转,求解欧拉角的一种方法:

针对上面等式:

这里用Eigen验证下, 对于等式左边:

1 #include"Pose.h"
 2 #include<iostream>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     // 低级错误:是60.0,不是60
 8     Eigen::Matrix3d R1;
 9     R1 = Eigen::AngleAxisd(60.0 / 180 * M_PI, Eigen::Vector3d::UnitX()) *
10          Eigen::AngleAxisd(30.0 / 180 * M_PI, Eigen::Vector3d::UnitY()) *
11           Eigen::AngleAxisd(              0.0, Eigen::Vector3d::UnitZ());
12 
13     Pose pose3(R1);
14     cout << "旋转矩阵 = " << endl; cout << pose3.rotation() << endl;
15     cout << "欧拉角 = " << endl;   cout << pose3.euler_angle().transpose()*(180 / M_PI) << endl;
16     cout << "四元数 = " << endl;   cout << pose3.quaternion().coeffs().transpose() << endl;
17     cout << "角轴 = " << endl;
18     cout << pose3.angle_axis().angle()* (180 / M_PI) << " " << pose3.angle_axis().axis().transpose() << endl;
19     cout << "-----------------------------" << endl;
22     return 1;
23 }

针对等式右边,同理有:

#include"Pose.h"
#include<iostream>
using namespace std;

int main()
{
    Eigen::Vector3d RPY;
    RPY << -56.3 / 180 * M_PI, 64.3 / 180 * M_PI, 73.9 / 180 * M_PI;

    cout << RPY(2, 0) << endl;


    Eigen::Matrix3d R2;
    // note: ZYZ
    R2 = Eigen::AngleAxisd(RPY(0, 0), Eigen::Vector3d::UnitZ()) *
         Eigen::AngleAxisd(RPY(1, 0), Eigen::Vector3d::UnitY()) *
         Eigen::AngleAxisd(RPY(2, 0), Eigen::Vector3d::UnitZ());
    Pose pose4(R2);
    cout << "旋转矩阵 = " << endl; cout << pose4.rotation() << endl;
    cout << "欧拉角 = " << endl;   cout << pose4.euler_angle().transpose()*(180 / M_PI) << endl;
    cout << "四元数 = " << endl;   cout << pose4.quaternion().coeffs().transpose() << endl;
    cout << "角轴 = " << endl;
    cout << pose4.angle_axis().angle()* (180 / M_PI) << " " << pose4.angle_axis().axis().transpose() << endl;
    cout << "-----------------------------" << endl;

    return 1;
}

对比两种旋转方式,可以看到Eigen计算的结果完全一致;但是比较有意思的是,对于下面,我用的欧拉角明明是( -56.3, 64.3, 73.9 )(ZYZ),结果打印输出的。欧拉角居然是(59.9, 29.99, 0.031)。这是由于我写的Pose类底层,我只定义了ZYX的固定旋转方式。同时,也说明了,同一个旋转矩阵,可能对应不同的旋转方式(如:欧拉旋转、固定旋转),不同的旋转欧拉角、甚至不同的旋转次序

 三、旋转矩阵小结

       欧拉旋转和固定旋转的次序有效的排列组合为:12 = 3 * 2 * 2

       姿态的数学形式有旋转矩阵(约束:RTR=E)、欧拉角(万向锁问题)、旋转向量(角轴)、四元数(约束norm(x y z w) = 1),所以VSLAM在对位姿进行优化的时候,

为了避免“带约束的优化”问题,一般都会采用旋转向量的形式作为姿态。

四、参考

(台大机器人学之运动学——林沛群)

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

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

相关文章

【深度学习】卷积层填充和步幅以及其大小关系

参考链接 【深度学习】&#xff1a;《PyTorch入门到项目实战》卷积神经网络2-2&#xff1a;填充(padding)和步幅(stride) 一、卷积 卷积是在深度学习中的一种重要操作&#xff0c;但实际上它是一种互相关操作&#xff0c;&#xff0c;首先我们来了解一下二维互相关&#xff…

Redis主从配置和哨兵模式

主从简介 1、主从 – 用法 像MySQL一样&#xff0c;redis是支持主从同步的&#xff0c;而且也支持一主多从以及多级从结构。 主从结构&#xff0c;一是为了纯粹的冗余备份&#xff0c;二是为了提升读性能&#xff0c;比如很消耗性能的SORT就可以由从服务器来承担。 redis的主…

oracle-sql语句解析类型

语句执行过程&#xff1a;1. 解析(将sql解析成执行计划) 2.执行 3.获取数据(fetch) 1. shared pool的组成。 share pool是一块内存池。 主要分成3块空间。free&#xff0c; library(库缓存&#xff0c;缓存sql以及执行计划)&#xff0c;row cache(字典缓存) select * from v…

云贝教育 |【PostgreSQL PGCA】pg15安装pg_hint_plan扩展包

pg15安装pg_hint_plan扩展包 pg当前是支持HINT固定执行计划&#xff0c;需要通过扩展包pg_hint_plan来实现 一、扩展包下载&#xff1a; Releases ossc-db/pg_hint_plan GitHub 二、选择v15版本 pg_hint_plan15 1.5.1 is released pg_hint_plan15 1.5.1 is released. This…

SLAM从入门到精通(安全避障)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 在工业生产中&#xff0c;安全是底线。没有安全性的技术&#xff0c;一般也不会在工业生产中进行部署、使用。对于slam来说&#xff0c;同样也是这…

机器人制作开源方案 | 行星探测车实现云端控制

1. 功能描述 本文示例所实现的功能为&#xff1a;手机端控制R261样机行星探测车的显示屏显示心形图。 2. 电子硬件 在这个示例中&#xff0c;我们采用了以下硬件&#xff0c;请大家参考&#xff1a; 3. 功能实现 编程环境&#xff1a;Milxy 0.999及以上版本 下面提供一个手机…

TerraNoise for 3dMax插件教程

TerraNoise for 3dMax插件教程 创建地形&#xff1a; - 从列表中拖动生成器并将其放到画布上 - 将导出器拖放到画布上 - 通过将一条线从生成器黄色输出“拖动”到导出器绿色输入来连接 2 个组件 - 单击导出器中的“无”按钮用于选择输出名称和格式&#xff08;导出 terragen 地…

Python装饰器的艺术

文章目录 装饰器基础示例代码:执行结果:参数化装饰器示例代码:执行结果:类装饰器示例代码:执行结果:装饰器的堆栈示例代码:执行结果:在Python中,装饰器是一种非常强大的特性,允许开发人员以一种干净、可读性强的方式修改或增强函数和方法。以下是一个关于Python装饰器…

聊聊定时器 setTimeout 的时延问题

给大家推荐一个实用面试题库 1、前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;web前端面试题库 全局的 setTimeout() 方法设置一个定时器&#xff0c;一旦定时器到期&#xff0c;就会执行一个函数或指定的代码片…

【开源】前后端分离后台管理系统

系统环境 JDK 17Maven 3.0.0MySQL 5.7.0Spring Boot 3.0.10 演示 橙子官网&#xff1a;http://hengzq.cnGitHub 代码下载&#xff1a;https://github.com/mmd0308/orangeGitee 代码下载&#xff1a;https://gitee.com/hengzq/orange 项目截图

Algorithms_LSM树(Log-Structured Merge Tree)

文章目录 引言1. LSM树的原理1.1 写入日志1.2 内存组件1.3 磁盘上的SSTable文件1.4 合并操作 2. LSM树的使用场景2.1 分布式数据库系统2.2 云存储系统2.3 日志和时间序列数据2.4 数据备份和归档 LSM VS BTree结论 引言 在当今信息时代&#xff0c;数据的存储和管理变得越来越重…

信息系统项目管理师第四版--风险管理--可搜索可编辑版本

1. 对目录进行了细化&#xff0c;从目录可以清晰看到每个过程的输入输出工具技术都有哪些&#xff0c;直接点击目录就可以跳转到相应的章节&#xff0c;免得自己在pdf文件里面一直翻一直翻&#xff0c;非常方便。是可编辑版本&#xff0c;还可以进行全文搜索。 下图是目录的部…

LoRaWAN物联网架构

与其他网关一样&#xff0c;LoRaWAN网关也需要在规定的工作频率上工作。在特定国家部署网关时&#xff0c;必须要遵循LoRa联盟的区域参数。不过&#xff0c;它是没有通用频率的&#xff0c;每个国家对使用非授权MHZ频段都有不同的法律规定。例如&#xff0c;中国的LoRaWAN频段是…

Centos7下搭建H3C log服务器

一、rsyslogH3C 安装rsyslog服务器 关闭防火墙 systemctl stop firewalld && systemctl disable firewalld关闭selinux sed -i s/enforcing/disabled/ /etc/selinux/config && setenforce 0centos7服务器&#xff0c;通过yum安装rsyslog yum -y install r…

如何用devtools快速开发一个R语言包?

如何用devtools快速开发一个R语言包&#xff1f; 1. 准备工作2. 如何完整开发一个R包3. 初始化新包4. 启用Git仓库5. 按照目标实现一个函数6. 在.R文件夹下创建文件并保存代码7. 函数测试8. 阶段性总结9. 时不时地检查完整工作状态10. 编辑DESCRIPTION文件11. 配置许可证12. 配…

vmware 启动qnx 环境下载配置

SDP QNX 安装手册 http://www.qnx.com/developers/docs/7.0.0/#com.qnx.doc.qnxsdp.quickstart/topic/install_host.html qnxsdp-6.5.0-x86-201007091524-nto.iso https://dude6.com/q/a/4990303.html http://www.qnx.com/download/feature.html?programid23647 vmarea …

【Linux】补充:进程管理之手动控制进程,以及计划任务

目录 一、手动启动进程 1、理解前台启动与后台启动 2、如何完成前台启动后台启动的切换 3、完成并行执行多个任务 4、结束进程 1、kill 2、killall 2、pkill 二、计划任务 1、at一次性计划任务 2、实操 2、周期性计划任务 1、关于设置周期性任务的配置文件以及格式…

react 实现chatGPT的打印机效果 兼容富文本,附git地址

1、方式一 &#xff1a;使用插件 typed.js typed.js 网站地址&#xff0c;点我打开 1.1、核心代码如下&#xff1a; //TypeWriteEffect/index.tsx 组件 import React, { useEffect, useRef } from react; import Typed from typed.js; import { PropsType } from ./index.d;…

【STM32】定时器

systick定时器&#xff1a; 【STM32】Systick定时器-CSDN博客 0.通用定时器框图 1.时钟源 2.控制器 3.输入捕获 计数器实际上是与比较寄存器的影子寄存器进行比较的。 4.输出比较 1.STM32的定时器学习要点 参考手册 STM32F1xx中文参考手册.pdf 林何/STM32F103C8 - 码云 -…

【LIUNX】机器互访:免密登陆

服务器端 /etc/ssh/sshd_config 口常见SSH服务器监听的选项如下&#xff1a; Port 22//监听的端口为22 Protocol 2//使用SSH V2协议 ListenAdderss 0.0.0.0 //监听的地址为所有地址 UseDNS no//禁止DNS反向解析 客户端 /etc/ssh/ssh_config 口常见用户登录控制选项如下&#…