【51单片机快速入门指南】4.3.3: MPU6050使用Mahony AHRS算法实现六轴姿态融合获取四元数、欧拉角

目录

  • 源码
    • Mahony_6.c
    • Mahony_6.h
  • 使用方法
  • 测试程序
    • main.c
    • 效果

STC89C516 32MHz
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0
上位机:Vofa+ 1.3.10


       移植自MPU6050姿态解算——Mahony互补滤波 —— 大写的小写字母

       加入了输入数据范围的自动处理,即使更改量程也能正确解算。

源码

       为了避免所用RAM超标,部分变量设为idata类型,移植时需注意。
       所用MCU为STC89C516 晶振16MHz 6T模式

       stdint.h见【51单片机快速入门指南】1:基础知识和工程创建
       软件I2C程序见【51单片机快速入门指南】4: 软件 I2C
       串口部分见【51单片机快速入门指南】3.3:USART 串口通信
       MPU6050.c、MPU6050.h见【51单片机快速入门指南】4.3: I2C读取MPU6050陀螺仪的原始数据

       Kp和Ki要按需调整,我这里取1.5和0.005

Mahony_6.c

#include <math.h>
#include "MPU6050.h"#define G 9.80665f					// m/s^2#define PI 3.141592653589793idata float halfT = 1;
idata float GYRO_K = 1, ACCEL_K = 1;void MPU6050_Mahony_Init(float loop_ms)
{halfT = loop_ms/1000./2;	//计算周期的一半,单位sswitch((MPU_Read_Byte(MPU_GYRO_CFG_REG) >> 3) & 3){case 0:GYRO_K = 1./131/57.3;break;case 1:GYRO_K = 1./65.5/57.3;break;case 2:GYRO_K = 1./32.8/57.3;break;case 3:GYRO_K = 1./16.4/57.3;break;}switch((MPU_Read_Byte(MPU_ACCEL_CFG_REG) >> 3) & 3){case 0:ACCEL_K = G/16384;break;case 1:ACCEL_K = G/8192;break;case 2:ACCEL_K = G/4096;break;case 3:ACCEL_K = G/2048;break;}
}static float invSqrt(float x) 		//快速计算 1/Sqrt(x)
{float halfx = 0.5f * x;float y = x;long i = *(long*)&y;i = 0x5f3759df - (i >> 1);y = *(float*)&i;y = y * (1.5f - (halfx * y * y));return y;
}#define Kp 1.50f
#define Ki 0.005fidata float Pitch, Roll, Yaw;
idata float q0 = 1, q1 = 0, q2 = 0, q3 = 0;		//四元数
idata float exInt = 0, eyInt = 0, ezInt = 0;		//叉积计算误差的累计积分void Imu_Update(float gx, float gy, float gz, float ax, float ay, float az)
{unsigned char i;float vx, vy, vz;							//实际重力加速度float ex, ey, ez;							//叉积计算的误差float norm;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;//将加速度原始AD值转换为m/s^2ax = ax * ACCEL_K;ay = ay * ACCEL_K;az = az * ACCEL_K;//将陀螺仪AD值转换为 弧度/sgx = gx * GYRO_K;gy = gy * GYRO_K;gz = gz * GYRO_K;if (ax * ay * az == 0)return;//加速度计测量的重力方向(机体坐标系)norm = invSqrt(ax * ax + ay * ay + az * az);			//之前这里写成invSqrt(ax*ax + ay+ay + az*az)是错误的,现在修改过来了ax = ax * norm;ay = ay * norm;az = az * norm;//四元数推出的实际重力方向(机体坐标系)vx = 2 * (q1q3 - q0q2);vy = 2 * (q0q1 + q2q3);vz = q0q0 - q1q1 - q2q2 + q3q3;//叉积误差ex = (ay * vz - az * vy);ey = (az * vx - ax * vz);ez = (ax * vy - ay * vx);//叉积误差积分为角速度exInt = exInt + ex * Ki;eyInt = eyInt + ey * Ki;ezInt = ezInt + ez * 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 = invSqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);q0 = q0 * norm;q1 = q1 * norm;q2 = q2 * norm;q3 = q3 * norm;//四元数反解欧拉角Yaw = atan2(2.f * (q1q2 + q0q3), q0q0 + q1q1 - q2q2 - q3q3) * 57.3f;Pitch = -asin(2.f * (q1q3 - q0q2)) * 57.3f;Roll = atan2(2.f * q2q3 + 2.f * q0q1, q0q0 - q1q1 - q2q2 + q3q3) * 57.3f;
}

Mahony_6.h

#ifndef Mahony_6_H_
#define Mahony_6_H_extern idata float Pitch, Roll, Yaw;
extern idata float q0, q1, q2, q3;		//四元数void MPU6050_Mahony_Init(float loop_ms);
void Imu_Update(float gx, float gy, float gz, float ax, float ay, float az);#endif

