MPU6050卡尔曼滤波解算姿态角

本文介绍了使用卡尔曼滤波算法结合MPU6050传感器解算姿态角的过程。从理论推导到C、Python实现,详细探讨了假定条件、欧拉角、四元数、卡尔曼滤波调参及其实质,并提供了代码示例。最终结果显示,尽管存在明显跳动,但实现了惯导模块的初步效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

自己在课上吹的牛,课程作业再麻烦也得干。模了好几天鱼,终于在DDL前一天弄完了惯导模块的简单demo,卡尔曼滤波算是我弄的最久的了(大概2-3天),虽然没有彻底弄懂原理(概率论没学,隐马尔可夫链啥的更是不会),好歹就着教程推导给实现了。
实现的效果不咋的,还是存在明显的跳动,估计是MPU6050陀螺仪的事,方差大、数值基本是不准的,爬了。

理论推导

假定条件

使用陀螺仪和加速度计实现卡尔曼滤波有几个基本假设,我码字的时候忘了几个,先列出来,以后想起来再填。

  1. 线性系统。对于稳态卡尔曼滤波,应该是线性时不变系统?
  2. 静态条件,也就是只有重力加速度G的情况下,才能使用加速度推导出欧拉角。

欧拉角和四元数

这个部分其实只用了解一下欧拉角即可,但是作为一个开发备忘,绕任意轴旋转的矩阵、四元数还是要有的,万一以后用到了呢(狗头)。

欧拉角

我们这里说的欧拉角是Z-Y-X欧拉角,也就是先绕Z轴旋转α角,再绕Y轴旋转β角,最后绕X轴旋转γ角。示意图大概是这么个样子。一般Z轴取铅垂轴,X轴为物体主对称轴,Y轴为辅对称轴或用右手定则确定欧拉角示意图
那么我们就将绕Z轴旋转的角度Yaw称为偏航,绕X轴旋转的角度称为Roll滚转,绕Y轴旋转的角度Pitch称为俯仰角。

绕任意轴旋转的矩阵(Goldman公式)

欧拉角实际上是一种转角排列设定法,转角的排列顺序比较多,但是很多旋转实际上是一样的。我们可以找到一个等效的旋转轴和对应这个轴的转角,那么我们假定 K ^ 是 一 个 表 示 旋 转 轴 的 单 位 向 量 , R K ( θ ) 为 等 效 旋 转 矩 阵 \hat{K}是一个表示旋转轴的单位向量,R_{K}(θ)为等效旋转矩阵 K^RK(θ)
那么我们可以将被旋转向量V分解为沿轴分量V_c和V_1,利用向量叉积取垂直V_c和V_1的V_2。设旋转后的向量为V’,其在平面分量为V’_1,有: V ⃗ = V c ⃗ + V 1 ⃗ \vec{V} = \vec{V_{c}}+\vec{V_{1}} V =Vc +V1
V ′ ⃗ = V c ⃗ + V 1 ′ ⃗ \vec{V^{'}} =\vec{V_{c}}+\vec{V_{1}^{'}} V =Vc +V1
示意图(意思意思就行了(狗头))在这里插入图片描述
下面就是用V_1和V_2表示旋转后的向量投影,假设转角为θ,θ实际上就是V’_1和V_1的夹角(图上忘画了),那么旋转后的向量就是:
V ’ ⃗ = V c ⃗ + V 1 ⃗ c o s θ + V 2 ⃗ s i n θ \vec{V^{’}}=\vec{V_{c}}+\vec{V_{1}}cosθ+\vec{V_{2}}sinθ V =Vc +V1 cosθ+V2 sinθ
带入轴K的单位向量表示和各个坐标轴的坐标即可得到Goldman公式。例如:
K ^ = ( K x , K y , K z ) , V c ⃗ = ( V c ⃗ ⋅ K ^ ) K ^ \hat{K} = (K_{x},K_{y},K_{z}),\vec{V_{c}}= (\vec{V_{c}}\cdot\hat{K})\hat{K} K^=(Kx,Ky,Kz),Vc =(Vc K^)K^
如果令V=(1,0,0),即X轴,那么代入旋转后向量公式就可以求得矩阵的第一列。
最后的旋转矩阵应该是:
[ K x 2 ( 1 − c ) + c K x K y ( 1 − c ) − K z s K x K z ( 1 − c ) − K y s

### 卡尔曼滤波算法处理MPU6050传感器数据计姿态角 #### 理卡尔曼滤波原理 卡尔曼滤波是一种递归的最小方差估计方法,适用于线性和非线性系统的状态预测和更新。该算法通过组合先验信息(模型预测)和测量信息(传感器读数),提供了一个最优的状态估计方案[^1]。 #### MPU6050传感器特性 MPU6050集成了三轴加速度计和三轴陀螺仪,能够实时获取物体的空间运动参数。为了提高姿态精度,通常采用卡尔曼滤波器对原始传感数据进行平滑处理,减少噪声干扰并改善角度估效果[^2]。 #### 实现过程概述 以下是利用Python实现基于卡尔曼滤波姿态角流程: ```python import numpy as np class KalmanFilter: def __init__(self, Q_angle=0.001, Q_gyro=0.003, R_angle=0.03): self.Q_angle = Q_angle # 加速度计误差协方差 self.Q_gyro = Q_gyro # 陀螺仪误差协方差 self.R_angle = R_angle # 测量噪声水平 self.angle = 0 # 当前倾角预估值 self.bias = 0 # 偏置项初始值设为零 def getAngle(self, new_acc_angle, gyro_rate, dt): """ 计新的角度 """ # 预测阶段:仅考虑陀螺仪变化率的影响 angle_predict = self.angle + (gyro_rate - self.bias) * dt # 更新阶段:引入加速度计观测修正 y = new_acc_angle - angle_predict S = self.Q_angle + self.Q_gyro*dt*(dt) + self.R_angle K = (self.Q_angle + self.Q_gyro*dt*(dt)) / S # 应用卡尔曼增益K调整最终输出的角度以及偏移补偿 self.angle = angle_predict + K*y self.bias = self.bias + K*(-(gyro_rate-self.bias)*dt)/(S/(self.Q_angle+self.Q_gyro*dt)) return self.angle ``` 此代码片段定义了一个简单的单变量卡尔曼滤波类`KalmanFilter`用于处理来自MPU6050的一维倾斜角度数据[^3]。需要注意的是,在实际应用场景下还需要进一步扩展至三维空间坐标系,并综合考虑更多因素如磁力计辅助校准等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值