搜索
bottom↓
回复: 18

加速度数据滑动滤波莫名错误!求救!

[复制链接]

出0入0汤圆

发表于 2014-11-15 14:24:38 | 显示全部楼层 |阅读模式
本帖最后由 zzipeng 于 2014-11-15 16:40 编辑

如题,我现在弄四轴代码。姿态已经初步解算出来。但是遇到一个很奇怪的问题。即加速度数据平滑滤波时,输出的数据莫名变大。先上代码:

  1. #define gyro_denominator 3753.15f //陀螺仪灵敏度
  2. #define acc_denominator 836.943f //加计灵敏度  8192/9.788=836.943 广州重力加速度 9.788m/s^2
  3. int16_t G_X,G_Y,G_Z,A_X,A_Y,A_Z;//减去零偏后的数据
  4. int16_t ACC_Axis_X,ACC_Axis_Y,ACC_Axis_Z;//加计滑动滤波后输出的数据
  5. float IMU_GYRO_X,IMU_GYRO_Y,IMU_GYRO_Z;//角速度rad/s
  6. float IMU_ACC_X,IMU_ACC_Y,IMU_ACC_Z;//加速度m/s^2
  7. 。。。。。。。。
  8. if(Data_Slid_Analys==TRUE)//检测加计平滑滤波标志
  9.         {
  10.                 uint8_t i;
  11.                 static u8 coun=0;
  12.                 static int16_t ACC_BUF_X[20];
  13.                 static int16_t ACC_BUF_Y[20];
  14.                 static int16_t ACC_BUF_Z[20];
  15.                 int32_t Tempx,Tempy,Tempz;
  16.                
  17.        
  18.                 ACC_BUF_X[coun] = A_X;
  19.                    ACC_BUF_Y[coun] = A_Y;
  20.                 ACC_BUF_Z[coun] = A_Z;
  21.                
  22.                 for(i=0;i<20;i++)
  23.                 {
  24.                         Tempx+=ACC_BUF_X[i];
  25.                         Tempy+=ACC_BUF_Y[i];
  26.                         Tempz+=ACC_BUF_Z[i];
  27.               }
  28.                
  29.                 ACC_Axis_X=Tempx / 20;//求平均输出
  30.                 ACC_Axis_Y=Tempy / 20;
  31.                 ACC_Axis_Z=Tempz / 20;

  32.        
  33.                 IMU_ACC_X=ACC_Axis_X / acc_denominator; //将滑动滤波后的加计数据转换成以m/s^2为单位的加速度数据
  34.                 IMU_ACC_Y=ACC_Axis_Y / acc_denominator;
  35.                   IMU_ACC_Z=ACC_Axis_Z / acc_denominator;
  36.                
  37.                 IMU_GYRO_X=G_X / gyro_denominator; //将陀螺仪数据转换成以rad/s为单位的角速度数据
  38.                 IMU_GYRO_Y=G_Y / gyro_denominator;//
  39.                 IMU_GYRO_Z=G_Z / gyro_denominator; //
  40.                
  41.                 coun++;
  42.                 if(coun==20)   {coun=0;        IMUupdate_Flag=TRUE;//可以解算姿态了}
  43.                
  44.        
  45.         }
复制代码

可以看到,代码其实很简单的。就是对减去零偏后的加计数据平滑滤波后转换成加速度输出,陀螺仪数据不作滤波处理,直接转换成角速度输出。问题是我用匿名的上位机对加计平滑滤波后的数据进行显示观看。发现变量ACC_Axis_X明显变大,直接飙到26000!见图1。奇怪的是ACC_Axis_Y,ACC_Axis_Z并无影响。于是我将ACC_Axis_X=Tempx / 20;//求平均输出这语句屏蔽掉;将IMU_ACC_X=ACC_Axis_X / acc_denominator; 这语句中的ACC_Axis_X 改为A_X,即X轴加计数据放弃滤波输出,这时发现轮到ACC_Axis_Y数据发飙了,ACC_Axis_Z无影响!
        试过将acc_denominator,gyro_denominator两个参数改为整数,结果并无变化。。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2014-11-15 15:22:58 | 显示全部楼层
可以參考我之前寫的
https://github.com/QCopter/QCopt ... algorithm_moveAve.c

沒仔細看, 但覺得可能是靈敏度或是益位問題

出0入0汤圆

发表于 2014-11-15 15:42:26 | 显示全部楼层
额 还没有累加到20个数 就去求均值?

出0入0汤圆

 楼主| 发表于 2014-11-15 16:37:48 | 显示全部楼层
asha 发表于 2014-11-15 15:42
额 还没有累加到20个数 就去求均值?

这个代码是局部的。。。实际的代码是这个函数执行20次之后才允许后面姿态解算

出0入0汤圆

 楼主| 发表于 2014-11-15 16:52:24 | 显示全部楼层
john800422 发表于 2014-11-15 15:22
可以參考我之前寫的
https://github.com/QCopter/QCopterFlightControl/blob/Pre-v2.2/Software/QCopterFC_ ...

你给的链接上的代码看了,感觉没什么区别啊。。。原理都一样
能讲一下什么事溢位吗?与溢出有什么不同。。。谢了

出0入0汤圆

发表于 2014-11-15 17:00:49 | 显示全部楼层
应该是硬件的问题。。。。

出0入0汤圆

发表于 2014-11-15 14:24:39 | 显示全部楼层
累加和Tempx临时变量,会不会有时候进入的时候不是0呢?一般我们定义成静态变量,,计算一次之后清0,也就是=20的时候清0.

出0入0汤圆

 楼主| 发表于 2014-11-15 20:39:43 | 显示全部楼层
本帖最后由 zzipeng 于 2014-11-15 20:43 编辑
lovecxm 发表于 2014-11-15 19:11
累加和Tempx临时变量,会不会有时候进入的时候不是0呢?一般我们定义成静态变量,,计算一次之后清0,也就 ...


靠。。按你的说法,将Tempx、Tempy、Tempz三个变量由临时类型改为static类型还真奇迹发生了——问题解决。见图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-11-15 21:20:49 | 显示全部楼层
给你一个平滑滤波的算法。我已经用了10年了,非常好用,比起你那个20点统计一次并求平均的算法要简单很多。这个算法同样也是求平均值滤波算法。
uint8  filter_NUM=20; //定义需要滤波数据的个数
Out_AD_Data=(filter_NUM*AD_Data_filter_last+AD_Data))/(filter_NUM+1);
AD_Data_filter_last=Out_AD_Data;