使用方法

先调用MPU6050_Mahony_Init(dt),参数为一次循环的时间,单位为ms
再使用Imu_Update姿态融合函数。

测试程序

main.c

#include <STC89C5xRC.H>
#include "intrins.h"
#include "stdint.h"
#include "USART.h"
#include "./MPU6050/MPU6050.h"
#include "./MPU6050/Mahony_6.h"void Delay1ms()		//@32MHz
{unsigned char i, j;i = 6;j = 44;do{while (--j);} while (--i);
}void Delay_ms(int i)
{while(i--)Delay1ms();
}void main(void)
{int16_t aacx,aacy,aacz;		//加速度传感器原始数据int16_t gyrox,gyroy,gyroz;	//陀螺仪原始数据USART_Init(USART_MODE_1, Rx_ENABLE, STC_USART_Priority_Lowest, 32000000, 4800, DOUBLE_BAUD_DISABLE, USART_TIMER_2);MPU_Init(); MPU6050_Mahony_Init(85);while(1){	MPU_Get_Accelerometer(&aacx, &aacy, &aacz);	//得到加速度传感器数据MPU_Get_Gyroscope(&gyrox, &gyroy, &gyroz);	//得到陀螺仪数据Imu_Update(gyrox, gyroy, gyroz, aacx, aacy, aacz);printf("%f, ", Pitch);printf("%f, ", Roll);printf("%f\r\n", Yaw);}
}

效果

       个人感觉在51上,Mahony的效果要远远好于DMP及其他滤波算法的表现,如果把零偏处理了,效果会更好。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400417.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux文件系统及bash基础特性

linux文件系统 一、根文件系统 linux被识别的第一个被称为根之间关联的文件系统叫做根文件系统&#xff08;rootfs&#xff09;&#xff0c;其他分区要想被读到&#xff0c;需要挂载到根目录的某个挂载点&#xff08;根的子目录&#xff09;上。根文件系统至关重要&#xff0c;…

【51单片机快速入门指南】4.3.4: MPU6050使用Madgwick AHRS算法实现六轴姿态融合获取四元数、欧拉角

目录源码Madgwick_6.cMadgwick_6.h使用方法测试程序main.c效果STC89C516 32MHz Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 上位机&#xff1a;Vofa 1.3.10 移植自AHRS —— LOXO&#xff0c;算法作者&#xff1a;SOH Madgwick 源码 为了避免所用R…

Hybris商品图片导入与压缩有关的配置.

1. 在电脑上安装 ImageMagick 软件&#xff08;windows平台还需要安装VC&#xff09;&#xff0c;下载路径&#xff1a;http://www.imagemagick.org/script/download.php#windows 在local.properies文件配置安装路径和配置文件路径&#xff1a; Windows版本的&#xff0c;安装…

poj 2507Crossed ladders 计算几何

链接&#xff1a;http://poj.org/problem?id2507 题意&#xff1a;哪个直角三角形&#xff0c;一直角边重合&#xff0c; 斜边分别为 X, Y&#xff0c; 两斜边交点高为 C &#xff0c; 求重合的直角边长度~ 思路&#xff1a; 设两个三角形不重合的两条直角边长为 a &#xff0…

【机器视觉学习笔记】VS2015 安装 opencv_contrib并测试

目录opencv_contrib的获取主要工具编译 opencv编译 opencv_contribVisual Studio 编译配置新项目的环境添加包含目录添加库目录配置调试环境添加依赖项测试平台&#xff1a;Windows 10 20H2 Visual Studio 2015 opencv_contrib-3.4.12 参考文章&#xff1a; 添加OpenCV_contr…

Windows Server 2012 R2 或 2016 无法安装 .Net 3.5.1

租用阿里云ECS服务器的用户使用 Windows Server 2012 R2 或 Windows Server 2016 64位系统&#xff0c;发现在安装 .net framework 3.5.1 时报错&#xff0c;报错内容如下&#xff1a; 原因分析 找不到安装源文件。 解决办法 可以通过如下 PowerShell 脚本进行安装&#xff1a;…

Concept3D推出交互式3D地图平台

对于活动组织者而言&#xff0c;能够在不必实际旅行的情况下参观活动地点的想法非常具有吸引力&#xff0c;特别是对于日程安排繁忙的人员。Concept3D通过其交互式地图和身临其境的虚拟导览软件实现了这一点。 Concept3D平台的首要位置之一是棕榈泉会议中心&#xff0c;该中心支…

【机器视觉学习笔记】OpenCV C++ 调用笔记本摄像头

