mpu9250磁力计校准 mpl库数据校准

  • 写在前面
  • 为什么磁力计需要校准
  • 官方的mpl库简介
  • 如何磁力计校准以及保存校准数据
  • 参考代码
  • 总结

写在前面

 前段时间弄了MPU9250,也就是9轴传感器,用的是官方的mpl库。但是读的欧拉角翻滚角和俯仰角都很准,就是航向角不准。快速的转动一下,再回到原来的角度,航向角就偏移了几十度,完全达不到预期。因为航向角需要融合磁力计数据但是磁力计需要校准,一开始不知道怎么校准磁力计数据所以这个问题困扰了我好久,直到最近才弄好,所以想把我的一些经验分享给大家,以免大家遇到同样的困扰。

为什么磁力计需要校准

 至于为什么磁力计需要校准,大家看下下面这几个图就应该清楚了,有需要椭圆拟合Matlab程序的可以直接百度云下载,链接:https://pan.baidu.com/s/1eQ_A84vkUf3B_sdN6DUvQg 提取码:mpyn

图1 磁力计原始数据

 如图1所示是我通过串口助手获取的原始磁力计数据,然后再将数据导入excel表格,在matlab上面显示的结果。大家应该可以清楚的发现,磁力计读出的数据是个椭球。这是因为磁力计是三个互相垂直的霍尔元件组成的一个传感器,每个轴的数据都是地磁场在每个轴的分量,但是由于传感器之间有差异所以导致椭圆的轴并不相同,而且大家可以从图上看出磁力传感器和加速度传感器一样,磁力计的数据原点并不是0,所以我们还要进行椭圆拟合求出,椭球的原点和椭球的轴长。

图2 通过matlab拟合后的图形显示

 上图2是我通过matlab拟合椭圆中心和轴长的数据,说到椭球拟合也是费了我不少功夫,我也是在一篇博客上看到一个博主推到的公式,以前没怎么弄过matlab,所以又花了时间把matlab看了下才写出的这个拟合函数。

图3 matlab拟合后的结果

 图3是我通过matlab拟合后的结果,但是拟合好数据又要将数据融合到世界坐标系,然后又是各种资料,各种数学公式,又困扰了我好久,最后感觉自己实在弄不好,就又重新看了下mpl的库文档,发现库文档上面说mpl库会自动校准数据,让传感器做8字运动会加快磁力计校准,所以我又重新试了下,8字运动了一两分钟后发现果然可以了,数据很准。相比于我们网上很多的数据融合算法,官方的mpl库还是更强大一些,毕竟是大公司的产品。

官方的mpl库简介

 官方的mpl库具有以下特点:
 1.陀螺仪实时校准,只要检测到陀螺仪停止5s就回重新校准陀螺仪。
 2.陀螺仪温度补偿。
 3.磁力计校准,只要收集到足够的数据就会在算法中融合磁力计数据,不然就只融合6轴传感器数据,做8字运动会加快校准。
 4.抗强磁干扰,当有强磁干扰的时候会启动6轴融合,不融合磁力计数据。

如何磁力计校准以及保存校准数据

 但是我们怎么知道数据什么时候融合好呢?其中有一个这个函数,

int inv_get_sensor_type_euler(long *data, int8_t *accuracy, inv_time_t *timestamp)

大家可以获取accuracy的值,在没有磁力计没有校准钱accuracy为0,校准后值为3,大家可以一直把这个值显示出来,在校准好数据前一直让传感器做8字运动,加快校准。
但是每次校准都要不少时间每次重启都要校准的话岂不是很麻烦,当然这个问题官方也肯定想到了。
其中有三个函数是关于储存校准数据的:

inv_error_t inv_get_mpl_state_size(size_t *size);
inv_error_t inv_load_mpl_states(const unsigned char *data, size_t len);
inv_error_t inv_save_mpl_states(unsigned char *data, size_t len);

 inv_save_mpl_states()此函数保存校准的数据,大家只要把数据通过flash存下来就好了,然后下次上电的时候通过inv_load_mpl_states()函数重新读取下数据。至于存放数据的大小可以同此函数inv_get_mpl_state_size()来获取。

图4 校准后的数据结果

 如图4所示为校准后的数据结果,我们可以发现在校准后第一个数据还是1.3,第二个数据才变成正在的校准后的数据,所以我们在使用的时候可以把第一个结果舍去。
 还要一点需要注意的是,我在测试过程中发现数据校准好了,也就是accuracy值为3了,但是一会accuracy又变为0了,这事大家可以把强磁干扰给关了,这样校准好数据后accuracy值就不会变为0了。至于怎么关,我用的是正点原子的程序改的,只要把mpu_dmp_init()函数中的inv_enable_magnetic_disturbance()使能抗强磁干扰给关了就行了。

