a

Dependencies:   HCSR04_2 MPU6050_2 mbed SDFileSystem3

Fork of Autoflight2018_12 by 航空研究会

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