姿态解算进阶:互补滤波(陀螺仪、加速度计、地磁计数据融合)

2023-05-16

互补滤波原理:  

     在四轴入门理论知识那节我们说,加速度计和磁传感器都是极易受外部干扰的传感器,都只能得到2维的角度关系,但是测量值随时间的变化相对较小,结合加速度计和磁传感器可以得到3维的角度关系。陀螺仪可以积分得到三维的角度关系,动态性能好,受外部干扰小,但测量值随时间变化比较大。可以看出,它们优缺点互补,结合起来才能有好的效果。那么三者的数据如何融合呢,接下来介绍互补滤波算法。

     互补滤波就是在短时间内采用陀螺仪得到的角度做为最优,定时对加速度采样来的角度进行取平均值来校正陀螺仪的得到的角度。即短时间内用陀螺仪比较准确,以它为主;长时间用加速度计比较准确,这时候加大它的比重,这就是互补了,不过滤波在哪里?加速度计要滤掉高频信号,陀螺仪要滤掉低频信号,互补滤波器就是根据传感器特性不同,通过不同的滤波器(高通或低通,互补的),然后再相加得到整个频带的信号,例如,加速度计测倾角,其动态响应较慢,在高频时信号不可用,所以可通过低通抑制高频;陀螺响应快,积分后可测倾角,不过由于零漂等,在低频段信号不好。通过高通滤波可抑制低频噪声。将两者结合,就将陀螺和加表的优点融合起来,得到在高频和低频都较好的信号,互补滤波需要选择切换的频率点,即高通和低通的频率。

互补滤波原理框图:


加速度计补偿:

    假设n系为地理坐标系,b系为机体坐标系,在地理坐标系中,加速度的输出为:,经过矩阵转换后的值为:。在b系中,加速度的测量值为:,现在都表示在b系中数值向下的向量,由此,我们对这两个向量做向量积(叉积),得到误差:,利用这个误差来修正矩阵,于是乎,我们的四元数就在这样一个过程中被修正了。

    但是,由于加速度计无法感知Z轴上的旋转运动,所以还需要用地磁计来进一步补偿。现在我们假设旋转矩阵是经过加速度计校正后的矩阵,当某个确定的向量(b系中)经过这个矩阵旋转之后(到n系),这两个坐标系在XOY平面上重合,只是在Z轴旋转上会存在一个偏航角的误差。下图表示的是经过旋转之后的b系和n系的相对关系。可以明显发现加速度计可以把b系通过四元数法从任意角度拉到与n系水平的位置上,这时,只剩下一个偏航角误差。这也是为什么加速度计误差修正偏航的原因。


地磁计补偿:

    现在我们反过来从b系到n系,假设地磁计在b系中的输出为:,经过的转换后得到:。由于是经过加速度计修正过的旋转矩阵,因此该旋转矩阵只在Z轴上存在一个偏航的误差,这就导致中的hy不为零。如果不存在误差,这里的hy应该为0。在n系中,地磁方向与x轴呈一个角度,与z轴呈一个角度,这里我们让x轴对准北边,那么地磁向量为:。在n系的XOY平面上(水平面),的投影为:Sqrt(bx * bx),的投影为:Sqrt((hx * hx)+ (hy * hy))。由于存在的偏航误差,导致的hy不为零,这就是说现在得到的是真实的地磁向量绕Z轴旋转一定的角度后得到的。但由于是绕Z轴旋转,所以该地磁向量在XOY平面上(n系)投影的大小必定相同,所以有bx^2= hx^2+hy^2,我们求出了地磁向量在X轴方向的真实值。而得到hz就是地磁向量在Z轴方向上的真实值,我们不做改变,令bz=hz即可。经过这样处理之后我们得到,这个地磁向量就是地磁的真实值,类似于重力加速度的。接着把经过变换后到b系中得到:向量积求误差,再次修正这样就完成了一次地磁计的补偿。

    将加速度计没能做到的z轴上的旋转修正,通过地磁计在XOY平面上的地磁力相同原理,得到了修正。于是乎,Pitch和Roll通过加速度计修正,然后在这个基础之上(该地磁计补偿方法必须依靠加速度计修正提供一致的XOY平面,才会有bx^2= hx^2+hy^2等式成立),Yaw通过地磁计来补偿,最终得到了没有偏差的实时姿态(也就是由四元数组成的旋转矩阵)。

