【ROS&GAZEBO】多旋翼无人机仿真(七)——四元数姿态控制

2023-05-16

【ROS&GAZEBO】多旋翼无人机仿真(一)——搭建仿真环境
【ROS&GAZEBO】多旋翼无人机仿真(二)——基于rotors的仿真
【ROS&GAZEBO】多旋翼无人机仿真(三)——自定义多旋翼模型
【ROS&GAZEBO】多旋翼无人机仿真(四)——探索控制器原理
【ROS&GAZEBO】多旋翼无人机仿真(五)——位置控制器
【ROS&GAZEBO】多旋翼无人机仿真(六)——SE(3)几何姿态控制器
【ROS&GAZEBO】多旋翼无人机仿真(七)——四元数姿态控制

为什么需要四元数

从直观来看,欧拉角或者姿态角是最直观的能感受到三维旋转的表示方法。因此,在做多旋翼或者其他机器人的姿态控制时,最能够直观接受的方法就是欧拉角姿态控制。可能很多人会觉得,为什么需要那么多花里胡哨的方法呢,控制俯仰-滚转-航向三个姿态角就能够稳定姿态了。但是,用姿态角进行控制是有前提的,那就是小角度假设,如果不满足小角度的条件,那么姿态角控制就不适用。姿态角是存在旋转顺序的,并且存在万向节死锁,具体可以看上一篇【ROS&GAZEBO】多旋翼无人机仿真(六)——SE(3)几何姿态控制器

四元数表示

因此,我们想要一种参数少,并且不存在旋转顺序和死锁的姿态描述方法。因此,四元数表示法就被提出来了,四元数通常表示形式是这样的:
q = [ q 0 q 1 q 2 q 3 ] \mathbf q=\begin{bmatrix}q_0&q_1&q_2&q_3\end{bmatrix} q=[q0q1q2q3]
采用轴角方式表达如下:
q = [ c o s α 2 u s i n α 2 ] \mathbf q=\begin{bmatrix}cos\frac\alpha2\\\mathbf usin\frac\alpha2\end{bmatrix} q=[cos2αusin2α]
它对应于绕一个向量 v = ( v x , v y , v z ) \mathbf v=\left(v_x,v_y,v_z\right) v=(vx,vy,vz)为轴旋转 θ \theta θ的操作(右手法则的旋转):
q = c o s θ 2 + i s i n θ 2 + j s i n θ 2 + k s i n θ 2 \mathbf q=cos\frac\theta2+\mathbf isin\frac\theta2+\mathbf jsin\frac\theta2+\mathbf ksin\frac\theta2 q=cos2θ+isin2θ+jsin2θ+ksin2θ

四元数旋转

我们知道,姿态矩阵左乘向量即可得到旋转后的向量,四元数同样也可以对向量进行旋转,四元数对三维向量的旋转公式如下:
v ′ = q v q ∗ \mathbf v'=\mathbf q\mathbf{vq}^\ast v=qvq
其中 v \mathbf{v} v为纯四元数:
v = [ 0 v ⃗ ] \mathbf v=\left[\begin{array}{l}0\\\vec v\end{array}\right] v=[0v ]
v ⃗ \vec v v 就是三维向量,实部为0,这个公式也是四元数旋转中用得最广泛的一个公式。本篇讲的是如何做四元数误差控制,因此证明过程这里不做讲解

