Quad X Type Multicopter

Dependencies:   IAP

Revision:
3:27407c4984cf
Parent:
2:59ac9df97701
Child:
4:4060309b9cc0
--- a/main.cpp	Fri Nov 15 20:53:36 2013 +0000
+++ b/main.cpp	Thu Feb 13 16:07:07 2014 +0000
@@ -35,13 +35,14 @@
     #define p6 dp9
     #define p7 dp10
     #define p8 dp11
-    #define p9 dp25
+    #define p9 dp13
     #define p10 dp26
     #define p13 dp16
     #define p21 dp1
     #define p22 dp2
     #define p23 dp18
     #define p24 dp24
+    #define p26 dp25
     #define p27 dp27
     #define p28 dp5
 #else                   //LPC1768
@@ -87,10 +88,11 @@
 int channel = 0;
 //int intrupt_cnt = 0;
 //int intrupt_cnt2 = 0;
-volatile int CH[5];
+int volatile CH[5];
 volatile int M[6];
 volatile float Gyro[3];
 volatile float Accel[3];
+volatile float Accel_Save[3];
 volatile float Angle[3];
 volatile float Gyro_Ref[3];
 volatile float Gyro_Save[3];
@@ -102,6 +104,7 @@
 //volatile bool tick_flag;
 //volatile bool buzz_flag;
 float interval;
+float pid_interval;
 int pid_reg[3];
 int loop_cnt;
 
@@ -113,8 +116,8 @@
 void Get_Stick_Pos();
 void CalibrateGyros(void);
 void CalibrateAccel(void);
-void Get_Gyro();
-bool Get_Accel();
+void Get_Gyro(float);
+bool Get_Accel(float);
 void Get_Angle(float);
 void ReadConfig();
 void WriteConfig();
@@ -171,7 +174,7 @@
 {
     int i=0;
     
-    wait(0.5);
+    wait(1.5);
     initialize();
 
     Get_Stick_Pos();
@@ -223,7 +226,7 @@
 
 void  initialize()
 {
-    buzz.period_us(500);
+    buzz.period_us(400);
     ReadConfig();               //config.inf file read
 
     i2c.start(conf.LCD_Contrast);
@@ -312,20 +315,25 @@
     char mem[MEM_SIZE];
     char *send;
     int i;
+//pc.printf("start\n\r");
     if ( sizeof(config) > 255 ) {
         LCD_printf("config size over");
         wait(3);
         return;
     }
+//pc.printf("iap start\n\r");
     send = (char*)&conf;
     for ( i=0;i<sizeof(config);i++ ) mem[i] = send[i];
     for ( i=sizeof(config);i<MEM_SIZE;i++ ) mem[i] = 0x00;
-    iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
-    iap.erase( TARGET_SECTOR, TARGET_SECTOR );
-//pc.printf("erase\n");
-    iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
-    iap.write( mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE );
-//pc.printf("write\n");
+//pc.printf("prepare start\n\r");
+    int rc = iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
+//pc.printf("prepare1(%5d)\n\r",rc);
+    rc = iap.erase( TARGET_SECTOR, TARGET_SECTOR );
+//pc.printf("erase(%5d)\n\r",rc);
+    rc = iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
+//pc.printf("prepare2(%5d)\n\r",rc);
+    rc = iap.write( mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE );
+//pc.printf("write(%5d)\n\r",rc);
 #endif
 }
 
@@ -345,7 +353,7 @@
     Stick[GAIN] = ( AUX - conf.Stick_Ref[GAIN] ) / 4;
 }
 
-void Get_Gyro()
+void Get_Gyro(float interval)
 {
     float x,y,z;
     bool err;
@@ -359,43 +367,63 @@
     Gyro[ROL] = x - Gyro_Ref[0] ;
     Gyro[PIT] = y - Gyro_Ref[1] ;
     Gyro[YAW] = z - Gyro_Ref[2] ;
-    
+/*
+    x -= Gyro_Ref[0];
+    y -= Gyro_Ref[1];
+    z -= Gyro_Ref[2];
+    float i = 3.14 * 2 * 10 * interval;     LPF 10Hz
+    Gyro[ROL] += -Gyro[ROL] * i + x * i;
+    Gyro[PIT] += -Gyro[PIT] * i + y * i;
+    Gyro[YAW] += -Gyro[YAW] * i + z * i;
+*/    
     if ( fabs(Gyro[ROL]) > 300.0 ) Gyro[ROL] = Gyro_Save[ROL];
     if ( fabs(Gyro[PIT]) > 300.0 ) Gyro[PIT] = Gyro_Save[PIT];
     if ( fabs(Gyro[YAW]) > 300.0 ) Gyro[YAW] = Gyro_Save[YAW];       
 }
 