代码分析:

// 加速度计、地磁计、陀螺仪数据融合,更新四元数
/*
   [gx,gy,gz]为陀螺仪的测量值
   [ax,at,az]为加速度的测量值
   [mx,my,mz]为地磁计的测量值 
*/
void AHRSupdate(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz) 
{  
            float norm;               
            float hx, hy, hz, bx, bz;
            float vx, vy, vz, wx, wy, wz; 
            float ex, ey, ez;  
  
            // 定义一些辅助变量用于转换矩阵
            float q0q0 = q0*q0;  
            float q0q1 = q0*q1;  
            float q0q2 = q0*q2;  
            float q0q3 = q0*q3;  
            float q1q1 = q1*q1;  
            float q1q2 = q1*q2;  
            float q1q3 = q1*q3;  
            float q2q2 = q2*q2;  
            float q2q3 = q2*q3;  
            float q3q3 = q3*q3;  
             
            // 归一化加速度计和地磁计的度数 
            norm = sqrt(ax*ax + ay*ay + az*az);   
            ax = ax / norm;  
            ay = ay / norm;  
            az = az / norm;  
            norm = sqrt(mx*mx + my*my + mz*mz);   
            mx = mx / norm;  
            my = my / norm;  
            mz = mz / norm;  
             
            //将b系中的地磁计分量[mx,my,mz]转换到n系,得到[hx,hy,hz]  
            hx = 2*mx*(0.5 - q2q2 - q3q3) + 2*my*(q1q2 - q0q3) + 2*mz*(q1q3 + q0q2);  
            hy = 2*mx*(q1q2 + q0q3) + 2*my*(0.5 - q1q1 - q3q3) + 2*mz*(q2q3 - q0q1);  
            hz = 2*mx*(q1q3 - q0q2) + 2*my*(q2q3 + q0q1) + 2*mz*(0.5 - q1q1 - q2q2);        

            //得到n系中的地磁向量的真实值[bx,bz,by],其中by=0   
            bx = sqrt((hx*hx) + (hy*hy));  
            bz = hz;     

            //n系中的地磁向量[bx,by,bz]转换到b系中,得到[wx,wy,wz]
            wx = 2*bx*(0.5 - q2q2 - q3q3) + 2*bz*(q1q3 - q0q2);  
            wy = 2*bx*(q1q2 - q0q3) + 2*bz*(q0q1 + q2q3);  
            wz = 2*bx*(q0q2 + q1q3) + 2*bz*(0.5 - q1q1 - q2q2);                        
 
            //n系中重力加速度[0,0,1]转换到b系中得到三个分量[vx,vy,vz]        
            vx = 2*(q1q3 - q0q2);  
            vy = 2*(q0q1 + q2q3);  
            vz = q0q0 - q1q1 - q2q2 + q3q3;    
             
            //计算[wx,wy,wz] X [mx,my,mz],[ax,at,az] X [vx,vy,vz],得到两个误差后求和
            ex = (ay*vz - az*vy) + (my*wz - mz*wy);  
            ey = (az*vx - ax*vz) + (mz*wx - mx*wz);  
            ez = (ax*vy - ay*vx) + (mx*wy - my*wx);  
             
            //PI控制器中的积分部分
            exInt = exInt + ex*Ki* (1.0f / sampleFreq);  
            eyInt = eyInt + ey*Ki* (1.0f / sampleFreq);  
            ezInt = ezInt + ez*Ki* (1.0f / sampleFreq);  
            
            //误差经过PI控制器后输出,然后补偿到角速度的三个分量,Kp、Ki是需要调节的参数
            gx = gx + Kp*ex + exInt;  
            gy = gy + Kp*ey + eyInt;  
            gz = gz + Kp*ez + ezInt;               
            
            //一阶龙格库塔法更新四元数  
            q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;  
            q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;  
            q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;  
            q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;    
             
            // 归一化四元数
            norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);  
            q0 = q0 / norm;  
            q1 = q1 / norm;  
            q2 = q2 / norm;  
            q3 = q3 / norm;  
}  

参考:https://blog.csdn.net/qq_21842557/article/details/50993809
          https://blog.csdn.net/superrunner_wujin/article/details/55809648
          https://legacy.gitbook.com/book/nephen/direction-cosine-matrix-imu-theory/details
          https://blog.csdn.net/qq_21842557/article/details/50993809
         

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