Out_AD_Data是最终输出后的滤波值,也就是你要用的值
AD_Data_filter_last是缓存值,存储上一次得到的滤波数据结果
AD_Data为AD采样到的数据
filter_NUM为定义需要滤波数据的个数

这个算法有个缺点,当前20个数据进入前Out_AD_Data输出数据会偏小很多。但是一旦AD数据超过20个以后,这个平滑滤波系统输出数据就很稳定了,并且不需要每次都采集20个数据后再进行滤波。可以直接一直滤波。      

出0入0汤圆

 楼主| 发表于 2014-11-15 21:28:25 | 显示全部楼层
dj1981812 发表于 2014-11-15 21:20
给你一个平滑滤波的算法。我已经用了10年了,非常好用,比起你那个20点统计一次并求平均的算法要简单很多。 ...

谢谢!代码看了,的确很巧妙!

出0入0汤圆

发表于 2014-11-15 21:57:17 | 显示全部楼层
不客气,好用就行。

出0入0汤圆

发表于 2014-11-16 10:17:41 | 显示全部楼层
你这个不对吧?!temp本来就应该是临时变量,所以你贴的源码没有错误。然后就是,加速度计静止时读数不应该是零而是重力加速度值,所以一般平放时Z轴会有很大的输出。另外确保没有数据类型错误!

出0入4汤圆

发表于 2014-11-16 10:30:38 | 显示全部楼层
略看了一下代码,发现你Tempx,Tempy,Tempz根本没清零,不飙大数据才奇怪呢。
你用的是均值滤波,连续采集20次后,再求平均值。即在
                ACC_Axis_X=Tempx / 20;//求平均输出
                ACC_Axis_Y=Tempy / 20;
                ACC_Axis_Z=Tempz / 20;
后面加上一下清零代码:
                Tempx =0;
                Tempy =0;
                Tempz =0;
这样就解决你的问题了。目测是这个问题,你可以试一下。

应用在四轴上不太建议用均值滤波,降低频响.......

出0入0汤圆

 楼主| 发表于 2014-11-16 12:15:05 | 显示全部楼层
oner 发表于 2014-11-16 10:30
略看了一下代码,发现你Tempx,Tempy,Tempz根本没清零,不飙大数据才奇怪呢。
你用的是均值滤波,连续采集20 ...

已经按照你的意见将Tempx、Tempy、Tempz三个变量由static改为临时变量(去掉static),然后加上Tempx=0;Tempy=0;Tempz=0;几句代码,结果并无改变。忘记说了,我现在用的代码是Tempx、Tempy、Tempz为static变量,然后Tempx=0;Tempy=0;Tempz=0;这三句代码也是有的。
还有要说明的是,我用的是滑动滤波而不是简单的每采样20次然后求平均值输出。看到        ACC_BUF_X[coun]=A_X;这代码中的coun和数组ACC_BUF_X[]为static 变量就知道了。
                       
                       

出0入4汤圆

发表于 2014-11-17 17:43:19 来自手机 | 显示全部楼层
zzipeng 发表于 2014-11-16 12:15
已经按照你的意见将Tempx、Tempy、Tempz三个变量由static改为临时变量(去掉static),然后加上Tempx=0;Te ...

哦哦,的确是滑动滤波,我之前没细看误导你了。

出0入0汤圆

发表于 2015-4-11 14:39:59 | 显示全部楼层
dj1981812 发表于 2014-11-15 21:20
给你一个平滑滤波的算法。我已经用了10年了,非常好用,比起你那个20点统计一次并求平均的算法要简单很多。 ...

你这个滤波算法滞后会不会很大,第一个点怎么取呢

出0入0汤圆

发表于 2015-5-7 10:16:32 | 显示全部楼层
yanghuanchun 发表于 2015-4-11 14:39
你这个滤波算法滞后会不会很大,第一个点怎么取呢

当然会有滞后了,要看你怎么设计了,你的滤波计数的多少决定你的延迟时间。

出0入0汤圆

发表于 2015-7-7 15:52:24 | 显示全部楼层
dj1981812 发表于 2014-11-15 21:20
给你一个平滑滤波的算法。我已经用了10年了,非常好用,比起你那个20点统计一次并求平均的算法要简单很多。 ...

这个实际就是加权平均~

出0入0汤圆

发表于 2015-7-7 16:03:00 | 显示全部楼层
临时变量声明,求和是,变量要初始化为0,不然会错
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 15:41

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表