宁采儿 发表于 2013-7-10 17:20:30

茶哥的一段关于飞控算法的程序我在看时遇到了问题

#include <math.h>
#include "suanfa.h"
#include "myiic.h"
#include "timer.h"
#include "delay.h"
#include "output.h"

/*数据类型转换,float型-double型支持相互识别+-;已经验证
然而short型和float/double型不支持识别+-!!所以添加转换函数。 */

void ACCEL_F_Data(float *cord,unsigned int *timerc)          
{       
        #define g 10.0
        #define cici 5
        #define tine 0.00001
        static signed short S_F;        //当需要保留函数上一次调用结束时的值时就要用到静态局部变量
        static unsigned char i;
        //////////////////////////////       <ACCELXY:16384.0LSB>        <GYROXY:65.5LSB>
        static double DATA_Deal;                //double型中间变量用于abs,asin,acos,atan等函数

        static float X_Data0;                        //前一刻最优估计X
        static float Y_Data0;                        //前一刻最优估计Y
        static float X_Data_cova0;                //前一刻X最优估计协方差
        static float Y_Data_cova0;                //前一刻Y最优估计协方差              
        ////////////////////////////////////////////////////////////////////////ACCEL_XYOUT       剪头方向为负                  
        static float X_Data1;                        //当前刻最优估计X
        static float Y_Data1;                        //当前刻最优估计Y
        static float X_ACCEL_Data;//当前刻测量值X数据
        static float Y_ACCEL_Data;//当前刻测量值Y数据
        static float X_ACCEL_Data_avr;//当前刻测量值X平均值
        static float Y_ACCEL_Data_avr;//当前刻测量值Y平均值
        static float X_ACCEL_Data_cova; //当前刻测量值X协方差
        static float Y_ACCEL_Data_cova; //当前刻测量值Y协方差

        static float X_GYRO_Data; //当前刻X状态控制量
        static float Y_GYRO_Data; //当前刻Y状态控制量
        static float X_GYRO_Data_avr;   //当前刻X状态控制量平均值
        static float Y_GYRO_Data_avr;   //当前刻Y状态控制量平均值
        static float X_GYRO_Data_cova;//当前刻X状态控制量协方差
        static float Y_GYRO_Data_cova;//当前刻Y状态控制量协方差


        X_Data0=cord;                //cord为前一刻最优估计X       单位°
        X_Data_cova0=cord;        //cord为前一刻最优估计X协方差

        Y_Data0=cord;                //cord为前一刻最优估计Y       单位°
        Y_Data_cova0=cord;        //cord为前一刻最优估计Y协方差
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        for(i=0;i<cici;i++)
        {
                S_F=(IIC_Read(ACCEL_XOUT_H)<<8)|(IIC_Read(ACCEL_XOUT_L));                    //当前X测量值
                X_ACCEL_Data=((float)S_F);                                                                           //类型转换 c语言分配float型数据4个字节,得到6位有效数字
                S_F=(IIC_Read(GYRO_YOUT_H)<<8)|(IIC_Read(GYRO_YOUT_L));                           //当前X控制量                Y_GYRO_Data-=50; 朝箭头为正
                X_GYRO_Data=((float)S_F);                                                                           //类型转换
                X_GYRO_Data-=50;
                                                                                                                                                  
                S_F=(IIC_Read(ACCEL_YOUT_H)<<8)|(IIC_Read(ACCEL_YOUT_L));                    //当前Y测量值
                Y_ACCEL_Data=((float)S_F);                                                                           //类型转换
                S_F=(IIC_Read(GYRO_XOUT_H)<<8)|(IIC_Read(GYRO_XOUT_L));                           //当前Y控制量                X _GYRO_Data+=140;朝箭头为负= =
                Y_GYRO_Data=((float)S_F);                                                                           //类型转换
                Y_GYRO_Data+=140;
        }
        for(i=0,X_ACCEL_Data_avr=0,Y_ACCEL_Data_avr=0,X_GYRO_Data_avr=0,Y_GYRO_Data_avr=0;i<cici;i++)
        {
                X_ACCEL_Data_avr+=X_ACCEL_Data;
                Y_ACCEL_Data_avr+=Y_ACCEL_Data;
                X_GYRO_Data_avr+=X_GYRO_Data;
                Y_GYRO_Data_avr+=Y_GYRO_Data;
        }
        X_ACCEL_Data_avr/=cici;                                                                                                          //当前X测量值平均值
        Y_ACCEL_Data_avr/=cici;                                                                                                          //当前Y测量值平均值
        X_GYRO_Data_avr/=cici;                                                                                                          //当前X状态控制量平均值
        Y_GYRO_Data_avr/=cici;                                                                                                          //当前X状态控制量平均值




        for(i=0,X_ACCEL_Data_cova=0,X_GYRO_Data_cova=0,Y_ACCEL_Data_cova=0,Y_GYRO_Data_cova=0;i<cici;i++)
        {
               //平均值即方差的期望值
                X_ACCEL_Data_cova+=(X_ACCEL_Data-X_ACCEL_Data_avr)*(X_ACCEL_Data-X_ACCEL_Data_avr);
                X_GYRO_Data_cova+=(X_GYRO_Data-X_GYRO_Data_avr)*(X_GYRO_Data-X_GYRO_Data_avr);
                Y_ACCEL_Data_cova+=(Y_ACCEL_Data-Y_ACCEL_Data_avr)*(Y_ACCEL_Data-Y_ACCEL_Data_avr);
                Y_GYRO_Data_cova+=(Y_GYRO_Data-Y_GYRO_Data_avr)*(Y_GYRO_Data-Y_GYRO_Data_avr);
        }





        //c语言在处理float型数据时会将float型数据先转化为double型数据进行处理
        X_ACCEL_Data_cova/=cici;                                                                                                  //当前测量值X协方差    需要转换为°
        DATA_Deal=X_ACCEL_Data_cova;
        DATA_Deal=(DATA_Deal/16384.0)*10;
        X_ACCEL_Data_cova=asin(DATA_Deal/g)*57.3;                                                                  //测量值X协方差°
    //-----------------------------------------
        Y_ACCEL_Data_cova/=cici;                                                                                                  //当前测量值Y协方差    需要转换为°
        DATA_Deal=Y_ACCEL_Data_cova;
        DATA_Deal=(DATA_Deal/16384.0)*10;
        Y_ACCEL_Data_cova=asin(DATA_Deal/g)*57.3;                                                                  //测量值Y协方差°
        ///////////////////////////////////////////
        X_GYRO_Data_cova/=cici;                                                                                                            //当前X状态控制量协方差       需要转换为°
    X_GYRO_Data_cova=(X_Data_cova0+X_GYRO_Data_cova)/2*tine*timerc/65.5;          //X控制量协方差°
        //-----------------------------------------
        Y_GYRO_Data_cova/=cici;                                                                                                            //当前Y状态控制量协方差       需要转换为°
    Y_GYRO_Data_cova=(Y_Data_cova0+Y_GYRO_Data_cova)/2*tine*timerc/65.5;          //Y控制量协方差°
        ///////////////////////////////////////////////////////////////////////ACCEL_OUTXY单位转换               
       




        DATA_Deal=X_ACCEL_Data_avr;
        X_ACCEL_Data_avr=1;                                                        //为角度的正负做准备
        if(DATA_Deal<0){
                DATA_Deal=(-1)*DATA_Deal;
                X_ACCEL_Data_avr=-1;                                        //角度为负
        }
        DATA_Deal=(DATA_Deal/16384.0)*10;                        //g = 10
        DATA_Deal=asin(DATA_Deal/g)*57.3;                        //结果是弧度制 转换为角度
        X_ACCEL_Data_avr*=DATA_Deal;                                                                                           //当前X测量值 单位°
        DATA_Deal=cos(DATA_Deal);
        //-----------------------------------------
        DATA_Deal=Y_ACCEL_Data_avr;
        Y_ACCEL_Data_avr=1;                                                        //为角度的正负做准备
        if(DATA_Deal<0){
                DATA_Deal=(-1)*DATA_Deal;
                Y_ACCEL_Data_avr=-1;                                        //角度为负
        }
        DATA_Deal=(DATA_Deal/16384.0)*10;                        //g = 10
        DATA_Deal=asin(DATA_Deal/g)*57.3;                        //结果是弧度制 转换为角度
        Y_ACCEL_Data_avr*=DATA_Deal;                                                                                           //当前Y测量值 单位°
                       
        ////////////////////////////////////////////////////////////////////////GYRO_XY单位转换
        X_GYRO_Data_avr/=65.5;                                                                                                          //当前控制量x值 单位°/S
        //-----------------------------------------
        Y_GYRO_Data_avr/=65.5;                                                                                                          //当前控制量x值 单位°/S
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        X_Data0=X_Data0-(X_GYRO_Data_avr*timerc*tine);                                                        //当前预测值 赋值X_data0
        //-----------------------------------------
        Y_Data0=Y_Data0+(Y_GYRO_Data_avr*timerc*tine);                                                        //当前预测值 赋值Y_data0
        timerc=0;
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        DATA_Deal=X_GYRO_Data_cova/(X_GYRO_Data_cova+X_ACCEL_Data_cova);//协方差X 权重比
        if(DATA_Deal>=1.0)DATA_Deal=0;
        X_Data1=X_Data0+(X_ACCEL_Data_avr-X_Data0)*DATA_Deal; //得到当前X最优估计值

        cord=X_Data1;                                                                                                                        //记录当前X最优估计值
        cord=X_GYRO_Data_cova+(X_ACCEL_Data_cova-X_GYRO_Data_cova)*DATA_Deal;        //记录当前X最优估计协方差
        //-----------------------------------------
        DATA_Deal=Y_GYRO_Data_cova/(Y_GYRO_Data_cova+Y_ACCEL_Data_cova);//协方差Y 权重比
        if(DATA_Deal>=1.0)DATA_Deal=0;
        Y_Data1=Y_Data0+(Y_ACCEL_Data_avr-Y_Data0)*DATA_Deal; //得到当前Y最优估计值

        cord=Y_Data1;                                                                                                                        //记录当前Y最优估计值
        cord=Y_GYRO_Data_cova+(Y_ACCEL_Data_cova-Y_GYRO_Data_cova)*DATA_Deal;        //记录当前Y最优估计协方差
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////        
        cord=X_Data1;                                                                                                                        //cord X_ANGLE                                                                                               
        cord=Y_Data1;                                                                                                                        //cord Y_ANGLE
        }

void ACCEL_Z_Data(float *cord)                          
{
        //g的标准值需要在水平情况下测量: G 16124
        static float Z_ACCEL_Data;
        static signed short S_F;
        S_F=(IIC_Read(ACCEL_ZOUT_H)<<8)|(IIC_Read(ACCEL_ZOUT_L));
        Z_ACCEL_Data=(float)S_F;
        Z_ACCEL_Data/=16384.0;                                                                                                                //cord Z
        cord=Z_ACCEL_Data;                                                                                                                                       
}


上面标为红色的部分哪位懂的大神给解释下吧?感激不尽呐


页: [1]
查看完整版本: 茶哥的一段关于飞控算法的程序我在看时遇到了问题