机器人学基础——旋转矩阵转四元数的C++程序实现

一、理论基础

1. 旋转矩阵

旋转矩阵通常是一个3x3矩阵,表示物体的旋转变换。一个标准的旋转矩阵 ( R ) 如下:

R = ( r 11 r 12 r 13 r 21 r 22 r 23 r 31 r 32 r 33 ) R = \begin{pmatrix} r_{11} & r_{12} & r_{13} \\ r_{21} & r_{22} & r_{23} \\ r_{31} & r_{32} & r_{33} \end{pmatrix} R= r11r21r31r12r22r32r13r23r33

2. 四元数的定义

四元数的形式为 ( q = (w, x, y, z) ),其中:

  • ( w ) 是实部,
  • ( x, y, z ) 是虚部。

四元数 ( q ) 和旋转矩阵 ( R ) 之间的关系可以通过以下公式进行转换。

3. 姿态矩阵转四元数公式

根据旋转矩阵 ( R ) 的迹(trace),可以选择不同的公式来计算四元数。

(1) 如果矩阵的迹 trace ( R ) > 0 \text{trace}(R) > 0 trace(R)>0

矩阵的迹是对角线元素之和:

trace ( R ) = r 11 + r 22 + r 33 \text{trace}(R) = r_{11} + r_{22} + r_{33} trace(R)=r11+r22+r33

在这种情况下,四元数可以通过以下公式计算:

S = 2 × trace ( R ) + 1 S = 2 \times \sqrt{\text{trace}(R) + 1} S=2×trace(R)+1

w = 0.25 × S w = 0.25 \times S w=0.25×S
x = r 32 − r 23 S x = \frac{r_{32} - r_{23}}{S} x=Sr32r23
y = r 13 − r 31 S y = \frac{r_{13} - r_{31}}{S} y=Sr13r31
z = r 21 − r 12 S z = \frac{r_{21} - r_{12}}{S} z=Sr21r12

(2) 如果矩阵的迹 trace ( R ) ≤ 0 \text{trace}(R) \leq 0 trace(R)0

