航空研究会 / Mbed 2 deprecated AutoFlight2017_now_copy

Dependencies:   HCSR04_2 MPU6050_2 mbed SDFileSystem3

Fork of AutoFlight2017_now_copy by Bot Furukawa

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //mbed
00002 #include "mbed.h"
00003 #include "FATFileSystem.h"
00004 #include "SDFileSystem.h"
00005 //C
00006 #include "math.h"
00007 //sensor
00008 #include "MPU6050_DMP6.h"
00009 //#include "MPU9250.h"
00010 //#inclu
00011 #include "BMP280.h"
00012 #include "hcsr04.h"
00013 //device
00014 #include "sbus.h"
00015 //config
00016 #include "SkipperSv2.h"
00017 #include "falfalla.h"
00018 //other
00019 #include "pid.h"
00020 
00021 #define DEBUG_SEMIAUTO 0
00022 #define DEBUG_PRINT_INLOOP
00023 
00024 #define KP_ELE 2.0
00025 #define KI_ELE 0.0
00026 #define KD_ELE 0.0
00027 #define KP_RUD 3.0
00028 #define KI_RUD 0.0
00029 #define KD_RUD 0.0
00030 
00031 #define GAIN_CONTROLVALUE_TO_PWM 3.0
00032 
00033 #define RIGHT_ROLL -17.0
00034 #define RIGHT_PITCH -6.3
00035 #define LEFT_ROLL 16.0
00036 #define LEFT_PITCH -6.0
00037 #define STRAIGHT_ROLL 2.0
00038 #define STRAIGHT_PITCH -3.0
00039 #define TAKEOFF_THR 1.0
00040 #define LOOP_THR 0.58
00041 
00042 #define RIGHT_ROLL_SHORT -20.0
00043 #define RIGHT_PITCH_SHORT -7.0
00044 #define LEFT_ROLL_SHORT 22.0
00045 #define LEFT_PITCH_SHORT -6.0
00046 
00047 #define GLIDE_ROLL 16.0
00048 #define GLIDE_PITCH 0.0
00049 
00050 //コンパスキャリブレーション
00051 //SkipperS2基板
00052 /*
00053 #define MAGBIAS_X -35.0
00054 #define MAGBIAS_Y 535.0
00055 #define MAGBIAS_Z -50.0
00056 */
00057 //S2v2 1番基板
00058 #define MAGBIAS_X 395.0
00059 #define MAGBIAS_Y 505.0
00060 #define MAGBIAS_Z -725.0
00061 //S2v2 2番基板
00062 /*
00063 #define MAGBIAS_X 185.0
00064 #define MAGBIAS_Y 220.0
00065 #define MAGBIAS_Z -350.0
00066 */
00067 
00068 #define ELEMENT 1
00069 #define LIMIT_STRAIGHT_YAW 5.0 
00070 #define LIMIT_LOOPSTOP_YAW 1.0
00071 #define THRESHOLD_TURNINGRADIUS_YAW 60.0 
00072 #define ALLOWHEIGHT 15
00073 
00074 #ifndef PI
00075 #define PI 3.14159265358979
00076 #endif
00077 
00078 const int16_t lengthdivpwm = 320; 
00079 const int16_t changeModeCount = 6;
00080 
00081 const float trim[4] = {Trim_Falfalla[0],Trim_Falfalla[1],Trim_Falfalla[2],Trim_Falfalla[3]};
00082 const float expMax[4] = {ExpMax_Falfalla[0],ExpMax_Falfalla[1],ExpMax_Falfalla[2],ExpMax_Falfalla[3]};
00083 const float expMin[4] = {ExpMin_Falfalla[0],ExpMin_Falfalla[1],ExpMin_Falfalla[2],ExpMin_Falfalla[3]};
00084 const int16_t reverce[4] = {ExpMin_Falfalla[0],Reverce_falfalla[1],Reverce_falfalla[2],Reverce_falfalla[3]};
00085 
00086 SBUS sbus(PA_9, PA_10); //SBUS
00087 
00088 //PwmOut servo1(PC_6); // TIM3_CH1  //echo
00089 PwmOut servo2(PC_7); // TIM3_CH2    //PC_7
00090 PwmOut servo3(PB_0); // TIM3_CH3
00091 PwmOut servo4(PB_1); // TIM3_CH4
00092 PwmOut servo5(PB_6); // TIM4_CH1
00093 //PwmOut servo6(PB_7); // TIM4_CH2  //trigger
00094 //PwmOut servo7(PB_8); // TIM4_CH3    //PB_8
00095 //PwmOut servo8(PB_9); // TIM4_CH4
00096 
00097 RawSerial pc(PA_2,PA_3, 115200);    //tx,rx.baudrate pin;PA_2=UART2_TX, PA_3=UART2_RX
00098 SDFileSystem sd(PB_15, PB_14, PB_13, PB_12, "sd");
00099 
00100 DigitalOut led1(PA_0);  //黄色のコネクタ
00101 DigitalOut led2(PA_1);
00102 DigitalOut led3(PB_4); 
00103 DigitalOut led4(PB_5);
00104 
00105 //InterruptIn switch2(PC_14);
00106 MPU6050DMP6 mpu6050(PC_0,&pc); //割り込みピン,シリアルポインタ i2cのピン指定は MPU6050>>I2Cdev.h 内のdefine
00107 HCSR04 usensor(PB_7,PC_6); //trig,echo  9,8 
00108 
00109 PID pid_ELE(g_kpELE,g_kiELE,g_kdELE);
00110 PID pid_RUD(g_kpRUD,g_kiRUD,g_kdRUD);
00111 
00112 enum Channel{AIL, ELE, THR, RUD, DROP, Ch6, Ch7, Ch8};
00113 enum Angle{ROLL, PITCH, YAW};   //yaw:北を0とした絶対角度
00114 enum OperationMode{StartUp, SemiAuto, RightLoop, LeftLoop, GoStraight, BombwithPC, ZERO, Moebius, Glide};
00115 enum BombingMode{Takeoff, Chicken, Transition, Approach};
00116 enum OutputStatus{Manual, Auto};
00117 
00118 static OutputStatus output_status = Manual;
00119 OperationMode operation_mode = StartUp;
00120 BombingMode bombing_mode = Takeoff;
00121 static int16_t autopwm[8] = {1500,1500,1180,1500,1446,1500};
00122 static int16_t trimpwm[6] = {1500,1500,1180,1500,1446,1500};
00123 int16_t maxpwm[6] = {1820,1820,1820,1820,1820,1820};
00124 int16_t minpwm[6] = {1180,1180,1180,1180,1180,1180};
00125 int16_t oldTHR = 1000;
00126 
00127 static float nowAngle[3] = {0,0,0};
00128 const float trimAngle[3] = {0.0, 0.0, 0.0};
00129 const float maxAngle[2] = {90, 90};
00130 const float minAngle[2] = {-90, -90};
00131 
00132 float FirstROLL = 0.0, FirstPITCH = 0.0 ,FirstYAW = 0.0;
00133 
00134 unsigned int g_distance;
00135 Ticker USsensor;
00136 static char g_buf[16];
00137 char g_landingcommand;
00138 float g_SerialTargetYAW = 0.0;
00139 
00140 Timer t;
00141 Timeout RerurnChickenServo1;
00142 Timeout RerurnChickenServo2;
00143 
00144 /*-----関数のプロトタイプ宣言-----*/
00145 void setup();
00146 void loop();
00147 
00148 void Init_PWM();
00149 void Init_servo();              //サーボ初期化
00150 void Init_sbus();               //SBUS初期化
00151 void Init_sensors();
00152 void DisplayClock();            //クロック状態確認
00153 
00154 //センサの値取得
00155 void SensingMPU();
00156 void UpdateDist();
00157 
00158 //void offsetRollPitch(float FirstROLL, float FirstPITCH);
00159 //void TransYaw(float FirstYAW);
00160 float TranslateNewYaw(float beforeYaw,  float newzeroYaw);
00161 void UpdateTargetAngle(float targetAngle[3]);
00162 void CalculateControlValue(float targetAngle[3], float controlValue[3]);
00163 void UpdateAutoPWM(float controlValue[3]);
00164 void ConvertPWMintoRAD(float targetAngle[3]);
00165 inline float CalcRatio(float value, float trim, float limit);
00166 bool CheckSW_Up(Channel ch);
00167 int16_t ThresholdMaxMin(int16_t value, int16_t max, int16_t min);
00168 inline int16_t SetTHRinRatio(float ratio);
00169 
00170 //sbus割り込み
00171 void Update_PWM();              //マニュアル・自動モードのpwmデータを整形しpwm変数に入力
00172 void Output_PWM(int16_t pwm[6]);    //pwmをサーボへ出力
00173 
00174 //シリアル割り込み
00175 void SendSerial();   //1文字きたら送り返す
00176 void SendArray();
00177 void getSF_Serial();
00178 float ConvertByteintoFloat(char high, char low);
00179 
00180 //SD設定
00181 int GetParameter(FILE *fp, const char *paramName,char parameter[]);
00182 int SetOptions(float *g_kpELE, float *g_kiELE, float *g_kdELE,
00183                float *g_kpRUD, float *g_kiRUD, float *g_kdRUD,
00184                float *g_rightloopROLL, float *g_rightloopPITCH,
00185                float *g_leftloopROLL, float *g_leftloopPITCH,
00186                float *g_gostraightROLL, float *g_gostraightPITCH,
00187                float *g_takeoffTHR, float *g_loopTHR,
00188                float *g_rightloopROLLshort, float *g_rightloopPITCHshort,
00189                float *g_leftloopROLLshort, float *g_leftloopPITCHshort,
00190                float *g_glideloopROLL, float *g_glideloopPITCH);
00191 //switch2割り込み
00192 void ResetTrim();
00193 
00194 //自動操縦
00195 void UpdateTargetAngle_GoStraight(float targetAngle[3]);
00196 void UpdateTargetAngle_Rightloop(float targetAngle[3]);
00197 void UpdateTargetAngle_Rightloop_short(float targetAngle[3]);
00198 void UpdateTargetAngle_Leftloop(float targetAngle[3]);
00199 void UpdateTargetAngle_Leftloop_short(float targetAngle[3]);
00200 void UpdateTargetAngle_Moebius(float targetAngle[3]);
00201 void UpdateTargetAngle_Glide(float targetAngle[3]);
00202 void UpdateTargetAngle_Takeoff(float targetAngle[3]);
00203 void UpdateTargetAngle_Approach(float targetAngle[3]);
00204 void Take_off_and_landing(float targetAngle[3]);
00205 
00206 char Rotate(float targetAngle[3], float TargetYAW, char mode);
00207 
00208 //投下
00209 void Chicken_Drop();
00210 void ReturnChickenServo1();
00211 void ReturnChickenServo2();
00212 
00213 //超音波による高度補正
00214 void checkHeight(float targetAngle[3]);
00215 void UpdateTargetAngle_NoseUP(float targetAngle[3]);
00216 void UpdateTargetAngle_NoseDOWN(float targetAngle[3]);
00217 
00218 //デバッグ用
00219 void DebugPrint();
00220 
00221 /*---関数のプロトタイプ宣言終わり---*/
00222 
00223 int main()
00224 {
00225     setup();
00226     
00227     while(1){
00228         
00229         loop();
00230         
00231         if(!CheckSW_Up(Ch7)){
00232             led3=0;
00233         }else{
00234             led3=1;
00235         }
00236     }
00237 }
00238 
00239 void setup(){
00240     //buzzer = 0;
00241     led1 = 1;
00242     led2 = 1;
00243     led3 = 1;
00244     led4 = 1;
00245     
00246     SetOptions(&g_kpELE, &g_kiELE, &g_kdELE,
00247                &g_kpRUD, &g_kiRUD, &g_kdRUD,
00248                &g_rightloopROLL, &g_rightloopPITCH,
00249                &g_leftloopROLL, &g_leftloopPITCH,
00250                &g_gostraightROLL, &g_gostraightPITCH,
00251                &g_takeoffTHR, &g_loopTHR,
00252                &g_rightloopROLLshort, &g_rightloopPITCHshort,
00253                &g_leftloopROLLshort, &g_leftloopPITCHshort,
00254                &g_glideloopROLL, &g_glideloopPITCH);    
00255     
00256         
00257     Init_PWM();
00258     Init_servo();
00259     Init_sbus();    
00260     Init_sensors();
00261     //switch2.rise(ResetTrim);
00262     pc.attach(getSF_Serial, Serial::RxIrq);
00263     USsensor.attach(&UpdateDist, 0.05);
00264     
00265     NVIC_SetPriority(USART1_IRQn,0);
00266     NVIC_SetPriority(EXTI0_IRQn,1);
00267     NVIC_SetPriority(TIM5_IRQn,2);
00268     NVIC_SetPriority(EXTI9_5_IRQn,3);
00269     NVIC_SetPriority(USART2_IRQn,4);
00270     DisplayClock();
00271     t.start();
00272     
00273     
00274     pc.printf("MPU calibration start\r\n");
00275     
00276     float offsetstart = t.read();
00277     while(t.read() - offsetstart < 26){
00278         SensingMPU();
00279         for(uint8_t i=0; i<3; i++) pc.printf("%3.2f\t",nowAngle[i]);
00280         pc.printf("\r\n");
00281         led1 = !led1;
00282         led2 = !led2;
00283         led3 = !led3;
00284         led4 = !led4;
00285     }
00286     
00287     FirstROLL = nowAngle[ROLL];
00288     FirstPITCH = nowAngle[PITCH];
00289     nowAngle[ROLL] -=FirstROLL;
00290     nowAngle[PITCH] -=FirstPITCH;
00291     
00292     led1 = 0;
00293     led2 = 0;
00294     led3 = 0;
00295     led4 = 0;
00296     wait(0.2);
00297     
00298     
00299     pc.printf("All initialized\r\n");
00300 }
00301 
00302 void loop(){
00303     static float targetAngle[3] = {0.0, 0.0, 0.0}, controlValue[2] = {0.0, 0.0};
00304 
00305     SensingMPU();
00306     UpdateTargetAngle(targetAngle);
00307     //Rotate(targetAngle, 30.0);
00308     CalculateControlValue(targetAngle, controlValue);
00309     UpdateAutoPWM(controlValue);
00310     wait_ms(23);
00311 //#if DEBUG_PRINT_INLOOP
00312     DebugPrint();
00313 //#endif
00314 }
00315 
00316 //サーボ初期化関数
00317 void Init_servo(){
00318     
00319     //servo1.period_ms(14);
00320     //servo1.pulsewidth_us(trimpwm[AIL]);
00321     
00322     servo2.period_ms(14);
00323     servo2.pulsewidth_us(trimpwm[ELE]);
00324     
00325     servo3.period_ms(14);
00326     servo3.pulsewidth_us(trimpwm[THR]);
00327     
00328     servo4.period_ms(14);
00329     servo4.pulsewidth_us(trimpwm[RUD]);
00330     
00331     servo5.period_ms(14);
00332     servo5.pulsewidth_us(1392);
00333 
00334     pc.printf("servo initialized\r\n");
00335 }
00336 
00337 //Sbus初期化
00338 void Init_sbus(){
00339     sbus.initialize();
00340     sbus.setLastfuncPoint(Update_PWM);
00341     sbus.startInterrupt();
00342 }
00343 
00344 void Init_sensors(){
00345     if(mpu6050.setup() == -1){
00346         pc.printf("failed initialize\r\n");
00347         while(1){
00348             led1 = 1; led2 = 0; led3 = 1; led4 = 0;
00349             wait(1);
00350             led1 = 0; led2 = 1; led3 = 0; led4 = 1;
00351             wait(1);
00352         }
00353     }
00354 }
00355 
00356 void Init_PWM(){
00357     for (uint8_t i = 0; i < 4; ++i){
00358         trimpwm[i] = 1500 + (int16_t)(lengthdivpwm * (trim[i]/100));
00359         maxpwm[i] = 1500 + (int16_t)(lengthdivpwm * (expMax[i]/100));
00360         minpwm[i] = 1500 - (int16_t)(lengthdivpwm * (expMin[i]/100));
00361     }
00362     pc.printf("PWM initialized\r\n");
00363 }
00364 
00365 void DisplayClock(){
00366     pc.printf("System Clock = %d[MHz]\r\n", HAL_RCC_GetSysClockFreq()/1000000);
00367     pc.printf("HCLK Clock   = %d[MHz]\r\n", HAL_RCC_GetHCLKFreq()/1000000);
00368     pc.printf("PCLK1 Clock  = %d[MHz]\r\n", HAL_RCC_GetPCLK1Freq()/1000000);
00369     pc.printf("PCLK2 Clock  = %d[MHz]\r\n", HAL_RCC_GetPCLK2Freq()/1000000);
00370     pc.printf("\r\n");
00371 }
00372 
00373 void UpdateTargetAngle(float targetAngle[3]){
00374     static int16_t count_op = 0, count_out = 0;
00375 #if DEBUG_SEMIAUTO    
00376     switch(operation_mode){
00377         case StartUp:
00378             if(!CheckSW_Up(Ch7) && CheckSW_Up(Ch8)){
00379                 count_op++;
00380                 if(count_op > changeModeCount){
00381                     operation_mode = SemiAuto;
00382                     pc.printf("Goto SemiAuto mode\r\n");
00383                     count_op = 0;
00384                 }
00385             }else count_op = 0;
00386             break;
00387 
00388         case SemiAuto:
00389         /*  大会用では以下のif文を入れてoperation_modeを変える
00390             if(CheckSW_Up(Ch6)){
00391                 count_op++;
00392                 if(count_op>changeModeCount){
00393                     output_status = XXX;
00394                     led2 = 0;
00395                     pc.printf("Goto XXX mode\r\n");
00396                     count_op = 0;
00397                 }else count_op = 0;
00398                 ConvertPWMintoRAD(targetAngle);
00399             }
00400         */
00401             ConvertPWMintoRAD(targetAngle);
00402             break;
00403 
00404         default:
00405             operation_mode = SemiAuto;
00406             break;
00407     }
00408 
00409 #else
00410 
00411     switch(operation_mode){
00412         case StartUp:
00413             if(!CheckSW_Up(Ch7) && !CheckSW_Up(Ch8)){        //ch7;自動・手動切り替え ch8;自動操縦モード切替
00414                 count_op++;
00415                 if(count_op > changeModeCount){
00416                     operation_mode = LeftLoop;
00417                     pc.printf("Goto LeftLoop mode\r\n");
00418                     count_op = 0;
00419                 }
00420             }else count_op = 0;
00421             break;
00422 
00423         case LeftLoop:
00424             if(!CheckSW_Up(Ch7) && CheckSW_Up(Ch8)){
00425                 count_op++;
00426                 if(count_op > changeModeCount){
00427                     operation_mode = RightLoop;
00428                     pc.printf("Goto RightLoop mode\r\n");
00429                     count_op = 0;
00430                 }
00431             }else count_op = 0;
00432             UpdateTargetAngle_Leftloop(targetAngle);
00433             break;
00434         
00435         case RightLoop:
00436             if(!CheckSW_Up(Ch7) && !CheckSW_Up(Ch8)){
00437                 count_op++;
00438                 if(count_op > changeModeCount){
00439                     operation_mode = Moebius;
00440                     pc.printf("Goto Moebius mode\r\n");
00441                     count_op = 0;
00442                 }
00443             }else count_op = 0;
00444             UpdateTargetAngle_Rightloop(targetAngle);
00445             
00446             //Rotate確認用
00447             /*
00448             static char mode = 'G';
00449             mode = Rotate(targetAngle,g_SerialTargetYAW,mode); 
00450             */
00451             break;
00452         
00453         case Moebius:
00454             if(!CheckSW_Up(Ch7) && CheckSW_Up(Ch8)){
00455                 count_op++;
00456                 if(count_op > changeModeCount){
00457                     operation_mode = Glide;
00458                     pc.printf("Goto Glide mode\r\n");
00459                     count_op = 0;
00460                 }
00461             }else count_op = 0;
00462             UpdateTargetAngle_Moebius(targetAngle);
00463             break;
00464 
00465         case Glide:
00466             if(!CheckSW_Up(Ch7) && !CheckSW_Up(Ch8)){
00467                 count_op++;
00468                 if(count_op > changeModeCount){
00469                     operation_mode = BombwithPC;
00470                     pc.printf("Goto Bombing mode\r\n");
00471                     count_op = 0;
00472                 }
00473             }else count_op = 0;
00474             UpdateTargetAngle_Glide(targetAngle);
00475             break;
00476 
00477         case BombwithPC:
00478             if(!CheckSW_Up(Ch7) && CheckSW_Up(Ch8)){
00479                 count_op++;
00480                 if(count_op > changeModeCount){
00481                     operation_mode = GoStraight;
00482                     pc.printf("Goto GoStraight mode\r\n");
00483                     count_op = 0;
00484                 }
00485             }else count_op = 0;
00486             Take_off_and_landing(targetAngle);
00487             break;
00488         
00489         case GoStraight:
00490             if(!CheckSW_Up(Ch7) && !CheckSW_Up(Ch8)){
00491                 count_op++;
00492                 if(count_op > changeModeCount){
00493                     operation_mode = LeftLoop;
00494                     pc.printf("Goto Leftloop mode\r\n");
00495                     count_op = 0;
00496                 }
00497             }else count_op = 0;
00498             UpdateTargetAngle_GoStraight(targetAngle);
00499             break;
00500 
00501         
00502         default:
00503         
00504             operation_mode = StartUp;
00505             break;
00506     }
00507 #endif
00508 
00509     if(CheckSW_Up(Ch7) && output_status == Manual){
00510         count_out++;
00511         if(count_out > changeModeCount){
00512             output_status = Auto;
00513             //led3 = 1;
00514             count_out = 0;
00515         }
00516     }else if(!CheckSW_Up(Ch7) && output_status == Auto){
00517         count_out++;
00518         if(count_out > changeModeCount){
00519             output_status = Manual;
00520             count_out = 0;
00521             //led3 = 0;
00522         }
00523     }else count_out = 0;
00524 }
00525 
00526 int GetParameter(FILE *fp, const char *paramName,char parameter[]){
00527     int i=0, j=0;
00528     int strmax = 200;
00529     char str[strmax];
00530 
00531     rewind(fp); //ファイル位置を先頭に
00532     while(1){
00533         if (fgets(str, strmax, fp) == NULL) {
00534             return 0;
00535         }
00536         if (!strncmp(str, paramName, strlen(paramName))) {
00537             while (str[i++] != '=') {}
00538             while (str[i] != '\n') {
00539                     parameter[j++] = str[i++];
00540             }
00541             parameter[j] = '\0';
00542             return 1;
00543         }
00544     }
00545     return 0;
00546 }
00547 
00548 
00549 //sdによる設定
00550 int SetOptions(float *g_kpELE, float *g_kiELE, float *g_kdELE,
00551                float *g_kpRUD, float *g_kiRUD, float *g_kdRUD,
00552                float *g_rightloopROLL, float *g_rightloopPITCH,
00553                float *g_leftloopROLL, float *g_leftloopPITCH,
00554                float *g_gostraightROLL, float *g_gostraightPITCH,
00555                float *g_takeoffTHR, float *g_loopTHR,
00556                float *g_rightloopROLLshort, float *g_rightloopPITCHshort,
00557                float *g_leftloopROLLshort, float *g_leftloopPITCHshort,
00558                float *g_glideloopROLL, float *g_glideloopPITCH
00559                ){
00560 
00561     pc.printf("SDsetup start.\r\n");    
00562     
00563     FILE *fp;
00564     char parameter[30]; //文字列渡す用の配列
00565     int SDerrorcount = 0;  //取得できなかった数を返す
00566     const char *paramNames[] = { 
00567         "KP_ELEVATOR",
00568         "KI_ELEVATOR",
00569         "KD_ELEVATOR",
00570         "KP_RUDDER",
00571         "KI_RUDDER",
00572         "KD_RUDDER",
00573         "RIGHTLOOP_ROLL",
00574         "RIGHTLOOP_PITCH",
00575         "LEFTLOOP_ROLL",
00576         "LEFTLOOP_PITCH",
00577         "GOSTRAIGHT_ROLL",
00578         "GOSTRAIGHT_PITCH",
00579         "TAKEOFF_THR_RATE",
00580         "LOOP_THR_RATE",
00581         "RIGHTLOOP_ROLL_SHORT",
00582         "RIGHTLOOP_PITCH_SHORT",
00583         "LEFTLOOP_ROLL_SHORT",
00584         "LEFTLOOP_PITCH_SHORT",
00585         "AUTOGLIDE_ROLL",
00586         "AUTOGLIDE PITCH"        
00587     };
00588 
00589     fp = fopen("/sd/option.txt","r");
00590     
00591     if(fp != NULL){ //開けたら
00592         pc.printf("File was openned.\r\n");
00593         if(GetParameter(fp,paramNames[0],parameter)) *g_kpELE = atof(parameter);
00594         else{                                        *g_kpELE = KP_ELE;
00595                                                      SDerrorcount++;
00596         }
00597         if(GetParameter(fp,paramNames[1],parameter)) *g_kiELE = atof(parameter);
00598         else{                                        *g_kiELE = KI_ELE;
00599                                                       SDerrorcount++;
00600         }
00601         if(GetParameter(fp,paramNames[2],parameter)) *g_kdELE = atof(parameter);
00602         else{                                        *g_kdELE = KD_ELE;
00603                                                      SDerrorcount++;
00604         }
00605         if(GetParameter(fp,paramNames[3],parameter)) *g_kpRUD = atof(parameter);
00606         else{                                        *g_kpRUD = KP_RUD;
00607                                                       SDerrorcount++;
00608         }
00609         if(GetParameter(fp,paramNames[4],parameter)) *g_kiRUD = atof(parameter);
00610         else{                                        *g_kiRUD = KI_RUD;
00611                                                       SDerrorcount++;
00612         }
00613         if(GetParameter(fp,paramNames[5],parameter)) *g_kdRUD = atof(parameter);
00614         else{                                        *g_kdRUD = KD_RUD;
00615                                                       SDerrorcount++;
00616         }
00617         if(GetParameter(fp,paramNames[6],parameter)) *g_rightloopROLL = atof(parameter);
00618         else{                                        *g_rightloopROLL = RIGHT_ROLL;
00619                                                       SDerrorcount++;
00620         }
00621         if(GetParameter(fp,paramNames[7],parameter)) *g_rightloopPITCH = atof(parameter);
00622         else{                                        *g_rightloopPITCH = RIGHT_PITCH;
00623                                                       SDerrorcount++;
00624         }
00625         if(GetParameter(fp,paramNames[8],parameter)) *g_leftloopROLL = atof(parameter);
00626         else{                                        *g_leftloopROLL = LEFT_ROLL;
00627                                                       SDerrorcount++;
00628         }
00629         if(GetParameter(fp,paramNames[9],parameter)) *g_leftloopPITCH = atof(parameter);
00630         else{                                         *g_leftloopPITCH = LEFT_PITCH;
00631                                                       SDerrorcount++;
00632         }
00633         if(GetParameter(fp,paramNames[10],parameter)) *g_gostraightROLL = atof(parameter);
00634         else{                                         *g_gostraightROLL = STRAIGHT_ROLL;
00635                                                       SDerrorcount++;
00636         }
00637         if(GetParameter(fp,paramNames[11],parameter)) *g_gostraightPITCH = atof(parameter);
00638         else{                                         *g_gostraightPITCH = STRAIGHT_PITCH;
00639                                                       SDerrorcount++;
00640         }
00641         if(GetParameter(fp,paramNames[12],parameter)) *g_takeoffTHR = atof(parameter);
00642         else{                                         *g_takeoffTHR = TAKEOFF_THR;
00643                                                       SDerrorcount++;
00644         }
00645         if(GetParameter(fp,paramNames[13],parameter)) *g_loopTHR = atof(parameter);
00646         else{                                         *g_loopTHR = LOOP_THR;
00647                                                       SDerrorcount++;
00648         }
00649         if(GetParameter(fp,paramNames[14],parameter)) *g_rightloopROLLshort = atof(parameter);
00650         else{                                         *g_rightloopROLLshort = RIGHT_ROLL_SHORT;
00651                                                       SDerrorcount++;
00652         }
00653         if(GetParameter(fp,paramNames[15],parameter)) *g_rightloopPITCHshort = atof(parameter);
00654         else{                                         *g_rightloopPITCHshort = RIGHT_PITCH_SHORT;
00655                                                       SDerrorcount++;
00656         }
00657         if(GetParameter(fp,paramNames[16],parameter)) *g_leftloopROLLshort = atof(parameter);
00658         else{                                         *g_leftloopROLLshort = LEFT_ROLL_SHORT;
00659                                                       SDerrorcount++;
00660         }
00661         if(GetParameter(fp,paramNames[17],parameter)) *g_leftloopPITCHshort = atof(parameter);
00662         else{                                         *g_leftloopPITCHshort = LEFT_PITCH_SHORT;
00663                                                       SDerrorcount++;
00664         }
00665         if(GetParameter(fp,paramNames[18],parameter)) *g_glideloopROLL = atof(parameter);
00666         else{                                         *g_glideloopROLL = GLIDE_ROLL;
00667                                                       SDerrorcount++;
00668         }
00669         if(GetParameter(fp,paramNames[19],parameter)) *g_glideloopPITCH = atof(parameter);
00670         else{                                         *g_glideloopPITCH = GLIDE_PITCH;
00671                                                       SDerrorcount++;
00672         }
00673         fclose(fp);
00674 
00675     }else{  //ファイルがなかったら
00676         pc.printf("fp was null.\r\n");
00677         *g_kpELE = KP_ELE;
00678         *g_kiELE = KI_ELE;
00679         *g_kdELE = KD_ELE;
00680         *g_kpRUD = KP_RUD;
00681         *g_kiRUD = KI_RUD;
00682         *g_kdRUD = KD_RUD;
00683         *g_rightloopROLL = RIGHT_ROLL;
00684         *g_rightloopPITCH = RIGHT_PITCH;
00685         *g_leftloopROLL = LEFT_ROLL;
00686         *g_leftloopPITCH = LEFT_PITCH;
00687         *g_gostraightROLL = STRAIGHT_ROLL;
00688         *g_gostraightPITCH = STRAIGHT_PITCH;
00689         *g_takeoffTHR = TAKEOFF_THR;
00690         *g_loopTHR = LOOP_THR;
00691         SDerrorcount = -1;
00692     }
00693     pc.printf("SDsetup finished.\r\n");
00694     if(SDerrorcount == 0)  pc.printf("setting option is success\r\n");
00695     else if(SDerrorcount == -1) pc.printf("ERROR 1. cannot open option\r\n");
00696     else if(SDerrorcount > 0)  pc.printf("ERROR 2. reading parameter is failed[%d]\r\n",SDerrorcount); 
00697     
00698     pc.printf("kpELE = %f, kiELE = %f, kdELE = %f\r\n", *g_kpRUD, *g_kiRUD, *g_kdRUD);
00699     pc.printf("kpRUD = %f, kiRUD = %f, kdRUD = %f\r\n", *g_kpELE, *g_kiELE, *g_kdELE);
00700     pc.printf("rightloopROLL = %f, rightloopPITCH = %f\r\n", *g_rightloopROLL, *g_rightloopPITCH);
00701     pc.printf("leftloopROLL = %f, g_leftloopPITCH =  %f\r\n", *g_leftloopROLL, *g_leftloopPITCH);
00702     pc.printf("gostraightROLL = %f, g_gostraightPITCH = %f\r\n", *g_gostraightROLL, *g_gostraightPITCH);
00703     pc.printf("g_takeoffTHR = %f, g_loopTHR = %f\r\n", *g_takeoffTHR, *g_loopTHR);
00704     pc.printf("rightloopROLLshort = %f, rightloopPITCHshort = %f\r\n", *g_rightloopROLLshort, *g_rightloopPITCHshort);
00705     pc.printf("leftloopROLLshort = %f, g_leftloopPITCHshort =  %f\r\n", *g_leftloopROLLshort, *g_leftloopPITCHshort);
00706     pc.printf("glideROLL = %f, glidePITCH = %f\r\n", *g_glideloopROLL, *g_glideloopPITCH);
00707     
00708     return SDerrorcount;
00709 }                  
00710 
00711 void CalculateControlValue(float targetAngle[3], float controlValue[3]){
00712     static int t_last;
00713     int t_now;
00714     float dt;
00715 
00716     t_now = t.read_us();
00717     dt = (float)((t_now - t_last)/1000000.0f) ;
00718     t_last = t_now;
00719 
00720     controlValue[ROLL] = pid_RUD.calcPID(nowAngle[ROLL], targetAngle[ROLL], dt);    
00721     controlValue[PITCH] = pid_ELE.calcPID(nowAngle[PITCH], targetAngle[PITCH], dt);
00722 }
00723 
00724 void UpdateAutoPWM(float controlValue[3]){    
00725     int16_t addpwm[2]; //-500~500
00726     addpwm[PITCH] = (float)GAIN_CONTROLVALUE_TO_PWM * controlValue[PITCH];    //センサ:機首下げ正    レバー:機首上げ正
00727     addpwm[ROLL] = (float)GAIN_CONTROLVALUE_TO_PWM * controlValue[ROLL];           //センサ:右回転正(8月13日時点;左回転が正!)     レバー:右回転正
00728     
00729     autopwm[ELE] = trimpwm[ELE] + reverce[ELE] * addpwm[PITCH];
00730     autopwm[RUD] = trimpwm[RUD] + reverce[RUD] * addpwm[ROLL];
00731     //autopwm[THR] = oldTHR;
00732 
00733     autopwm[ELE] = ThresholdMaxMin(autopwm[ELE], maxpwm[ELE], minpwm[ELE]);
00734     autopwm[RUD] = ThresholdMaxMin(autopwm[RUD], maxpwm[RUD], minpwm[RUD]);
00735 }
00736 
00737 inline float CalcRatio(float value, float trim, float limit){
00738     return  (value - trim) / (limit - trim);
00739 }
00740 
00741 bool CheckSW_Up(Channel ch){
00742     if(SWITCH_CHECK < sbus.manualpwm[ch]){
00743         return true;
00744     }else{
00745         return false;
00746     }
00747 }
00748 
00749 int16_t ThresholdMaxMin(int16_t value, int16_t max, int16_t min){
00750     if(value > max) return max;
00751     if(value < min) return min;
00752     return value;
00753 }
00754 
00755 inline int16_t SetTHRinRatio(float ratio){
00756     return minpwm[THR] + (int16_t)(2 * lengthdivpwm * ratio);
00757 }
00758 
00759 /*---SBUS割り込み処理---*/
00760 
00761 //udate_Inputで抽出したpwmデータを整形して各変数に代入する。(マニュアルモード)
00762 //各stabiGylo関数で算出したpwmを各変数に代入する(自動モード)
00763 void Update_PWM()
00764 {    
00765     static int16_t pwm[5], sbuspwm[5];
00766     static int16_t temppwm[6]={trimpwm[0],trimpwm[1],trimpwm[2],trimpwm[3],trimpwm[4]};
00767     static int16_t tempsbuspwm[5] = {trimpwm[0],trimpwm[1],trimpwm[2],trimpwm[3],trimpwm[4]};
00768     static int counter_abnormalpwm=0;
00769     if(sbus.flg_ch_update == true){
00770         switch(output_status){    //マニュアルモード,自動モード,自動着陸もモードを切替
00771             case Manual:
00772                 for(uint8_t i=1;i<4;i++){
00773                     if(abs(sbus.manualpwm[i]-tempsbuspwm[i])>300){
00774                         counter_abnormalpwm++;
00775                         if(counter_abnormalpwm<=1) sbuspwm[i]=tempsbuspwm[i];
00776                         else {
00777                             counter_abnormalpwm = 0;
00778                             sbuspwm[i] = sbus.manualpwm[i];
00779                         }
00780                     }
00781                     else{
00782                         counter_abnormalpwm = 0;
00783                         sbuspwm[i] = sbus.manualpwm[i];
00784                     }
00785                     tempsbuspwm[i]=sbus.manualpwm[i];
00786                 }
00787                 sbuspwm[4] = sbus.manualpwm[4];
00788                 
00789                 for(uint8_t i=1;i<5;i++){
00790                     pwm[i] = sbuspwm[i];
00791                 }
00792                 oldTHR = sbuspwm[THR];
00793                                 
00794                 //pc.printf("update_manual\r\n");
00795                 break;
00796         
00797             case Auto:
00798                 pwm[ELE] = autopwm[ELE];
00799                 pwm[THR] = autopwm[THR];
00800                 pwm[RUD] = autopwm[RUD];
00801                 pwm[DROP] = autopwm[DROP];
00802                 //pc.printf("update_auto\r\n");
00803                 break;
00804                 
00805             default:
00806                 for(uint8_t i=1;i<5;i++){
00807                     pwm[i] = sbus.manualpwm[i];
00808                 } //pc.printf("update_manual\r\n");
00809                 break;
00810         }
00811         for(uint8_t i=1;i<5;i++) if(pwm[i]<1000 || pwm[i]>2000) pwm[i]=temppwm[i];
00812     
00813         if(pwm[4]>1600 || pwm[4]<1420) pwm[4]=temppwm[4];
00814         temppwm[4] = pwm[4];
00815         
00816     }else{
00817         pc.printf("0\r\n");
00818     }
00819     sbus.flg_ch_update = false;
00820     
00821     Output_PWM(pwm);    
00822 }
00823 
00824 
00825 //pwmをサーボに出力。
00826 void Output_PWM(int16_t pwm[5])
00827 {
00828     //servo1.pulsewidth_us(pwm[0]);
00829     servo2.pulsewidth_us(pwm[1]);
00830     servo3.pulsewidth_us(pwm[2]);
00831     servo4.pulsewidth_us(pwm[3]);
00832     servo5.pulsewidth_us(pwm[4]);
00833 }
00834 
00835 void ResetTrim(){
00836     for(uint8_t i=1; i<4; i++){
00837         trimpwm[i] = sbus.manualpwm[i];
00838     }
00839     pc.printf("reset PWM trim\r\n");
00840 }
00841 
00842 
00843 void SensingMPU(){
00844     //static int16_t deltaT = 0, t_start = 0;
00845     //t_start = t.read_us();
00846     
00847     float rpy[3] = {0}, oldrpy[3] = {0};
00848     static uint16_t count_changeRPY = 0;
00849     static bool flg_checkoutlier = false;
00850     NVIC_DisableIRQ(USART1_IRQn);
00851     NVIC_DisableIRQ(USART2_IRQn);
00852     NVIC_DisableIRQ(TIM5_IRQn);
00853     NVIC_DisableIRQ(EXTI0_IRQn);
00854     NVIC_DisableIRQ(EXTI9_5_IRQn);
00855 
00856     mpu6050.getRollPitchYaw_Skipper(rpy);
00857  
00858     NVIC_EnableIRQ(USART1_IRQn);
00859     NVIC_EnableIRQ(USART2_IRQn);
00860     NVIC_EnableIRQ(TIM5_IRQn);
00861     NVIC_EnableIRQ(EXTI0_IRQn);
00862     NVIC_EnableIRQ(EXTI9_5_IRQn);
00863     
00864     
00865     //外れ値対策
00866     for(uint8_t i=0; i<3; i++) rpy[i] *= 180.0f/PI;
00867     rpy[ROLL] -= FirstROLL;
00868     rpy[PITCH] -= FirstPITCH;
00869     rpy[YAW] -= FirstYAW;
00870     
00871     for(uint8_t i=0; i<3; i++) {if(rpy[i] < nowAngle[i]-10 || rpy[i] > nowAngle[i]+10) {flg_checkoutlier = true;}}
00872     if(!flg_checkoutlier || count_changeRPY >= 2){
00873         for(uint8_t i=0; i<3; i++){
00874             nowAngle[i] = (rpy[i] + nowAngle[i])/2.0f;  //2つの移動平均
00875         }
00876         count_changeRPY = 0;
00877     }else   count_changeRPY++;
00878     flg_checkoutlier = false;
00879     
00880 }
00881 
00882 float TranslateNewYaw(float beforeYaw,  float newzeroYaw){
00883     float newYaw = beforeYaw - newzeroYaw;
00884     
00885     if(newYaw<-180.0f) newYaw += 360.0f;
00886     else if(newYaw>180.0f) newYaw -= 360.0f;
00887     return newYaw;
00888 }
00889 
00890 
00891 void getSF_Serial(){
00892     
00893         static char SFbuf[16];
00894         static int bufcounter=0;
00895         
00896         SFbuf[bufcounter]=pc.getc();
00897         if(SFbuf[0]=='S'&&bufcounter<5) bufcounter++;
00898             
00899         if(bufcounter==5 && SFbuf[4]=='F'){
00900             g_landingcommand = SFbuf[1];
00901             if(g_landingcommand=='Y' || g_landingcommand=='C')g_SerialTargetYAW = ConvertByteintoFloat(SFbuf[2], SFbuf[3]);
00902             bufcounter = 0;
00903             memset(SFbuf, 0, strlen(SFbuf));
00904             //pc.printf("command = %c, commandYAW = %f\r\n", g_landingcommand, g_SerialTargetYAW); 
00905         }
00906             else if(bufcounter>=5 && SFbuf[4]!='F'){
00907                 //pc.printf("Communication Falsed.\r\n");
00908                 bufcounter = 0;
00909             }
00910     }
00911     
00912 float ConvertByteintoFloat(char high, char low){
00913 
00914         //int16_t intvalue = (int16_t)high*256 + (int16_t)low;
00915         int16_t intvalue = (int16_t)(((int16_t)high << 8) | low);  // Turn the MSB and LSB into a signed 16-bit value
00916         float floatvalue = (float)intvalue;
00917         return floatvalue;
00918 }
00919 
00920 
00921 //超音波割り込み
00922 void UpdateDist(){
00923     g_distance = usensor.get_dist_cm();
00924     usensor.start();
00925 }
00926 
00927 //8の字旋回
00928 void UpdateTargetAngle_Moebius(float targetAngle[3]){
00929     static uint8_t RotateCounter=0;
00930     static uint8_t precounter=0;
00931     static bool flg_setInStartAuto = false;
00932     static float FirstYAW_Moebius = 0.0;
00933     float newYaw_Moebius;
00934 
00935     if(!flg_setInStartAuto && CheckSW_Up(Ch7)){
00936         FirstYAW_Moebius = nowAngle[YAW];
00937         RotateCounter = 0;
00938         flg_setInStartAuto = true;
00939     }else if(!CheckSW_Up(Ch7)){
00940         flg_setInStartAuto = false;
00941         led2 = 0;
00942     }
00943     
00944     newYaw_Moebius = TranslateNewYaw(nowAngle[YAW], FirstYAW_Moebius);
00945 
00946     if(RotateCounter == 0 && newYaw_Moebius >90.0f && newYaw_Moebius < 180.0f){
00947         precounter++;
00948         if(precounter>3){RotateCounter++; led2 = 1; pc.printf("Rotate 90\r\n"); precounter=0;}
00949     }
00950     if(RotateCounter == 1 && newYaw_Moebius >-180.0f && newYaw_Moebius < -90.0f){
00951         precounter++;
00952         if(precounter>3){RotateCounter++; led2 = 0; pc.printf("Rotate 180\r\n"); precounter=0;}
00953     
00954     }
00955     if(RotateCounter == 2 && newYaw_Moebius >-90.0f && newYaw_Moebius < 10.0f){
00956         precounter++;
00957         if(precounter>3){RotateCounter++; led2 = 1; pc.printf("Rotate 270\r\n"); precounter=0;}
00958     }
00959     if(RotateCounter == 3 && newYaw_Moebius >10.0f && newYaw_Moebius < 90.0f){
00960         precounter++;
00961         if(precounter>3){RotateCounter++; led2 = 0; pc.printf("Rotate 360\r\n"); precounter=0;}
00962     }
00963     if(RotateCounter == 4 && newYaw_Moebius >90.0f && newYaw_Moebius < 180.0f){
00964         precounter++;
00965         if(precounter>3){RotateCounter++; led2 = 1; pc.printf("Rotate 90\r\n"); precounter=0;}
00966     }
00967     if(RotateCounter == 5 && newYaw_Moebius >-180.0f && newYaw_Moebius < -90.0f){
00968         precounter++;
00969         if(precounter>3){RotateCounter++; led2 = 0; pc.printf("Rotate 180\r\n"); precounter=0;}
00970     }
00971     if(RotateCounter == 6 && newYaw_Moebius >-90.0f && newYaw_Moebius < 10.0f){
00972         precounter++;
00973         if(precounter>3){RotateCounter++; led2 = 1; pc.printf("Rotate 270\r\n"); precounter=0;}
00974     }
00975     if(RotateCounter == 7 && newYaw_Moebius >10.0f && newYaw_Moebius < 180.0f){
00976         precounter++;
00977         if(precounter>3){RotateCounter++; led2 = 0; pc.printf("Rotate 360\r\n"); precounter=0;}
00978     }
00979     
00980     
00981     if(RotateCounter < 6) UpdateTargetAngle_Rightloop_short(targetAngle);    
00982     else UpdateTargetAngle_Leftloop_short(targetAngle);   //左旋回
00983 }
00984 
00985 //自動滑空
00986 void UpdateTargetAngle_Glide(float targetAngle[3]){
00987     static int THRcount = 0;
00988     static int t_start = 0;
00989     static bool flg_tstart = false;
00990     int t_diff = 0;
00991     static int groundcount = 0;
00992     
00993     targetAngle[ROLL] = g_glideloopROLL;
00994     targetAngle[PITCH] = g_glideloopPITCH;
00995     
00996     //時間計測開始設定
00997     if(!flg_tstart && CheckSW_Up(Ch7)){
00998         t_start = t.read();
00999         flg_tstart = true;
01000         pc.printf("timer start\r\n");
01001     }else if(!CheckSW_Up(Ch7)){
01002         t_start = 0;
01003         flg_tstart = false;
01004     }
01005 
01006 
01007     //フラグが偽であれば計測は行わない    
01008     if(flg_tstart){
01009         t_diff = t.read() - t_start;
01010         //一定高度or15秒でled点灯
01011         if((groundcount>5 && g_distance>0) || t_diff > 15){
01012             led2 = 1;
01013             //pc.printf("Call [Stop!] calling!\r\n");
01014         }
01015         if(g_distance<180 && g_distance > 0) groundcount++;
01016     }else{
01017         t_diff = 0;
01018         groundcount = 0;
01019         led2 = 0;
01020     }
01021     
01022     if(t_diff > 17){
01023         autopwm[THR] = SetTHRinRatio(0.5);
01024     }else{
01025         if(g_distance<150 && g_distance>0 ){
01026             THRcount++;
01027             if(THRcount>5){
01028                 autopwm[THR] = SetTHRinRatio(0.6);
01029                 //pc.printf("throttle ON\r\n");
01030             }
01031         }else{
01032             autopwm[THR] = 1180;
01033             THRcount = 0;
01034         }
01035     }
01036 }
01037 
01038 //離陸-投下-着陸一連
01039 void Take_off_and_landing(float targetAngle[3]){
01040     if(!CheckSW_Up(Ch7)) bombing_mode = Takeoff;
01041     
01042     switch(bombing_mode){
01043         case Takeoff:
01044             static bool flg_setFirstYaw = false;
01045             static int TakeoffCount = 0;
01046 
01047             if(!flg_setFirstYaw && CheckSW_Up(Ch7)){
01048                 FirstYAW = nowAngle[YAW] + FirstYAW;
01049                 flg_setFirstYaw = true;
01050             }else if(flg_setFirstYaw && !CheckSW_Up(Ch7)){
01051                 flg_setFirstYaw = false;
01052             }
01053             
01054             UpdateTargetAngle_Takeoff(targetAngle);
01055             
01056             if(g_distance>150) TakeoffCount++;
01057             else TakeoffCount = 0;
01058             if(TakeoffCount>5){
01059                 led2=1;
01060                 autopwm[THR] = SetTHRinRatio(g_loopTHR);
01061                 pc.printf("Now go to Approach mode!!");
01062                 bombing_mode = Approach;
01063                 led2=0;
01064             }
01065             
01066             break;
01067         /*    
01068         case Chicken:    
01069             break;
01070         */    
01071         case Transition:
01072             /*
01073             static int ApproachCount = 0;
01074             targetAngle[YAW]=180.0;
01075             int Judge = Rotate(targetAngle, g_SerialTargetYAW);
01076             
01077             if(Judge==0) ApproachCount++;
01078             if(ApproachCount>5) bombing_mode = Approach;
01079             */
01080             break;
01081             
01082         case Approach:
01083             UpdateTargetAngle_Approach(targetAngle);
01084             break;
01085             
01086         default:
01087             bombing_mode = Takeoff;
01088             break;    
01089     }
01090 }
01091 
01092 //離陸モード
01093 void UpdateTargetAngle_Takeoff(float targetAngle[3]){
01094     static int tELE_start = 0;
01095     static bool flg_ELEup = false;
01096     int t_def = 0;
01097     if(!flg_ELEup && CheckSW_Up(Ch7)){
01098         tELE_start = t.read_ms();
01099         flg_ELEup = true;
01100         pc.printf("timer start\r\n");
01101     }else if(!CheckSW_Up(Ch7)){
01102         tELE_start = 0;
01103         flg_ELEup = false;
01104     }
01105     if(flg_ELEup){
01106         t_def = t.read_ms() - tELE_start;
01107         
01108         //1.5秒経過すればELE上げ舵へ
01109         if(t_def>500) targetAngle[PITCH]=-25.0;
01110         else{
01111             t_def = 0;
01112             targetAngle[PITCH]=g_gostraightPITCH;
01113         }
01114     }
01115     autopwm[THR] = SetTHRinRatio(g_takeoffTHR); //0.7;スロットルの割合
01116     targetAngle[ROLL] = 3.5;
01117 /*
01118     //pc.printf("%d \r\n",g_distance);
01119     targetAngle[ROLL] = g_gostraightROLL;
01120     if UptargetAngle[PITCH] = -10.0;
01121     autopwm[THR] = SetTHRinRatio(g_takeoffTHR); //0.7;スロットルの割合
01122 */
01123 }
01124 
01125 //ヨーを目標値にして許容角度になるまで水平旋回
01126 char Rotate(float targetAngle[3], float TargetYAW, char mode){
01127     float diffYaw = TranslateNewYaw(TargetYAW, nowAngle[YAW]);
01128 
01129     switch(mode){
01130         case 'G': //直進
01131             UpdateTargetAngle_GoStraight(targetAngle);
01132             if(diffYaw > LIMIT_STRAIGHT_YAW)        mode = 'R';
01133             else if(diffYaw < -LIMIT_STRAIGHT_YAW)  mode = 'L';
01134             break;
01135             
01136         case 'R': //右旋回
01137             UpdateTargetAngle_Rightloop_short(targetAngle);
01138             if(diffYaw < LIMIT_LOOPSTOP_YAW && diffYaw > -LIMIT_STRAIGHT_YAW)   mode = 'G';
01139             break;
01140             
01141         case 'L': //左旋回
01142             UpdateTargetAngle_Leftloop_short(targetAngle);
01143             if(diffYaw > -LIMIT_LOOPSTOP_YAW && diffYaw < LIMIT_STRAIGHT_YAW)   mode = 'G';
01144             break;
01145     }
01146     
01147     return mode;
01148     
01149 /*
01150     if(diffYaw > LIMIT_STRAIGHT_YAW){
01151         UpdateTargetAngle_Rightloop_short(targetAngle);
01152         return 1;
01153     }else if(diffYaw < -LIMIT_STRAIGHT_YAW){
01154         UpdateTargetAngle_Leftloop_short(targetAngle);
01155         return 1;
01156     }else{
01157         UpdateTargetAngle_GoStraight(targetAngle);
01158         return 0;
01159     }
01160 */
01161 }
01162 
01163 //チキラー投下
01164 void Chicken_Drop(){
01165     if(CheckSW_Up(Ch7)){
01166         autopwm[DROP] = 1572;
01167         pc.printf("Bombed!\r\n");
01168         RerurnChickenServo1.attach(&ReturnChickenServo1, 3);
01169         //operation_mode = Approach;
01170         //buzzer = 0;
01171     }
01172 }
01173 
01174 void ReturnChickenServo1(){
01175     autopwm[DROP] = 1438;
01176     pc.printf("first reverse\r\n");
01177     RerurnChickenServo2.attach(&ReturnChickenServo2, 1);
01178 }
01179 
01180 void ReturnChickenServo2(){
01181     autopwm[DROP] = 1446;
01182     pc.printf("second reverse\r\n");
01183 }
01184 
01185 //着陸モード(PCからの指令に従う)
01186 void UpdateTargetAngle_Approach(float targetAngle[3]){
01187     static char rotatemode = 'G';
01188     if(output_status == Manual) rotatemode = 'G';    
01189 
01190     //pc.putc(g_landingcommand);
01191     switch(g_landingcommand){
01192         case 'R':   //右旋回セヨ
01193             UpdateTargetAngle_Rightloop(targetAngle);
01194             break;
01195             
01196         case 'L':   //左旋回セヨ
01197             UpdateTargetAngle_Leftloop(targetAngle);
01198             break;
01199             
01200         case 'G':   //直進セヨ
01201             UpdateTargetAngle_GoStraight(targetAngle);
01202             break;
01203         
01204         case 'Y':   //指定ノヨー方向ニ移動セヨ
01205             rotatemode = Rotate(targetAngle, g_SerialTargetYAW, rotatemode);
01206             break;
01207         
01208         case 'B':   //ブザーヲ鳴ラセ
01209             //buzzer = 1;
01210             break;
01211             
01212         case 'D':   //物資ヲ落トセ
01213             Chicken_Drop();
01214             break;
01215                     
01216         case 'C':   //停止セヨ
01217             rotatemode = Rotate(targetAngle, g_SerialTargetYAW, rotatemode);
01218             autopwm[THR] = minpwm[THR];
01219             break;
01220     }
01221 }
01222 
01223 void checkHeight(float targetAngle[3]){
01224     
01225     static int targetHeight = 200; 
01226     
01227     if(g_distance < targetHeight + ALLOWHEIGHT){
01228         UpdateTargetAngle_NoseUP(targetAngle);
01229         if(CheckSW_Up(Ch7)) led2 = 1;
01230     }
01231     else if(g_distance > targetHeight - ALLOWHEIGHT){
01232         UpdateTargetAngle_NoseDOWN(targetAngle);
01233         if(CheckSW_Up(Ch7)) led2 = 1;
01234     }
01235     else led2=0;
01236 }
01237 
01238 void UpdateTargetAngle_NoseUP(float targetAngle[3]){
01239     
01240     //targetAngle[PITCH] += 2.0f;
01241     //if(nowAngle[PITCH]<targetAngle[PITCH]) autopwm[THR] = SetTHRinRatio(0.6);
01242     autopwm[THR] = SetTHRinRatio(g_loopTHR+0.05f);
01243     //pc.printf("nose UP");
01244 }
01245 
01246 void UpdateTargetAngle_NoseDOWN(float targetAngle[3]){
01247     
01248     //targetAngle[PITCH] -= 2.0f;
01249     autopwm[THR] = SetTHRinRatio(g_loopTHR-0.05f);
01250     //pc.printf("nose DOWN");
01251 }
01252 
01253 //直進
01254 void UpdateTargetAngle_GoStraight(float targetAngle[3]){
01255 
01256     targetAngle[ROLL] = g_gostraightROLL;
01257     targetAngle[PITCH] = g_gostraightPITCH;
01258     autopwm[THR] = SetTHRinRatio(g_loopTHR);
01259     
01260     //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
01261 }
01262 
01263 //右旋回
01264 void UpdateTargetAngle_Rightloop(float targetAngle[3]){ //右旋回
01265 
01266     targetAngle[ROLL] = g_rightloopROLL;
01267     targetAngle[PITCH] = g_rightloopPITCH ;
01268     autopwm[THR] = SetTHRinRatio(g_loopTHR);
01269     //checkHeight(targetAngle);
01270     //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
01271 }
01272 
01273 void UpdateTargetAngle_Rightloop_short(float targetAngle[3]){ //右旋回
01274 
01275     targetAngle[ROLL] = g_rightloopROLLshort;
01276     targetAngle[PITCH] = g_rightloopPITCHshort;
01277     autopwm[THR] = SetTHRinRatio(g_loopTHR);
01278     
01279     
01280     //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
01281 }
01282 
01283 //左旋回
01284 void UpdateTargetAngle_Leftloop(float targetAngle[3]){
01285     
01286     targetAngle[ROLL] = g_leftloopROLL;
01287     targetAngle[PITCH] = g_leftloopPITCH;
01288     autopwm[THR] = SetTHRinRatio(g_loopTHR);
01289     //checkHeight(targetAngle);
01290 
01291     //printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
01292 }
01293 
01294 void UpdateTargetAngle_Leftloop_short(float targetAngle[3]){
01295     
01296     targetAngle[ROLL] = g_leftloopROLLshort;
01297     targetAngle[PITCH] = g_leftloopPITCHshort;
01298     autopwm[THR] = SetTHRinRatio(g_loopTHR);
01299     
01300     //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
01301 }
01302 
01303 //デバッグ用
01304 void DebugPrint(){    
01305     /*
01306     static int16_t deltaT = 0, t_start = 0;
01307     deltaT = t.read_u2s() - t_start;
01308     pc.printf("t:%d us, ",deltaT);
01309     pc.printf("\r\n");
01310     t_start = t.read_us();
01311     */
01312     
01313     //pc.printf("%d", sbus.manualpwm[4]);
01314     
01315     //for(uint8_t i=0; i<8; i++) pc.printf("%d ",sbus.manualpwm[i]);
01316     //for(uint8_t i=1; i<5; i++) pc.printf("%d ",sbus.manualpwm[i]);
01317     //pc.printf("\r\n");
01318     //for(uint8_t i=0; i<3; i++) pc.printf("%3.2f\t",nowAngle[i]);
01319     //for(uint8_t i=0; i<2; i++) pc.printf("%3.2f\t",nowAngle[i]); //ロール、ピッチのみ 小数点以下2ケタ
01320     //pc.printf("%d\t",autopwm[ELE]);  pc.printf("%d\t",autopwm[RUD]);
01321     //pc.printf("%d",g_distance);
01322 
01323     //pc.printf("Mode: %c: ",g_buf[0]);
01324     //if(g_buf[0] == 'Y') pc.printf(" %3.1f",g_SerialTargetYAW);
01325     //pc.printf("%x ",sbus.failsafe_status);
01326     
01327     //pc.printf("\r\n");
01328 }