有了这个公式,我们就可以定义四元数的连续旋转。我们来看下面的情况。首先对 v 1 \mathbf {v_1} v1进行旋转,这里旋转的四元数是 q 1 \mathbf q_1 q1
v 1 ′ = q 1 v 1 q 1 ∗ \mathbf {v_1}'=\mathbf q_1\mathbf {v_1}\mathbf {q_1}^\ast v1=q1v1q1
接着用 q 2 \mathbf {q_2} q2 v 1 ′ \mathbf {v_1}' v1进行旋转:
v ′ ′ = q 2 v ′ q 2 ∗ \mathbf v''={\mathbf q}_2\mathbf v'\mathbf q_2^\ast v=q2vq2
可以发现,这里的 v ′ ′ \mathbf v'' v v 1 \mathbf {v_1} v1经过了两次旋转得到的结果,那 v ′ ′ \mathbf v'' v v 1 \mathbf {v_1} v1的关系是什么样的呢?下面的式子很明显成立
v ′ ′ = q 2 ( q 1 v q 1 ∗ ) q 2 ∗ \mathbf v''={\mathbf q}_2\left({\mathbf q}_1\mathbf v{\mathbf q}_1{}^\ast\right){\mathbf q}_2{}^\ast v=q2(q1vq1)q2
然后根据单位四元数共轭的性质:
q ∗ = q − 1 \mathbf q^\ast=\mathbf q^{-1} q=q1
可得
v ′ ′ = ( q 2 q 1 ) v ( q 2 q 1 ) ∗ \mathbf v''=\left({\mathbf q}_2{\mathbf q}_1\right)\mathbf v\left({\mathbf q}_2{\mathbf q}_1\right)^\ast v=(q2q1)v(q2q1)
因此, q 2 q 1 {\mathbf q}_2{\mathbf q}_1 q2q1是这两次旋转复合的四元数。也说明了四元数乘法在几何上的意义就是连续的旋转。好了,有了这个性质,我们就可以去计算四元数的姿态误差了。我们来看下面这个图,这个图表示的就是连续旋转两次的意思。
在这里插入图片描述
那如果我们把 θ 2 \theta_2 θ2换一下,用 Δ θ \Delta\theta Δθ来表示, v \mathbf {v} v表示初始水平姿态的向量, v s \mathbf {v_s} vs表示当前姿态的向量, v d \mathbf {v_d} vd表示期望姿态的向量。那么连续旋转公式变为:
q d = Δ q ⋅ q s {\mathbf q}_d=\Delta\mathbf q\cdot{\mathbf q}_s qd=Δqqs
Δ q \Delta\mathbf q Δq表示的是旋转 Δ θ \Delta\theta Δθ对应的四元数, q d \mathbf q_d qd表示旋转 θ d \theta_d θd对应的四元数,用图来表示如下:
在这里插入图片描述
Δ q \Delta\mathbf q Δq很明显,就是从当前的姿态到期望姿态的误差。那如何得到 Δ q \Delta\mathbf q Δq呢?很明显,这不能直接通过减法得到,将上面的式中进行变换:
q d ⋅ ( q s ) − 1 = Δ q ⋅ q s ⋅ ( q s ) − 1 Δ q = q d ⋅ ( q s ) − 1 \begin{array}{c}{\mathbf q}_d\cdot\left({\mathbf q}_s\right)^{-1}=\Delta\mathbf q\cdot{\mathbf q}_s\cdot\left({\mathbf q}_s\right)^{-1}\\\Delta\mathbf q={\mathbf q}_d\cdot\left({\mathbf q}_s\right)^{-1}\end{array} qd(qs)1=Δqqs(qs)1Δq=qd(qs)1
终于大功告成,误差四元数计算公式就有了。然后怎么得到各轴误差角度呢?假设期望和当前的误差角很小,那么下式中的 s i n θ sin\theta sinθ θ \theta θ就可以替换:
q = c o s θ 2 + i s i n θ 2 + j s i n θ 2 + k s i n θ 2 \mathbf q=cos\frac\theta2+\mathbf isin\frac\theta2+\mathbf jsin\frac\theta2+\mathbf ksin\frac\theta2 q=cos2θ+isin2θ+jsin2θ+ksin2θ
因此,得到的误差四元数的虚部就是各轴的姿态误差分量,但是还忽略了一个重要的问题,那就是同样的旋转,四元数并不是唯一的,可以通过图来直观的理解一下:

在这里插入图片描述
v \mathbf v v v d \mathbf v_d vd除了虚线表示的 θ d \theta_d θd之外, 2 π − θ d 2\mathrm\pi-\theta_d 2πθd很显然也可以达到同样的旋转,这其中就有一个最短旋转角度的问题,但是这两个旋转是有关系的,即 2 π − θ d 2\mathrm\pi-\theta_d 2πθd的四元数为 − q -\mathbf q q。所以,假想一下,飞机从15度回到0度有两种方式,一种是绕轴旋转15度,还有一种是绕轴旋转365度,程序算出来说,哎,我就是玩,我不直接用最小的角度回去,我要绕轴旋转365度回去,,,,好像从原理上来说没毛病,没有错,都可以回到0度,但是实际上没人也不会有人用后面这种方式去这样做吧。。除了谁有十年的脑血栓。

回到正题,我们得到误差的时候也需要去回避这个问题,那怎么去回避呢,上面说过了, − q -\mathbf q q旋转的角度为 2 π − θ d 2\mathrm\pi-\theta_d 2πθd,那就好办了, q \mathbf q q的实部 q 0 \mathrm q_0 q0 c o s θ 2 cos\frac\theta2 cos2θ,而 c o s θ 2 cos\frac\theta2 cos2θ只有在 [ − π , π ] \left[-\pi,\pi\right] [π,π]上为正,超过这个范围就为负,那可不可以根据 q 0 \mathrm q_0 q0来判断旋转角是不是最小的呢,答案很明显是的。

因此,只要判断 q 0 \mathrm q_0 q0的正负,就可以判断误差四元数是不是最小的旋转角,如果不是,我们将四元数取反,那最终根据四元数求得到的各轴误差角度分量,误差角度也就是期望的角速度,计算公式就可以整理出来了:
ω d = k s g n ( q e r r , 0 ) q e r r , 1 : 3 q e r r = q d ⋅ q s − 1 \begin{array}{c}{\mathbf\omega}_d=ksgn\left({\mathbf q}_{err,0}\right){\mathbf q}_{err,1:3}\\{\mathbf q}_{err}={\mathbf q}_d\cdot{\mathbf q}_s{}^{-1}\end{array} ωd=ksgn(qerr,0)qerr,1:3qerr=qdqs1
k k k是可调节的误差系数,因为是近似的,所以 k k k可以用来调节误差得到期望角速度的大小。需要注意的是,这里面的乘法是四元数乘法,并且四元数都是单位四元数。

好了,关于四元数姿态控制的内容就讲到这里,下一篇,将介绍如何将四元数控制方法用在四旋翼的仿真中。