需要根据不同的矩阵元素选择最大对角线元素,选择不同的公式进行计算。

  • 如果 r 11 r_{11} r11 是最大值:
    S = 2 × 1 + r 11 − r 22 − r 33 S = 2 \times \sqrt{1 + r_{11} - r_{22} - r_{33}} S=2×1+r11r22r33
    w = r 32 − r 23 S w = \frac{r_{32} - r_{23}}{S} w=Sr32r23
    x = 0.25 × S x = 0.25 \times S x=0.25×S
    y = r 12 + r 21 S y = \frac{r_{12} + r_{21}}{S} y=Sr12+r21
    z = r 13 + r 31 S z = \frac{r_{13} + r_{31}}{S} z=Sr13+r31

  • 如果 r 22 r_{22} r22是最大值:
    S = 2 × 1 + r 22 − r 11 − r 33 S = 2 \times \sqrt{1 + r_{22} - r_{11} - r_{33}} S=2×1+r22r11r33
    w = r 13 − r 31 S w = \frac{r_{13} - r_{31}}{S} w=Sr13r31
    x = r 12 + r 21 S x = \frac{r_{12} + r_{21}}{S} x=Sr12+r21
    y = 0.25 × S y = 0.25 \times S y=0.25×S
    z = r 23 + r 32 S z = \frac{r_{23} + r_{32}}{S} z=Sr23+r32

  • 如果 ( r 33 ( r_{33} (r33是最大值:
    S = 2 × 1 + r 33 − r 11 − r 22 S = 2 \times \sqrt{1 + r_{33} - r_{11} - r_{22}} S=2×1+r33r11r22
    w = r 21 − r 12 S w = \frac{r_{21} - r_{12}}{S} w=Sr21r12
    x = r 13 + r 31 S x = \frac{r_{13} + r_{31}}{S} x=Sr13+r31
    y = r 23 + r 32 S y = \frac{r_{23} + r_{32}}{S} y=Sr23+r32
    z = 0.25 × S z = 0.25 \times S z=0.25×S



二、C++程序实现

根据第一部分理论基础的介绍,很容易可以写出对应的C++程序,我写的一个示例如下所示,其中matrixToQuaternion函数接收一个3x3旋转矩阵,利用上面介绍的四元数和旋转矩阵之间的数学公式,计算并返回对应的四元数。 printQuaternion函数用于将四元数的值输出到终端。

#include <iostream>
#include <cmath>struct Quaternion {double w, x, y, z;
};// 旋转矩阵转换为四元数的函数
Quaternion matrixToQuaternion(double R[3][3]) {Quaternion q;double trace = R[0][0] + R[1][1] + R[2][2]; // 矩阵的迹if (trace > 0.0) {double s = 0.5 / sqrt(trace + 1.0);q.w = 0.25 / s;q.x = (R[2][1] - R[1][2]) * s;q.y = (R[0][2] - R[2][0]) * s;q.z = (R[1][0] - R[0][1]) * s;} else {if (R[0][0] > R[1][1] && R[0][0] > R[2][2]) {double s = 2.0 * sqrt(1.0 + R[0][0] - R[1][1] - R[2][2]);q.w = (R[2][1] - R[1][2]) / s;q.x = 0.25 * s;q.y = (R[0][1] + R[1][0]) / s;q.z = (R[0][2] + R[2][0]) / s;} else if (R[1][1] > R[2][2]) {double s = 2.0 * sqrt(1.0 + R[1][1] - R[0][0] - R[2][2]);q.w = (R[0][2] - R[2][0]) / s;q.x = (R[0][1] + R[1][0]) / s;q.y = 0.25 * s;q.z = (R[1][2] + R[2][1]) / s;} else {double s = 2.0 * sqrt(1.0 + R[2][2] - R[0][0] - R[1][1]);q.w = (R[1][0] - R[0][1]) / s;q.x = (R[0][2] + R[2][0]) / s;q.y = (R[1][2] + R[2][1]) / s;q.z = 0.25 * s;}}return q;
}// 打印四元数的函数
void printQuaternion(const Quaternion &q) {std::cout << "Quaternion: (x = " << q.x << ", y = " << q.y << ", z = " << q.z << ", w = " << q.w << ", )\n";
}int main() {// 设定旋转矩阵double R[3][3] = {-0.8545994, -0.5192878,  0.0000000,-0.5192878,  0.8545994,  0.0000000,0.0000000,  0.0000000, -1.0000000};// 将旋转矩阵转换为四元数Quaternion q = matrixToQuaternion(R);// 打印四元数printQuaternion(q);return 0;
}

编译和运行:

  1. 将以上代码保存到一个文件,例如 matrix_to_quaternion.cpp

  2. 然后在终端执行以下指令编译该程序(文件名自行修改):

    g++ matrix_to_quaternion.cpp -o matrix_to_quaternion
    
  3. 编译成功后,使用以下指令运行程序:

    ./matrix_to_quaternion
    
  4. 上述程序中提供的旋转矩阵示例,运行输出的对应的四元数如下所示:

在这里插入图片描述

Quaternion: (x = -0.26963, y = 0.962964, z = 0, w = 0, )

在这里插入图片描述

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

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

相关文章

github demo网页制作

demo网页制作 1.创建一个空项目 2.上传编辑好的文件到本地服务器 3.申请一个token 4.本地项目夹下执行 git init git add --all git commit -m ‘first try’ git remote add origin https://github.com/username/reponame.git git push -u origin master 这个时候需要输入用…

在曲线图上最值和极值点位置进行适当标注

1、首先生成一组0-100的随机数&#xff0c;组内共有100个数据&#xff1b; yyrandi([0,100],[1,100]); 2、求这组数据的功率谱密度&#xff0c;并绘图&#xff1b; msize(yy,2); xdft fft(yy); % 计算功率谱密度 psd (1/m) * abs(xdft).^2; x1:m; loglog(x,psd,Linewid…

树及二叉树(选择题)

树 在树中&#xff0c;总结点数为所有结点的度和再加一 5、设一棵度为3的树&#xff0c;其中度为2&#xff0c;1.0的结点数分别为3&#xff0c;1&#xff0c;6。该树中度为3 的结点数为_。 二叉树 设二叉树的所有节点个数为N&#xff0c;度为零的结点&#xff08;叶子结点…

基于Java springboot+mybatis 家具城进销存管理系统 (1)

基于Java springbootmybatis 家具城进销存管理系统 一、系统介绍二、功能展示1.登记出库(销售员)2.出库记录&#xff08;销售员&#xff09;3.首页(仓库管理员)4.出库管理&#xff08;仓库管理员&#xff09;5.统计分析&#xff08;仓库管理员&#xff09;6.账号管理&#xff0…

8588 表达式求值

### 思路 1. **初始化栈**&#xff1a;创建两个栈&#xff0c;一个用于存储操作数&#xff0c;另一个用于存储操作符。 2. **遍历表达式**&#xff1a;逐个字符检查&#xff1a; - 如果是数字&#xff0c;读取完整数字并压入操作数栈。 - 如果是操作符&#xff0c;根据优…

asp.net门诊管理系统网站(含协同过滤算法)VS开发sqlserver数据库web结构c#编程web网页设计

一、源码特点 asp.net门诊管理系统网站是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语言 开发。 应用技术&#xff1a;asp.net c…

x-cmd pkg | bat: cat 命令现代化替代品,终端用户必备工具

目录 简介快速上手安装使用与第三方工具组合使用 功能特点竞品和相关作品进一步阅读 简介 bat 是由 github.com/sharkdp 用 Rust 开发的 cat 命令现代化替代品。它比 cat 命令扩展了更多的现代化功能&#xff0c;如语法高亮、自动分页、Git集成等&#xff0c;能为用户提供更为…

[001-02-001].第2节:java开发环境搭建

4.1.书籍推荐&#xff1a; 4.2.人机交互方式 1.图形化界面(Graphical User Interface GUI)这种方式简单直观&#xff0c;使用者易于接受&#xff0c;容易上手操作2.命令行方式(Command Line Interface CLI)&#xff1a;需要有一个控制台&#xff0c;输入特定的指令&#xff0c…

0基础跟德姆(dom)一起学AI 数据处理和统计分析06-数据组合和缺失值处理

* 数据组合 * concat * merge * join(了解) * 缺失值处理 * apply方法详解 --- 1.DataFrame数据组合-concat连接 * 概述 * 连接是指把某行或某列追加到数据中, 数据被分成了多份可以使用连接把数据拼接起来 * 把计算的结果追加到现有数据集&#xff0c;也可以使用连…

Netty源码-业务流程之构建连接

Netty基本介绍&#xff0c;参考 Netty与网络编程 1、Netty构建连接 构建连接的流程 1.1 我们知道客户端连接服务端都是通过NioEventLoop来处理请求&#xff0c;NioEventLoop是一个线程&#xff0c;连接进来首先进入run()方法。 所以我们需要启动服务端&#xff0c;然后再启动…

基于JAVA+SpringBoot+Vue的线上辅导班系统的开发与设计

基于JAVASpringBootVue的线上辅导班系统的开发与设计 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#…

《当人工智能考上名校》:拥抱变化,让自己无可替代

01 说起人工智能&#xff0c;你会想起什么呢&#xff1f; 2016年3月&#xff0c;谷歌&#xff08;Google&#xff09;旗下DeepMind公司人工智能机器人阿尔法狗&#xff08;AlphaGo&#xff09;与围棋世界冠军、职业九段棋手李世石进行围棋人机大战&#xff0c;以4比1的总比分获…

【Canvas与诗词】木兰辞节选

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>金边钢底徽章</title><style type"text/css">…

通信入门系列书籍推荐一:通信原理和通信原理学习辅导

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 本节目录 一、背景 二、通信原理 …

探秘 Web Bluetooth API:连接蓝牙设备的新利器

引言 随着物联网技术的快速发展&#xff0c;蓝牙设备在日常生活中扮演着越来越重要的角色。而在 Web 开发领域&#xff0c;Web Bluetooth API 的出现为我们提供了一种全新的方式来连接和控制蓝牙设备。本文将深入探讨 Web Bluetooth API 的使用方法和原理&#xff0c;帮助开发…

react:React Hook函数

使用规则 只能在组件中或者其他自定义的Hook函数中调用 只能在组件的顶层调用&#xff0c;不能嵌套在if、for、 其他函数中 基础Hook 函数 useState useState是一个hook函数&#xff0c;它允许我们向组件中添加一个状态变量&#xff0c;从而控制影响组件的渲染结果 示例1…

全面详尽的 PHP 环境搭建教程

目录 目录 PHP 环境搭建概述 在 Windows 上搭建 PHP 环境 使用集成环境 XAMPP 安装步骤 配置和测试 常用配置 手动安装 Apache、PHP 和 MySQL 安装 Apache 安装 PHP 安装 MySQL 配置 PHP 连接 MySQL 在 Linux 上搭建 PHP 环境 使用 LAMP 方案 安装 Apache 安装 …

【管理文档】项目管理计划书(word原件套用2024)

本文档为XXX系统项目管理计划&#xff0c;本计划的主要目的是通过本方案明确本项目的项目管理体系。方案的主要内容包括&#xff1a;明确项目的目标及工作范围&#xff0c;明确项目的组织结构和人员分工&#xff0c;确立项目的沟通环境&#xff0c;确立项目进度管理方法&#x…

麻豆源码/视频源码/苹果cms-v10版本/带采集规则/完美运营版

麻豆源码/视频源码/苹果cms-v10版本/带采集规则/完美运营版 一键部署版本 完美运营版本带采集规则模块 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/89776673 更多资源下载&#xff1a;关注我。

系列课程:从零开始接触人工智能大模型

人工智能是计算机科学领域中最具前瞻性和影响力的技术之一。它是一种智慧型算法&#xff0c;能够模拟人类的思维过程&#xff0c;处理大量的数据和信息&#xff0c;从而发现隐藏在其中的规律和趋势。人工智能的应用范围非常广泛&#xff0c;包括语音识别、图像识别、自然语言处…