发新帖我要提问
12
返回列表
打印
[资源共享]

移植MPU6050-DMP库实现姿态角PRY解算

[复制链接]
楼主: 回复就哭哭
手机看帖
扫描二维码
随时随地手机跟帖
21
回复就哭哭|  楼主 | 2022-6-30 13:58 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
mpu_dmp_get_data 函数代码如下:
//得到dmp处理后的数据(注意,本函数需要比较多堆栈,局部变量有点多)
//pitch:俯仰角 精度:0.1°   范围:-90.0° <---> +90.0°
//roll:横滚角  精度:0.1°   范围:-180.0°<---> +180.0°
//yaw:航向角   精度:0.1°   范围:-180.0°<---> +180.0°
//返回值:0,正常
//    其他,失败
u8 mpu_dmp_get_data(float *pitch,float *roll,float *yaw)
{
        float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f;
        unsigned long sensor_timestamp;
        short gyro[3], accel[3], sensors;
        unsigned char more;
        long quat[4];
        if(dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,&more))return 1;         
        /* Gyro and accel data are written to the FIFO by the DMP in chip frame and hardware units.
         * This behavior is convenient because it keeps the gyro and accel outputs of dmp_read_fifo and mpu_read_fifo consistent.
        **/
        /*if (sensors & INV_XYZ_GYRO )
        send_packet(PACKET_TYPE_GYRO, gyro);
        if (sensors & INV_XYZ_ACCEL)
        send_packet(PACKET_TYPE_ACCEL, accel); */
        /* Unlike gyro and accel, quaternions are written to the FIFO in the body frame, q30.
         * The orientation is set by the scalar passed to dmp_set_orientation during initialization.
        **/
        if(sensors&INV_WXYZ_QUAT)
        {
                q0 = quat[0] / q30;        //q30格式转换为浮点数
                q1 = quat[1] / q30;
                q2 = quat[2] / q30;
                q3 = quat[3] / q30;
                //计算得到俯仰角/横滚角/航向角
                *pitch = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3;        // pitch
                *roll  = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3;        // roll
                *yaw   = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3;        //yaw
        }else return 2;
        return 0;
}

使用特权

评论回复
22
回复就哭哭|  楼主 | 2022-6-30 13:59 | 只看该作者
这里就用到了我们前面介绍的四元数转欧拉角公式,将 dmp_read_fifo 函数读到的 q30 格式四元数转换成欧拉角。

其中 quat[0]~ quat[3]是 MPU6050 的 DMP 解算后的四元数, q30 格式,所以要除以一个2 的 30 次方,其中 q30 是一个常量: 1073741824,即 2 的 30 次方,然后带入公式,计算出欧拉角。

上述计算公式的 57.3 是弧度转换为角度,即 180/π,这样得到的结果就是以度(°)为单位的。

关于四元数与欧拉角的公式推导,这里我们不进行讲解,感兴趣的朋友,可以自行查阅相关资料学习。

此函数用于得到 DMP 姿态解算后的俯仰角、横滚角和航向角。

使用特权

评论回复
23
回复就哭哭|  楼主 | 2022-6-30 14:02 | 只看该作者
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
#include "dmpKey.h"
#include "dmpmap.h"

#include "SEEKFREE_IIC.h"
#include "zf_systick.h"

//定义目标板采用MSP430
#define  MOTION_DRIVER_TARGET_MSP430

/* The following functions must be defined for this platform:
* i2c_write(unsigned char slave_addr, unsigned char reg_addr,
*      unsigned char length, unsigned char const *data)
* i2c_read(unsigned char slave_addr, unsigned char reg_addr,
*      unsigned char length, unsigned char *data)
* delay_ms(unsigned long num_ms)
* get_ms(unsigned long *count)
*/
#if defined MOTION_DRIVER_TARGET_MSP430
//#include "msp430.h"
//#include "msp430_clock.h"
#define delay_ms    systick_delay_ms
#define get_ms      mget_ms
#define log_i                 printf
#define log_e                  printf

使用特权

评论回复
24
回复就哭哭|  楼主 | 2022-6-30 14:03 | 只看该作者
4、 inv_mpu_dmp_motion_driver.c移植
这个文件只需要修改头文件调用和函数重新定义,不需要修改函数。

