ROS学习笔记之——机器人航向角的求解

最近在做项目的时候,需要测量移动机器人的航向角,为此写下本博文,来作为学习笔记。本博文的主要内容来自于网上的各种资料,并附上参考链接。

目录

四元数

欧拉角

轴角

四元数(Quaternion)的定义

四元数表示角度

四元数的各种转换

四元数转欧拉角

欧拉角转四元数

四元数转旋转矩阵

机器人航向角的求解

基于地磁传感器求解机器人航向角

基于IMU求解机器人航向角

基于IMU与地磁传感器求解机器人航向角(九轴姿态融合)

陀螺仪(gyroscope)

加速度计(accelerometer)

基于里程计求解机器人航向角

ROS中多传感器数据同步问题

message_filters

多线程

参考资料


四元数

旋转的表达方式有很多种,有欧拉角,旋转矩阵,轴角,四元素等等。首先我们来看看机器人中常用的四元数。

欧拉角

描述坐标系{B}相对于参考坐标系{A}的姿态有两种方式。第一种是绕固定(参考)坐标轴旋转:假设开始两个坐标系重合,先将{B}绕{A}的X轴旋转γ,然后绕{A}的Y轴旋转β,最后绕{A}的Z轴旋转α,就能旋转到当前姿态。可以称其为X-Y-Z fixed angles或RPY角(Roll横滚, Pitch俯仰, Yaw航向)。

由于是绕固定坐标系旋转,则旋转矩阵为

欧拉角使用最简单的x,y,z值来分别表示在x,y,z轴上的旋转角度,其取值为0-360(或者0-2pi),一般使用roll,pitch,yaw来表示这些分量的旋转值。需要注意的是,这里的旋转是针对世界坐标系说的,这意味着第一次的旋转不会影响第二、三次的转轴。

欧拉角容易出现的问题是 1)不易在任意方向的旋转轴插值; 2)万向节死锁;3)旋转的次序无法确定

轴角

轴角用一个以单位矢量定义的旋转轴,再加上一个标量定义的旋转角来表示旋转。通常的表示[x,y,z,theta],前面三个表示轴,最后一个表示角度。

轴角最大的一个局限就是不能进行简单的插值,此外,轴角形式的旋转不能直接施于点或矢量,必转换为矩阵或者四元素。

四元数(Quaternion)的定义

四元数是四维超复数。由一个实数单位加上三个虚数单位 。其中实数部分为四元数中的标量部分,虚数部分为四元数的矢量部分。一般定义:

q=w+xi+yj+zk

其中 w,x,y,z是实数。而i,j,k为虚数

四元数也可以表示为q=[w,v],其中v=(x,y,z)是矢量,v虽然是矢量,但不能简单的理解为3D空间的矢量,它是4维空间中的的矢量通俗的讲,一个四元数(Quaternion)描述了一个旋转轴和一个旋转角度。

这个旋转轴和这个角度可以通过Quaternion::ToAngleAxis转换得到。当然也可以随意指定一个角度一个旋转轴来构造一个Quaternion。这个角度是相对于单位四元数而言的,也可以说是相对于物体的初始方向而言的。当用一个四元数乘以一个向量时,实际上就是让该向量围绕着这个四元数所描述的旋转轴,转动这个四元数所描述的角度而得到的向量。

归一化的四元数可以用于表示三维空间中刚体或坐标系的旋转。

四元数可以表示刚体姿态,这里的姿态是指载体坐标系相对于地理坐标系的旋转。

四元数表示角度

四元素感觉上就是轴角的进化,也是使用一个3维向量表示转轴和一个角度分量表示绕此转轴的旋转角度,即(x,y,z,w)。绕坐标轴的多次旋转可以等效为绕某一转轴旋转一定的角度。假设等效旋转轴方向向量为等效旋转角为θ,则四元数q=(x,y,z,w)有:

且有

即四元数存储了旋转轴和旋转角的信息,它能方便的描述刚体绕任意轴的旋转。

