搜索
bottom↓
回复: 13

ADIS16405通过Kalman融合问题 高手给看看吧

[复制链接]

出0入0汤圆

发表于 2011-5-5 12:05:26 | 显示全部楼层 |阅读模式
ADIS16405 通过Kalman融合加速度和角速度计算出俯仰角,
由于安装原因,Z-Y两轴互换!


(原文件名:图.jpg)
红色为加速度的曲线,
蓝色为Kalman后的图形,
陀螺仪的没有打印出来,沿ADIS16405的Z轴(对调后的X轴)晃动,Kalman滤波后的数据还是跟着加速度晃动,这是什么原因!

#include <math.h>
#include <stdlib.h>

void matrix_multiply(float* A, float* B, int m, int p, int n, float* C)
{

    int i, j, k;
    for (i=0;i<m;i++)
        for(j=0;j<n;j++)
        {
          C[n*i+j]=0;
          for (k=0;k<p;k++)
            C[n*i+j]= C[n*i+j]+A[p*i+k]*B[n*k+j];
        }
}


static void matrix_addition(float* A, float* B, int m, int n, float* C)

{

    int i, j;
    for (i=0;i<m;i++)
        for(j=0;j<n;j++)
            C[n*i+j]=A[n*i+j]+B[n*i+j];
}

