MPU 6050姿态角度融合算法

1、介绍1.1 姿态角(Euler角)pitch yaw roll介绍飞行器的姿态角并不是指哪个角度,是三个角度的统称。它们是:俯仰、滚转、偏航。你可以想象是飞机围绕XYZ三个轴分别转动形成的夹角。地面坐标系(earth-surface inertial reference frame)Sg--------OXgYgZg①在地面上选一点Og②使Xg轴在水平面内并指向某一方向③Zg轴垂直于地面并指向地心(重力方向)④Yg轴在水平面内垂直于Xg轴,其指向按右手定则确定机体坐标系(Aircraf
摘要由CSDN通过智能技术生成

1、介绍

1.1 姿态角(Euler角)pitch yaw roll介绍
飞行器的姿态角并不是指哪个角度,是三个角度的统称。它们是:俯仰、滚转、偏航。你可以想象是飞机围绕XYZ三个轴分别转动形成的夹角。
地面坐标系(earth-surface inertial reference frame)Sg--------OXgYgZg
在这里插入图片描述

①在地面上选一点Og
②使Xg轴在水平面内并指向某一方向
③Zg轴垂直于地面并指向地心(重力方向)
④Yg轴在水平面内垂直于Xg轴,其指向按右手定则确定

机体坐标系(Aircraft-body coordinate frame)Sb-------OXYZ

在这里插入图片描述

①原点O取在飞机质心处,坐标系与飞机固连
②x轴在飞机对称平面内并平行于飞机的设计轴线指向机头
③y轴垂直于飞机对称平面指向机身右方
④z轴在飞机对称平面内,与x轴垂直并指向机身下方
欧拉角/姿态角(Euler Angle)

在这里插入图片描述

在这里插入图片描述

机体坐标系与地面坐标系的关系是三个Euler角,反应了飞机相对地面的姿态。
俯仰角θ(pitch):机体坐标系X轴与水平面的夹角。当X轴的正半轴位于过坐标原点的水平面之上(抬头)时,俯仰角为正,否则为负。
在这里插入图片描述

偏航角ψ(yaw):
机体坐标系xb轴在水平面上投影与地面坐标系xg轴(在水平面上,指向目标为正)之间的夹角,由xg轴逆时针转至机体xb的投影线时,偏航角为正,即机头右偏航为正,反之为负。

在这里插入图片描述

滚转角Φ(roll):机体坐标系zb轴与通过机体xb轴的铅垂面间的夹角,机体向右滚为正,反之为负。
在这里插入图片描述

首先要明确,MPU6050 是一款姿态传感器,使用它就是为了得到待测物体(如四轴、平衡小车) x、y、z 轴的倾角(俯仰角 Pitch、滚转角 Roll、偏航角 Yaw) 。我们通过 I2C 读取到 MPU6050 的六个数据(三轴加速度 AD 值、三轴角速度 AD 值)经过姿态融合后就可以得到 Pitch、Roll、Yaw 角。
本帖主要介绍三种姿态融合算法:四元数法 、一阶互补算法和卡尔曼滤波算法。

二、四元数法

关于四元数的一些概念和计算就不写上来了,我也不懂。我能告诉你的是:通过下面的算法,可以把六个数据转化成四元数(q0、q1、q2、q3),然后四元数转化成欧拉角(P、R、Y 角)。
虽然 MPU6050 自带的 DMP库可以直接输出四元数,减轻 STM32 的运算负担, 这里在此没有使用,因为我是用 STM32 的硬件 I2C 读取 MPU6050 数据的,DMP库需要对 I2C 函数进行修改,如 DMP 库中的 I2C 写:i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, &(data[0]));有4个输入变量,而 STM32 硬件 I2C 的 I2C 写为:
void MPU6050_I2C_ByteWrite(u8 slaveAddr, u8 pBuffer, u8 writeAddr),只有 3 个输入量(这之间的差异好像是由于 MPU6050 的 DMP 库是针对 MSP430 单片机写的),所以必须进行修改,但是改固件库是一件很痛苦的事,你们应该都懂。当然,如果你用模拟 I2C 的话,是容易实现的,网上的 DMP 移植几乎都是基于模拟 I2C 的。

#include<math.h>
#include "stm32f10x.h"
//---------------------------------------------------------------------------------------------------
// 变量定义
 
#define Kp 100.0f                        // 比例增益支配率收敛到加速度计/磁强计
#define Ki 0.002f                // 积分增益支配率的陀螺仪偏见的衔接
#define halfT 0.001f                // 采样周期的一半
 
