四元数

四元数的定义与基本运算
在飞行器姿态解算中一般采用四元数表达旋转,个人理解,旋转矩阵用3*3的矩阵以及附加的6个非线性约束(列向量之间相互正交且模长为1)描述了旋转,而四元数通过4个数以及一个约束(单位四元数)描述了同样的信息量,类似对于一个线性方程组,通过代换消元的方式减少约束,减少变量数,达到减少计算量的目的。实际上,惯性导航系统中是通过四元数实现快速循环迭代,它能够以1000Hz的速度更新运动对象的姿态。

三维旋转表示

  1. 单位四元数 q~=cos(θ/2)+w^sin(θ/2)\tilde{q}=cos(\theta/2)+\widehat{w}sin(\theta/2)q~​=cos(θ/2)+wsin(θ/2) 可以表示在三维空间中绕(单位向量)w^\widehat{w}w 旋转 θ\thetaθ 角的旋转算子。注意,w^\widehat{w}w 在这里被看作三维空间的一个向量而不是一个超复数。
  2. 向量的旋转:
    a. 将向量“四元化”:x~=0+x→\tilde{x}=0+\overrightarrow{x}x~=0+x;
    b. 对向量进行绕轴 w^\widehat{w}w 旋转 θ\thetaθ 角,得到新向量 x~′=q~x~q~∗\tilde{x}^{'}=\tilde{q}\tilde{x}\tilde{q}^{*}x~′=q~​x~q~​∗.
  3. 等价的旋转矩阵:
    对于四元数 q=q0+q1i+q2j+q3kq=q_0+q_1i+q_2j+q_3kq=q0​+q1​i+q2​j+q3​k
    将 x~′=q~x~q~∗\tilde{x}^{'}=\tilde{q}\tilde{x}\tilde{q}^{*}x~′=q~​x~q~​∗ 展开,合并同类项得
    R=[2(q02+q12)−12(q1q2−q0q3)2(q1q3+q0q2)2(q1q2+q0q3)2(q02+q22)−12(q2q3−q0q1)2(q1q3−q0q2)2(q0q1+q2q3)2(q02+q32)−1]R = \left [ \begin{matrix} 2(q_0^2+q_1^2)-1 & 2(q_1q_2-q_0q_3) & 2(q_1q_3+q_0q_2) \\ 2(q_1q_2+q_0q_3) & 2(q_0^2+q_2^2)-1 & 2(q_2q_3-q_0q_1) \\ 2(q_1q_3-q_0q_2) & 2(q_0q_1+q_2q_3) & 2(q_0^2+q_3^2)-1 \\ \end{matrix} \right ] R=⎣⎡​2(q02​+q12​)−12(q1​q2​+q0​q3​)2(q1​q3​−q0​q2​)​2(q1​q2​−q0​q3​)2(q02​+q22​)−12(q0​q1​+q2​q3​)​2(q1​q3​+q0​q2​)2(q2​q3​−q0​q1​)2(q02​+q32​)−1​⎦⎤​
    以上是左手系下的表示,关于左/右手系的区分:左右手比“枪”的形状,食指指向对手(You),代表 Y 轴,大拇指是用来瞄准的(x 像不像准心),因此是 X 轴,剩下的中指代表 Z 轴。此时,左手对应的坐标系就是左手系,右手对应右手系。
    右手系表达:
    R=[1−2(q22+q32)2(q1q2−q0q3)2(q1q3+q0q2)2(q1q2+q0q3)1−2(q12+q32)2(q2q3−q0q1)2(q1q3−q0q2)2(q0q1+q2q3)1−2(q12+q22)]R = \left [ \begin{matrix} 1-2(q_2^2+q_3^2) & 2(q_1q_2-q_0q_3) & 2(q_1q_3+q_0q_2) \\ 2(q_1q_2+q_0q_3) & 1-2(q_1^2+q_3^2) & 2(q_2q_3-q_0q_1) \\ 2(q_1q_3-q_0q_2) & 2(q_0q_1+q_2q_3) & 1-2(q_1^2+q_2^2) \\ \end{matrix} \right ] R=⎣⎡​1−2(q22​+q32​)2(q1​q2​+q0​q3​)2(q1​q3​−q0​q2​)​2(q1​q2​−q0​q3​)1−2(q12​+q32​)2(q0​q1​+q2​q3​)​2(q1​q3​+q0​q2​)2(q2​q3​−q0​q1​)1−2(q12​+q22​)​⎦⎤​
    后面的 code 用的是右手系,书本上讲的左手系,在其他地方也有用途,注意区分。

四元数的微分形式

https://blog.csdn.net/qq_39554681/article/details/88909564

姿态解算

主要结合一个四轴飞控项目进行理解。
首先说明一下导航坐标系 n 的定义: x/y/z 轴依次指向东、北、天,设航偏角为 ψ\psiψ (注意:顺时针为正,习惯上北偏东为正),俯仰角为 θ\thetaθ,横滚角为 γ\gammaγ ,机体坐标系 b 与 n 的关系为
Tnb=[cγcψ+sγsψsθ−cγsψ+sγcψsθ−sγcθsψcθcψcθsθsγcψ−cγsψsθ−sγsψ−cγcψsθcγcθ]T^b_n=\left [ \begin{matrix} c\gamma{c}\psi+s\gamma{s}\psi{s}\theta & -c\gamma{s}\psi+s\gamma{c}\psi{s}\theta & -s\gamma{c}\theta \\ {s}\psi{c}\theta & {c}\psi{c}\theta & {s}\theta \\ s\gamma{c}\psi-c\gamma{s}\psi{s}\theta & -s\gamma{s}\psi-c\gamma{c}\psi{s}\theta & c\gamma{c}\theta \\ \end{matrix} \right ] Tnb​=⎣⎡​cγcψ+sγsψsθsψcθsγcψ−cγsψsθ​−cγsψ+sγcψsθcψcθ−sγsψ−cγcψsθ​−sγcθsθcγcθ​⎦⎤​
变量定义:

 volatile struct V{float x;float y;float z;} Gravity, Acc, Gyro, AccGravity;static struct V GyroIntegError = {0};static float KpDef = 0.8f;static float KiDef = 0.0003f;static Quaternion NumQ = {1, 0, 0, 0};float q0_t, q1_t, q2_t, q3_t;// float NormAcc;float NormQuat;float HalfTime = dt * 0.5f;
  1. 重力加速度归一化为单位向量;
 // 加速度归一化NormQuat = Q_rsqrt(squa(MPU6050.accX) + squa(MPU6050.accY) + squa(MPU6050.accZ));// Q_rsqrt:快速计算 1/Sqrt(x)Acc.x = pMpu->accX * NormQuat;Acc.y = pMpu->accY * NormQuat;Acc.z = pMpu->accZ * NormQuat;
  1. 提取四元数等效旋转矩阵中的重力分量,就是通过旋转矩阵将重力(设为 1,步骤 1 中加速度归一化做铺垫)转换至机体坐标系下;
 // 提取等效旋转矩阵中的重力分量Gravity.x = 2 * (NumQ.q1 * NumQ.q3 - NumQ.q0 * NumQ.q2);Gravity.y = 2 * (NumQ.q0 * NumQ.q1 + NumQ.q2 * NumQ.q3);Gravity.z = 1 - 2 * (NumQ.q1 * NumQ.q1 + NumQ.q2 * NumQ.q2);
  1. 向量叉积得出姿态误差,Acc 是通过加速度计测量得到的,AccGravity 是通过陀螺积分计算而来,本质上代表的是一个量,叉积仍是在机体坐标系上的,而且其大小与陀螺积分误差成正比,用于纠正陀螺,这里体现了传感器数据的融合;
 // 向量叉乘得出的值AccGravity.x = (Acc.y * Gravity.z - Acc.z * Gravity.y);AccGravity.y = (Acc.z * Gravity.x - Acc.x * Gravity.z);AccGravity.z = (Acc.x * Gravity.y - Acc.y * Gravity.x);
  1. 进行补偿;
 // 再做加速度积分补偿角速度的补偿值GyroIntegError.x += AccGravity.x * KiDef;GyroIntegError.y += AccGravity.y * KiDef;GyroIntegError.z += AccGravity.z * KiDef;// 角速度融合加速度积分补偿值Gyro.x = pMpu->gyroX * Gyro_Gr + KpDef * AccGravity.x + GyroIntegError.x; // 弧度制Gyro.y = pMpu->gyroY * Gyro_Gr + KpDef * AccGravity.y + GyroIntegError.y;Gyro.z = pMpu->gyroZ * Gyro_Gr + KpDef * AccGravity.z + GyroIntegError.z;
  1. 一阶 Runge-Kutta 更新四元数;
 // 一阶龙格库塔法, 更新四元数q0_t = (-NumQ.q1 * Gyro.x - NumQ.q2 * Gyro.y - NumQ.q3 * Gyro.z) * HalfTime;q1_t = (NumQ.q0 * Gyro.x - NumQ.q3 * Gyro.y + NumQ.q2 * Gyro.z) * HalfTime;q2_t = (NumQ.q3 * Gyro.x + NumQ.q0 * Gyro.y - NumQ.q1 * Gyro.z) * HalfTime;q3_t = (-NumQ.q2 * Gyro.x + NumQ.q1 * Gyro.y + NumQ.q0 * Gyro.z) * HalfTime;NumQ.q0 += q0_t;NumQ.q1 += q1_t;NumQ.q2 += q2_t;NumQ.q3 += q3_t;
  1. 四元数归一化,因为计算机中的浮点运算存在误差,计算过程中四元数会失去规范化特性(表征旋转我们使用单位四元数或者规范化的四元数)。
 // 四元数归一化NormQuat = Q_rsqrt(squa(NumQ.q0) + squa(NumQ.q1) + squa(NumQ.q2) + squa(NumQ.q3));NumQ.q0 *= NormQuat;NumQ.q1 *= NormQuat;NumQ.q2 *= NormQuat;NumQ.q3 *= NormQuat;

移动机器人学(二)四元数相关推荐

  1. 机器人学:四元数插值方法SLERP和SQUAD的C语言实现

    目录 文件声明 使用到的基本运算 SLERP SQUAD 在理解四元数的SLERP和SQUAD的数学推导的基础上,使用C语言实现这两种插值方法: 参考:Understanding Quaternion ...

  2. 四元数左乘右乘_复数/四元数和转动/转动群

    关于U(1)与SO(2)或SU(2)与SO(3)之间关系的讨论在很多的群论书.或讲物理中对称性的教材中都已有详细的论述.对于复数.四元数和转动之间的讨论更是在一般形式.e指数.矩阵之间随意切换.这样可 ...

  3. 四元数与旋转——学习笔记(一)

    联系方式:860122112@qq.com 四元数与旋转--学习笔记(一) 四元数与旋转--学习笔记(二) 四元数与旋转--学习笔记(三) 一.引言 三维空间里向量或坐标系之间的旋转关系可以用 3×3 ...

  4. 从零开始学习VIO笔记 --- 第一讲:基础知识(四元数,李代数)

    从零开始学习VIO笔记 --- 第一讲:基础知识(四元数,李代数) 一. 向量的内积与外积 二. 旋转与平移 2.1 旋转表示 --- 旋转矩阵R 2.2 平移向量 2.3 变换矩阵T与齐次坐标 2. ...

  5. 欧拉角,万向节锁和四元数

    一.欧拉角 对于一个3D空间中的一个物体的旋转,我们都可以理解为围绕三维空间中的绕着基向量为轴的三次旋转的结果. 绕基向量为轴的旋转我们可以用旋转矩阵来表示,其中Rx,Ry,Rz是沿着x,y,z轴旋转 ...

  6. D3D中四元数的表示

    1.定义. DIRECTX9文档中定义,令q为一四元数,theta为绕轴axis旋转的角度,则: q.x = sin(theta/2) * axis.x q.y = sin(theta/2) * ax ...

  7. 空间表示与变换—— 台湾交通大学机器人学公开课(二)

    额外参考教程:<熊有伦. 机器人学: 建模, 控制与视觉. 华中科技大学出版社, 2018.> 1. 刚体位姿描述 机械臂的各个连杆,以及其与环境之间的位置和姿态描述,需要一种描述刚体位姿 ...

  8. 机器人学一些概念2——四元数,D-H 参数

    文章目录 机器人学一些概念2 四元数 D-H 参数 机器人学一些概念2 四元数 ​ 这里是机器人旋转中用到的四元数,总结来看主要是用于运算方便,避免θ\thetaθ接近0的时候造成旋转矩阵无法求解. ...

  9. 【飞控理论】【惯性导航基础】二维平面的旋转如何用代数表示?三维平面的旋转如何用代数表示?什么是四元数?四元数、欧拉角、方向余弦之间有什么关系?

    上一篇欧拉角 由于欧拉角在描述三维空间物体旋转问题时存在万向节死锁问题(详情戳这里),所以引入四元数概念. 目录 1.二维平面的旋转 2.三维平面的旋转(什么是四元数) 3.<捷联惯性导航> ...

最新文章

  1. 邮件服务器 之 基于FreeBSD和Postfix的邮件系统与邮件列表的web mail安装
  2. vc++6.0 同步本机时间到Internet NTP服务器 编译通过
  3. rust(43)-rust语言特点与版本发布
  4. SpringBoot_入门-Spring Boot简介
  5. LRU缓存实现(Java)
  6. 使用onclick跳转到其他页面。使用button跳转到指定url
  7. WSGI服务器实践二--实践一个基本功能的WSGI服务器
  8. 重磅!AI大牛邢波出任AI大学校长,李开复姚期智都是校董
  9. linux一键搭建ddns,LINUX下搭建DDNS
  10. java11新特性_Java11 发布前抓紧掌握这些新特性
  11. DataGrid固定列宽
  12. 如何用python打开qq_如何用python登录qq
  13. 命令行下获取公网IP地址汇总
  14. Android手机无法识别SD卡的处理方法
  15. Python的异步编程介绍(MD)
  16. 按键精灵模拟键盘批量输入英文大小写
  17. 使用高德SDK开发安卓地图应用软件
  18. 使用Openoffice实现并发多进程word文档转换预览
  19. 自家的摇头扇线掉了 (电风扇的五根线怎么接)
  20. c# 读hex_C# Hex编码和解码

热门文章

  1. Fiddler抓包工具详细介绍
  2. php的字体 怎么变大,网页字体怎么变大
  3. CAD图案填充:什么是CAD线图案?
  4. 计算机少了4个磁盘,电脑硬盘突然少了几个分区,这是怎么回事?如何修复?...
  5. 华为上半年手机销量_霸气侧漏,如何看待小米和华为的上半年手机销量
  6. mapi java_Powershell从注册表中查询默认MAPI客户端的例子
  7. 有哪些靠谱的服务器安全软件?
  8. c语言循环程序模板,循环结构程序设计C语言程序
  9. 显卡超频稳定测试软件,显卡超频稳定性测试终极手段
  10. 自学python(2):利用opencv实现读图,显示,画框,裁剪的python代码