void matrix_subtraction(float* A, float* B, int m, int n, float* C)
{
    int i, j;
    for (i=0;i<m;i++)
        for(j=0;j<n;j++)
            C[n*i+j]=A[n*i+j]-B[n*i+j];
}
void matrix_transpose(float* A, int m, int n, float* C)
{     
     int i, j;
    for (i=0;i<m;i++)
        for(j=0;j<n;j++)
            C[m*j+i]=A[n*i+j];
}
int matrix_inversion(float* A, int n, float* AInverse)
{
    int i, j, iPass, imx, icol, irow;
    float det, temp, pivot, factor;
        float ac[10]={0,};
//    float* ac = (float*)calloc(n*n, sizeof(float));
    det = 1;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            AInverse[n*i+j] = 0;
            ac[n*i+j] = A[n*i+j];
        }
        AInverse[n*i+i] = 1;
    }


    for (iPass = 0; iPass < n; iPass++)
    {
        imx = iPass;
        for (irow = iPass; irow < n; irow++)
        {
            if (fabs(A[n*irow+iPass]) > fabs(A[n*imx+iPass])) imx = irow;
        }


        if (imx != iPass)
        {
            for (icol = 0; icol < n; icol++)
            {
                temp = AInverse[n*iPass+icol];
                AInverse[n*iPass+icol] = AInverse[n*imx+icol];
                AInverse[n*imx+icol] = temp;
                if (icol >= iPass)
                {
                    temp = A[n*iPass+icol];
                    A[n*iPass+icol] = A[n*imx+icol];
                    A[n*imx+icol] = temp;
                }
            }
        }

        pivot = A[n*iPass+iPass];
        det = det * pivot;
        if (det == 0)
        {
          //  free(ac);
            return 0;
        }

        for (icol = 0; icol < n; icol++)
        {

            AInverse[n*iPass+icol] = AInverse[n*iPass+icol] / pivot;
            if (icol >= iPass) A[n*iPass+icol] = A[n*iPass+icol] / pivot;
        }

        for (irow = 0; irow < n; irow++)
        {

            if (irow != iPass) factor = A[n*irow+iPass];
            for (icol = 0; icol < n; icol++)
            {
                if (irow != iPass)
                {
                    AInverse[n*irow+icol] -= factor * AInverse[n*iPass+icol];
                    A[n*irow+icol] -= factor * A[n*iPass+icol];
                }
            }
        }
    }

   // free(ac);
    return 1;
}
float kalman_update(float gyroscope_rate, float accelerometer_angle)
{

   static  float A[2][2] = {{1.0, -0.01}, {0.0, 1.0}};
   static  float B[2][1] = {{0.01}, {0.0}};
  static   float C[1][2] = {{1.0, 0.0}};
  static   float Sz[1][1] = {{20.0}};
  static   float Sw[2][2] = {{0.005, 0.005}, {0.005, 0.005}};


   static   float xhat[2][1] = {{0.0}, {0.0}};
   static   float P[2][2] = {{0.005, 0.005}, {0.005, 0.005}};


    float u[1][1];        
    float y[1][1];         

    float AP[2][2];            
    float CT[2][1];         
    float APCT[2][1];         
    float CP[1][2];  
    float CPCT[1][1];   
    float CPCTSz[1][1];   
    float CPCTSzInv[1][1];
    float K[2][1];   
    float Cxhat[1][1];   
    float yCxhat[1][1];      
    float KyCxhat[2][1];  
    float Axhat[2][1];      
    float Bu[2][1];  
    float AxhatBu[2][1];  
    float AT[2][2];   
    float APAT[2][2];      
    float APATSw[2][2];         
    float KC[2][2];         
    float KCP[2][2];        
    float KCPAT[2][2];     


    u[0][0] = gyroscope_rate;
    y[0][0] = accelerometer_angle;



    matrix_multiply((float*) A, (float*) xhat, 2, 2, 1, (float*) Axhat);
    matrix_multiply((float*) B, (float*) u, 2, 1, 1, (float*) Bu);
    matrix_addition((float*) Axhat, (float*) Bu, 2, 1, (float*) AxhatBu);




    matrix_multiply((float*) C, (float*) xhat, 1, 2, 1, (float*) Cxhat);
    matrix_subtraction((float*) y, (float*) Cxhat, 1, 1, (float*) yCxhat);


    matrix_transpose((float*) C, 1, 2, (float*) CT);
    matrix_multiply((float*) C, (float*) P, 1, 2, 2, (float*) CP);
    matrix_multiply((float*) CP, (float*) CT, 1, 2, 1, (float*) CPCT);
    matrix_addition((float*) CPCT, (float*) Sz, 1, 1, (float*) CPCTSz);

    matrix_multiply((float*) A, (float*) P, 2, 2, 2, (float*) AP);
    matrix_multiply((float*) AP, (float*) CT, 2, 2, 1, (float*) APCT);
    matrix_inversion((float*) CPCTSz, 1, (float*) CPCTSzInv);
    matrix_multiply((float*) APCT, (float*) CPCTSzInv, 2, 1, 1, (float*) K);


    matrix_multiply((float*) K, (float*) yCxhat, 2, 1, 1, (float*) KyCxhat);
    matrix_addition((float*) AxhatBu, (float*) KyCxhat, 2, 1, (float*) xhat);

    matrix_transpose((float*) A, 2, 2, (float*) AT);
    matrix_multiply((float*) AP, (float*) AT, 2, 2, 2, (float*) APAT);
    matrix_addition((float*) APAT, (float*) Sw, 2, 2, (float*) APATSw);
    matrix_multiply((float*) K, (float*) C, 2, 1, 2, (float*) KC);
    matrix_multiply((float*) KC, (float*) P, 2, 2, 2, (float*) KCP);
    matrix_multiply((float*) KCP, (float*) AT, 2, 2, 2, (float*) KCPAT);
    matrix_subtraction((float*) APATSw, (float*) KCPAT, 2, 2, (float*) P);


    return xhat[0][0];
}
/------------------------------------------------------------------------------------/
void CalcAngle(void)
{
        Sensor.AccPitch  = atan2f((float)SensorBuff[ZACCL],(float)SensorBuff[XACCL])*(180/PI);
        Sensor.AccRoll   = atan2f((float)SensorBuff[YACCL],(float)SensorBuff[XACCL])*(180/PI);
        Sensor.GyroPitch = ((float)SensorBuff[YGYRO])*0.000061;
        Sensor.GyroRoll  = ((float)SensorBuff[ZGYRO])*0.000061;
        Sensor.Pitch = kalman_update(Sensor.GyroPitch,Sensor.AccPitch);
        Sensor.Roll  = kalman_update(Sensor.GyroRoll,Sensor.AccRoll);       
}
int main(void)
        while(1)
        {
                if(SensorReay==TRUE){                //中断频率为819.2Hz T=0.001220703125
                        SensorReay=FALSE;
                        GetSensorData();
                        CalcAngle();
                        if(DmaFlag==TRUE){
                                DmaFlag=FALSE;
                                SendData();
                        }
                }
}