最后再讲两句,鄙人也在深入研究四元数、李群和李代数这部分的内容,也深刻体会到四元数误差的推导过程可能会有一点抽象,因为四元数是四维空间的变量,所以并不能很直观的理解,这里需要小伙伴去深入琢磨。此外,四元数是复数的扩展,可能有的小伙伴会说,我连复数都没玩明白,复数其实就可以表示旋转,只不过是2维的旋转,四元数是3维的旋转,因此,复数和四元数有许多相似的性质,讲到这里,是不是感觉有些奇妙和不可思议,这就是数理美妙的所在。欢迎感兴趣的小伙伴添加微信 Reed_UAV 进行交流:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【ROS&GAZEBO】多旋翼无人机仿真(七)——四元数姿态控制 的相关文章

  • 解决sudo rosdep init ERROR: cannot download default sources list from问题,亲测可用

    解决sudo rosdep init ERROR cannot download default sources list from问题 xff0c 亲测可用 问题描述 按照 ros installation在ubuntu 16 04上安装
  • realsense d435i SDK及ROS Wrapper安装

    1 安装Realsense SDK git clone https span class token punctuation span span class token operator span github span class tok
  • 解决Git中下载assets文件列表转圈问题

    打开的Git项目 这里我以PcapPlusPlus为例 这里一直转圈打不开 xff0c 使用F12开发者工具 xff0c 用箭头选中这个转圈得到一个网站 通过这个网站可直接打开看见assets里面的全部内容
  • Ubuntu安装CMake

    cmake所做的事其实就是告诉编译器如何去编译链接源代码 你也许想问不是有makefile吗 xff0c 为什么还要它 xff1f 这里就牵涉到跨平台问题 而且其语法也简单 卸载已经安装的旧版的CMake 非必需 apt get autor
  • gPRC基本介绍

    1 说明 gRPC英文全名为Google Remote Procedure Call xff0c 即Google远程过程调用 xff0c 是Google发布的一个高性能 通用的开源RPC框架 xff0c 2 gRPC定义 gRPC是一个现代
  • STM32的引脚模式

    文章目录 51单片机引脚模式STM32单片机的引脚模式上拉输入 GPIO Mode IPU下拉输入 GPIO Mode IPD浮空输入 GPIO Mode IN FLOATING模拟输入 GPIO Mode AIN推挽输出 GPIO Mod
  • Qt QMessageBox使用详解

    本文详细的介绍了QMessageBox控件的各种操作 xff0c 例如 xff1a 消息提示框的使用 判断消息提示框的按钮 标准图标和自定义图标 定时关闭 自定义样式等操作 本文作者原创 xff0c 转载请附上文章出处与本文链接 Qt QM
  • SpringBoot_实现基本增删改查(前后端分离版)

    目录 自学自编实现一个简单的增删改查 xff08 前后端分离版本 xff09 与大家一起分享 xff0c 一起交流和学习 xff01 xff08 1 xff09 程序入口 xff08 2 xff09 建立数据库文件 xff08 3 xff0
  • 云服务器调出图形化界面

    如果需要在云服务器 xff08 centos xff09 上安装软件 xff0c 而且用图形化安装 xff0c 此方法可行以作记录 方法 span class token comment 命令行依次执行 span span class to
  • 超级产品:喜茶,凭什么能估值90亿

    疫情期间 xff0c 呆在家里的这些人 xff0c 最怀念的莫过于以前那一段靠奶茶续命的的日子了 肺炎快点结束吧 xff01 我想出门晒太阳 xff0c 吹海风 xff0c 我想念喜茶了 喜茶居然成为这些人的一个生活场景符号了 喜茶是一家什
  • linux应用编程和网络编程

    注 xff1a 本文是对朱老师linux应用编程和网络编程课程的备忘引导性笔记 xff0c 主要是为了能够在学完后快速回忆起相关内容 本文主要记录了一些关键易忘性知识点并包含少量理解性内容 xff0c 遵循尽量精简的原则 xff0c 以尽量
  • bsp_uart_fifo

    bsp uart fifo h 模块名称 串口中断 43 FIFO驱动模块 文件名称 bsp uart fifo h 说 明 头文件 ifndef BSP USART FIFO H define BSP USART FIFO H
  • 记一次自镜像Docker启动失败ubuntu 安装tini

    使用ubuntu18 04打包镜像启动失败报错信息 xff1a bin sh 1 tini not found 需要安装tini 而ubuntu本身软件源没有这个软件包 apt install y tini 报错 Unable to loc
  • Bluerov电池充电参数及过放补救方法

    Bluerov电池 1 Bluerov电池2 容量3 C rating xff08 放电倍率 xff09 4 充电电流5 充电注意事项及操作说明6 过放使用补救方法 xff08 但电池损耗已不可逆转 xff09 方法步骤 xff1a 1 B
  • Android Parcelable

    一 xff1a 是什么 xff1f Paracelable是android自己的实现序列化的接口 是anroid推荐使用的 那么什么事序列化呢 xff1f 简单来说就是将对象转换为可以传输的二进制流 二进制序列 的过程 这样我们就可以通过序
  • 字符串和字符串结束标志

    在C语言中 xff0c 是将字符串作为字符数组来处理的 例如 xff0c 如下程序 xff1a include lt stdio h gt int main char c 15 61 39 I 39 39 39 39 a 39 39 m 3
  • 单目相机标定方法总结

    单目相机标定的常用方法 xff0c 这里主要总结一下ROS和matlab标定工具箱 ROS相机标定 链接 xff1a https blog csdn net learning tortosie article details 7990125
  • Prometheus之修炼篇

    Prometheus之修炼篇 官方文档 xff1a https prometheus io 中文文档 xff1a 非官方 xff1a https songjiayang gitbooks io prometheus content 一 入门
  • QT视频播放不出来,报错 DirectShowPlayerService::doRender: Unresolved error code 80040266——没有安装视频解码器

    出错1 没有安装视频解码器 DirectShowPlayerService doRender Unresolved error code 0x80040266 出错2 文件路径不对或者文件名是中文的 DirectShowPlayerServ
  • ROS(1)编写第一个ROS程序(创建工作空间workspace和功能包package)

    一 先从三个方面去理解ROS xff1a xff08 自己查 xff0c 不详表 xff09 ROS是什么 xff0c 为什么使用ROS xff0c 如何使用ROS ROS xff08 Robot Operating System xff0

