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

目录

  • 源码
    • Madgwick_6.c
    • Madgwick_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


移植自AHRS —— LOXO,算法作者:SOH Madgwick

源码

       为了避免所用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陀螺仪的原始数据

        beta要按需调整,我这里取0.1

Madgwick_6.c

//=====================================================================================================
//
// Implementation of Madgwick's IMU and AHRS algorithms.
// See: http://www.x-io.co.uk/node/8#open_source_ahrs_and_imu_algorithms
//
// Date			Author          Notes
// 29/09/2011	SOH Madgwick    Initial release
// 02/10/2011	SOH Madgwick	Optimised for reduced CPU load
// 19/02/2012	SOH Madgwick	Magnetometer measurement is normalised
//
//=====================================================================================================//---------------------------------------------------------------------------------------------------
// Header files
#include <math.h>
#include "MPU6050.h"//---------------------------------------------------------------------------------------------------
// Definitions#define beta	0.1f										// 2 * proportional gain (Kp)//---------------------------------------------------------------------------------------------------
// Variable definitionsidata volatile float q0 = 1.0f, q1 = 0.0f, q2 = 0.0f, q3 = 0.0f;	// quaternion of sensor frame relative to auxiliary frame
idata volatile float Pitch = 0.0f, Roll = 0.0f, Yaw = 0.0f;//====================================================================================================
// Functionsidata float sampleFreq = 1;
idata float GYRO_K = 1;void MPU6050_Madgwick_Init(float loop_ms)
{sampleFreq = 1000. / loop_ms;	//sample frequency in Hzswitch((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;}
}//---------------------------------------------------------------------------------------------------
// Fast inverse square-root
// See: http://en.wikipedia.org/wiki/Fast_inverse_square_rootfloat invSqrt(float 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;
}//---------------------------------------------------------------------------------------------------
// AHRS algorithm update
//---------------------------------------------------------------------------------------------------
// IMU algorithm updatevoid MadgwickAHRSupdate_6(float gx, float gy, float gz, float ax, float ay, float az) 
{float recipNorm;float s0, s1, s2, s3;float qDot1, qDot2, qDot3, qDot4;float _2q0, _2q1, _2q2, _2q3, _4q0, _4q1, _4q2 ,_8q1, _8q2, q0q0, q1q1, q2q2, q3q3;//将陀螺仪AD值转换为 弧度/sgx = gx * GYRO_K;gy = gy * GYRO_K;gz = gz * GYRO_K;// Rate of change of quaternion from gyroscopeqDot1 = 0.5f * (-q1 * gx - q2 * gy - q3 * gz);qDot2 = 0.5f * (q0 * gx + q2 * gz - q3 * gy);qDot3 = 0.5f * (q0 * gy - q1 * gz + q3 * gx);qDot4 = 0.5f * (q0 * gz + q1 * gy - q2 * gx);// Compute feedback only if accelerometer measurement valid (avoids NaN in accelerometer normalisation)if(!((ax == 0.0f) && (ay == 0.0f) && (az == 0.0f))) {// Normalise accelerometer measurementrecipNorm = invSqrt(ax * ax + ay * ay + az * az);ax *= recipNorm;ay *= recipNorm;az *= recipNorm;   // Auxiliary variables to avoid repeated arithmetic_2q0 = 2.0f * q0;_2q1 = 2.0f * q1;_2q2 = 2.0f * q2;_2q3 = 2.0f * q3;_4q0 = 4.0f * q0;_4q1 = 4.0f * q1;_4q2 = 4.0f * q2;_8q1 = 8.0f * q1;_8q2 = 8.0f * q2;q0q0 = q0 * q0;q1q1 = q1 * q1;q2q2 = q2 * q2;q3q3 = q3 * q3;// Gradient decent algorithm corrective steps0 = _4q0 * q2q2 + _2q2 * ax + _4q0 * q1q1 - _2q1 * ay;s1 = _4q1 * q3q3 - _2q3 * ax + 4.0f * q0q0 * q1 - _2q0 * ay - _4q1 + _8q1 * q1q1 + _8q1 * q2q2 + _4q1 * az;s2 = 4.0f * q0q0 * q2 + _2q0 * ax + _4q2 * q3q3 - _2q3 * ay - _4q2 + _8q2 * q1q1 + _8q2 * q2q2 + _4q2 * az;s3 = 4.0f * q1q1 * q3 - _2q1 * ax + 4.0f * q2q2 * q3 - _2q2 * ay;recipNorm = invSqrt(s0 * s0 + s1 * s1 + s2 * s2 + s3 * s3); // normalise step magnitudes0 *= recipNorm;s1 *= recipNorm;s2 *= recipNorm;s3 *= recipNorm;// Apply feedback stepqDot1 -= beta * s0;qDot2 -= beta * s1;qDot3 -= beta * s2;qDot4 -= beta * s3;}// Integrate rate of change of quaternion to yield quaternionq0 += qDot1 * (1.0f / sampleFreq);q1 += qDot2 * (1.0f / sampleFreq);q2 += qDot3 * (1.0f / sampleFreq);q3 += qDot4 * (1.0f / sampleFreq);// Normalise quaternionrecipNorm = invSqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);q0 *= recipNorm;q1 *= recipNorm;q2 *= recipNorm;q3 *= recipNorm;Pitch = asin(-2.0f * (q1*q3 - q0*q2))* 57.3f;Roll = atan2(q0*q1 + q2*q3, 0.5f - q1*q1 - q2*q2) * 57.3f;Yaw = atan2(q1*q2 + q0*q3, 0.5f - q2*q2 - q3*q3)* 57.3f;
}//====================================================================================================
// END OF CODE
//====================================================================================================

Madgwick_6.h

#ifndef Madgwick_6_H_
#define Madgwick_6_H_extern idata float Pitch, Roll, Yaw;
extern idata float q0, q1, q2, q3;void MPU6050_Madgwick_Init(float loop_ms);
void MadgwickAHRSupdate_6(float gx, float gy, float gz, float ax, float ay, float az);#endif

使用方法

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

测试程序

main.c

#include <STC89C5xRC.H>
#include "intrins.h"
#include "stdint.h"
#include "USART.h"
#include "./MPU6050/MPU6050.h"
#include "./MPU6050/Madgwick_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)
{idata int16_t aacx,aacy,aacz;		//加速度传感器原始数据idata 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_Madgwick_Init(95);while(1){	MPU_Get_Accelerometer(&aacx, &aacy, &aacz);	//得到加速度传感器数据MPU_Get_Gyroscope(&gyrox, &gyroy, &gyroz);	//得到陀螺仪数据MadgwickAHRSupdate_6(gyrox, gyroy, gyroz, aacx, aacy, aacz);printf("%f, ", Pitch);printf("%f, ", Roll);printf("%f\r\n", Yaw);}
}

效果

在这里插入图片描述

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

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

相关文章

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指定…

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

目录传感器的方向源码Madgwick_9.cMadgwick_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 移植自AHRS —— LOXO&#xff0c;算法作者&#xff1a;SOH Madgwick 传…

关于json格式字符串解析并用mybatis存入数据库

园子里面找了很多关于json解析后存入数据库的方法&#xff0c;不是太乱&#xff0c;就是没有写完&#xff0c;我下面的主题代码多是受下面两位的启发&#xff0c;请按顺序查看 http://www.cnblogs.com/tian830937/p/6364622.html,我沿用了这个例子中的json数据格式&#xff0c;…