出0入0汤圆

 楼主| 发表于 2011-5-5 12:10:23 | 显示全部楼层
回复【楼主位】Peng  
-----------------------------------------------------------------------

点击此处下载 ourdev_636678Z1K57H.rar(文件大小:1.94M) (原文件名:图.bmp.rar)

上面的图不清楚,重新传一个BMP格式的,论坛不支持BMP改一下扩展名再看吧!

出0入0汤圆

发表于 2011-5-6 00:06:36 | 显示全部楼层
试试把R阵变大,Q阵变小,
你用的几阶的滤波器?

出0入0汤圆

发表于 2011-5-6 09:01:38 | 显示全部楼层
楼主啊   能不能够将你的那个监测波形的软件传给我一份啊   谢谢了  我的邮箱是1135245312@qq.com  我也在做这个的  谢谢了

出0入0汤圆

发表于 2011-5-6 09:01:54 | 显示全部楼层
楼主啊   能不能够将你的那个监测波形的软件传给我一份啊   谢谢了  我的邮箱是1135245312@qq.com  我也在做这个的  谢谢了

出0入0汤圆

发表于 2011-5-9 18:09:21 | 显示全部楼层
回复【楼主位】Peng
-----------------------------------------------------------------------

跟着加速度变是正常的,必竟还是要相信加速计,只是相信的多少而已,当然你可以想办法把加速的影响减小,比如用norm base的方式,在大加速度的情况下认为加速度测量是野值的,这时把相应的R增加(同空中飞猪所说),或者直接不做测量更新,更好的办法就是想办法补偿掉加速度,比如用GPS测加速度来补偿,当然也会带来其它的问题,如运算量等,也可以于新息的判断来自适应地改变R值,以减小加速度的影响.

出0入0汤圆

发表于 2011-7-12 15:05:54 | 显示全部楼层
回复【3楼】panstephan
-----------------------------------------------------------------------

你好,楼主给你传监测波形的软件了嘛?给我也传一份吧,我的邮箱huleiyonghao@126.com。谢谢了,你那有没有DSP的SPI接收程序啊?有的话麻烦给我传下啦。谢谢了啊。

出0入0汤圆

发表于 2011-7-12 15:09:37 | 显示全部楼层
楼主,请问一下,你用的是公司给的开发板吗?

出0入0汤圆

发表于 2012-4-25 22:07:34 | 显示全部楼层
楼主很厉害。。。我是刚入门的!!请问楼主用的是什么单片机去采集ADIS16405的数据呢???我用的是STM32去采集,总是有问题,参考了ADI给的例子程序也效果不大,楼主能否传一份您写的采集程序给小弟呢????邮箱:rongjiangang5255@163.com

出0入0汤圆

发表于 2013-3-13 16:43:41 | 显示全部楼层
保持下顶顶顶顶

出0入0汤圆

发表于 2013-3-15 09:53:32 | 显示全部楼层
我覺得圖形很怪,如果只有加速度計的數據,你應該是使用了自適應的卡爾曼濾波,我是沒有仔細的看你的code,但我覺得你的自適應模型大概有點問題, 基本上波峰波谷不應該比原始數據更高更低...

出0入0汤圆

发表于 2013-4-23 15:27:48 | 显示全部楼层
楼主你好,我现在也在调试adis16405,现在碰到的问题是磁阻和加速度计读出来的寄存器值转换后都不对,楼主能否传一份您写的采集程序给参考下邮箱:nicholas_lin@yeah.net,万分感谢!

出0入0汤圆

发表于 2013-5-31 15:37:35 | 显示全部楼层
hainanadang 发表于 2012-4-25 22:07
楼主很厉害。。。我是刚入门的!!请问楼主用的是什么单片机去采集ADIS16405的数据呢???我用的是STM32去 ...

你现在有了采集数据的程序了吗?能给我一份吗?超级感谢~~邮箱:171722198@qq.com

出0入0汤圆

发表于 2015-8-8 21:45:42 | 显示全部楼层
群主把整个工程都给共享吧,谢谢
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-5 04:14

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

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