float q0 = 1, q1 = 0, q2 = 0, q3 = 0;          // 四元数的元素,代表估计方向
float exInt = 0, eyInt = 0, ezInt = 0;        // 按比例缩小积分误差
 
float Yaw,Pitch,Roll;  //偏航角,俯仰角,翻滚角

void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az)
{
   
        float norm;
        float vx, vy, vz;
        float ex, ey, ez;  
 
        // 测量正常化
        norm = sqrt(ax*ax + ay*ay + az*az);      
        ax = ax / norm;                   //单位化
       
  • 39
    点赞
  • 224
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
以下是一个示例代码片段,展示了如何使用MPU6050传感器进行姿态角度累加的过程。请注意,这是一个简化的示例,实际的实现可能会有所不同,具体取决于你使用的开发平台和编程语言。 ```python import smbus import math # MPU6050的I2C地址 MPU6050_ADDR = 0x68 # 加速度计的灵敏度(根据具体设置进行调整) ACCEL_SENSITIVITY = 16384.0 # 陀螺仪的灵敏度(根据具体设置进行调整) GYRO_SENSITIVITY = 131.0 # 初始化I2C总线 bus = smbus.SMBus(1) def read_word(reg): # 读取一个16位的寄存器值 high = bus.read_byte_data(MPU6050_ADDR, reg) low = bus.read_byte_data(MPU6050_ADDR, reg + 1) value = (high << 8) | low return value def read_word_2c(reg): # 读取一个16位的补码值 value = read_word(reg) if value >= 0x8000: return -((65535 - value) + 1) else: return value def get_accelerometer_data(): # 获取加速度计的原始数据 accel_x = read_word_2c(0x3B) accel_y = read_word_2c(0x3D) accel_z = read_word_2c(0x3F) return accel_x, accel_y, accel_z def get_gyroscope_data(): # 获取陀螺仪的原始数据 gyro_x = read_word_2c(0x43) gyro_y = read_word_2c(0x45) gyro_z = read_word_2c(0x47) return gyro_x, gyro_y, gyro_z def calculate_angle(accel_data, gyro_data, dt): # 计算姿态角度 accel_x, accel_y, accel_z = accel_data gyro_x, gyro_y, gyro_z = gyro_data # 计算加速度计的角度(以弧度为单位) accel_angle_x = math.atan2(accel_y, accel_z) accel_angle_y = math.atan2(-accel_x, math.sqrt(accel_y**2 + accel_z**2)) # 将陀螺仪的角速度转换为角度变化 gyro_x_angle = gyro_x / GYRO_SENSITIVITY * dt gyro_y_angle = gyro_y / GYRO_SENSITIVITY * dt gyro_z_angle = gyro_z / GYRO_SENSITIVITY * dt # 将陀螺仪角度变化与加速度计角度进行融合 angle_x = 0.98 * (gyro_x_angle + accel_angle_x) + 0.02 * accel_angle_x angle_y = 0.98 * (gyro_y_angle + accel_angle_y) + 0.02 * accel_angle_y # 返回姿态角度(以度为单位) return math.degrees(angle_x), math.degrees(angle_y) # 初始化MPU6050 bus.write_byte_data(MPU6050_ADDR, 0x6B, 0x00) # 主循环 previous_time = time.time() previous_angle_x = 0.0 previous_angle_y = 0.0 total_angle_x = 0.0 total_angle_y = 0.0 while True: # 计算时间间隔 current_time = time.time() dt = current_time - previous_time previous_time = current_time # 获取加速度计和陀螺仪的数据 accel_data = get_accelerometer_data() gyro_data = get_gyroscope_data() # 计算姿态角度 angle_x, angle_y = calculate_angle(accel_data, gyro_data, dt) # 累计角度 total_angle_x += angle_x - previous_angle_x total_angle_y += angle_y - previous_angle_y # 更新前一次的角度值 previous_angle_x = angle_x previous_angle_y = angle_y # 打印累计角度 print("Total Angle X: {:.2f}".format(total_angle_x)) print("Total Angle Y: {:.2f}".format(total_angle_y)) ``` 这个代码片段使用Python语言,并假设你已经正确设置了MPU6050传感器的连接和引脚配置。你需要安装smbus库来进行I2C通信。代码中的`calculate_angle`函数实现了姿态角度的计算,使用了加速度计和陀螺仪的原始数据,并通过融合算法将它们结合起来。在主循环中,累加了每次姿态角度的变化,得到了累计角度。最后,代码打印了累计角度的值。 请注意,这只是一个示例代码,具体的实现可能需要根据你的需求进行修改和调整。另外,为了获得更准确的姿态角度和累计角度,可能需要进行更复杂的姿态解算算法和传感器校准。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值