随机推荐

  • jetson nano TF卡镜像复制

    很重要的第一点 xff0c TF卡一定要进行格式化 xff0c 再进行其他操作 1 使用USB xff12 xff10 2 在win10无法将TF卡格式化成FAT32时 xff0c 使用DiskGenius xff0c 将TF卡格式化成FA
  • C++里数组名+1和数组名的地址+1的区别

    C C 43 43 里面的数组名字会退化为指针 xff0c 所以数组名a实际指的是数组的第一个元素的地址 而数组名作为指针来讲有特殊性 xff0c 它正在它所指向的内存区域中 xff0c amp a的值和a的数值是相同的 xff08 可以输
  • AD软件之模块化原理图

    首先我们创建两个原理图文件 然后我们在Sheet2 SchDoc里放置一个页面符并双击绿色的方框 选择目标文件 我们选择我们刚才创建的Sheet4 SchDoc 然后在 视图 gt 面板 gt Navigator选项 里点一下交互式导航 就
  • c语言中判断一个字符串是否包含另一个字符串

    1 使用库函数 string h strstr函数 函数名 strstr 功 能 在串中查找指定字符串的第一次出现 用 法 char strstr char str1 char str2 说明 xff1a 返回指向第一次出现str2位置的指
  • TCP协议-握手与挥手

    认识TCP协议 TCP全称为 传输控制协议 xff0c 这是传输层的一个协议 xff0c 对数据的传输进行一个详细的控制 特点 xff1a 面向字节流安全可靠面向连接 TCP协议段格式 源端口号与目的端口号 xff1a 这里与UDP的一样
  • C语言volatile的作用及使用场景介绍

    简介 volatile 先从基础的知识说起吧 xff0c 这样也有个来龙去脉 我们都知道 xff0c 程序运行后 xff0c 程序的数据都会被从磁盘加载到内存里面 xff08 主存 xff09 而当局部的指令被执行的时候 xff0c 内存中
  • SNMPv3报文

    相应的数字表示 xff08 对象标识符OID xff0c 唯一标识一个MIB对象 xff09 为 xff1a 1 3 6 1 2 1 4 3 图2 MIB树结构 当网络管理协议在报文中使用MIB变量时 xff0c 每个变量名后还要加一个后缀
  • 详解C语言中volatile关键字

    volatile提醒编译器它后面所定义的变量随时都有可能改变 xff0c 因此编译后的程序每次需要存储或读取这个变量的时候 xff0c 都会直接从变量地址中读取数据 如 果没有volatile关键字 xff0c 则编译器可能优化读取和存储
  • EtherCAT从站学习笔记——2.4通信模式

    在实际的控制系统中 xff0c 应用程序之间一般有两种类型的数据交换形式 xff1a 时间关键数据 time critical 和非时间关键数据 non time critial 时间关键表示特定的动作必须在确定的时间内完成或处理 xff0
  • 在linux下利用ls命令进行模糊查找

    如上图 xff0c 我们当前路径下有三个文件 xff0c 分别为helloworld c以及helloworld和1 c xff0c 直接输入命令ls则显示所有文件 xff0c 我们可以利用ls 加 的方向进行模糊查找 输入ls 目录名 形
  • 树莓派第一次开机自动连接WIFI(不用显示屏方法)

    当我们把树莓派系统镜像烧录到SD卡之后 xff0c 我们在windows看到的TF卡变成了空间很小的名为boot的盘 xff0c 我们在此目录下新建一个名为wpa supplicant conf空白文件 xff0c 并在其中加入以下代码 c
  • linux交叉编译时报错 libfreetype.so: file not recognized: File format not recognized

    root 64 ubuntu home linuxsystemcode 04th print info arm none linux gnueabi gcc finput charset 61 GBK o example1 example1
  • 神经网络epoch和batch的粗浅理解

    关于神经网络epoch和batch的理解 理解粗浅 xff0c 仅为个人想法 xff0c 提前感谢指正 epoch 一个epoch代表全部数据进入网络一次 xff0c 这个时候 xff0c 整个网络结构只对这批数据全部走完一次 xff0c
  • 目标检测与位姿估计(二十三):OpenCV+Aruco完成目标检测

    一份识别图像图像中所有Aruco的代码 include lt opencv2 core core hpp gt include lt opencv2 imgproc imgproc hpp gt include lt opencv2 hig
  • 随记(2):PP-Tracking工具

    目标跟踪任务意义 需求 xff1a 自动驾驶 智慧城市 安防领域面向车辆 行人 飞行器等快速运行的物体实时跟踪及分析 算法优势 xff1a 单纯的目标检测算法只能输出目标的定位 43 分类 xff0c 无法对移动的目标具体的运动行为及运动特
  • 【ROS&GAZEBO】多旋翼无人机仿真(一)——搭建仿真环境

    ROS amp GAZEBO 多旋翼无人机仿真 xff08 一 xff09 搭建仿真环境 ROS amp GAZEBO 多旋翼无人机仿真 xff08 一 xff09 搭建仿真环境 ROS amp GAZEBO 多旋翼无人机仿真 xff08
  • 【ROS&GAZEBO】多旋翼无人机仿真(三)——自定义多旋翼模型

    ROS amp GAZEBO 多旋翼无人机仿真 xff08 一 xff09 搭建仿真环境 ROS amp GAZEBO 多旋翼无人机仿真 xff08 二 xff09 基于rotors的仿真 ROS amp GAZEBO 多旋翼无人机仿真 x
  • 当使用CUBEMX,STM32F429阿波罗开发板的PCF8574与1-Wire冲突的解决办法。

    hello 大家好 xff01 距离上次写博客还是上半年呢 这几个月做了很多实验 xff0c 不过都很懒 xff0c 一直没有写上来 准备慢慢补回来 下面是我在使用原子哥的STM32F429的开发板做温度传感器项目的小实验时遇到的问题 1
  • 【ROS&GAZEBO】解决“is neither a launch file in package ”的问题

    这两天有小伙伴问到在安装完rotors后出现如下问题 xff1a 这个问题其实是ros环境没有配置好 xff0c 运行下面的命令 xff0c 将catkub ws加入ros的工作空间 span class token function mk
  • 【ROS&GAZEBO】多旋翼无人机仿真(七)——四元数姿态控制

    ROS amp GAZEBO 多旋翼无人机仿真 xff08 一 xff09 搭建仿真环境 ROS amp GAZEBO 多旋翼无人机仿真 xff08 二 xff09 基于rotors的仿真 ROS amp GAZEBO 多旋翼无人机仿真 x