使用特权

评论回复
25
回复就哭哭|  楼主 | 2022-6-30 14:03 | 只看该作者
三、MM32程序编写
软件 IIC 引脚定义连接
#define SEEKFREE_SCL        B13                                                                                                                        // 定义SCL引脚
#define SEEKFREE_SDA        B15                                                                                                                        // 定义SDA引脚  

使用特权

评论回复
26
回复就哭哭|  楼主 | 2022-6-30 14:06 | 只看该作者
1、MPU6050初始化
//-------------------------------------------------------------------------------------------------------------------
// @brief                初始化MPU6050
// @param                NULL
// @return                void
//-------------------------------------------------------------------------------------------------------------------
void mpu6050_init(void)
{
        simiic_init();                                                                                                                        //模拟IIC的初始化
        systick_delay_ms(100);                                                                                                        // 上电延时

        mpu6050_self1_check();                                                                                                        //上电自检
        simiic_write_reg(MPU6050_DEV_ADDR, PWR_MGMT_1, 0x00);                                        // 解除休眠状态
        simiic_write_reg(MPU6050_DEV_ADDR, SMPLRT_DIV, 0x07);                                        // 125HZ采样率
        simiic_write_reg(MPU6050_DEV_ADDR, MPU6050_CONFIG, 0x04);                                //
        simiic_write_reg(MPU6050_DEV_ADDR, GYRO_CONFIG, 0x18);                                        // 2000
        simiic_write_reg(MPU6050_DEV_ADDR, ACCEL_CONFIG, 0x10);                                        // 8g
        simiic_write_reg(MPU6050_DEV_ADDR, User_Control, 0x00);
        simiic_write_reg(MPU6050_DEV_ADDR, INT_PIN_CFG, 0x02);
}

使用特权

评论回复
27
回复就哭哭|  楼主 | 2022-6-30 14:07 | 只看该作者
2、主函数编写
1、引入头文件
2、调用mpu6050初始化
3、dmp初始化
4、得到加速度值
5、解算欧拉角
6、屏幕显示
#include "headfile.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
// **************************** 代码区域 ****************************

int main(void)
{
        float pitch,roll,yaw;                 //欧拉角
        mpu6050_init();
        while(mpu_dmp_init()!=0)
        {
                LCD_ShowString(0,0,"dmp-error",MAGENTA);
        }
        LCD_ShowString(0,0,"dmp-init-ok",MAGENTA);

        while(1)
        {
                get_gyro();
                mpu_dmp_get_data(&pitch,&roll,&yaw);

                LCD_ShowFloat(0,40,pitch,5,BLACK);
                LCD_ShowFloat(0,60,roll,5,BLACK);
                LCD_ShowFloat(0,80,yaw,5,BLACK
        }
}

使用特权

评论回复
28
回复就哭哭|  楼主 | 2022-6-30 14:08 | 只看该作者
四、工程源码
最后工程文件我将放置在百度网盘链接: https://pan.baidu.com/s/1QRNr87n38MjN-yKf30Uiww提取码:jr2t

不足之处多多指教,工程的dmp我是根据正点原子的dmp库移植而来。

使用特权

评论回复
29
tpgf| | 2022-7-5 14:51 | 只看该作者
PRY解算如何解释呀

使用特权

评论回复
30
labasi| | 2022-7-5 15:00 | 只看该作者
mpu_init 函数来初始化哪一部分啊

使用特权

评论回复
31
paotangsan| | 2022-7-5 15:09 | 只看该作者
传感器的精度一般需要达到多少啊

使用特权

评论回复
32
renzheshengui| | 2022-7-5 15:15 | 只看该作者
姿态解算需要什么参数呢

使用特权

评论回复
33
wakayi| | 2022-7-5 15:25 | 只看该作者
需要更改的东西多吗

使用特权

评论回复
34
wowu| | 2022-7-5 15:32 | 只看该作者
可以采集什么种类的模拟信号啊

使用特权

评论回复
35
chenqianqian| | 2022-7-6 08:08 | 只看该作者
谢谢分享,学习一下。

使用特权

评论回复
36
daichaodai| | 2022-7-7 08:33 | 只看该作者
学习了,谢谢分享。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则