Facebook
From Cobalt Gibbon, 6 Years ago, written in C.
Embed
Download Paste or View Raw
Hits: 398
  1. #define F_CPU 8000000UL                                                                 /* Define CPU clock Frequency e.g. here its 8MHz */
  2. #include <avr/io.h>                                                                             /* Include AVR std. library file */
  3. #include <util/delay.h>                                                                 /* Include delay header file */
  4. #include <inttypes.h>                                                                   /* Include integer type header file */
  5. #include <stdlib.h>                                                                             /* Include standard library file */
  6. #include <stdio.h>                                                                              /* Include standard library file */
  7. #include "calman.h"
  8. #include "MPU6050_res_define.h"                                                 /* Include MPU6050 register define file */
  9. #include "I2C_Master_H_file.h"                                                  /* Include I2C Master header file */
  10. #include "USART_RS232_H_file.h"                                                 /* Include USART header file */
  11.  
  12. float Acc_x,Acc_y,Acc_z,Temperature,Gyro_x,Gyro_y,Gyro_z, arx, ary, arz, grx, gry,grz;
  13. float dt = 0.01;
  14.  
  15. void Gyro_Init()                                                                                /* Gyro initialization function */
  16. {
  17.         _delay_ms(150);                                                                         /* Power up time >100ms */
  18.         I2C_Start_Wait(0xD0);                                                           /* Start with device write address */
  19.         I2C_Write(SMPLRT_DIV);                                                          /* Write to sample rate register */
  20.         I2C_Write(0x07);                                                                        /* 1KHz sample rate */
  21.         I2C_Stop();
  22.  
  23.         I2C_Start_Wait(0xD0);
  24.         I2C_Write(PWR_MGMT_1);                                                          /* Write to power management register */
  25.         I2C_Write(0x01);                                                                        /* X axis gyroscope reference frequency */
  26.         I2C_Stop();
  27.  
  28.         I2C_Start_Wait(0xD0);
  29.         I2C_Write(CONFIG);                                                                      /* Write to Configuration register */
  30.         I2C_Write(0x00);                                                                        /* Fs = 8KHz */
  31.         I2C_Stop();
  32.  
  33.         I2C_Start_Wait(0xD0);
  34.         I2C_Write(GYRO_CONFIG);                                                         /* Write to Gyro configuration register */
  35.         I2C_Write(0x18);                                                                        /* Full scale range +/- 2000 degree/C */
  36.         I2C_Stop();
  37.  
  38.         I2C_Start_Wait(0xD0);
  39.         I2C_Write(INT_ENABLE);                                                          /* Write to interrupt enable register */
  40.         I2C_Write(0x01);
  41.         I2C_Stop();
  42. }
  43.  
  44. void MPU_Start_Loc()
  45. {
  46.         I2C_Start_Wait(0xD0);                                                           /* I2C start with device write address */
  47.         I2C_Write(ACCEL_XOUT_H);                                                        /* Write start location address from where to read */
  48.         I2C_Repeated_Start(0xD1);                                                       /* I2C start with device read address */
  49. }
  50.  
  51. void Read_RawValue()
  52. {
  53.         MPU_Start_Loc();                                                                        /* Read Gyro values */
  54.         Acc_x = ~((((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Ack())-1);
  55.         Acc_y = ~((((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Ack())-1);
  56.         Acc_z = ~((((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Ack())-1);
  57.         Temperature = (((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Ack());
  58.         Gyro_x = ~((((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Ack())-1);
  59.         Gyro_y = ~((((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Ack())-1);
  60.         Gyro_z = ~((((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Nack())-1);
  61.         I2C_Stop();
  62. }
  63.  
  64. void calman_init_roll(void)
  65. {
  66.         //stan
  67.         stan.theta=0.0;
  68.         stan.omega=0.0;
  69.         stan.pomiar_theta=0.0;
  70.         stan.pomiar_omega=0.0;
  71.         //kalman
  72.         kalm.Q=0.055;//0.00000009; //mniejsza liczba zmniejsza wrazliwosc na przyspieszenia
  73.         kalm.R=1.0;             //
  74.         kalm.theta=0.0;
  75.         kalm.omega_previous=0.0;
  76.         kalm.omega=0.0;
  77.         kalm.g_bias=0.0;
  78.         kalm.P11=kalm.R;
  79.         kalm.P13=0.0;
  80.         kalm.P21=0.0;
  81.         kalm.P31=0.0;
  82.         kalm.P33=0.0;
  83.         kalm.K1=0.0;
  84.         kalm.K2=0.0;
  85.         kalm.K3=0.0;
  86. }
  87. void calman_init_pitch(void)
  88. {
  89.         //stan
  90.         stan1.theta=0.0;
  91.         stan1.omega=0.0;
  92.         stan1.pomiar_theta=0.0;
  93.         stan1.pomiar_omega=0.0;
  94.         //kalman
  95.         kalm1.Q=0.055;//0.00000009; //mniejsza liczba zmniejsza wrazliwosc na przyspieszenia
  96.         kalm1.R=1.0;            //
  97.         kalm1.theta=0.0;
  98.         kalm1.omega_previous=0.0;
  99.         kalm1.omega=0.0;
  100.         kalm1.g_bias=0.0;
  101.         kalm1.P11=kalm.R;
  102.         kalm1.P13=0.0;
  103.         kalm1.P21=0.0;
  104.         kalm1.P31=0.0;
  105.         kalm1.P33=0.0;
  106.         kalm1.K1=0.0;
  107.         kalm1.K2=0.0;
  108.         kalm1.K3=0.0;
  109. }
  110. /*
  111. ustawienia dla Q
  112. 0.0001 szybka reakcja na plyniecie zyroskopu duza wrazliwosc na przyspieszenie układu
  113. 0.00001 -podobnie
  114. 0.000001-w miare szybka kompensacja dryftu +-15st wrazliowsc na przyspieszenia
  115. 0.0000001-wolna kompencajca dryftu +- 3 st wrazliwosci na przyspieszenia
  116. */
  117. float calman_filtr_roll(float akcel,float gyro)
  118. {
  119.         stan.pomiar_theta=akcel;//(float)deg_roll_pitch[ROLL];          //odczyt kata z akcel do filtra
  120.         stan.pomiar_omega=(0.0-gyro)*0.061052;//(0.0-value_gyro_axis[ROLL])*0.061052;  // przy rozdzielczosci 2000st/sec
  121.        
  122.         kalm.theta=((stan.pomiar_omega-kalm.g_bias)*dt)+kalm.theta;
  123.        
  124.         kalm.omega=stan.pomiar_omega-kalm.g_bias;
  125.        
  126.         //kalm.omega_previous=kalm.omega;
  127.        
  128.         //Pk=Ap_{k-1}A^T+Q
  129.         kalm.P11 = kalm.P11-kalm.P31*dt+kalm.P33*dt*dt-kalm.P13*dt+kalm.Q;
  130.         kalm.P13=kalm.P13-kalm.P33*dt;
  131.         kalm.P21=kalm.P33*dt-kalm.P31;
  132.         kalm.P31=kalm.P31-kalm.P33*dt;
  133.         kalm.P33=kalm.P33+kalm.Q;
  134.  
  135.  
  136.         //KOREKCJA
  137.  
  138.         //Kk=PkH^T(HPk^T+R)^-1
  139.  
  140.         kalm.K1=kalm.P11*(1.0/(kalm.P11+kalm.R));
  141.         kalm.K2=kalm.P21*(1.0/(kalm.P11+kalm.R));
  142.         kalm.K3=kalm.P31*(1.0/(kalm.P11+kalm.R));
  143.  
  144.         //xk=xk-K(zk-Hxk)
  145.  
  146.         kalm.theta=kalm.theta+kalm.K1*(stan.pomiar_theta-kalm.theta);
  147.         kalm.omega=kalm.omega+kalm.K2*(stan.pomiar_theta-kalm.theta);
  148.         kalm.g_bias=kalm.g_bias+kalm.K3*(stan.pomiar_theta-kalm.theta);
  149.  
  150.         //Pk=(1-Kkh)Pk
  151.  
  152.         kalm.P11=(1.0-kalm.K1)*kalm.P11;
  153.         kalm.P13=(1.0-kalm.K1)*kalm.P13;
  154.         kalm.P21=kalm.P21-kalm.P11*kalm.K2;
  155.         kalm.P31=kalm.P31-kalm.P11*kalm.K3;
  156.         kalm.P33=kalm.P33-kalm.P13*kalm.K3;
  157.  
  158.         //aktualizacja wektora stanu
  159.  
  160.         stan.theta=kalm.theta;
  161.         stan.omega=kalm.omega;
  162.  
  163.         return stan.theta;
  164. }
  165.  
  166. float calman_filtr_pitch(float akcel,float gyro)
  167. {
  168.         stan1.pomiar_theta=akcel;//(float)deg_roll_pitch[ROLL];         //odczyt kata z akcel do filtra
  169.         stan1.pomiar_omega=(0.0-gyro)*0.061052;//(0.0-value_gyro_axis[ROLL])*0.061052;  // przy rozdzielczosci 2000st/sec
  170.        
  171.         kalm1.theta=((stan1.pomiar_omega-kalm1.g_bias)*dt)+kalm1.theta;
  172.        
  173.         kalm1.omega=stan1.pomiar_omega-kalm1.g_bias;
  174.        
  175.         //kalm.omega_previous=kalm.omega;
  176.        
  177.         //Pk=Ap_{k-1}A^T+Q
  178.         kalm1.P11 = kalm1.P11-kalm1.P31*dt+kalm1.P33*dt*dt-kalm1.P13*dt+kalm1.Q;    
  179.         kalm1.P13=kalm1.P13-kalm1.P33*dt;
  180.         kalm1.P21=kalm1.P33*dt-kalm1.P31;
  181.         kalm1.P31=kalm1.P31-kalm1.P33*dt;
  182.         kalm1.P33=kalm1.P33+kalm1.Q;  
  183.        
  184.         //KOREKCJA
  185.        
  186.         //Kk=PkH^T(HPk^T+R)^-1
  187.        
  188.         kalm1.K1=kalm1.P11*(1.0/(kalm1.P11+kalm1.R));
  189.         kalm1.K2=kalm1.P21*(1.0/(kalm1.P11+kalm1.R));
  190.         kalm1.K3=kalm1.P31*(1.0/(kalm1.P11+kalm1.R));
  191.        
  192.         //xk=xk-K(zk-Hxk)
  193.        
  194.         kalm1.theta=kalm1.theta+kalm1.K1*(stan1.pomiar_theta-kalm1.theta);
  195.         kalm1.omega=kalm1.omega+kalm1.K2*(stan1.pomiar_theta-kalm1.theta);
  196.         kalm1.g_bias=kalm1.g_bias+kalm1.K3*(stan1.pomiar_theta-kalm1.theta);
  197.        
  198.         //Pk=(1-Kkh)Pk
  199.        
  200.         kalm1.P11=(1.0-kalm1.K1)*kalm1.P11;
  201.         kalm1.P13=(1.0-kalm1.K1)*kalm1.P13;
  202.         kalm1.P21=kalm1.P21-kalm1.P11*kalm1.K2;  //?
  203.         kalm1.P31=kalm1.P31-kalm1.P11*kalm1.K3; //?
  204.         kalm1.P33=kalm1.P33-kalm1.P13*kalm1.K3; //?
  205.        
  206.         //aktualizacja wektora stanu
  207.        
  208.         stan1.theta=kalm1.theta;
  209.         stan1.omega=kalm1.omega;
  210.        
  211.         return stan1.theta;
  212. }
  213.  
  214. void timer_init(){
  215.         TCCR1A = ((1 << COM1A1) | (1<<COM1B1) | (1 << WGM11)); // clear OC1A on match + WGM mode 14
  216.         TCCR1B = ((1 << WGM12) | (1 << WGM13) | (1 << CS10)); // WGM mode 14 (Fast PWM)
  217.        
  218.         ICR1  = 19999;  //set ICR1 to produce 50Hz frequency
  219.         //(8000000 / 8 / 20000 = 50hz)
  220. }
  221.  
  222. void servo_angle(uint8_t degree){
  223.         OCR1A=9.73*degree+388;
  224. }
  225. void servo_angle_2(uint8_t degree){
  226.         OCR1B=9.73*degree+388;
  227. }
  228.  
  229. int main()
  230. {
  231.         char buffer[20], float_[10];
  232.         float Xa,Ya,Za,t;
  233.         float Xg=0,Yg=0,Zg=0, kalPitch, kalRoll, kalYaw;
  234.         I2C_Init();                                                                                     /* Initialize I2C */
  235.         Gyro_Init();                                                                            /* Initialize Gyro */
  236.         USART_Init(9600);                                                                       /* Initialize USART with 9600 baud rate */
  237.         calman_init_roll();
  238.         calman_init_pitch();
  239.         timer_init();
  240.         servo_angle(90);
  241.         servo_angle_2(90);
  242.        
  243.         DDRD = 0xff;
  244.        
  245.         while(1)
  246.         {
  247.                 Read_RawValue();
  248.  
  249.                 Xa = Acc_x/16384.0;                                                             /* Divide raw value by sensitivity scale factor to get real values */
  250.                 Ya = Acc_y/16384.0;
  251.                 Za = Acc_z/16384.0;
  252.                
  253.                 Xg = Gyro_x/16.4;
  254.                 Yg = Gyro_y/16.4;
  255.                 Zg = Gyro_z/16.4;
  256.  
  257.                 t = (Temperature/340.00)+36.53;                                 /* Convert temperature in °/c using formula */
  258.  
  259.                 arx = (180/3.141592) * atan(Xa / sqrt(square(Ya) + square(Za)));  //pitch
  260.                 ary = (180/3.141592) * atan(Ya / sqrt(square(Xa) + square(Za)));        //roll
  261.                 arz = (180/3.141592) * atan(sqrt(square(Ya) + square(Xa)) / Za);    //yaw
  262.                  
  263.                 grx = grx + (0.047 * Xg);
  264.                 gry = gry + (0.047 * Yg);
  265.                 grz = grz + (0.047 * Zg);
  266.                
  267.                 kalPitch = calman_filtr_pitch(arx, gry);
  268.                 kalRoll = calman_filtr_roll(ary, grx);
  269.                
  270.                
  271.                 if(kalRoll < 3 && kalRoll > -3) {
  272.                         servo_angle(90);
  273.                         servo_angle_2(-90);
  274.                 } else if(kalRoll > 3) {
  275.                         servo_angle(90-kalRoll);
  276.                         servo_angle_2(-90+kalRoll);
  277.                 } else if(kalRoll < -3) {
  278.                         servo_angle(90-(kalRoll));
  279.                         servo_angle_2(-90+(kalRoll));
  280.                 }
  281.                
  282.                
  283.                 dtostrf( arx, 3, 2, float_ );
  284.                 sprintf(buffer," AP = %s o\t",float_);
  285.                 USART_SendString(buffer);
  286.  
  287.                 dtostrf( ary, 3, 2, float_ );
  288.                 sprintf(buffer," AR = %s o\t",float_);
  289.                 USART_SendString(buffer);
  290.                
  291.                 dtostrf( grx, 3, 2, float_ );
  292.                 sprintf(buffer," Gx = %s o\t",float_);
  293.                 USART_SendString(buffer);
  294.  
  295.                 dtostrf( gry, 3, 2, float_ );
  296.                 sprintf(buffer," Gy = %s o\t",float_,0xF8);
  297.                 USART_SendString(buffer);
  298.  
  299.                 dtostrf( kalPitch, 3, 2, float_ );
  300.                 sprintf(buffer," kP = %s o\t",float_,0xF8);
  301.                 USART_SendString(buffer);
  302.  
  303.                 dtostrf( kalRoll, 3, 2, float_ );
  304.                 sprintf(buffer," kR = %s 0\t\n",float_,0xF8);
  305.                 USART_SendString(buffer);
  306.                 dtostrf( Xa, 3, 2, float_ );                                   
  307.                 sprintf(buffer," Ax = %s g\t",float_);
  308.                 USART_SendString(buffer);
  309.  
  310.                 dtostrf( Ya, 3, 2, float_ );
  311.                 sprintf(buffer," Ay = %s g\t",float_);
  312.                 USART_SendString(buffer);
  313.                
  314.                 dtostrf( Za, 3, 2, float_ );
  315.                 sprintf(buffer," Az = %s g\t",float_);
  316.                 USART_SendString(buffer);
  317.  
  318.                 dtostrf( t, 3, 2, float_ );
  319.                 sprintf(buffer," T = %s%cC\t",float_,0xF8);          
  320.                 USART_SendString(buffer);
  321.  
  322.                 dtostrf( Xg, 3, 2, float_ );
  323.                 sprintf(buffer," Gx = %s%c/s\t",float_,0xF8);
  324.                 USART_SendString(buffer);
  325.  
  326.                 dtostrf( Yg, 3, 2, float_ );
  327.                 sprintf(buffer," Gy = %s%c/s\t",float_,0xF8);
  328.                 USART_SendString(buffer);
  329.                
  330.                 dtostrf( Zg, 3, 2, float_ );
  331.                 sprintf(buffer," Gz = %s%c/s\r\n",float_,0xF8);
  332.                 USART_SendString(buffer);
  333.                
  334.                 dtostrf( grx, 3, 2, float_ );
  335.                 sprintf(buffer," Grx = %s%c/s\t",float_,0xF8);
  336.                 USART_SendString(buffer);
  337.  
  338.                 dtostrf( gry, 3, 2, float_ );
  339.                 sprintf(buffer," Gry = %s%c/s\t",float_,0xF8);
  340.                 USART_SendString(buffer);
  341.                
  342.                 dtostrf( grz, 3, 2, float_ );
  343.                 sprintf(buffer," Grz = %s%c/s\r",float_,0xF8);
  344.                 USART_SendString(buffer);
  345.                
  346.                 dtostrf( arx, 3, 2, float_ );
  347.                 sprintf(buffer," Arx = %s%c/s\t",float_,0xF8);
  348.                 USART_SendString(buffer);
  349.  
  350.                 dtostrf( ary, 3, 2, float_ );
  351.                 sprintf(buffer," Ary = %s%c/s\t",float_,0xF8);
  352.                 USART_SendString(buffer);
  353.                
  354.                 dtostrf( arz, 3, 2, float_ );
  355.                 sprintf(buffer," Arz = %s%c/s\r\n",float_,0xF8);
  356.                 USART_SendString(buffer);
  357.         }
  358. }
  359.