四元数中的每个数都是经过“处理”的轴和角,轴角描述的“四元组”并不是一个空间下的东西,首先(ax,ay,az)是一个3维坐标下的矢量,而theta则是极坐标下的角度,简单的将他们组合到一起并不能保证他们插值结果的稳定性,因为他们无法归一化,所以不能保证最终插值后得到的矢量长度(经过旋转变换后两点之间的距离)相等,而四元数在是在一个统一的4维空间中,方便归一化来插值,又能方便的得到轴、角这样用于3D图像的信息数据,所以用四元数再合适不过了。相比于矩阵,四元素也只要存储4个浮点数,优势很明显。

四元数的优点有:

  • 四元数不会有欧拉角存在的 gimbal lock 问题
  • 四元数由4个数组成,旋转矩阵需要9个数
  • 两个四元数之间更容易插值
  • 四元数、矩阵在多次运算后会积攒误差,需要分别对其做规范化(normalize)和正交化(orthogonalize),对四元数规范化更容易
  • 与旋转矩阵类似,两个四元组相乘可表示两次旋转

四元数的各种转换

四元数转欧拉角

(参考资料:https://www.cnblogs.com/21207-iHome/p/6894128.html

也可以通过下面代码进行转换

#include "tf/transform_datatypes.h"//转换函数头文件
#include <nav_msgs/Odometry.h>//里程计信息格式
 
 
/****************四元数转RPY欧拉角,以odomsub的回调函数为例*****************/
 
void odomCallback(const nav_msgs::Odometry &odom) {
 
     
      tf::Quaternion quat;
      tf::quaternionMsgToTF(odom.pose.pose.orientation, quat);
 
     
      double roll, pitch, yaw;//定义存储r\p\y的容器
      tf::Matrix3x3(quat).getRPY(roll, pitch, yaw);//进行转换
 
    }
 
 
/****************RPY欧拉角转四元数*****************/
tf::createQuaternionMsgFromRollPitchYaw(double r, double p, double y);//返回四元数
 
 
tf::createQuaternionMsgFromYaw(double y);//只通过y即绕z的旋转角度计算四元数,用于平面小车。返回四元数

欧拉角转四元数

四元数转旋转矩阵

四元数转换为旋转矩阵:

已知旋转矩阵为:

 则对应的四元数为:

机器人航向角的求解

基于地磁传感器求解机器人航向角

地磁传感器即magnetometer。关于地磁传感器检测旋转角度,网上都是用把测量到的地磁场值进行最小二乘法进行椭圆拟合,然后用三角函数获取相对转动的角度;

但是这局限于静态不动条件下的旋转;当机器人位置发生改变时,地磁场也会相应的发生较大的改变,拟合出的椭圆和上一个位置拟合的椭圆有很大的不同,可以说一个位置一个不同的椭圆,这样在运动时就没法用这种方法获取角度。故此单纯用地磁传感器来求解机器人的航向角误差较大

基于IMU求解机器人航向角

在turtlebot3中,所谓的IMU其实是包括了accelerometer和gyroscope

一般而言,采用IMUupdate算法融合加速度计和陀螺仪就可以得到比较准确的数据了,在大多情况下使用也就足够了。但是IMUupdate算法的一个缺陷是它不能长时间得到准确的Yaw角,在经过一定时间后Yaw角会随着陀螺仪积分误差的增大而偏差越来越大。为此通过地磁传感器可以矫正其Yaw角度

在ROS中,imu是直接发布出四元数,因此要做的就是将四元数转换成欧拉角,并取其中的航向角

基于IMU与地磁传感器求解机器人航向角(九轴姿态融合)

(原文可参考:https://x-io.co.uk/res/doc/madgwick_internal_report.pdf

AHRS算法是自动航向基准系统(Automatic Heading Reference System)的简称,是通过IMU和magnetometer来实现航向角的计算。该算法分为两部分:

首先是IMU是惯性测量装置(Inertial Measurement Unit)的简称,通常包含陀螺仪(gyroscope)和加速度计(accelerometer)。

陀螺仪(gyroscope

陀螺仪测量的是角速度,即物体转动的速度,把速度和时间相乘,即可以得到某一时间段内物体转过的角度。对于陀螺仪的角速度测量,比较好理解,简单来说,相当于一个人绕着一个圆圈行走,假如他的速度是1度没秒,那么通过速度乘以时间,我们就可以知道他距离起点走了多少度。

加速度计(accelerometer

加速度计测量的是物体的加速度,重力加速度是一个物体受重力作用的情况下所具有的加速度。当物体处于静止状态时,加速度计测量出来的值就等于重力加速度1g, 约等于9.8米每平方秒。重力加速度g的方向总是竖直向下的,通过获得重力加速度在其X轴,Y轴上的分量,我们可以计算出物体相对于水平面的倾斜角度。

一个简单的例子如下: 一个单轴的加速计位于重力水平面上的时候,它在垂直方向上受到的加速度为1g,在水平方向上受到的加速度为0。当我们把它旋转一个角度的时候,就会在水平轴上产生一个加速度分量。通过它们的关系,就可以计算出该单轴加速计的倾角。

在一个三轴的加速度传感器中,可以通过下列的反正切函数运算公式来计算加速度计各个轴的倾角

故此,陀螺仪测量yaw;加速度计测量roll,pitch。

MPU6050和MPU9150的传感器方向定义,其中MPU6050只包含陀螺仪和加速计共六个轴,而MPU9150还包含磁力计,共九个轴。

 

基于里程计求解机器人航向角

在ROS中,odom是直接发布出四元数,因此要做的就是将四元数转换成欧拉角,并取其中的航向角

ROS中多传感器数据同步问题

message_filters

(参考资料http://wiki.ros.org/message_filters

消息过滤器message_filters类似一个消息缓存,当消息到达消息过滤器的时候,可能并不会立即输出,而是在稍后的时间点里满足一定条件下输出。为此如果采用消息过滤器来做同步处理,必须等多个传感器在时间点内满足某个条件才输出,这样容易导致某一个传感器的条件没满足,一直等待,没有结果输出的“卡顿”现象。

比如时间同步器,它接收来自多个源的不同类型的消息,并且仅当它们在具有相同时间戳的每个源上接收到消息时才输出它们,也就是起到了一个消息同步输出的效果。

多线程

ROS使用master管理节点,各节点之间可以使用同步异步多种通信方式,这种设计的思想本身其实鼓励把功能分别在多个节点实现,但是真实情况中处理复杂任务,多线程是必不可少的。

https://blog.csdn.net/tobebest_lah/article/details/103050076#t5

https://blog.csdn.net/yaked/article/details/50776224

https://stackoverflow.com/questions/48497670/multithreading-behaviour-with-ros-asyncspinner

参考资料

https://blog.csdn.net/m0_37142194/article/details/81784761(AHRS论文的翻译)

https://blog.csdn.net/sddxseu/article/details/53414501?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param(AHRS算法代码)

https://blog.csdn.net/superfly_csu/article/details/79128460?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param

https://blog.csdn.net/log_zhan/article/details/52181535

https://blog.csdn.net/log_zhan/article/details/54376602?utm_medium=distribute.pc_relevant.none-task-blog-title-1&spm=1001.2101.3001.4242

https://blog.csdn.net/qq_42348833/article/details/106013882?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

https://blog.csdn.net/shenshen211/article/details/78492055(四元数)

https://blog.csdn.net/weixin_38294178/article/details/87872893(四元数)

http://www.wy182000.com/2012/07/17/quaternion%E5%9B%9B%E5%85%83%E6%95%B0%E5%92%8C%E6%97%8B%E8%BD%AC%E4%BB%A5%E5%8F%8Ayaw-pitch-roll-%E7%9A%84%E5%90%AB%E4%B9%89/(四元数)

https://blog.csdn.net/chishuideyu/article/details/77479758(message_filter)

https://blog.csdn.net/chengde6896383/article/details/90755850?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param(message_filter)

https://blog.csdn.net/qq_23670601/article/details/87968936

猜你喜欢

转载自blog.csdn.net/gwplovekimi/article/details/108724471
今日推荐