-bool Get_Accel()
+bool Get_Accel(float interval)
 {
     float x,y,z;
-    bool err;
+    bool err;   
+    Accel_Save[ROL] = Accel[ROL];
+    Accel_Save[PIT] = Accel[PIT];
+    Accel_Save[YAW] = Accel[YAW];    
     if ( conf.Gyro_Dir[3] ==1 ) err=i2c.Acceleration(&x,&y,&z);
     else err=i2c.Acceleration(&y,&x,&z);
     if ( err == false ) return false;
-    float wx = x - conf.Accel_Ref[0];
-    float wy = y - conf.Accel_Ref[1];
-    float wz = z - conf.Accel_Ref[2];
-    Accel[ROL] = atan(wx/sqrt( pow(wy,2)+pow(wz,2)))*180/3.14;
-    Accel[PIT] = atan(wy/sqrt( pow(wx,2)+pow(wz,2)))*180/3.14;
-    Accel[YAW] = atan(sqrt( pow(wx,2)+pow(wy,2))/wz)*180/3.14;      
+//    Accel[ROL] = x - conf.Accel_Ref[0];
+//    Accel[PIT] = y - conf.Accel_Ref[1];
+//    Accel[YAW] = z - conf.Accel_Ref[2];
+
+    x -= conf.Accel_Ref[0];
+    y -= conf.Accel_Ref[1];
+    z -= conf.Accel_Ref[2];
+//    float i = 3.14 * 2 * 10 * interval;       //LPF 10Hz
+//    Accel[ROL] += -Accel[ROL] * i + x * i;
+//    Accel[PIT] += -Accel[PIT] * i + y * i;
+//    Accel[YAW] += -Accel[YAW] * i + z * i;
+
+    Accel[ROL] = atan(x/sqrt( pow(y,2)+pow(z,2)))*180/3.14;
+    Accel[PIT] = atan(y/sqrt( pow(x,2)+pow(z,2)))*180/3.14;
+//    Accel[YAW] = atan(sqrt( pow(x,2)+pow(y,2))/z)*180/3.14;      
     return true;  
 }
 
 void Get_Angle(float interval)
 {
-    Get_Gyro();
-    Get_Accel();
     float x,y,z;
+    Get_Accel(interval);
+    Get_Gyro(interval);
 
     x = ( (Gyro[ROL] + Gyro_Save[ROL]) ) * 0.5;
     y = ( (Gyro[PIT] + Gyro_Save[PIT]) ) * 0.5;
     z = ( (Gyro[YAW] + Gyro_Save[YAW]) ) * 0.5;
-    if ( Get_Accel() == true )  {
+    if ( Get_Accel(interval) == true )  {
         float i =  3.14 * 2 * conf.Cutoff_Freq * interval;
         Angle[ROL] += -Angle[ROL] * i + Accel[ROL] * i + x * interval;
         Angle[PIT] += -Angle[PIT] * i + Accel[PIT] * i + y * interval;
     }
-    else    {
+    else    {  
         Angle[ROL] += x * interval;
         Angle[PIT] += y * interval;
     }
@@ -442,7 +470,7 @@
     }
     conf.Accel_Ref[0] = k[0]/16;       
     conf.Accel_Ref[1] = k[1]/16;
-    conf.Accel_Ref[2] = k[2]/16-9.8;
+    conf.Accel_Ref[2] = k[2]/16-1;  
 //    FlashLED(3);
 }
 
@@ -452,11 +480,9 @@
     int i;
     float gain;
     
-    Get_Stick_Pos();
-    M1 = M2 = M3 = M4 = Stick[COL];
     interval = CycleTime.read();
     CycleTime.reset();
-    if ( interval > 0.1 ) return;
+    if ( interval > 0.2 ) return;
     TotalTime += interval;
     if ( TotalTime > 0.5 )    {
         led1 = !led1; 
@@ -466,37 +492,50 @@
     }
     
     Get_Angle(interval);
-    
+    pid_interval += interval;
+    if ( pid_interval < conf.PID_Interval && Stick[GAIN] < 0 ) return; 
+    Get_Stick_Pos();
+    M1 = M2 = M3 = M4 = Stick[COL];
+       
     for ( i=0;i<3;i++ ) {
             
 //      Stick Angle Mixing
         if ( conf.Gyro_Gain_Setting == 1 ) gain = conf.Gyro_Gain[i] * conf.Gyro_Dir[i];
         else gain = ( (float)abs(Stick[GAIN])/100 + conf.Gyro_Gain[i+3] ) * conf.Gyro_Dir[i];
         if ( Stick[GAIN] > 0 
-//            || i == YAW 
-//            || (fabsf)(Angle[i]) > conf.Control_Exchange_Angle 
+            || i == YAW 
             )  {
             reg[i] = Stick[i] * conf.Stick_Mix[i];
             reg[i] += Gyro[i] * gain * GYRO_ADJUST;
         }
         else   {
+//            reg[i] = Stick[i] * conf.Stick_Mix[i];
+//            reg[i] += pid[i].calc(Angle[i],0,pid_interval) * conf.Gyro_Dir[i];
+            float x = -(float)Stick[i]*45/400;
+            reg[i] = pid[i].calc(Angle[i],x*conf.Gyro_Dir[i],pid_interval) * conf.Gyro_Dir[i];
             if ( (i == YAW) || (i2c.GetAddr(ACCEL_ADDR)==0) )   {
-                if ( abs(Stick_Save[i]) <= abs(Stick[i]>>2) )   {
-                    Stick_Save[i] = Stick[i]>>2;
+                if ( ( fabsf(Angle[i]) < fabsf(x) ) && ( fabsf(Angle[i]) > fabsf(x*0.7) ) ) { Angle[i] = 0; pid[i].reset(); }
+                if ( abs(Stick_Save[i]) <= abs(Stick[i]) )   {
+                    Stick_Save[i] = Stick[i];
                 }
                 else    {
-//                    pc.printf("PID RESET.%3d",i);wait(1);
-                    Stick_Save[i] = 0;
-                    pid[i].reset();
-                    Angle[i] = 0;
+                    if ( (abs(Stick_Save[i]) - abs(Stick[i])) > 10 ) {
+                        Stick_Save[i] = 0;
+                        pid[i].reset();
+                        Angle[i] = 0;
+                    }
                 }
             } 
-            reg[i] = Stick[i] * conf.Stick_Mix[i];
-            reg[i] += pid[i].calc(Angle[i],0,interval);
-//            reg[i] = pid[i].calc(Angle[i],-(float)Stick[i]*60/400,interval);
+//            else    {
+//                if ( fabsf(Accel[i]) < 0.001 )  {
+//                    pid[i].reset();
+//                    Angle[i] = 0;
+//                }
+//            }
         }
         pid_reg[i] = reg[i];
     }
+    pid_interval = 0;
     //Calculate Roll Pulse Width
     M1 += reg[ROL];
     M2 -= reg[ROL];
@@ -519,7 +558,7 @@
     {
 //        if ( Stick[COL] > 150 && M[i] < 150 )   M[i] = 150; 
         if ( M[i] > Thro_Hi )   M[i] = Thro_Hi; 
-        if ( M[i] < Thro_Lo )   M[i] = Thro_Lo;     // this is the motor idle level
+        if ( M[i] < Thro_Lo )   M[i] = Thro_Lo;     // motor idle level
     }
     
     if (Stick[COL] < Thro_Zero ) M1=M2=M3=M4=0;
@@ -549,12 +588,13 @@
     for ( i=0;i<4;i++ ) pwm[i].pulsewidth_us(0);
     for ( i=0;i<4;i++ ) pwm[i].period_us(conf.PWM_Interval);
     for ( i=0;i<4;i++ ) pwm[i].pulsewidth_us(Pulse_Min);
-    for ( i=0;i<4;i++ ) pid[i].init(conf.kp[i],conf.ki[i],conf.kd[i]*(float)abs(Stick[GAIN])*0.02
-                                            ,conf.PID_Limit,conf.Integral_Limit);
+    for ( i=0;i<4;i++ ) pid[i].init(conf.kp[i],conf.ki[i],conf.kd[i]
+                                            ,conf.PID_Limit,conf.Differential_Limit);
     Angle[ROL]=Angle[PIT]=Angle[YAW]=0;
     loop_cnt = 0;
     FlyghtTime.start();
     CycleTime.start();
+    pid_interval = 0;
     FlashLED(5);
 }
 
@@ -583,3 +623,5 @@
 
 
 
+
+