参考代码

 这是我写的校准代码,大家可以参考下,功能是将mpu获取的欧拉角数据和accuracy值通过串口打印出来,如果accuracy为3,说明数据校准完成,当按下按键时就把校准数据保存到flash中,下次再启动则直接读取上传的校准数据。

//MAIN函数
int main(void)
{u8 res;u32 size;u8 key;float pitch,roll,yaw;Cache_Enable();                 //打开L1-CacheHAL_Init();                        //初始化HAL库Stm32_Clock_Init(160,5,2,4);    //设置时钟,400Mhz delay_init(400);             //延时初始化uart_init(256000);               //串口初始化LED_Init();                      //初始化LEDKEY_Init();                     //初始化按键while(MPU9250_Init()){printf("MPU9250_Init Error\r\n");delay_ms(1000);}  LCD_Init();      res=mpu_dmp_init();printf("res:%d\r\n",res);LCD_Clear(WHITE);      //清屏  Draw_Font16B(16,16,RED, (u8 *)"MPU TEST");NORFLASH_Init();             //NORFLASH(W25Q64)初始化if(NORFLASH_ReadID()!=W25Q64){printf("W25Q64 error\r\n");delay_ms(500);LED0_Toggle;}else {printf("W25Q64 ok\r\n");}NORFLASH_Read(mpudateBuff,MpuSaveDateAddr,sizeof(mpudateBuff));//读取mpu9250校准数据if(inv_load_mpl_states(mpudateBuff,sizeof(mpudateBuff))==INV_SUCCESS){printf("=======inv_load_mpl_states ok====================\r\n");}else {printf("=======inv_load_mpl_states error====================\r\n");}while(1){LED0_Toggle;key=KEY_Scan(0);if(key==KEY1_PRES){printf("key1_press====================\r\n");if(inv_get_mpl_state_size(&size)==INV_SUCCESS){printf("=======inv_get_mpl_state_size ok====================\r\n");printf("lensize:%d\r\n",size);if(inv_save_mpl_states(mpudateBuff,sizeof(mpudateBuff))==INV_SUCCESS){printf("=======inv_save_mpl_states ok====================\r\n");NORFLASH_Write((u8*)mpudateBuff,MpuSaveDateAddr,sizeof(mpudateBuff));}else{printf("=======inv_save_mpl_states error====================\r\n");}}}if(mpu_mpl_get_data(&pitch,&roll,&yaw)==0){printf("pitch:%.1f,roll:%.1f,yaw:%.1f\r\n",pitch,roll,yaw);}delay_us(10000);                           //延时1s,也就是1000个时钟节拍  }
}
//mpu_mpl_get_data欧拉角获取函数
u8 mpu_mpl_get_data(float *pitch,float *roll,float *yaw)
{unsigned long sensor_timestamp=0,timestamp=0;short gyro[3], accel_short[3],compass_short[3],sensors;unsigned char more;long compass[3],accel[3],quat[4],temperature; long data[9];int8_t accuracy;if(dmp_read_fifo(gyro, accel_short, quat, &sensor_timestamp, &sensors,&more))return 1;  if(sensors&INV_XYZ_GYRO){inv_build_gyro(gyro,sensor_timestamp);          //把新数据发送给MPLmpu_get_temperature(&temperature,&sensor_timestamp);inv_build_temp(temperature,sensor_timestamp);   //把温度值发给MPL,只有陀螺仪需要温度值}if(sensors&INV_XYZ_ACCEL){accel[0] = (long)accel_short[0];accel[1] = (long)accel_short[1];accel[2] = (long)accel_short[2];inv_build_accel(accel,0,sensor_timestamp);      //把加速度值发给MPL}if (!mpu_get_compass_reg(compass_short, &sensor_timestamp)) {compass[0]=(long)compass_short[0];compass[1]=(long)compass_short[1];compass[2]=(long)compass_short[2];inv_build_compass(compass,0,sensor_timestamp); //把磁力计值发给MPL}inv_execute_on_data();inv_get_sensor_type_euler(data,&accuracy,&timestamp);*roll  = (data[0]/q16);*pitch = -(data[1]/q16);*yaw   = -data[2] / q16;printf("accuracy %d\r\n",accuracy);return 0;
}

总结

 总结一下我遇到的问题:
 1.如果用杜邦线连mpu9250的话杜邦线要尽量短,不然读出来的设备地址可能就是0xff或者0xd1等等了,我是把杜邦线剪短再重新用热缩管接好才解决这个问题的。
 2.mpu9250要正这放,不然自检通不过。
 3.通过inv_get_sensor_type_euler()函数来获取accuracy值来确定磁力计数据是否校准好,为3则校准好,为0没校准好。
 4.做8字校准会加快校准速度,如果如果2分钟也没校准好也不要急慢慢来。
 5.通过inv_save_mpl_states()等函数来保存校准数据。

mpu9250磁力计校准 mpl库数据校准相关推荐

  1. QCA三天写论文!模糊集数据校准实战

    QCA三天写论文!模糊集数据校准实战

  2. STM32L0 ADC使用HAL库关于校准问题的说明

    STM32 系列 ADC校准问题说明 前言 最近是有一个产品用到了ADC,使用的是STM32L051 芯片,使用 STM32CubeMX 生成的代码,本来以为简简单单,但是在调用 HAL ADC校准函 ...

  3. 移植MPL库(基于STM32CubeIDE开发环境)

    移植MPL库(基于STM32CubeIDE开发环境) 目前在开发利用MPU9250做9轴的应用的时候,查到的资料基本上都是基于STM32F4平台,MDK开发环境.MDK需要license,STM32前 ...

  4. 独家 | Python的“predict_prob”方法不能真实反映预测概率校准(如何实现校准)...

    作者:  Samuele Mazzanti 翻译:欧阳锦 校对:王可汗 本文约2300字,建议阅读8分钟 本文讨论了使用python中" predict_proba"的方法所生成的 ...

  5. DTX1800校准的意义?---DTX-1800线缆测试仪此校准而非彼校准

    DTX1800校准的意义?-DTX-1800线缆测试仪此校准而非彼校准 首先我们要搞清楚,什么是校准? 一,第三方校准:该定义的含义是: ⒈在规定的条件下,用一个可参考的标准,对包括参考物质在内的测量 ...

  6. android校准电池,为什么电池校准不适用于Android智能手机

    原标题:为什么电池校准不适用于Android智能手机 智能手机制造商建议每月或每三个月校准一次手机电池.但是,这是什么意思?今天真的有必要进行电池校准吗?事实证明,您可能不需要校准电池. Androi ...

  7. abb外部轴零位校准_ABB机器人零点校准详细解读

    一.本节要点 ★ 了解需校准情况 ★ 熟悉零点校准原理 ★ 熟练掌握零点校准方法 二.需校准情况 在以下几种情况下,ABB机器人需要校准机械零点: (1)新购买机器人时,厂家未进行机器人零点校准. ( ...

  8. Python: sklearn库——数据预处理

    Python: sklearn库 -- 数据预处理 数据集转换之预处理数据:       将输入的数据转化成机器学习算法可以使用的数据.包含特征提取和标准化.       原因:数据集的标准化(服从均 ...

  9. calibration trl 设计_校准:怎样设计和验证TRL校准件以及TRL校准的具体过程

    1.1 TRL标准件的要求 通常来说,TRL标准件的要求如下: (1)   直通标准件 电气长度为0时,无损耗,无反射,传输系数为1:电气长度不为0时,直通标准件的特性阻抗必须和延迟线标准件相同,无须 ...

最新文章

  1. python生成word目录_Word&Python-创建目录
  2. 毕设开发日志2017-11-03
  3. 使用Storm实现WordSum
  4. 没有找到borlandmm.dll 报错的解决方法
  5. Setting Gdb on Windows
  6. 深入浅出理解有限状态机
  7. 第八届蓝桥杯决赛 平方十位数(枚举)
  8. 第五章 类加载器ClassLoader源码解析
  9. Opencv 配置VS2012
  10. Opportunity workflow debug
  11. Dijkstra算法——计算一个点到其他所有点的最短路径的算法
  12. Qt多线程-QThreadPool线程池与QRunnable
  13. java写入excel文件poi
  14. [转载] Java中如何在方法中return返回多个值
  15. ubuntu下安装php的curl扩展
  16. 【代码优化】注解优先命名模式
  17. JAVA学习-类与对象(韩顺平java-高级篇)
  18. linux服务器上的cad病毒,LibreCAD_LibreCAD下载[2021官方最新版]LibreCAD安全下载_ 极速下载...
  19. boost创建线程池_linux下boost的一个扩展线程池-threadpool-的学习
  20. 最新论文阅读(17)--Pyramidal RoR for Image Classification

热门文章

  1. 如何用python处理pdf_用Python处理PDF
  2. Cadence Allegro修改图纸尺寸和栅格大小图文教程及视频演示
  3. 第一章 JavaWEB专题之Http基础协议解析
  4. Android进阶知识(二十五):Bitmap简介及其高效加载
  5. 最全的数据结构归纳总结
  6. 川希:普通人通过理财就能实现财务自由?大骗局!
  7. win10家庭版访问域文件服务器拒绝,解决Win10系统文件夹拒绝访问的方法
  8. 安卓IMS 原理解析(二、IMS之InputReader事件获取)
  9. 回调函数的注册机制为什么会在嵌入式固件开发中应用如此广泛?
  10. 【牛客网】 小白月赛16 D小阳买水果