姿态解算进阶:互补滤波(陀螺仪、加速度计、地磁计数据融合) 的相关文章

  • 进程、线程

    线程 xff08 thread xff09 线程其实是操作系统能够进行运算调度的最小单位 它是被包含在进程之中的 xff0c 是进程中的实际运作单位 一条线程指的是进程中一个单一顺序的控制流 xff0c 一个进程中可以并发多个线程 xff0
  • 基于Zynq7020双千兆以太网的数字信号处理板设计

    一 背景 背景 Xilinx公司在2010年发布了可扩展的处理器平台Zynq7000系列 xff0c 它采用了28nm工艺 xff0c 将FPGA与ARM cortex A9集成在一颗芯片上 xff0c 实现了高性能 高集成度 低功耗 Zy
  • 深入理解JS中的变量作用域

    在 JS 当中一个变量的作用域 xff08 scope xff09 是程序中定义这个变量的区域 变量分为两类 xff1a 全局 xff08 global xff09 的和局部的 其中全局变量的作用域是全局性的 xff0c 即在 JavaSc
  • 硬件工程师,从零开始无人机开发。

    毕业已经五年了 xff0c 一直在杭州某大厂 xff0c 做无人机硬件开发 无人机这块 xff0c 我进去的时候大厂刚开始 做 xff0c 有幸参与到整个无人机的硬件开发 我这个刚毕业的技术小白 xff0c 在这五年间成长了很多 无奈 今年
  • 个人总结:板球控制系统之串级PID整定方法,速度环与位置环,40S任务10S完成

    其实单环我们先出了所有题目 xff0c 但是效果显然没有串级PID的效果好 xff0c 有人需要的话可以把程序包发出来 xff0c 板球运行视屏也有 另外 xff1a 天下舵机参差不齐 xff08 哪怕型号相同 xff09 xff0c 想要
  • 树莓派3B+踩坑记录:一、安装Ubuntu Mate

    树莓派3B 43 踩坑记录 xff1a 一 安装Ubuntu Mate 树莓派 xff0c Ubuntu xff0c ROS硬件准备软件准备系统烧录安装Ubuntu Mate更换国内源网络配置开启ssh远程其他彩虹屏解决方案XShell和X
  • PointNet代码详解

    PointNet代码详解 最近在做点云深度学习的机器人抓取 xff0c 这篇博客主要是把近期学习PointNet的一些总结的知识点汇总一下 PointNet概述详见以下网址和博客 xff0c 这里也就不再赘述了 三维深度学习之pointne
  • 卡尔曼滤波通俗易懂的解释

    关于卡尔曼滤波 xff0c 网上的资料很多 xff0c 但是有很大一部分都是不断堆叠公式 xff0c 然后用各种晦涩难懂的专业术语进行解释 xff0c 说实话我刚开始看的时候也是云里雾里 xff0c 因此写下这篇博客是为了照顾和我一样的萌新
  • STM32通过PWM控制ESC30C电调

    最近在搞一个水下推进器 xff0c 这东西的控制其实跟四旋翼的螺旋桨控制差不多 但我也是第一次用STM32板子来控制电调驱动桨叶旋转 xff0c 因此踩了很多坑 网上找了很多资料 xff0c 但是很多都写的不是很清楚 xff0c 这边稍微记
  • STM32F7同一定时器多路输出PWM波通道之间相互影响问题

    2020 8 12更新 这次用Cube直接生成PWM控制代码 xff0c 然后再RT Thread Studio上编写程序 xff0c 发现可实现TIM1和TIM8的8路PWM波调控 xff0c 因此上面论述的问题可能是自己在写底层时有某些
  • Ardusub源码解析学习(一)——Ardusub主程序

    APM Sub源码解析学习 xff08 一 xff09 Ardusub主程序 前言一 准备工作二 Ardusub cpp解析2 1 scheduler table2 2 schedulerget scheduler tasks setup
  • Ardusub源码解析学习(二)——电机库

    Ardusub源码解析学习 xff08 二 xff09 电机库学习 一 RC输入与输出1 1 RC Input1 2 RC Output 二 电机库学习2 1 setup motors 2 2 add motor raw 6dof 2 3
  • Ardusub源码解析学习(三)——车辆类型

    APM Sub源码解析学习 xff08 三 xff09 车辆类型 一 前言二 class AP HAL HAL三 class AP Vehicle3 1 h3 2 cpp 四 class Sub4 1 h4 2 cpp 五 总结 一 前言
  • 年度回忆录(2012.10----2013.01)

    寒假结束了 xff0c 年也过完了 xff0c 提前回来一天就开始着手补上这迟到的年终总结 xff0c 写了一个多星期还觉得有些东西没有写出来 xff0c 无奈 xff0c 点到为止吧 2012 年的后半年经历了很多 xff0c 收获了很多
  • Ardusub学习——飞行模式

    参考资料 xff1a Ardusb官方手册 Sub Rework joystick input and pilot input in general Flight Modes Ardusub支持多种飞行模式 xff0c 但是其中一部分需要有
  • Ardusub源码解析学习(五)——从manual model开始

    Ardusub源码解析学习 xff08 五 xff09 从manual model开始 manual init manual run 从本篇开始 xff0c 将会陆续对Ardusub中各种模式进行介绍 xff0c stabilize mod
  • 重读Ardupilot中stabilize model+MAVLINK解包过程

    APM源码和MAVLINK解析学习 重读stabilize stabilize modelinit run handle attitude MAVLINK消息包姿态信息传输过程 之前写的模式都是基于master版本的 xff0c 这次重读s
  • QGC添加自定义组件和发送自定义MAVLINK消息

    QGC添加自定义组件和发送自定义MAVLINK消息 一 添加自定义组件1 1 在飞行界面添加组件1 2 实现组件事件1 3 在MOCK模拟链接中实现验证1 4 验证 二 自定义MAVLINK消息的一些预备知识三 QGC自定义MAVLINK消
  • MAVLINK消息在Ardupilot中的接收和发送过程

    MAVLINK消息在Ardupilot中的接收和发送过程 SCHED TASKupdate receive update send 由于现在网上很多的都是APM旧版本的解释 xff0c 因此把自己的一些学习所得记录下来 截至写博客日期 xf
  • Ardupilot姿态控制器 PID控制流程

    Ardupilot姿态控制器 PID控制流程 一 PID姿态控制器1 1 Copter姿态控制官方原图1 2 ArduCopter V4 X STABILIZE 二 姿态控制器类实现2 1 类成员解析2 1 1 类成员变量2 1 2 类成员

