Dependencies:   FatFileSystem mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // dot-HR EKF
00002 
00003 #include "mbed.h"
00004 #include "SDFileSystem.h"
00005 #include "ADXL345_I2C.h"
00006 #include "ITG3200.h"
00007 #include "HMC5883L.h"
00008 
00009 Serial pc(USBTX, USBRX);
00010 DigitalOut led1(LED1);
00011 DigitalOut led2(LED2);
00012 DigitalOut led3(LED3);
00013 DigitalOut led4(LED4);
00014 SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board
00015 ADXL345_I2C accelerometer(p9, p10);
00016 ITG3200 gyro(p9, p10);
00017 HMC5883L compass(p9, p10);
00018 Serial xbee(p13, p14);
00019 DigitalIn stop(p20);
00020 PwmOut ESC1(p21);
00021 PwmOut ESC2(p22);
00022 PwmOut ESC3(p23);
00023 PwmOut ESC4(p24);
00024 PwmOut ESC5(p25);
00025 PwmOut ESC6(p26);
00026 Serial navi(p28, p27);          // tx, rx
00027 DigitalOut navi_flag(p29);
00028 
00029 #define pi       3.14159265
00030 
00031 #define N            3       // phi, the, psi
00032 #define M            6       // The numbers of rotors
00033 #define L            5       // The numbers of state quantities (optimal regulator)
00034 #define chan         4       // The numbers of channels
00035 #define chan_buf    17
00036 #define N_LWMA      100
00037 
00038 int preparing_acc();
00039 double* calib();
00040 double* RK4( double, double[N], double[N] );
00041 double* func( double[N], double[N] );
00042 double* LWMA( double[N] );
00043 double* EKF_predict( double[N], double[N] );
00044 double* EKF_correct( double[N], double[N], double[N] );
00045 
00046 //             0       1       2
00047 //        [ accXn-1 accXn-2   ...   ] 0
00048 // zBuf = [ accYn-1 accYn-2   ...   ] 1
00049 //        [ accZn-1 accZn-2   ...   ] 2
00050 double z_buf[N][N_LWMA]    =    {0};                    // For LWMA
00051 
00052 double P[N][N]    =    {{1,0,0},{0,1,0},{0,0,1}};       // For EKF
00053 
00054 int main(){ 
00055     
00056     pc.baud(921600);
00057     navi.baud(57600);
00058     xbee.baud(57600);
00059     
00060     FILE *fp = fopen("/sd/sdtest.txt", "w");
00061     if(fp == NULL) {
00062         error("Could not open file for write\n");
00063         while(1){   led2 = 1;   wait(.5);   led2 = 0;   led3 = 0;    wait(.5);  led3 = 0;   }
00064     }
00065     
00066     int correct_period  =   100;
00067     int navi_period     =   10;
00068     int xbee_period     =   100;
00069     int correct_loop    =   0;
00070     int navi_loop       =   10;
00071     int xbee_loop       =   100;
00072         
00073     double dt_wait = 0.00043;
00074     //double dt_wait = 0.01;
00075     double dt =   0.01;
00076     double t  = 0;
00077 
00078     int bit_acc[N]   =   {0};    // Buffer of the accelerometer
00079     int get_mag[N]   =   {0};    // Buffer of the compass
00080     
00081     // Calibration routine
00082     double calib_acc[N]         =   {0};
00083     double calib_gyro[N]        =   {0};
00084     //double compass_basis_rad    =   0;
00085     
00086     // Getting data
00087     double acc[N]       =   {0, 0, 1};
00088     double acc0[N]      =   {0, 0, 1};
00089     double d_acc[N]     =   {0};
00090     double gyro_deg[N]  =   {0};
00091     double gyro_rad[N]  =   {0};
00092     //int    mag[N]       =   {0};
00093     
00094     // Measurement algorithm
00095     //double angle_acc[2] =   {0};
00096     double angle_deg[N] =   {0};
00097     double angle_rad[N] =   {0};
00098     double zLWMA[N]     =   {0};
00099     //double compass_rad  =   0;
00100     //double compass_deg  =   0;
00101     
00102     // Gravity z
00103     for( int i=0;i<N_LWMA;i++ ){    z_buf[2][i]    =    1;    }
00104     
00105     double* p_calib;
00106     double* p_RK4;
00107     double* p_EKF;
00108     double* p_zLWMA;
00109 
00110     // Optimal regulator
00111     double state[L];
00112     // Gain (q1=10, q2=10, q3=10, q4=10, q5=1)
00113 /*    double Kr[M][L] = {{     0, 1.826,     0, 1.984, 0.408},
00114                        {-1.581, 0.913,-1.718, 0.992,-0.408},
00115                        {-1.581,-0.913,-1.718,-0.992, 0.408},
00116                        {     0,-1.826,     0,-1.984,-0.408},
00117                        { 1.581,-0.913, 1.718,-0.992, 0.408},
00118                        { 1.581, 0.913, 1.718, 0.992,-0.408}};
00119 */
00120     // Gain (q1=100, q2=100, q3=1, q4=1, q5=1)
00121 /*    double Kr[M][L] = {{ 0, 5.774,     0, 1.496, 0.408},
00122                        {-5, 2.887,-1.296, 0.748,-0.408},
00123                        {-5,-2.887,-1.296,-0.748, 0.408},
00124                        { 0,-5.774,     0,-1.496,-0.408},
00125                        { 5,-2.887, 1.296,-0.748, 0.408},
00126                        { 5, 2.887, 1.296, 0.748,-0.408}};
00127 */
00128     // Gain (q1=100, q2=100, q3=10, q4=10, q5=1)
00129 /*    double Kr[M][L] = {{ 0, 5.774,     0, 2.288, 0.408},
00130                        {-5, 2.887,-1.982, 1.144,-0.408},
00131                        {-5,-2.887,-1.982,-1.144, 0.408},
00132                        { 0,-5.774,     0,-2.288,-0.408},
00133                        { 5,-2.887, 1.982,-1.144, 0.408},
00134                        { 5, 2.887, 1.982, 1.144,-0.408}};
00135 */
00136     // Gain (q1=100, q2=100, q3=50, q4=50, q5=1)
00137     double Kr[M][L] = {{ 0, 5.774,     0, 4.309, 0.408},
00138                        {-5, 2.887,-3.732, 2.155,-0.408},
00139                        {-5,-2.887,-3.732,-2.155, 0.408},
00140                        { 0,-5.774,     0,-4.309,-0.408},
00141                        { 5,-2.887, 3.732,-2.155, 0.408},
00142                        { 5, 2.887, 3.732, 2.155,-0.408}};
00143 
00144     // Gain (q1=100, q2=100, q3=100, q4=100, q5=1)
00145 /*    double Kr[M][L] = {{ 0, 5.774,     0, 5.936, 0.408},
00146                        {-5, 2.887,-5.141, 2.968,-0.408},
00147                        {-5,-2.887,-5.141,-2.968, 0.408},
00148                        { 0,-5.774,     0,-5.936,-0.408},
00149                        { 5,-2.887, 5.141,-2.968, 0.408},
00150                        { 5, 2.887, 5.141, 2.968,-0.408}};
00151 */
00152     // Gain (q1=300, q2=300, q3=100, q4=100, q5=1)
00153 /*    double Kr[M][L] = {{    0, 10,     0, 6.052, 0.408},
00154                        {-8.66,  5,-5.242, 3.026,-0.408},
00155                        {-8.66, -5,-5.242,-3.026, 0.408},
00156                        {    0,-10,     0,-6.052,-0.408},
00157                        { 8.66, -5, 5.242,-3.026, 0.408},
00158                        { 8.66,  5, 5.242, 3.026,-0.408}};
00159 */
00160     // Gain (q1=400, q2=400, q3=100, q4=100, q5=1)
00161 /*    double Kr[M][L] = {{  0, 11.547,     0, 6.094, 0.408},
00162                        {-10,  5.774,-5.278, 3.047,-0.408},
00163                        {-10, -5.774,-5.278,-3.047, 0.408},
00164                        {  0,-11.547,     0,-6.094,-0.408},
00165                        { 10, -5.774, 5.278,-3.047, 0.408},
00166                        { 10,  5.774, 5.278, 3.047,-0.408}};
00167 */
00168     // Gain (q1=500, q2=500, q3=50, q4=50, q5=1)
00169 /*    double Kr[M][L] = {{     0, 12.910,     0, 4.574, 0.408},
00170                        {-11.18,  6.455,-3.962, 2.287,-0.408},
00171                        {-11.18, -6.455,-3.962,-2.287, 0.408},
00172                        {     0,-12.910,     0,-4.574,-0.408},
00173                        { 11.18, -6.455, 3.962,-2.287, 0.408},
00174                        { 11.18,  6.455, 3.962, 2.287,-0.408}};
00175 */                       
00176     // Gain (q1=500, q2=500, q3=100, q4=100, q5=1)
00177 /*    double Kr[M][L] = {{     0, 12.910,    0, 6.131, 0.408},
00178                        {-11.18,  6.455,-5.31, 3.066,-0.408},
00179                        {-11.18, -6.455,-5.31,-3.066, 0.408},
00180                        {     0,-12.910,    0,-6.131,-0.408},
00181                        { 11.18, -6.455, 5.31,-3.066, 0.408},
00182                        { 11.18,  6.455, 5.31, 3.066,-0.408}};
00183 */
00184     double Ccom_r   =   0.2;
00185     double Ccom_p   =   0.2;
00186     double Ccom_y   =   0.1;
00187     
00188     double motor[M]             =   {0};
00189     double motor_control[M]     =   {0};    // Pulth width generated by the transmitter
00190     double motor_attitude[M]    =   {0};    // Pulth width generated by the attitude control 
00191 
00192     // Coefficient of transfering Force to Puls
00193     double Cfp      =   2*pow(10.0, -7);
00194     
00195     // Navigation
00196     char command_buf1[chan_buf] =   {0};
00197     int command_buf2[chan_buf]  =   {0};
00198     double command[chan]        =   {0};
00199     int set_navi_flag           =   0;
00200         
00201     // ***  Setting up sensors ***    
00202     //pc.printf("\r\n\r\nSetting up sensors\r\n");
00203     xbee.printf("\r\n\r\nSetting up sensors\r\n");
00204   
00205     // These are here to test whether any of the initialization fails. It will print the failure.
00206     if (accelerometer.setPowerControl(0x00)){
00207         //pc.printf("didn't intitialize power control\n\r"); 
00208         xbee.printf("didn't intitialize power control\n\r"); 
00209         return 0;
00210     }
00211     // Full resolution, +/-16g, 4mg/LSB.
00212     wait(.1);
00213      
00214     if(accelerometer.setDataFormatControl(0x0B)){
00215         //pc.printf("didn't set data format\n\r");
00216         xbee.printf("didn't set data format\n\r");
00217         return 0;
00218     }
00219     wait(.1);
00220      
00221     // 3.2kHz data rate.
00222     if(accelerometer.setDataRate(ADXL345_3200HZ)){
00223         //pc.printf("didn't set data rate\n\r");
00224         xbee.printf("didn't set data rate\n\r");
00225         return 0;
00226     }
00227     wait(.1);
00228       
00229     if(accelerometer.setPowerControl(MeasurementMode)) {
00230         //pc.printf("didn't set the power control to measurement\n\r"); 
00231         xbee.printf("didn't set the power control to measurement\n\r");
00232         return 0;
00233     } 
00234     wait(.1);
00235     
00236     gyro.setLpBandwidth(LPFBW_42HZ);
00237     compass.setDefault();
00238     wait(.1);                        // Wait some time for all sensors (Need at least 5ms)
00239     
00240     // *** Setting up motors ***
00241     //pc.printf("Setting up motors\r\n");
00242     xbee.printf("Setting up motors\r\n");
00243     ESC1.period(0.016044);    ESC2.period(0.016044);    ESC3.period(0.016044);    ESC4.period(0.016044);    ESC5.period(0.016044);    ESC6.period(0.016044);
00244     // pulsewidth 0.0011~0.00195
00245     ESC1.pulsewidth(0.001);   ESC2.pulsewidth(0.001);   ESC3.pulsewidth(0.001);   ESC4.pulsewidth(0.001);   ESC5.pulsewidth(0.001);   ESC6.pulsewidth(0.001);
00246     // Wait some time for ESC (about 10s)
00247     wait(5);
00248 
00249     // *** Setting up navigator ***
00250     //pc.printf("Setting up navigator\r\n");
00251     xbee.printf("Setting up navigator\r\n");
00252     while( set_navi_flag==0 ){
00253         navi_flag   =   1;
00254         for( int i=0;i<chan_buf;i++ ){
00255             navi.scanf("%c",&command_buf1[i]);
00256             if(command_buf1[i]=='a'){
00257                 set_navi_flag=1;
00258                 break;
00259             }
00260         }
00261         navi_flag   =   0;
00262         wait(.1);
00263     }
00264 
00265     // *** Calibration routine ***
00266     p_calib = calib();
00267     for( int i=0;i<3;i++ ){     calib_acc[i]    =   *p_calib;   p_calib = p_calib+1;    }
00268     for( int i=3;i<6;i++ ){     calib_gyro[i-3] =   *p_calib;   p_calib = p_calib+1;    }
00269     //compass_basis_rad   =   *p_calib;
00270 
00271     led1 = 1;    led2 = 1;  led3 = 1;   led4 = 1;
00272     
00273     //pc.printf("Starting IMU unit\n\r");
00274     xbee.printf("Starting IMU unit\n\r");
00275     //pc.printf("   time      phi      the        P        Q        R     accX     accY     accZ    LWMAX    LWMAY    LWMAZ      alt      T1      T2      T3      T4      T5      T6    thro    roll   pitch     yaw\n\r");
00276     xbee.printf("   time      phi      the        P        Q        R     accX     accY     accZ    LWMAX    LWMAY    LWMAZ      T1      T2      T3      T4      T5      T6    thro    roll   pitch     yaw\n\r");
00277     
00278     //while(1){
00279     while( stop==0 ){
00280         
00281         // Navigation 
00282         if( navi_loop>=navi_period ){
00283             
00284             navi_flag   =   1;
00285         
00286             for( int i=0;i<chan_buf;i++ ){  navi.scanf("%c",&command_buf1[i]);   }
00287             for( int i=0;i<chan_buf;i++ ){  
00288                 command_buf2[i] = (int)command_buf1[i]-48;
00289                 if( command_buf2[i]==-16 ){     command_buf2[i]=0;      }
00290             }
00291             //for( int i=0;i<chan;i++ ){  command[i]  =   0.0001*command_buf2[1+i*4]+0.00001*command_buf2[2+i*4]+0.000001*command_buf2[3+i*4]+0.001;  }
00292             command[0]  =   0.0001*command_buf2[1]+0.00001*command_buf2[2]+0.000001*command_buf2[3]+0.001;
00293             for( int i=1;i<chan;i++ ){  command[i]  =   0.0001*command_buf2[1+i*4]+0.00001*command_buf2[2+i*4]+0.000001*command_buf2[3+i*4]-0.0005;     }
00294             
00295             navi_flag   =   0;
00296             navi_loop   =   0;
00297         
00298         }
00299         navi_loop++;
00300         //command[0]    =   0.0016;         // Shiyougo comentout surukoto!!
00301         
00302         // Updating accelerometer and compass
00303         accelerometer.getOutput(bit_acc);
00304         compass.readData(get_mag);
00305         
00306         for( int i=0;i<N;i++ ){     acc0[i] = acc[i];   }
00307         
00308         // Transfering units and Coordinate transform
00309         acc[0]      =  (((int16_t)bit_acc[0]-calib_acc[0])-((int16_t)bit_acc[1]-calib_acc[1]))*0.004/sqrt(2.0);
00310         acc[1]      =  (((int16_t)bit_acc[0]-calib_acc[0])+((int16_t)bit_acc[1]-calib_acc[1]))*0.004/sqrt(2.0);
00311         acc[2]      =  ((int16_t)bit_acc[2]-calib_acc[2])*0.004+1;
00312 
00313         gyro_deg[0] = ((gyro.getGyroX()-calib_gyro[0])-(gyro.getGyroY()-calib_gyro[1]))/14.375/sqrt(2.0);
00314         gyro_deg[1] = (-(gyro.getGyroX()-calib_gyro[0])-(gyro.getGyroY()-calib_gyro[1]))/14.375/sqrt(2.0);          // Modify the differencial of the sensor axis 
00315         gyro_deg[2] = -(gyro.getGyroZ()-calib_gyro[2])/14.375;
00316 /*      
00317         for(  int i=0;i<N;i++ ){    acc[i]  =   (int16_t)bit_acc[i];    }
00318         gyro_deg[0] =   gyro.getGyroX();
00319         gyro_deg[1] =   gyro.getGyroY();
00320         gyro_deg[2] =   gyro.getGyroZ();
00321 */
00322         //for( int i=0;i<N;i++ ){     mag[0] = (int16_t)get_mag[0];   }
00323         
00324         // Low pass filter for acc
00325         //if( -0.05<acc[0] && acc[0]<0.05 ){    acc[0]=0;  }
00326         //if( -0.05<acc[1] && acc[1]<0.05 ){    acc[1]=0;  }
00327         //if( 0.95<acc[2] && acc[2]<1.05 ){    acc[2]=0;  }
00328         // Limitter for acc        
00329         if( acc[0]<-1 ){  acc[0]=-1;    }  if( 1<acc[0] ){  acc[0]=1;    }
00330         if( acc[1]<-1 ){  acc[1]=-1;    }  if( 1<acc[1] ){  acc[1]=1;    }
00331         if( acc[2]<-0 ){  acc[2]=-0;    }  if( 2<acc[2] ){  acc[2]=2;    }
00332 
00333         for( int i=0;i<N;i++ ){     d_acc[i] = acc[i]-acc0[i];      }
00334         if( abs(d_acc[0])>=0.5 && abs(acc[0])>=0.3 ){     acc[0] = acc0[0];    }
00335         if( abs(d_acc[1])>=0.5 && abs(acc[1])>=0.3 ){     acc[1] = acc0[1];    }
00336         if( abs(d_acc[2])>=0.5 ){     acc[2] = acc0[2];    }
00337 
00338         // Low pass filter for gyro
00339         //for( int i=0;i<N;i++ ){if( -0.5<gyro_deg[i] && gyro_deg[i]<0.5 ){    gyro_deg[i] = 0;  }}
00340         // Limitter for gyro
00341         //for( int i=0;i<N;i++ ){if( gyro_deg[i]<-90 ){  gyro_deg[i]=-90;    }}  for( int i=0;i<N;i++ ){if( 90<gyro_deg[i] ){  gyro_deg[i]=90;    }}
00342         
00343         for( int i=0;i<N;i++ ){    gyro_rad[i] = gyro_deg[i]*pi/180;    }
00344 /*        
00345         // Compass yaw
00346         compass_rad    =    (double)mag[1]/mag[0];
00347         compass_rad    =    atan(compass_rad);
00348         //compass_rad    =    compass_rad-compass_basis_rad;
00349         compass_deg    =    compass_rad*180/pi;
00350 */
00351         // LWMA (Observation)
00352         p_zLWMA = LWMA(acc);
00353         for( int i=0;i<N;i++ ){     zLWMA[i] = *p_zLWMA;    p_zLWMA = p_zLWMA+1;    }
00354         // LWMA angle
00355         //angle_acc[0] = asin(zLWMA[1])*180/pi;
00356         //angle_acc[1] = asin(zLWMA[0])*180/pi;
00357         
00358         // RK4 (Prediction)
00359         p_RK4 = RK4(dt,angle_rad,gyro_rad);
00360         for( int i=0;i<N;i++ ){    angle_rad[i] = *p_RK4;   p_RK4 = p_RK4+1;    }
00361         
00362         // EKF (Correction)
00363         EKF_predict(angle_rad,gyro_rad);
00364         if ( correct_loop>=correct_period ){
00365             p_EKF = EKF_correct(angle_rad,gyro_rad,zLWMA);
00366             for ( int i=0;i<N;i++ ){    angle_rad[i] = *p_EKF;  p_EKF = p_EKF+1;    }
00367             correct_loop    =    0;
00368         }
00369         correct_loop++;
00370         
00371         for( int i=0;i<N;i++ ){    angle_deg[i] = angle_rad[i]*180/pi;    }
00372 
00373         state[0]    =   angle_deg[0];   state[1]    =   angle_deg[1];
00374         state[2]    =   gyro_deg[0];    state[3]    =   gyro_deg[1];    state[4]    =   gyro_deg[2];
00375         
00376         for( int i=0;i<M;i++ ){
00377             motor_attitude[i] = 0;
00378             for( int j=0;j<L;j++ ){     motor_attitude[i] += -Kr[i][j]*state[j];     }
00379         }
00380         
00381         motor_control[0]    =   command[0]+0*Ccom_r*command[1]+2*Ccom_p*command[2]+1*Ccom_y*command[3];
00382         motor_control[1]    =   command[0]-1*Ccom_r*command[1]-1*Ccom_p*command[2]-1*Ccom_y*command[3];
00383         motor_control[2]    =   command[0]+1*Ccom_r*command[1]-1*Ccom_p*command[2]+1*Ccom_y*command[3];
00384         motor_control[3]    =   command[0]+0*Ccom_r*command[1]+2*Ccom_p*command[2]-1*Ccom_y*command[3];
00385         motor_control[4]    =   command[0]-1*Ccom_r*command[1]-1*Ccom_p*command[2]+1*Ccom_y*command[3];
00386         motor_control[5]    =   command[0]+1*Ccom_r*command[1]-1*Ccom_p*command[2]-1*Ccom_y*command[3];
00387         
00388         for( int i=0;i<M;i++ ){     motor[i] = motor_control[i]+motor_attitude[i]*Cfp;     }
00389         //for( int i=0;i<M;i++ ){     motor[i] = command[0];     }
00390         
00391         // pulsewidth 0.0011~0.0019 (0.001~0.002?)
00392         for( int i=0;i<M;i++ ){
00393             if( motor[i]>0.00195 ){     motor[i]=0.00195;     }
00394             if( motor[i]<0.0011 ){     motor[i]=0.00105;      }
00395             if( command[0]<0.0011 ){     motor[i]=0.00105;      }
00396         }
00397 
00398         ESC1.pulsewidth(motor[0]);  ESC2.pulsewidth(motor[1]);  ESC3.pulsewidth(motor[2]);  ESC4.pulsewidth(motor[3]);  ESC5.pulsewidth(motor[4]);  ESC6.pulsewidth(motor[5]);
00399         
00400         //for( int i=0;i<M;i++ ){    thrust[i] = 630000.0*motor[i]*motor[i]-700.0*motor[i];  }
00401         
00402         //pc.printf("%7.2f, %7.3f, %7.3f, %7.3f, %7.1f, %7.1f, %7.1f, %5d, %5d, %5d\n\r", t, acc[0], acc[1], acc[2], gyro_deg[0], gyro_deg[1], gyro_deg[2], mag[0], mag[1], mag[2]);
00403         //pc.printf("%7.2f, %7.1f, %7.1f, %7.1f, %7.1f, %7.1f, %7.3f, %7.3f, %7.3f, %7.1f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f\n\r", t, state[0], state[1], state[2], state[3], state[4], zLWMA[0], zLWMA[1], zLWMA[2], alt, motor[0]*1000, motor[1]*1000, motor[2]*1000, motor[3]*1000, motor[4]*1000, motor[5]*1000, command[0]*1000, command[1]*1000, command[2]*1000, command[3]*1000);
00404         //fprintf(fp,"%7.2f, %7.3f, %7.3f, %7.3f, %7.1f, %7.1f, %7.1f, %6.3f\r", t, acc[0], acc[1], acc[2], gyro_deg[0], gyro_deg[1], gyro_deg[2], command[0]*1000);
00405         fprintf(fp,"%7.2f, %7.1f, %7.1f, %7.1f, %7.1f, %7.1f, %7.3f, %7.3f, %7.3f, %7.3f, %7.3f, %7.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f\n", t, state[0], state[1], state[2], state[3], state[4], acc[0], acc[1], acc[2], zLWMA[0], zLWMA[1], zLWMA[2], motor[0]*1000, motor[1]*1000, motor[2]*1000, motor[3]*1000, motor[4]*1000, motor[5]*1000, command[0]*1000, command[1]*1000, command[2]*1000, command[3]*1000);
00406         if( xbee_loop>=xbee_period ){
00407             xbee.printf("%7.2f, %7.1f, %7.1f, %7.1f, %7.1f, %7.1f, %7.3f, %7.3f, %7.3f, %7.3f, %7.3f, %7.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f\n\r", t, state[0], state[1], state[2], state[3], state[4], acc[0], acc[1], acc[2], zLWMA[0], zLWMA[1], zLWMA[2], motor[0]*1000, motor[1]*1000, motor[2]*1000, motor[3]*1000, motor[4]*1000, motor[5]*1000, command[0]*1000, command[1]*1000, command[2]*1000, command[3]*1000);
00408             xbee_loop   =   0;
00409         }
00410         xbee_loop++;
00411         wait(dt_wait);
00412         t += dt;
00413         
00414     }
00415     
00416     // pulsewidth 0.0011~0.00195
00417     ESC1.pulsewidth(0.001);   ESC2.pulsewidth(0.001);   ESC3.pulsewidth(0.001);   ESC4.pulsewidth(0.001);   ESC5.pulsewidth(0.001);   ESC6.pulsewidth(0.001);
00418     led1 = 0;    led2 = 0;  led3 = 0;   led4    =   0;
00419     fclose(fp);
00420     
00421 }
00422 
00423 double* EKF_predict( double y[N], double x[N] ){ 
00424     // x = F * x;  
00425     // P = F * P * F' + G * Q * G';
00426 
00427     //double Q[N][N]        =    { {0.1, 0, 0}, {0, 0.1, 0}, {0, 0, 0.1} };
00428     double Q[N][N]        =    { {5198, 0, 0}, {0, 5518, 0}, {0, 0, 5722} };
00429 
00430     double Fjac[N][N]    =    {{x[1]*cos(y[0])*tan(y[1])-x[2]*sin(y[0])*tan(y[1]), x[1]*sin(y[0])/(cos(y[1])*cos(y[1]))+x[2]*cos(y[0])/(cos(y[1])*cos(y[1])), 0}, {-x[1]*sin(y[0])-x[2]*cos(y[0]), 0, 0}, {x[1]*cos(y[0])/cos(y[1])-x[2]*sin(y[0])/cos(y[1]), x[1]*sin(y[0])*sin(y[1])/(cos(y[1])*cos(y[1]))+x[2]*cos(y[0])*sin(y[1])/(cos(y[1])*cos(y[1])), 0}};
00431     double Fjac_t[N][N]    =    {{x[1]*cos(y[0])*tan(y[1])-x[2]*sin(y[0])*tan(y[1]), -x[1]*sin(y[0])-x[2]*cos(y[0]), x[1]*cos(y[0])/cos(y[1])-x[2]*sin(y[0])/cos(y[1])}, {x[1]*sin(y[0])/(cos(y[1])*cos(y[1]))+x[2]*cos(y[0])/(cos(y[1])*cos(y[1])), 0, x[1]*sin(y[0])*sin(y[1])/(cos(y[1])*cos(y[1]))+x[2]*cos(y[0])*sin(y[1])/(cos(y[1])*cos(y[1]))}, {0, 0, 0}};
00432     double Gjac[N][N]    =    {{1, sin(y[0])*tan(y[1]), cos(y[0])*tan(y[1])}, {0, cos(y[0]), -sin(y[0])}, {0, sin(y[0])/cos(y[1]), cos(y[0])/cos(y[1])}};
00433     double Gjac_t[N][N]    =    {{1, 0, 0}, {sin(y[0])*tan(y[1]), cos(y[0]), sin(y[0])/cos(y[1])}, {cos(y[0])*tan(y[1]), -sin(y[0]), cos(y[0])/cos(y[1])}};
00434 
00435     double FPF[N][N]    =    {0};
00436     double GQG[N][N]    =    {0};
00437 
00438     double FP[N][N]        =    {0};
00439     double GQ[N][N]        =    {0};
00440     
00441     for( int i=0;i<N;i++ ){
00442         for( int j=0;j<N;j++ ){
00443             for( int k=0;k<N;k++ ){
00444                 FP[i][j]    +=    Fjac[i][k]*P[k][j];
00445                 GQ[i][j]    +=    Gjac[i][k]*Q[k][j];
00446 
00447             }
00448         }
00449     }
00450 
00451     for( int i=0;i<N;i++ ){
00452         for( int j=0;j<N;j++ ){
00453             for( int k=0;k<N;k++ ){
00454                 FPF[i][j]        +=    FP[i][k]*Fjac_t[k][j];
00455                 GQG[i][j]        +=    GQ[i][k]*Gjac_t[k][j];
00456             }
00457         }
00458     }
00459     for( int i=0;i<N;i++ ){
00460         for( int j=0;j<N;j++ ){
00461             P[i][j]        =    FPF[i][j]+GQG[i][j];
00462         }
00463     }
00464     
00465     return 0;
00466 
00467 }
00468 
00469 double* EKF_correct( double y[N], double x[N], double z[N] ){
00470     // K = P * H' / ( H * P * H' + R )
00471     // x = x + K * ( yobs(t) - H * x )
00472     // P = P - K * H * P
00473 
00474     //double R[N][N]        =    { {0.15, 0, 0}, {0, 0.15, 0}, {0, 0, 0.15} };
00475     //double R[N][N]        =    { {0.00015, 0, 0}, {0, 0.00016, 0}, {0, 0, 0.00032} };
00476     double R[N][N]        =    { {272528, 0, 0}, {0, 295812, 0}, {0, 0, 908451} };
00477 
00478     double Hjac[N][N]    =    {{0, cos(y[1]), 0}, {cos(y[0]), 0, 0}, {-sin(y[0])*cos(y[1]), -cos(y[0])*sin(y[1]), 0}};
00479     double Hjac_t[N][N]    =    {{0, cos(y[0]), -sin(y[0])*cos(y[1])}, {cos(y[1]), 0, -cos(y[0])*sin(y[1])}, {0, 0, 0}};
00480     double K[N][N]        =    {0};    // Kalman gain
00481     double K_deno[N][N]    =    {0};    // Denominator of the kalman gain
00482     double det_K_deno_inv    =    0;
00483     double K_deno_inv[N][N]    =    {0};
00484     double HPH[N][N]    =    {0};
00485     double HP[N][N]        =    {0};
00486     double PH[N][N]        =    {0};
00487     double KHP[N][N]    =    {0};
00488 
00489     double Hx[N]        =    {0};
00490     double z_Hx[N]        =    {0};
00491     double Kz_Hx[N]        =    {0};
00492 
00493     double* py    =    y;
00494 
00495     // Kalman gain
00496     for( int i=0;i<N;i++ ){
00497         for( int j=0;j<N;j++ ){
00498             for( int k=0;k<N;k++ ){
00499                 HP[i][j]    +=    Hjac[i][k]*P[k][j];
00500                 PH[i][j]    +=    P[i][k]*Hjac_t[k][j];
00501             }
00502         }
00503     }
00504     for( int i=0;i<N;i++ ){
00505         for( int j=0;j<N;j++ ){
00506             for( int k=0;k<N;k++ ){
00507                 HPH[i][j]        +=    HP[i][k]*Hjac_t[k][j];
00508             }
00509         }
00510     }
00511     for( int i=0;i<N;i++ ){
00512         for( int j=0;j<N;j++ ){
00513             K_deno[i][j]    =    HPH[i][j]+R[i][j];
00514         }
00515     }
00516     // Inverce matrix
00517     det_K_deno_inv      =    K_deno[0][0]*K_deno[1][1]*K_deno[2][2]+K_deno[1][0]*K_deno[2][1]*K_deno[0][2]+K_deno[2][0]*K_deno[0][1]*K_deno[1][2]-K_deno[0][0]*K_deno[2][1]*K_deno[1][2]-K_deno[2][0]*K_deno[1][1]*K_deno[0][2]-K_deno[1][0]*K_deno[0][1]*K_deno[2][2];
00518     K_deno_inv[0][0]    =    (K_deno[1][1]*K_deno[2][2]-K_deno[1][2]*K_deno[2][1])/det_K_deno_inv;
00519     K_deno_inv[0][1]    =    (K_deno[0][2]*K_deno[2][1]-K_deno[0][1]*K_deno[2][2])/det_K_deno_inv;
00520     K_deno_inv[0][2]    =    (K_deno[0][1]*K_deno[1][2]-K_deno[0][2]*K_deno[1][1])/det_K_deno_inv;
00521     K_deno_inv[1][0]    =    (K_deno[1][2]*K_deno[2][0]-K_deno[1][0]*K_deno[2][2])/det_K_deno_inv;
00522     K_deno_inv[1][1]    =    (K_deno[0][0]*K_deno[2][2]-K_deno[0][2]*K_deno[2][0])/det_K_deno_inv;
00523     K_deno_inv[1][2]    =    (K_deno[0][2]*K_deno[1][0]-K_deno[0][0]*K_deno[1][2])/det_K_deno_inv;
00524     K_deno_inv[2][0]    =    (K_deno[1][0]*K_deno[2][1]-K_deno[1][1]*K_deno[2][0])/det_K_deno_inv;
00525     K_deno_inv[2][1]    =    (K_deno[0][1]*K_deno[2][0]-K_deno[0][0]*K_deno[2][1])/det_K_deno_inv;
00526     K_deno_inv[2][2]    =    (K_deno[0][0]*K_deno[1][1]-K_deno[0][1]*K_deno[1][0])/det_K_deno_inv;
00527 
00528     for( int i=0;i<N;i++ ){
00529         for( int j=0;j<N;j++ ){
00530             for( int k=0;k<N;k++ ){
00531                 K[i][j]        +=    PH[i][k]*K_deno_inv[k][j];
00532             }
00533         }
00534     }
00535 
00536     // Filtering
00537     for( int i=0;i<N;i++ ){
00538         for( int j=0;j<N;j++ ){
00539             Hx[i]        +=    Hjac[i][j]*y[j];
00540         }
00541     }
00542     for( int i=0;i<N;i++ ){
00543         z_Hx[i]    =    z[i]-Hx[i];
00544     }
00545     for( int i=0;i<N;i++ ){
00546         for( int j=0;j<N;j++ ){
00547             Kz_Hx[i]    +=    K[i][j]*z_Hx[j];
00548         }
00549     }
00550     for( int i=0;i<N;i++ ){
00551             y[i]    =    y[i]+Kz_Hx[i];
00552     }
00553 
00554     // Covarience
00555     for( int i=0;i<N;i++ ){
00556         for( int j=0;j<N;j++ ){
00557             for( int k=0;k<N;k++ ){
00558                 KHP[i][j]    +=    K[i][k]*HP[k][j];
00559             }
00560         }
00561     }
00562     for( int i=0;i<N;i++ ){
00563         for( int j=0;j<N;j++ ){
00564             P[i][j]    =    P[i][j]-KHP[i][j];
00565         }
00566     }
00567 
00568     return py;
00569 
00570 }
00571 
00572 double* LWMA( double z[N] ){
00573     
00574     double zLWMA[N]        =    {0};
00575     double zLWMA_num[N]    =    {0};
00576     double zLWMA_den    =    0;
00577 
00578     double* pzLWMA    =    zLWMA;
00579 
00580     for( int i=1;i<N_LWMA;i++ ){
00581         for( int j=0;j<N;j++ ){
00582             z_buf[j][N_LWMA-i]    =    z_buf[j][N_LWMA-i-1];
00583         }
00584     }
00585     for( int i=0;i<N;i++ ){
00586         z_buf[i][0]    =    z[i];
00587     }
00588 
00589     for( int i=0;i<N_LWMA;i++ ){
00590         for( int j=0;j<N;j++ ){
00591             zLWMA_num[j]    +=    (N_LWMA-i)*z_buf[j][i];    
00592         }
00593         zLWMA_den    +=    N_LWMA-i;
00594     }
00595     for( int i=0;i<N;i++ ){
00596         zLWMA[i]    =    zLWMA_num[i]/zLWMA_den;
00597     }
00598     
00599     return pzLWMA;
00600 
00601 }
00602 
00603 double* RK4( double dt, double y[N], double x[N] ){
00604     
00605     double yBuf[N]    =    {0};
00606     double k[N][4]    =    {0};
00607 
00608     double* p_y    =    y;
00609 
00610     double* pk1;
00611     double* pk2;
00612     double* pk3;
00613     double* pk4;
00614 
00615         for( int i=0;i<N;i++){    yBuf[i]    = y[i];    }
00616         pk1    =    func (yBuf,x);
00617         for( int i=0;i<N;i++ ){    k[i][0] = *pk1;        pk1    = pk1+1;    }
00618 
00619         for( int i=0;i<N;i++){    yBuf[i]    = y[i]+0.5*dt*k[i][1];    }
00620         pk2    =    func (yBuf,x);
00621         for( int i=0;i<N;i++ ){    k[i][1]    = *pk2;        pk2    = pk2+1;    }
00622 
00623         for( int i=0;i<N;i++){    yBuf[i]    = y[i]+0.5*dt*k[i][2];    }
00624         pk3    =    func (yBuf,x);
00625         for( int i=0;i<N;i++ ){    k[i][2]    = *pk3;        pk3    = pk3+1;    }
00626 
00627         for( int i=0;i<N;i++){    yBuf[i]    = y[i]+dt*k[i][3];    }
00628         pk4    =    func (yBuf,x);
00629         for( int i=0;i<N;i++ ){    k[i][3]    = *pk4;        pk4 = pk4+1;    }
00630 
00631         for( int i=0;i<N;i++){    y[i] = y[i]+dt*(k[i][0]+2.0*k[i][1]+2.0*k[i][2]+k[i][3])/6.0;    }
00632 
00633     return p_y;
00634 
00635 }
00636 
00637 double* func( double y[N], double x[N] ){
00638 
00639     double f[N]    =    {0};
00640     double* p_f    =    f;
00641     
00642     f[0] = x[0]+x[1]*sin(y[0])*tan(y[1])+x[2]*cos(y[0])*tan(y[1]);
00643     f[1] = x[1]*cos(y[0])-x[2]*sin(y[0]);
00644     f[2] = x[1]*sin(y[0])/cos(y[1])+x[2]*cos(y[0])/cos(y[1]);
00645 
00646     return p_f;
00647     
00648 }
00649 
00650 double* calib(){
00651 
00652     int calib_loop  =   1000;
00653 
00654     int bit_acc[N]   =   {0};    // Buffer of the accelerometer
00655     int get_mag[N]   =   {0};    // Buffer of the compass
00656 
00657     double calib_acc[N]         =   {0};
00658     double calib_gyro_buf[N]    =   {0};
00659     double calib_gyro[N]        =   {0};
00660     double compass_basis_buf[N] =   {0};
00661     double compass_basis_rad    =   0;
00662     double calib_result[7]      =   {0};
00663 
00664     double* p_calib_result      =   calib_result;
00665 
00666     pc.printf("Don't touch... Calibrating now!!\n\r");
00667     xbee.printf("Don't touch... Calibrating now!!\n\r");
00668     led1    =   1;
00669     
00670     for( int i=0;i<calib_loop;i++ ){
00671         
00672         accelerometer.getOutput(bit_acc);
00673         compass.readData(get_mag);
00674         
00675         calib_gyro_buf[0]   =   gyro.getGyroX();
00676         calib_gyro_buf[1]   =   gyro.getGyroY();
00677         calib_gyro_buf[2]   =   gyro.getGyroZ();
00678         
00679         for( int j=0;j<N;j++ ){
00680             calib_acc[j]            +=  (int16_t)bit_acc[j];
00681             calib_gyro[j]           +=  calib_gyro_buf[j];
00682             compass_basis_buf[j]    +=  (int16_t)get_mag[j];
00683         }
00684         
00685         if( i>calib_loop*3/4 ){
00686              led4   =   1;
00687         }else if( i>calib_loop/2 ){
00688             led3    =   1;
00689         }else if( i>calib_loop/4 ){
00690             led2    =   1;
00691         }
00692         
00693     }
00694     
00695     for( int i=0;i<N;i++ ){
00696         calib_acc[i]            =   calib_acc[i]/calib_loop;
00697         calib_gyro[i]           =   calib_gyro[i]/calib_loop;
00698         compass_basis_buf[i]    =   compass_basis_buf[i]/calib_loop;
00699     }
00700     
00701     compass_basis_rad   =   compass_basis_buf[1]/compass_basis_buf[0];
00702     compass_basis_rad   =   atan(compass_basis_rad);
00703     led1 = 0;    led2 = 0;  led3 = 0;   led4    =   0;
00704     
00705     pc.printf("  accX    accY    accZ   gyroX   gyroY   gyroZ    yaw_basis\n\r");
00706     xbee.printf("  accX    accY    accZ   gyroX   gyroY   gyroZ    yaw_basis\n\r");
00707     pc.printf("%6.1f, %6.1f, %6.1f, %6.1f, %6.1f, %6.1f, %6.1f\n\r",calib_acc[0],calib_acc[1],calib_acc[2],calib_gyro[0],calib_gyro[1],calib_gyro[2],compass_basis_rad*180/pi);
00708     xbee.printf("%6.1f, %6.1f, %6.1f, %6.1f, %6.1f, %6.1f, %6.1f\n\r",calib_acc[0],calib_acc[1],calib_acc[2],calib_gyro[0],calib_gyro[1],calib_gyro[2],compass_basis_rad*180/pi);
00709     
00710     for( int i=0;i<3;i++ ){     calib_result[i] =   calib_acc[i];    }
00711     for( int i=3;i<6;i++ ){     calib_result[i] =   calib_gyro[i-3];    }    
00712     calib_result[6] =  compass_basis_rad;
00713     
00714     if( calib_result[0]==0 && calib_result[1]==0 && calib_result[2]==0 ){
00715         pc.printf("Accelerometer is not available.\r\n");
00716         xbee.printf("Accelerometer is not available.\r\n");
00717     }
00718     
00719     for( int i=0;i<3;i++ ){
00720         wait(.5);
00721         led1 = 1;    led2 = 1;  led3 = 1;   led4    =   1;
00722         wait(.5);
00723         led1 = 0;    led2 = 0;  led3 = 0;   led4    =   0;
00724     }
00725 
00726     return p_calib_result;
00727 
00728 }