目录测试程序实验现象平台&#xff1a;Windows 10 20H2 Visual Studio 2015 opencv_contrib-3.4.12 转自【opencv七】利用opencv调用电脑摄像头 —— yuanCruise 测试程序 #include <opencv2/opencv.hpp> #include <iostream>using namespace cv;int main() {n…

深入分析 Java 中的中文编码问题

几种常见的编码格式 为什么要编码 不知道大家有没有想过一个问题&#xff0c;那就是为什么要编码&#xff1f;我们能不能不编码&#xff1f;要回答这个问题必须要回到计算机是如何表示我们人类能够理解的符号的&#xff0c;这些符号也就是我们人类使用的语言。由于人类的语言有…

APP图标生成工具

今天25学堂跟大家推荐一款非常有趣和简单的APP图标生成工具&#xff1a;Iconion Icon Generator&#xff08;iconion图标生成器&#xff09; 我们可以用它来创建美丽的扁平化图标&#xff0c;长投影图标&#xff0c;桌面图标&#xff0c;社会媒体图标和移动APP图标等&#xff0…

基本形态学算法

基本形态学算法为什么要做基本形态学算法的研究和实现&#xff1f;是因为形态学是一个非常有力&#xff0c;应用 广泛的工具&#xff0c;但同时也是研究不是很清楚的工具。往往一个恰到好处的变换&#xff0c;就能够省下许多的劳动。对此的分类和研究就显得非常有必要&#xff…

【51单片机快速入门指南】4.4:I2C 读取HMC5883L / QMC5883L 磁力计

目录硬知识简介操作模式HMC5883L连续测量模式单次测量模式闲置模式QMC5883L连续测量模式待命模式主要差异寄存器寄存器列表HMC5883LQMC5883L配置寄存器HMC5883L配置寄存器 A配置寄存器 B模式寄存器QMC5883L控制寄存器1控制寄存器2SET/RESET Period Register数据输出寄存器HMC58…

leaflet加载离线OSM(OpenStreetMap)

转载&#xff1a; https://www.cnblogs.com/RainyBear/p/6011832.html leaflet作为广为应用的开源地图操作的API,是非常受欢迎&#xff0c;轻量级的代码让使用者更容易操作。 废话不多说&#xff0c;下面直接给出范例。 首先在这个网站下载leaflet的压缩包&#xff0c;其中包括…

Nginx 实战(一) 集群环境搭建

Nginx是什么&#xff1f; Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器&#xff0c;也是一个 IMAP/POP3/SMTP 代理服务器。一直纳闷这个X是怎么来的在网上查了查原来X代表很牛逼的样子&#xff0c;Nginx就是代表一个非常牛逼的引擎服务器系统&#xf…

【51单片机快速入门指南】4.4.1:python串口接收磁力计数据并进行最小二乘法椭球拟合

目录硬知识Python代码使用方法串口收集数据椭球拟合验证STC15F2K60S2 16.384MHz Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 Python 3.8.11 (default, Aug 6 2021, 09:57:55) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32 参考资料&…

MATLAB之基本语法之常用命令

1. whos&#xff08;或者who&#xff09; 可以查看command window的变量 当调试MATLAB程序时&#xff0c;该条命令经常用到&#xff01;&#xff01;&#xff01; 2. clc 清除命令窗口内容但是不清除变量 3. clear 清除命令窗口内容并且清除变量 4. …

【51单片机快速入门指南】4.4.2:Mahony AHRS 九轴姿态融合获取四元数、欧拉角

目录传感器的方向源码Mahony_9.cMahony_9.h使用方法测试main.c效果STC15F2K60S2 22.1184MHz Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 上位机&#xff1a;Vofa 1.3.10 移植自MPU6050 获取角度理论推导(三)—9轴融合算法 —— shao15232_1 传感器…

BZOJ 2160 拉拉队排练

2160: 拉拉队排练 Description 艾利斯顿商学院篮球队要参加一年一度的市篮球比赛了。拉拉队是篮球比赛的一个看点&#xff0c;好的拉拉队往往能帮助球队增加士气&#xff0c;赢得最终的比赛。所以作为拉拉队队长的楚雨荨同学知道&#xff0c;帮助篮球队训练好拉拉队有多么的重要…

React Native获取设备信息组件

转载 https://www.jianshu.com/p/907b003835dc本文原创首发于公众号&#xff1a;ReactNative开发圈&#xff0c;转载需注明出处。这次介绍的获取移动设备信息的组件名叫&#xff1a;react-native-device-info&#xff0c;兼容IOS和安卓双平台&#xff0c;可以获取设备ID、设备品…

UNIX网络编程——套接字选项(SO_RCVBUF和SO_SNDBUF)

有时候我们需要控制套接字的行为(如修改缓冲区的大小),这个时候我们就要学习套接字选项。int getsockopt(int sockfd,int level,int optname,void *optval,socklen_t *optlen) int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t *optlen)level指定…