随机推荐

  • APM姿态旋转理论基础

    APM姿态旋转理论基础 一 坐标系1 1 NED坐标系1 2 机体坐标系 二 欧拉角姿态变化率与机体角速度的关系 三 旋转矩阵3 1 基本公式3 2 矩阵作差3 3 旋转矩阵与变换矩阵的区别 四 DCM五 轴角法5 1 基本概念5 2 与旋
  • 详解APM的开方控制器sqrt_controller

    前言 前面说过 xff0c sqrt controller是对P项进行整定用途的 xff0c 目的就是让P项的控制响应 软 下来 xff0c 实际上就是一个经过改进的P控制器 读懂了sqrt controller xff0c 那么你对APM
  • Ardupilot前馈及平滑函数input_euler_angle_roll_pitch_yaw解析

    Ardupilot前馈及平滑函数input euler angle roll pitch yaw解析 源码解析这个函数做了什么部分细节euler accel limit input shaping angle 姿态变化率与机体角速度之间的关
  • Ardupilot倾转分离函数thrust_heading_rotation_angles

    Ardupilot倾转分离函数thrust heading rotation angles 什么是轴角分离源码分析一些细节补充效果显示及进一步修改 本文主要写一下自己对于APM倾转分离 xff08 轴角分离 xff09 函数的一些学习笔记及
  • Spring IOC原理解析

    首先恭喜守宏同学找到了自己心仪的工作 xff0c 入职的事情终于尘埃落定 xff0c 也算是一个新的开始吧 和守宏聊天的时候也说了很多有关工作的事情 xff0c 畅想了以后美好的未来 xff0c 也想到了今后的种种困难 不说别的就是单单在北
  • Ardupilot四元数姿态控制函数attitude_controller_run_quat解析

    Ardupilot四元数姿态控制函数attitude controller run quat解析 源码解析细节讲解thrust heading rotation angles update ang vel target from att e
  • Ardupilot速率控制器rate_controller_run解析

    Ardupilot速率控制器rate controller run解析 PID速率控制器源码解析rate controller run PID运算积分限制update i get ff set xxx 内容补充 xff1a 函数中陀螺仪数据
  • muduo网络库学习总结:基本架构及流程分析

    muduo网络库学习 xff1a 基本架构及流程分析 基本架构Basic ReactorMutiple Reactor 43 ThreadPool muduo库的基本使用基本结构介绍EventLoop类Poller类Channel类TcpC
  • push_back和emplace_back比较以及vector扩容

    push back和emplace back比较以及vector扩容 push back和emplace back的比较使用测试类测试过程将实体类对象传入将右值数字传入将实体类对象move 转右值之后传入 vector扩容过程 关于这部分内
  • 在ubuntu 11.04下编写驱动程序

    在ubuntu11 04下直接就可以编写驱动程序 xff0c 并进行编译 hello c include 34 linux init h 34 include 34 linux module h 34 static int hello in
  • ROS的优势与不足(除了ROS 机器人自主定位导航还能怎么做?)

    导读 xff1a 随着这两年国内机器人的升温 xff0c 自主定位导航技术作为机器人智能化的第一步正不断引起行业内的重视 为了实现这一功能 xff0c 不少厂家选择采用机器人操作系统ROS xff08 Robot Operation Sys
  • C++版本发展史

    1 C 43 43 98 2 C 43 43 03 3 C 43 43 11 3 1 nullptr 3 2 auto 3 3 decltype 3 4 初始化列表 3 5 范围for循环 3 6 右值引用 3 7 字符串字面量 3 8 n
  • 分布式数据库难题(三):数据一致性

    1 什么是数据一致性 一直以来 xff0c 在 分布式系统 和 数据库 这两个学科中 xff0c 一致性 xff08 Consistency xff09 都是重要概念 xff0c 但它表达的内容却并不相同 对于分布式系统而言 xff0c 一
  • 分布式数据库难题(四):单机事务

    1 ACID的含义 在数据库中 xff0c 事务 是由多个操作构成的序列 1970 年詹姆斯 格雷 xff08 Jim Gray xff09 提出了事务的 ACID 四大特性 xff0c 将广义上的事务一致性具化到了原子性 一致性 隔离性和
  • 对一个整数进行因式分解,求出所有质因数

    1 题目描述 给定一个正整数N xff0c 对N进行质因数分解 xff0c 求解N的所有质因数 2 解题思路 xff08 1 xff09 2 是很特殊的 xff0c 必须单独列出 xff08 2 xff09 必须先判断是否质数 因为如果是质
  • Windows10下安装Ubuntu18.04LTS详细教程

    这篇文章分享自己在Windows10系统下安装VMware虚拟机 xff0c 然后在VMware中安装Ubuntu 18 04 LTS的详细过程 之所以选择在虚拟机中安装Ubuntu xff0c 主要是可以不影响自己电脑的正常使用 xff0
  • 我的2011 写给小白

    许久前就想写这篇日志了 xff0c 但是一直以各种理由搪塞着 xff0c 没空闲 xff0c 再加上该死的期末考试 xff0c 唉 xff0c 真是愁煞人也 xff0c 现在好了 xff0c 什么都完事了 xff0c 也淡定了 xff0c
  • Pixhawk的历史

    发展历程 xff1a APM gt PX4FMU IO gt Pixhawk xff1a 1 Arduino简介 Arduino就是主要以以AVR单片机为核心控制器的单片机应用开发板 xff08 当然也有其他核心的例如STM32版本的但是不
  • 姿态解算基础:欧拉角、方向余弦、四元数

    什么是姿态解算 xff1a 飞行器的姿态解算过程涉及到两个坐标系 xff0c 一个是运载体的机体坐标系 xff0c 该坐标系与运载体固连 xff0c 当运载体转动的时候 xff0c 这个坐标系也跟着转动 xff0c 我们假设运载体的坐标系为
  • 姿态解算进阶:互补滤波(陀螺仪、加速度计、地磁计数据融合)

    互补滤波原理 xff1a 在四轴入门理论知识那节我们说 xff0c 加速度计和磁传感器都是极易受外部干扰的传感器 xff0c 都只能得到2维的角度关系 xff0c 但是测量值随时间的变化相对较小 xff0c 结合加速度计和磁传感器可以得到3