test

Dependencies:   BMP280 HCSR04_from_mtmt MPU6050_2 mbed SDFileSystem3

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 "MPU9250_BMP.h"
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 1
00023 
00024 #define KP_ELE 16.5//15.0  //2.0
00025 #define KI_ELE 0.0
00026 #define KD_ELE 0.1  //0/0
00027 #define KP_RUD 3.0
00028 #define KI_RUD 0.0
00029 #define KD_RUD 0.0
00030 #define KP_AIL 0.11//0.1
00031 #define KI_AIL 0.2
00032 #define KD_AIL 0.2
00033 
00034 //#define g_AIL_L_Ratio_rightloop 0.5
00035 
00036 #define GAIN_CONTROLVALUE_TO_PWM 3.0
00037 
00038 #define RIGHT_ROLL 5.0//10
00039 #define RIGHT_PITCH 45//-20.0//-22//-24.0  //5.0
00040 #define LEFT_ROLL 15//-38.0//30
00041 
00042 #define LEFT_PITCH 10//-15.0
00043 #define STRAIGHT_ROLL 0//12.0//8.0
00044 #define STRAIGHT_PITCH 3.0
00045 #define TAKEOFF_THR 0.8
00046 #define LOOP_THR 0.6
00047 
00048 //#define g_rightloopRUD 1500
00049 
00050 #define RIGHT_ROLL_SHORT 10.0
00051 #define RIGHT_PITCH_SHORT -25.0
00052 #define LEFT_ROLL_SHORT -30.0
00053 #define LEFT_PITCH_SHORT -20.0
00054 #define RIGHTLOOPROLL_APPROACH 10.0
00055 #define LEFTLOOPROLL_APPROACH -30.0
00056 #define RIGHTLOOPPITCH_APPROACH -25.0
00057 #define LEFTLOOPPITCH_APPROACH -30.0
00058 
00059 #define ASCENDING_PITCH -35.0
00060 #define TAKE_OFF_THROTTLE 1650
00061 #define TAKE_OFF_PITCH 50//-40.0
00062 
00063 #define rightloopROLL2 -10.0
00064 
00065 /*#define rightloopRUD 1300  //1250
00066 #define rightloopshortRUD 1250
00067 #define leftloopRUD  1500
00068 #define leftloopshortRUD 1500
00069 #define glideloopRUD 1300
00070 */
00071 #define AIL_R_correctionrightloop 0
00072 #define AIL_L_correctionrightloop 0
00073 #define AIL_L_correctionrightloopshort 0
00074 #define AIL_L_correctionleftloop -0
00075 #define AIL_L_correctionleftloopshort 0
00076 
00077 
00078 #define RIGHTLOOP_RUD 1190//1150 //1200
00079 #define RIGHTLOOPSHORT_RUD 1250
00080 #define LEFTLOOP_RUD 1560 //1680//1750//1700
00081 #define LEFTLOOPSHORT_RUD 1500
00082 #define GLIDELOOP_RUD 1300
00083 #define RIGHTLOOPRUD_APPROACH 1500
00084 #define LEFTLOOPRUD_APPROACH  1500
00085 #define RIGHTLOOP_THR_RATE 0.64//0.66
00086 #define LEFTLOOP_THR_RATE 0.49//0.62//0.66
00087 #define ASCENDING_THR_RATE 0.75
00088 #define ASCENDING_ROLL 16.0
00089 #define ASCENDING_RUD 1200
00090 
00091 
00092 #define AIL_L_CORRECTION_RIGHTLOOP 0
00093 #define AIL_L_CORRECTION_RIGHTLOOPSHORT 0
00094 #define AIL_L_CORRECTION_LEFTLOOP 0
00095 #define AIL_L_CORRECTION_LEFTLOOPSHORT 0
00096 
00097 
00098 
00099 #define TRIM1 1590
00100 #define TRIM2 1579
00101 #define TRIM3 1177
00102 #define TRIM4 1392
00103 #define TRIM5 1176
00104 #define TRIM6 1560
00105 #define TRIM_CHECK 0
00106 
00107 #define GLIDE_ROLL -12.0
00108 #define GLIDE_PITCH -3.0
00109 
00110 
00111 #define AIL_L_RatioRising 0.5
00112 #define AIL_L_RatioDescent 2
00113 
00114 //コンパスキャリブレーション
00115 //SkipperS2基板
00116 /*
00117 #define MAGBIAS_X -35.0
00118 #define MAGBIAS_Y 535.0
00119 #define MAGBIAS_Z -50.0
00120 */
00121 //S2v2 1番基板
00122 #define MAGBIAS_X 395.0
00123 #define MAGBIAS_Y 505.0
00124 #define MAGBIAS_Z -725.0
00125 //S2v2 2番基板
00126 /*
00127 #define MAGBIAS_X 185.0
00128 #define MAGBIAS_Y 220.0
00129 #define MAGBIAS_Z -350.0
00130 */
00131 
00132 #define ELEMENT 1
00133 #define LIMIT_STRAIGHT_YAW 5.0
00134 #define THRESHOLD_TURNINGRADIUS_YAW 60.0
00135 #define ALLOWHEIGHT 15
00136 
00137 //気圧用
00138 #define SBUS_SIGNAL_OK          0x00
00139 #define SBUS_SIGNAL_LOST        0x01
00140 #define SBUS_SIGNAL_FAILSAFE    0x03
00141 MPU9250 mpu9250;
00142 float g_sum = 0;      //グローバルなので要注意!!
00143 uint32_t g_sumCount = 0;
00144 float g_grav = 9.80665;
00145 float g_st_press = 1018.5;
00146 float g_press, g_BMPheight;
00147 int g_BMPheight_int = 0;
00148 float g_InitPress[101];
00149 float g_InitPressAve = 0;
00150 float g_InitBMPHeight[101];
00151 float g_InitBMPHeightAve = 0;
00152 int g_temporary;
00153 float g_dt = 0.0;
00154 float g_v_prev = 0.0;
00155 float g_z_prev; 
00156 float g_z_PressHeight, g_z_AccelHeight;
00157 float g_z_comp;
00158 float g_tempaz[2];
00159 
00160 BMP280 bmp(PC_9, PA_8);
00161 Timer tBMP;
00162 
00163 
00164 #ifndef PI
00165 #define PI 3.14159265358979
00166 #endif
00167 
00168 const int16_t lengthdivpwm = 320;
00169 const int16_t changeModeCount = 6;
00170 
00171 
00172 SBUS sbus(PA_9, PA_10); //SBUS
00173 
00174 PwmOut servo1(PC_6); // TIM3_CH1  //old echo
00175 PwmOut servo2(PC_7); // TIM3_CH2    //PC_7
00176 PwmOut servo3(PB_0); // TIM3_CH3
00177 PwmOut servo4(PB_1); // TIM3_CH4
00178 PwmOut servo5(PB_6); // TIM4_CH1
00179 PwmOut servo6(PB_7); // TIM4_CH2  //old trigger
00180 //PwmOut servo7(PB_8); // TIM4_CH3    //PB_8 new echo
00181 //PwmOut servo8(PB_9); // TIM4_CH4   //new trigger
00182 
00183 RawSerial pc(PA_2,PA_3, 115200);    //tx,rx.baudrate pin;PA_2=UART2_TX, PA_3=UART2_RX
00184 //RawSerial pc2(PB_6,PB_7, 115200);   //sbus確認用
00185 SDFileSystem sd(PB_15, PB_14, PB_13, PB_12, "sd");
00186 
00187 DigitalOut led1(PA_0);  //黄色のコネクタ
00188 DigitalOut led2(PA_1);
00189 DigitalOut led3(PB_5);
00190 DigitalOut led4(PB_4);
00191 
00192 //InterruptIn switch2(PC_14);
00193 MPU6050DMP6 mpu6050(PC_0,&pc); //割り込みピン,シリアルポインタ i2cのピン指定は MPU6050>>I2Cdev.h 内のdefine
00194 HCSR04 usensor(PB_9,PB_8); //trig,echo  9,8
00195 
00196 PID pid_AIL(g_kpAIL,g_kiAIL,g_kdAIL);
00197 PID pid_ELE(g_kpELE,g_kiELE,g_kdELE);
00198 PID pid_RUD(g_kpRUD,g_kiRUD,g_kdRUD);
00199 
00200 enum Channel {AIL_R, ELE, THR, RUD, DROP, AIL_L, Ch7, Ch8};
00201 enum Angle {ROLL, PITCH, YAW};  //yaw:北を0とした絶対角度
00202 enum OperationMode {StartUp, SemiAuto, RightLoop, LeftLoop, GoStraight, BombwithPC, ZERO, Moebius, Glide};
00203 enum BombingMode {Takeoff, Chicken, Transition, Approach};
00204 enum OutputStatus {Manual, Auto};
00205 
00206 static OutputStatus output_status = Manual;
00207 OperationMode operation_mode = StartUp;
00208 BombingMode bombing_mode = Takeoff;
00209 
00210 static int16_t autopwm[8] = {1590,1579,1177,1392,1176,1560,1178,1178};//6:1848
00211 
00212 //1号機14SG
00213 
00214 static int16_t trimpwm[6] = {1590,1579,1177,1392,1176,1560};//1500
00215 int16_t maxpwm[6] = {1921,1895,1848,1728,1780,1891};
00216 int16_t minpwm[6] = {1249,1234,1177,1056,1176,1219};
00217 const int16_t reverce[4] = {Reverce_falfalla[0],Reverce_falfalla[1],Reverce_falfalla[2],Reverce_falfalla[3]};
00218 
00219 
00220 //2号機
00221 /*
00222 static int16_t trimpwm[6] = {1508,1559,1184,1664,1072,1952};
00223 int16_t maxpwm[6] = {1840,1884,1840,1992,1728,1952};
00224 int16_t minpwm[6] = {1183,1228,1176,1420,1420,1072};
00225 const int16_t reverce[4] = {Reverce_falfalla[0],Reverce_falfalla[1],Reverce_falfalla[2],Reverce_falfalla[3]};
00226 */
00227 
00228 int16_t oldTHR = 1000;
00229 
00230 int16_t g_AIL_L_Ratio_rightloop = 0.5;
00231 
00232 
00233 static float nowAngle[3] = {0,0,0};
00234 const float trimAngle[3] = {0.0, 0.0, 0.0};
00235 const float maxAngle[2] = {90, 90};
00236 const float minAngle[2] = {-90, -90};
00237 
00238 float FirstROLL = 0.0, FirstPITCH = 0.0,FirstYAW = 0.0;
00239 
00240 unsigned int g_distance;
00241 Ticker USsensor;
00242 static char g_buf[16];
00243 char g_landingcommand='T';
00244 float g_SerialTargetYAW;
00245 
00246 
00247 Timer t;
00248 Timer t2;
00249 Timeout RerurnChickenServo1;
00250 Timeout RerurnChickenServo2;
00251 
00252 /*-----関数のプロトタイプ宣言-----*/
00253 void setup();
00254 void loop();
00255 
00256 void Init_PWM();
00257 void Init_servo();              //サーボ初期化
00258 void Init_sbus();               //SBUS初期化
00259 void Init_sensors();
00260 void DisplayClock();            //クロック状態確認
00261 void SetupBMP280();
00262 void Set_trim();
00263 
00264 //センサの値取得
00265 void SensingMPU();
00266 void UpdateDist();
00267 void sensing();
00268 void getBMP280();
00269 
00270 //void offsetRollPitch(float FirstROLL, float FirstPITCH);
00271 //void TransYaw(float FirstYAW);
00272 float TranslateNewYaw(float beforeYaw,  float newzeroYaw);
00273 void UpdateTargetAngle(float targetAngle[3]);
00274 void CalculateControlValue(float targetAngle[3], float controlValue[3]);
00275 void UpdateAutoPWM(float controlValue[3]);
00276 void ConvertPWMintoRAD(float targetAngle[3]);
00277 inline float CalcRatio(float value, float trim, float limit);
00278 bool CheckSW_Up(Channel ch);
00279 int16_t ThresholdMaxMin(int16_t value, int16_t max, int16_t min);
00280 inline int16_t SetTHRinRatio(float ratio);
00281 void Ascending(float targetAngle[3]);
00282 
00283 //sbus割り込み
00284 void Update_PWM();              //マニュアル・自動モードのpwmデータを整形しpwm変数に入力
00285 void Output_PWM(int16_t pwm[6]);    //pwmをサーボへ出力
00286 
00287 //シリアル割り込み
00288 void getSF_Serial();
00289 float ConvertByteintoFloat(char high, char low);
00290 
00291 bool g_Finflag = false;
00292 
00293 
00294 //SD設定
00295 int GetParameter(FILE *fp, const char *paramName,char parameter[]);
00296 int SetOptions(float *g_kpELE, float *g_kiELE, float *g_kdELE,
00297                float *g_kpRUD, float *g_kiRUD, float *g_kdRUD,
00298                float *g_rightloopROLL, float *g_rightloopPITCH,
00299                float *g_leftloopROLL, float *g_leftloopPITCH,
00300                float *g_gostraightROLL, float *g_gostraightPITCH,
00301                float *g_takeoffTHR, float *g_loopTHR,
00302                float *g_rightloopROLLshort, float *g_rightloopPITCHshort,
00303                float *g_leftloopROLLshort, float *g_leftloopPITCHshort,
00304                float *g_glideloopROLL, float *g_glideloopPITCH,
00305                float *g_kpAIL, float *g_kiAIL, float *g_kdAIL,
00306                int *g_rightloopRUD, int *g_rightloopshortRUD,
00307                int *g_leftloopRUD, int *g_leftloopshortRUD,
00308                int *g_glideRUD,
00309                float *g_rightloopROLL_approach, float *g_leftloopROLL_approach,
00310                int *g_rightloopRUD_approach, int *g_leftloopRUD_approach,
00311                float *g_rightloopPITCH_approach, float *g_leftloopPITCH_approach,
00312                float *g_ascendingPITCH,
00313                int *g_take_off_THROTTLE, float *g_take_off_PITCH,
00314                float *g_rightloop_THR_rate, float *g_leftloop_THR_rate,
00315                float *g_ascendding_thr_rate, 
00316                float *g_ascending_ROLL, int *g_ascending_RUD,
00317                int *g_trim1, int *g_trim2, int *g_trim3,
00318                int *g_trim4, int *g_trim5, int *g_trim6,
00319                bool *g_trim_check
00320               );
00321 //switch2割り込み
00322 void ResetTrim();
00323 
00324 //自動操縦
00325 void UpdateTargetAngle_GoStraight(float targetAngle[3]);
00326 void UpdateTargetAngle_GoStraight_zero(float targetAngle[3]);       //着陸時にスロットルが0の時の直進
00327 void UpdateTargetAngle_Rightloop(float targetAngle[3]);
00328 void UpdateTargetAngle_Rightloop_short(float targetAngle[3]);
00329 void UpdateTargetAngle_Rightloop_zero(float targetAngle[3]);      //着陸時にスロットルが0の時の右旋回
00330 void UpdateTargetAngle_Rightloop_UP(float targetAngle[3]);
00331 void UpdateTargetAngle_Leftloop(float targetAngle[3]);
00332 void UpdateTargetAngle_Leftloop_short(float targetAngle[3]);
00333 void UpdateTargetAngle_Leftloop_zero(float targetAngle[3]);     //着陸時にスロットルが0の時の左旋回
00334 void UpdateTargetAngle_Moebius(float targetAngle[3]);
00335 void UpdateTargetAngle_Takeoff(float targetAngle[3]);
00336 void UpdateTargetAngle_Approach(float targetAngle[3]);
00337 void Take_off_and_landing(float targetAngle[3]);
00338 
00339 
00340 
00341 int Rotate(float targetAngle[3], float TargetYAW);
00342 int Rotate_zero(float targetAngle[3], float TargetYAW);
00343 
00344 //投下
00345 void Chicken_Drop();
00346 void ReturnChickenServo1();
00347 void ReturnChickenServo2();
00348 
00349 //超音波による高度補正
00350 void checkHeight(float targetAngle[3]);
00351 void UpdateTargetAngle_NoseUP(float targetAngle[3]);
00352 void UpdateTargetAngle_NoseDOWN(float targetAngle[3]);
00353 
00354 //デバッグ用
00355 void Sbusprintf();
00356 void DebugPrint();
00357 
00358 /*---関数のプロトタイプ宣言終わり---*/
00359 
00360 int main()
00361 {
00362     setup();
00363 
00364 
00365     while(1) {
00366 
00367         loop();
00368 
00369 
00370         NVIC_DisableIRQ(USART1_IRQn);
00371         if(!CheckSW_Up(Ch7)) {
00372             led3=0;
00373 
00374         } else {
00375             led3=1;
00376         }
00377         NVIC_EnableIRQ(USART1_IRQn);
00378     }
00379 
00380 }
00381 
00382 void setup()
00383 {
00384     //buzzer = 0;
00385     led1 = 1;
00386     led2 = 1;
00387     led3 = 1;
00388     led4 = 1;
00389 
00390     SetOptions(&g_kpELE, &g_kiELE, &g_kdELE,
00391                &g_kpRUD, &g_kiRUD, &g_kdRUD,
00392                &g_rightloopROLL, &g_rightloopPITCH,
00393                &g_leftloopROLL, &g_leftloopPITCH,
00394                &g_gostraightROLL, &g_gostraightPITCH,
00395                &g_takeoffTHR, &g_loopTHR,
00396                &g_rightloopROLLshort, &g_rightloopPITCHshort,
00397                &g_leftloopROLLshort, &g_leftloopPITCHshort,
00398                &g_glideloopROLL, &g_glideloopPITCH,
00399                &g_kpAIL, &g_kiAIL,&g_kdAIL,
00400                &g_rightloopRUD, &g_rightloopshortRUD,
00401                &g_leftloopRUD, &g_leftloopshortRUD,
00402                &g_glideloopRUD,
00403                &g_rightloopROLL_approach,&g_leftloopROLL_approach,
00404                &g_rightloopRUD_approach,&g_leftloopRUD_approach,
00405                &g_rightloopPITCH_approach,&g_leftloopPITCH_approach,
00406                &g_ascendingPITCH,
00407                &g_take_off_THROTTLE, &g_take_off_PITCH,
00408                &g_rightloop_THR_rate, &g_leftloop_THR_rate,
00409                &g_ascending_THR_rate, 
00410                &g_ascending_ROLL, &g_ascending_RUD,
00411                &g_trim1, &g_trim2, &g_trim3,
00412                &g_trim4, &g_trim5, &g_trim6,
00413                &g_trim_check
00414               );
00415               
00416     Set_trim();
00417         
00418 
00419 
00420     Init_PWM();
00421     Init_servo();
00422     Init_sbus();
00423     Init_sensors();
00424     //switch2.rise(ResetTrim);
00425 
00426     USsensor.attach(&UpdateDist, 0.05);
00427 
00428     NVIC_SetPriority(USART1_IRQn,0);//プロポ
00429     NVIC_SetPriority(EXTI0_IRQn,1);//MPU割り込み禁止
00430     NVIC_SetPriority(TIM5_IRQn,2);
00431     NVIC_SetPriority(EXTI9_5_IRQn,3);
00432     NVIC_SetPriority(EXTI4_IRQn,5);
00433     DisplayClock();
00434     t.start();
00435     t.start();
00436 
00437 
00438     pc.printf("MPU calibration start\r\n");
00439 
00440     float offsetstart = t.read();
00441     while(t.read() - offsetstart < 26) {
00442         SensingMPU();
00443         for(uint8_t i=0; i<3; i++) pc.printf("%3.2f\t",nowAngle[i]);
00444         pc.printf("\r\n");
00445         led1 = !led1;
00446         led2 = !led2;
00447         led3 = !led3;
00448         led4 = !led4;
00449     }
00450     //pc.attach(getSF_Serial, Serial::RxIrq);
00451     NVIC_SetPriority(USART2_IRQn,4);//シリアル
00452 
00453     FirstROLL = nowAngle[ROLL];
00454     FirstPITCH = nowAngle[PITCH];
00455     nowAngle[ROLL] -=FirstROLL;
00456     nowAngle[PITCH] -=FirstPITCH;
00457     
00458     SetupBMP280();
00459     
00460 //    NVIC_EnableIRQ(USART2_IRQn);
00461 //    
00462 //    if(pc.readable()) {    // 受信確認
00463 //        
00464 //        static char SFbuf[16]= {'Q','Q','Q','Q','Q','Q','Q','Q','Q','Q','Q','Q','Q','Q','Q','Q'}; 
00465 //        SFbuf[0] = pc.getc();    // 1文字取り出し
00466 //        if(SFbuf[0]=='S') {
00467 //            for(int i=0;i<3;i++){
00468 //                led1 = 1;
00469 //                led2 = 1;
00470 //                led3 = 1;
00471 //                led4 = 1;
00472 //                wait(0.2);
00473 //            }
00474 //        }
00475 //    }
00476 //    NVIC_DisableIRQ(USART2_IRQn);
00477 
00478 
00479     led1 = 0;
00480     led2 = 0;
00481     led3 = 0;
00482     led4 = 0;
00483     wait(0.2);
00484 
00485 
00486     pc.printf("All initialized\r\n");
00487 }
00488 
00489 void Set_trim(){
00490     trimpwm[0] = g_trim1;
00491     trimpwm[1] = g_trim2;
00492     trimpwm[2] = g_trim3;
00493     trimpwm[3] = g_trim4;
00494     trimpwm[4] = g_trim5;
00495     trimpwm[5] = g_trim6;
00496     
00497     maxpwm[0] = 1920;//trimpwm[0] + 330;1768
00498     maxpwm[1] = 1909;//trimpwm[1] + 330;1964
00499     maxpwm[2] = 1833;//trimpwm[2] + 660;1848
00500     maxpwm[3] = 1722;//trimpwm[3] + 330;1825
00501     maxpwm[4] = 1836;//trimpwm[4] + 660;1914
00502     maxpwm[5] = 1890;//trimpwm[5] + 330;1816
00503     
00504     minpwm[0]= 1260;//trimpwm[0] - 330;1186
00505     minpwm[1]= 1249;//trimpwm[1] - 330;1314
00506     minpwm[2]= trimpwm[2] - 0;
00507     minpwm[3]= 1062;//trimpwm[3] - 330;1154
00508     minpwm[4]= 1176;//trimpwm[4] - 0;1344
00509     minpwm[5]= 846;//trimpwm[5] - 330;1144
00510 }
00511 
00512 void loop()
00513 {
00514     static float targetAngle[3] = {0.0, 0.0, 0.0}, controlValue[2] = {0.0, 0.0};
00515     SensingMPU();
00516     UpdateTargetAngle(targetAngle);
00517     CalculateControlValue(targetAngle, controlValue);
00518     UpdateAutoPWM(controlValue);
00519     
00520 
00521     //NVIC_SetPriority(TIM5_IRQn,4);
00522     //NVIC_SetPriority(USART2_IRQn,2);
00523 
00524     //wait_ms(23);
00525     wait_ms(30);
00526 
00527     //NVIC_SetPriority(TIM5_IRQn,2);
00528     //NVIC_SetPriority(USART2_IRQn,4);
00529 
00530 
00531     // pc.printf("6\r\n");
00532     //NVIC_DisableIRQ(USART2_IRQn);
00533     //pc.printf("%c",g_landingcommand);
00534     //NVIC_EnableIRQ(USART2_IRQn);
00535 #if DEBUG_PRINT_INLOOP
00536     //Sbusprintf();
00537     DebugPrint();
00538 #endif
00539 }
00540 
00541 //サーボ初期化関数
00542 void Init_servo()
00543 {
00544     servo1.period_ms(16);
00545     servo1.pulsewidth_us(trimpwm[AIL_R]);
00546 
00547     servo2.period_ms(16);
00548     servo2.pulsewidth_us(trimpwm[ELE]);
00549 
00550     servo3.period_ms(16);
00551     servo3.pulsewidth_us(trimpwm[THR]);
00552 
00553     servo4.period_ms(16);
00554     servo4.pulsewidth_us(trimpwm[RUD]);
00555 
00556     servo5.period_ms(16);
00557     servo5.pulsewidth_us(trimpwm[DROP]);
00558 
00559     servo6.period_ms(16);
00560     servo6.pulsewidth_us(trimpwm[AIL_L]);
00561     
00562     int i = 0;
00563     
00564     for(i = 0;i<6;i++ ){
00565         autopwm[i]=trimpwm[i];
00566         }
00567 
00568     pc.printf("servo initialized\r\n");
00569 }
00570 
00571 //Sbus初期化
00572 void Init_sbus()
00573 {
00574     sbus.initialize();
00575     sbus.setLastfuncPoint(Update_PWM);
00576     sbus.startInterrupt();
00577 }
00578 
00579 void Init_sensors()
00580 {
00581     if(mpu6050.setup() == -1) {
00582         pc.printf("failed initialize\r\n");
00583         while(1) {
00584             led1 = 1;
00585             led2 = 0;
00586             led3 = 1;
00587             led4 = 0;
00588             wait(1);
00589             led1 = 0;
00590             led2 = 1;
00591             led3 = 0;
00592             led4 = 1;
00593             wait(1);
00594         }
00595     }
00596 }
00597 
00598 void Init_PWM()
00599 {
00600     pc.printf("PWM initialized\r\n");
00601 }
00602 
00603 void DisplayClock()
00604 {
00605     pc.printf("System Clock = %d[MHz]\r\n", HAL_RCC_GetSysClockFreq()/1000000);
00606     pc.printf("HCLK Clock   = %d[MHz]\r\n", HAL_RCC_GetHCLKFreq()/1000000);
00607     pc.printf("PCLK1 Clock  = %d[MHz]\r\n", HAL_RCC_GetPCLK1Freq()/1000000);
00608     pc.printf("PCLK2 Clock  = %d[MHz]\r\n", HAL_RCC_GetPCLK2Freq()/1000000);
00609     pc.printf("\r\n");
00610 }
00611 
00612 void UpdateTargetAngle(float targetAngle[3])
00613 {
00614 
00615 
00616     static int16_t count_op = 0;
00617 #if DEBUG_SEMIAUTO
00618     switch(operation_mode) {
00619         case StartUp:
00620             if(!CheckSW_Up(Ch7) && CheckSW_Up(Ch8)) {
00621                 count_op++;B
00622                 if(count_op > changeModeCount) {
00623                     operation_mode = SemiAuto;
00624                     pc.printf("Goto SemiAuto mode\r\n");
00625                     count_op = 0;
00626                 }
00627             } else count_op = 0;
00628             break;
00629 
00630         case SemiAuto:
00631             /*  大会用では以下のif文を入れてoperation_modeを変える
00632                 if(CheckSW_Up(Ch6)){
00633                     count_op++;
00634                     if(count_op>changeModeCount){
00635                         output_status = XXX;
00636                         led2 = 0;
00637                         pc.printf("Goto XXX mode\r\n");
00638                         count_op = 0;
00639                     }else count_op = 0;
00640                     ConvertPWMintoRAD(targetAngle);
00641                 }
00642             */
00643             ConvertPWMintoRAD(targetAngle);
00644             break;
00645 
00646         default:
00647             operation_mode = SemiAuto;
00648             break;
00649     }
00650 
00651 #else
00652 
00653     switch(operation_mode) {
00654         case StartUp:
00655             if(!CheckSW_Up(Ch7) && !CheckSW_Up(Ch8)) {       //ch7;自動・手動切り替え ch8;自動操縦モード切替
00656                 count_op++;
00657                 if(count_op > changeModeCount) {
00658                     operation_mode = LeftLoop;
00659                     pc.printf("Goto LeftLoop mode\r\n");
00660                     count_op = 0;
00661                 }
00662             } else count_op = 0;
00663             break;
00664 
00665         case LeftLoop:
00666             if(!CheckSW_Up(Ch7) && CheckSW_Up(Ch8)) {
00667                 count_op++;
00668                 if(count_op > changeModeCount) {
00669                     operation_mode = GoStraight;
00670                     pc.printf("Goto GoStraight mode\r\n");
00671                     count_op = 0;
00672                 }
00673             } else count_op = 0;
00674             UpdateTargetAngle_Leftloop(targetAngle);
00675             //UpdateTargetAngle_GoStraight_zero(targetAngle);
00676             break;
00677 
00678         case GoStraight:
00679             if(!CheckSW_Up(Ch7) && !CheckSW_Up(Ch8)) {
00680                 count_op++;
00681                 if(count_op > changeModeCount) {
00682                     operation_mode = Moebius;
00683                     pc.printf("Goto Moebius mode\r\n");
00684                     count_op = 0;
00685                 }
00686             } else count_op = 0;
00687             //UpdateTargetAngle_GoStraight(targetAngle);
00688             UpdateTargetAngle_GoStraight_zero(targetAngle);
00689             //UpdateTargetAngle_Leftloop_short(targetAngle);
00690             //UpdateTargetAngle_Leftloop_zero(targetAngle);
00691         
00692             
00693             break;
00694 
00695         case Moebius:
00696             if(!CheckSW_Up(Ch7) && CheckSW_Up(Ch8)) {
00697                 count_op++;
00698                 if(count_op > changeModeCount) {
00699                     operation_mode = Glide;
00700                     pc.printf("Goto Glide mode\r\n");
00701                     count_op = 0;
00702                 }
00703             } else count_op = 0;
00704             UpdateTargetAngle_Moebius(targetAngle);
00705             break;
00706 
00707         case Glide:
00708             if(!CheckSW_Up(Ch7) && !CheckSW_Up(Ch8)) {
00709                 count_op++;
00710                 if(count_op > changeModeCount) {
00711                     operation_mode = RightLoop;
00712                     pc.printf("Goto RightLoop mode\r\n");
00713                     count_op = 0;
00714                 }
00715             } else count_op = 0;
00716             //UpdateTargetAngle_Rightloop_short(targetAngle);
00717             //UpdateTargetAngle_Rightloop_zero(targetAngle);
00718             UpdateTargetAngle_GoStraight_zero(targetAngle);
00719             
00720             break;
00721 
00722         case RightLoop:
00723             if(!CheckSW_Up(Ch7) && CheckSW_Up(Ch8)) {
00724                 count_op++;
00725                 if(count_op > changeModeCount) {
00726                     operation_mode = BombwithPC;
00727                     pc.attach(getSF_Serial, Serial::RxIrq);
00728                     autopwm[DROP]=trimpwm[DROP];
00729                     pc.printf("Goto BombwithPC mode\r\n");
00730                     //g_AscendingFlag = false;
00731                     count_op = 0;
00732                 }
00733             } else count_op = 0;
00734             Ascending(targetAngle);
00735             break;
00736 
00737         case BombwithPC:
00738             if(!CheckSW_Up(Ch7) && !CheckSW_Up(Ch8)) {
00739                 count_op++;
00740                 if(count_op > changeModeCount) {
00741                     operation_mode = LeftLoop;
00742                     pc.printf("Goto Left mode\r\n");
00743                     pc.attach(getSF_Serial, Serial::RxIrq);
00744                     count_op = 0;
00745                 }
00746             } else count_op = 0;
00747             Take_off_and_landing(targetAngle);
00748             break;
00749 
00750         default:
00751             operation_mode = StartUp;
00752             break;
00753     }
00754 #endif
00755 
00756     if(CheckSW_Up(Ch7)) {
00757         output_status = Auto;
00758         led1 = 1;
00759     } else {
00760         output_status = Manual;
00761         led1 = 0;
00762     }
00763 
00764 
00765 }
00766 
00767 int GetParameter(FILE *fp, const char *paramName,char parameter[])
00768 {
00769     int i=0, j=0;
00770     int strmax = 200;
00771     char str[strmax];
00772 
00773     rewind(fp); //ファイル位置を先頭に
00774     while(1) {
00775         if (fgets(str, strmax, fp) == NULL) {
00776             return 0;
00777         }
00778         if (!strncmp(str, paramName, strlen(paramName))) {
00779             while (str[i++] != '=') {}
00780             while (str[i] != '\n') {
00781                 parameter[j++] = str[i++];
00782             }
00783             parameter[j] = '\0';
00784             return 1;
00785         }
00786     }
00787 }
00788 
00789 
00790 //sdによる設定
00791 int SetOptions(float *g_kpELE, float *g_kiELE, float *g_kdELE,
00792                float *g_kpRUD, float *g_kiRUD, float *g_kdRUD,
00793                float *g_rightloopROLL, float *g_rightloopPITCH,
00794                float *g_leftloopROLL, float *g_leftloopPITCH,
00795                float *g_gostraightROLL, float *g_gostraightPITCH,
00796                float *g_takeoffTHR, float *g_loopTHR,
00797                float *g_rightloopROLLshort, float *g_rightloopPITCHshort,
00798                float *g_leftloopROLLshort, float *g_leftloopPITCHshort,
00799                float *g_glideloopROLL, float *g_glideloopPITCH,
00800                float *g_kpAIL, float *g_kiAIL, float *g_kdAIL,
00801                int *g_rightloopRUD, int *g_rightloopshortRUD,
00802                int *g_leftloopRUD, int *g_leftloopshortRUD,
00803                int *g_glideloopRUD,
00804                float *g_rightloopROLL_approach,float *g_leftloopROLL_approach,
00805                int *g_rightloopRUD_approach,int *g_leftloopRUD_approach,
00806                float *g_rightloopPITCH_approach,float *g_leftloopPITCH_approach,
00807                float *g_ascendingPITCH,
00808                int *g_take_off_THROTTLE, float *g_take_off_PITCH,
00809                float *g_rightloop_THR_rate, float *g_leftloop_THR_rate,
00810                float *g_ascending_THR_rate, 
00811                float *g_ascending_ROLL, int *g_ascending_RUD,
00812                int *g_trim1, int *g_trim2, int *g_trim3,
00813                int *g_trim4, int *g_trim5, int *g_trim6,
00814                bool *g_trim_check
00815               )
00816 {
00817 
00818     pc.printf("SDsetup start.\r\n");
00819 
00820     FILE *fp;
00821     char parameter[50]; //文字列渡す用の配列
00822     int SDerrorcount = 0;  //取得できなかった数を返す
00823     const char *paramNames[] = {
00824         "KP_ELEVATOR",
00825         "KI_ELEVATOR",
00826         "KD_ELEVATOR",
00827         "KP_RUDDER",
00828         "KI_RUDDER",
00829         "KD_RUDDER",
00830         "RIGHTLOOP_ROLL",
00831         "RIGHTLOOP_PITCH",
00832         "LEFTLOOP_ROLL",
00833         "LEFTLOOP_PITCH",
00834         "GOSTRAIGHT_ROLL",
00835         "GOSTRAIGHT_PITCH",
00836         "TAKEOFF_THR_RATE",
00837         "LOOP_THR_RATE",
00838         "RIGHTLOOP_ROLL_SHORT",
00839         "RIGHTLOOP_PITCH_SHORT",
00840         "LEFTLOOP_ROLL_SHORT",
00841         "LEFTLOOP_PITCH_SHORT",
00842         "AUTOGLIDE_ROLL",
00843         "AUTOGLIDE PITCH",
00844         "KP_AILERON",
00845         "KI_AILERON",
00846         "KD_AILERON",
00847         "RIGHTLOOP_RUDDER",
00848         "RIGHTLOOPSHORT_RUDDER",
00849         "LEFTLOOP_RUDDER",
00850         "LEFTLOOPSHORT_RUDDER",
00851         "GLIDELOOP_RUDDER",
00852         "RIGHTLOOP_ROLL_APPROACH",
00853         "LEFTLOOP_ROLL_APPROACH",
00854         "RIGHTLOOP_RUDDER_APPROACH",
00855         "LEFTLOOP_RUDDER_APPROACH",
00856         "RIGHTLOOP_PITCH_APPROACH",
00857         "LEFTLOOP_PITCH_APPROACH",
00858         "ASCENDING_PITCH",
00859         "TAKE_OFF_THROTTLE",
00860         "TAKE_OFF_PITCH",
00861         "RIGHTLOOP_THR_RATE",
00862         "LEFTLOOP_THR_RATE",
00863         "ASCENDING_THR_RATE",
00864         "ASCENDING_ROLL",
00865         "ASCENDING_RUD",
00866         "TRIM1",
00867         "TRIM2",
00868         "TRIM3",
00869         "TRIM4",
00870         "TRIM5",
00871         "TRIM6",
00872         "TRIM_CHECK"
00873     };
00874 
00875     fp = fopen("/sd/option.txt","r");
00876 
00877     if(fp != NULL) { //開けたら
00878         pc.printf("File was openned.\r\n");
00879         if(GetParameter(fp,paramNames[0],parameter)) *g_kpELE = atof(parameter);
00880         else {
00881             *g_kpELE = KP_ELE;
00882             SDerrorcount++;
00883         }
00884         if(GetParameter(fp,paramNames[1],parameter)) *g_kiELE = atof(parameter);
00885         else {
00886             *g_kiELE = KI_ELE;
00887             SDerrorcount++;
00888         }
00889         if(GetParameter(fp,paramNames[2],parameter)) *g_kdELE = atof(parameter);
00890         else {
00891             *g_kdELE = KD_ELE;
00892             SDerrorcount++;
00893         }
00894         if(GetParameter(fp,paramNames[3],parameter)) *g_kpRUD = atof(parameter);
00895         else {
00896             *g_kpRUD = KP_RUD;
00897             SDerrorcount++;
00898         }
00899         if(GetParameter(fp,paramNames[4],parameter)) *g_kiRUD = atof(parameter);
00900         else {
00901             *g_kiRUD = KI_RUD;
00902             SDerrorcount++;
00903         }
00904         if(GetParameter(fp,paramNames[5],parameter)) *g_kdRUD = atof(parameter);
00905         else {
00906             *g_kdRUD = KD_RUD;
00907             SDerrorcount++;
00908         }
00909         if(GetParameter(fp,paramNames[6],parameter)) *g_rightloopROLL = atof(parameter);
00910         else {
00911             *g_rightloopROLL = RIGHT_ROLL;
00912             SDerrorcount++;
00913         }
00914         if(GetParameter(fp,paramNames[7],parameter)) *g_rightloopPITCH = atof(parameter);
00915         else {
00916             *g_rightloopPITCH = RIGHT_PITCH;
00917             SDerrorcount++;
00918         }
00919         if(GetParameter(fp,paramNames[8],parameter)) *g_leftloopROLL = atof(parameter);
00920         else {
00921             *g_leftloopROLL = LEFT_ROLL;
00922             SDerrorcount++;
00923         }
00924         if(GetParameter(fp,paramNames[9],parameter)) *g_leftloopPITCH = atof(parameter);
00925         else {
00926             *g_leftloopPITCH = LEFT_PITCH;
00927             SDerrorcount++;
00928         }
00929         if(GetParameter(fp,paramNames[10],parameter)) *g_gostraightROLL = atof(parameter);
00930         else {
00931             *g_gostraightROLL = STRAIGHT_ROLL;
00932             SDerrorcount++;
00933         }
00934         if(GetParameter(fp,paramNames[11],parameter)) *g_gostraightPITCH = atof(parameter);
00935         else {
00936             *g_gostraightPITCH = STRAIGHT_PITCH;
00937             SDerrorcount++;
00938         }
00939         if(GetParameter(fp,paramNames[12],parameter)) *g_takeoffTHR = atof(parameter);
00940         else {
00941             *g_takeoffTHR = TAKEOFF_THR;
00942             SDerrorcount++;
00943         }
00944         if(GetParameter(fp,paramNames[13],parameter)) *g_loopTHR = atof(parameter);
00945         else {
00946             *g_loopTHR = LOOP_THR;
00947             SDerrorcount++;
00948         }
00949         if(GetParameter(fp,paramNames[14],parameter)) *g_rightloopROLLshort = atof(parameter);
00950         else {
00951             *g_rightloopROLLshort = RIGHT_ROLL_SHORT;
00952             SDerrorcount++;
00953         }
00954         if(GetParameter(fp,paramNames[15],parameter)) *g_rightloopPITCHshort = atof(parameter);
00955         else {
00956             *g_rightloopPITCHshort = RIGHT_PITCH_SHORT;
00957             SDerrorcount++;
00958         }
00959         if(GetParameter(fp,paramNames[16],parameter)) *g_leftloopROLLshort = atof(parameter);
00960         else {
00961             *g_leftloopROLLshort = LEFT_ROLL_SHORT;
00962             SDerrorcount++;
00963         }
00964         if(GetParameter(fp,paramNames[17],parameter)) *g_leftloopPITCHshort = atof(parameter);
00965         else {
00966             *g_leftloopPITCHshort = LEFT_PITCH_SHORT;
00967             SDerrorcount++;
00968         }
00969         if(GetParameter(fp,paramNames[18],parameter)) *g_glideloopROLL = atof(parameter);
00970         else {
00971             *g_glideloopROLL = GLIDE_ROLL;
00972             SDerrorcount++;
00973         }
00974         if(GetParameter(fp,paramNames[19],parameter)) *g_glideloopPITCH = atof(parameter);
00975         else {
00976             *g_glideloopPITCH = GLIDE_PITCH;
00977             SDerrorcount++;
00978         }
00979         if(GetParameter(fp,paramNames[20],parameter)) *g_kpAIL = atof(parameter);
00980         else {
00981             *g_kpAIL = KP_AIL;
00982             SDerrorcount++;
00983         }
00984         if(GetParameter(fp,paramNames[21],parameter)) *g_kiAIL = atof(parameter);
00985         else {
00986             *g_kiAIL = KI_AIL;
00987             SDerrorcount++;
00988         }
00989         if(GetParameter(fp,paramNames[22],parameter)) *g_kdAIL = atof(parameter);
00990         else {
00991             *g_kdAIL = KP_AIL;
00992             SDerrorcount++;
00993         }
00994         if(GetParameter(fp,paramNames[23],parameter)) *g_rightloopRUD = atof(parameter);
00995         else {
00996             *g_rightloopRUD = RIGHTLOOP_RUD;
00997             SDerrorcount++;
00998         }
00999         if(GetParameter(fp,paramNames[24],parameter)) *g_rightloopshortRUD = atof(parameter);
01000         else {
01001             *g_rightloopshortRUD = RIGHTLOOPSHORT_RUD;
01002             SDerrorcount++;
01003         }
01004         if(GetParameter(fp,paramNames[25],parameter)) *g_leftloopRUD = atof(parameter);
01005         else {
01006             *g_leftloopshortRUD = LEFTLOOP_RUD;
01007             SDerrorcount++;
01008         }
01009         if(GetParameter(fp,paramNames[26],parameter)) *g_leftloopshortRUD = atof(parameter);
01010         else {
01011             *g_leftloopshortRUD = LEFTLOOPSHORT_RUD;
01012             SDerrorcount++;
01013         }
01014         if(GetParameter(fp,paramNames[27],parameter)) *g_glideloopRUD = atof(parameter);
01015         else {
01016             *g_glideloopRUD = GLIDELOOP_RUD;
01017             SDerrorcount++;
01018         }
01019         if(GetParameter(fp,paramNames[28],parameter)) *g_rightloopROLL_approach = atof(parameter);
01020         else {
01021             *g_rightloopROLL_approach  = RIGHTLOOPROLL_APPROACH;
01022             SDerrorcount++;
01023         }
01024         if(GetParameter(fp,paramNames[29],parameter)) *g_leftloopROLL_approach= atof(parameter);
01025         else {
01026             *g_leftloopROLL_approach = LEFTLOOPROLL_APPROACH;
01027             SDerrorcount++;
01028         }
01029         if(GetParameter(fp,paramNames[30],parameter)) *g_rightloopRUD_approach = atof(parameter);
01030         else {
01031             *g_rightloopRUD_approach = RIGHTLOOPRUD_APPROACH;
01032             SDerrorcount++;
01033         }
01034         if(GetParameter(fp,paramNames[31],parameter)) *g_leftloopRUD_approach= atof(parameter);
01035         else {
01036             *g_leftloopRUD_approach= LEFTLOOPRUD_APPROACH;
01037             SDerrorcount++;
01038         }
01039         if(GetParameter(fp,paramNames[32],parameter)) *g_rightloopPITCH_approach = atof(parameter);
01040         else {
01041             *g_rightloopPITCH_approach = RIGHTLOOPPITCH_APPROACH;
01042             SDerrorcount++;
01043         }
01044         if(GetParameter(fp,paramNames[33],parameter)) *g_leftloopPITCH_approach = atof(parameter);
01045         else {
01046             *g_leftloopPITCH_approach = LEFTLOOPPITCH_APPROACH;
01047             SDerrorcount++;
01048         }
01049         if(GetParameter(fp,paramNames[34],parameter)) *g_ascendingPITCH = atof(parameter);
01050         else {
01051             *g_ascendingPITCH = ASCENDING_PITCH;
01052             SDerrorcount++;
01053         }
01054         if(GetParameter(fp,paramNames[35],parameter)) *g_take_off_THROTTLE = atof(parameter);
01055         else {
01056             *g_take_off_THROTTLE = TAKE_OFF_THROTTLE;
01057             SDerrorcount++;
01058         }
01059         if(GetParameter(fp,paramNames[36],parameter)) *g_take_off_PITCH = atof(parameter);
01060         else {
01061             *g_take_off_PITCH = TAKE_OFF_PITCH;
01062             SDerrorcount++;
01063         }
01064         if(GetParameter(fp,paramNames[37],parameter)) *g_rightloop_THR_rate = atof(parameter);
01065         else {
01066             *g_rightloop_THR_rate = RIGHTLOOP_THR_RATE;
01067             SDerrorcount++;
01068         }
01069         if(GetParameter(fp,paramNames[38],parameter)) *g_leftloop_THR_rate = atof(parameter);
01070         else {
01071             *g_leftloop_THR_rate = LEFTLOOP_THR_RATE;
01072             SDerrorcount++;
01073         }
01074         if(GetParameter(fp,paramNames[39],parameter)) *g_ascending_THR_rate = atof(parameter);
01075         else {
01076             *g_ascending_THR_rate = ASCENDING_THR_RATE;
01077             SDerrorcount++;
01078         }
01079         if(GetParameter(fp,paramNames[40],parameter)) *g_ascending_ROLL = atof(parameter);
01080         else {
01081             *g_ascending_ROLL = ASCENDING_ROLL;
01082             SDerrorcount++;
01083         }
01084         if(GetParameter(fp,paramNames[41],parameter)) *g_ascending_RUD= atof(parameter);
01085         else {
01086             *g_ascending_RUD = ASCENDING_RUD;
01087             SDerrorcount++;
01088         }
01089         if(GetParameter(fp,paramNames[42],parameter)) *g_trim1 = atof(parameter);
01090         else {
01091             *g_trim1 = TRIM1;
01092             SDerrorcount++;
01093         }
01094         if(GetParameter(fp,paramNames[43],parameter)) *g_trim2 = atof(parameter);
01095         else {
01096             *g_trim2 = TRIM2;
01097             SDerrorcount++;
01098         }
01099         if(GetParameter(fp,paramNames[44],parameter)) *g_trim3 = atof(parameter);
01100         else {
01101             *g_trim3 = TRIM3;
01102             SDerrorcount++;
01103         }
01104         if(GetParameter(fp,paramNames[45],parameter)) *g_trim4 = atof(parameter);
01105         else {
01106             *g_trim4 = TRIM4;
01107             SDerrorcount++;
01108         }
01109         if(GetParameter(fp,paramNames[46],parameter)) *g_trim5 = atof(parameter);
01110         else {
01111             *g_trim5 = TRIM5;
01112             SDerrorcount++;
01113         }
01114         if(GetParameter(fp,paramNames[47],parameter)) *g_trim6 = atof(parameter);
01115         else {
01116             *g_trim6 = TRIM6;
01117             SDerrorcount++;
01118         }
01119         if(GetParameter(fp,paramNames[48],parameter)) *g_trim_check = atof(parameter);
01120         else {
01121             *g_trim_check = TRIM_CHECK;
01122             SDerrorcount++;
01123         }
01124 
01125 
01126         fclose(fp);
01127 
01128     } else { //ファイルがなかったら
01129         pc.printf("fp was null.\r\n");
01130         *g_kpELE = KP_ELE;
01131         *g_kiELE = KI_ELE;
01132         *g_kdELE = KD_ELE;
01133         *g_kpRUD = KP_RUD;
01134         *g_kiRUD = KI_RUD;
01135         *g_kdRUD = KD_RUD;
01136         *g_rightloopROLL = RIGHT_ROLL;
01137         *g_rightloopPITCH = RIGHT_PITCH;
01138         *g_leftloopROLL = LEFT_ROLL;
01139         *g_leftloopPITCH = LEFT_PITCH;
01140         *g_gostraightROLL = STRAIGHT_ROLL;
01141         *g_gostraightPITCH = STRAIGHT_PITCH;
01142         *g_takeoffTHR = TAKEOFF_THR;
01143         *g_loopTHR = LOOP_THR;
01144         *g_kpAIL = KP_AIL; //パラメータ変えるのお忘れなく!!
01145         *g_kiAIL = KI_AIL;
01146         *g_kdAIL = KD_AIL;
01147         *g_rightloopRUD = RIGHTLOOP_RUD;
01148         *g_rightloopshortRUD = RIGHTLOOPSHORT_RUD;
01149         *g_leftloopRUD = LEFTLOOP_RUD;
01150         *g_leftloopshortRUD = LEFTLOOPSHORT_RUD;
01151         *g_glideloopRUD = GLIDELOOP_RUD;
01152         *g_rightloopROLL_approach = RIGHTLOOPROLL_APPROACH;
01153         *g_leftloopROLL_approach = LEFTLOOPROLL_APPROACH;
01154         *g_rightloopRUD_approach = RIGHTLOOPRUD_APPROACH;
01155         *g_leftloopRUD_approach = LEFTLOOPRUD_APPROACH;
01156         *g_rightloopPITCH_approach = RIGHTLOOPPITCH_APPROACH;
01157         *g_leftloopPITCH_approach = LEFTLOOPPITCH_APPROACH;
01158         *g_ascendingPITCH = ASCENDING_PITCH;
01159         *g_take_off_THROTTLE = TAKE_OFF_THROTTLE;
01160         *g_take_off_PITCH = TAKE_OFF_PITCH;
01161         *g_rightloop_THR_rate = RIGHTLOOP_THR_RATE;
01162         *g_leftloop_THR_rate = LEFTLOOP_THR_RATE;
01163         *g_ascending_THR_rate = ASCENDING_THR_RATE;
01164         *g_ascending_ROLL = ASCENDING_ROLL;
01165         *g_ascending_RUD = ASCENDING_RUD; 
01166         *g_trim1 = TRIM1;
01167         *g_trim2 = TRIM2;
01168         *g_trim3 = TRIM3;
01169         *g_trim4 = TRIM4;
01170         *g_trim5 = TRIM5;
01171         *g_trim6 = TRIM6;
01172         *g_trim_check = TRIM_CHECK;
01173         
01174         SDerrorcount = -1;
01175     }
01176     pc.printf("SDsetup finished.\r\n");
01177     if(SDerrorcount == 0)  pc.printf("setting option is success\r\n");
01178     else if(SDerrorcount == -1) pc.printf("ERROR 1. cannot open option\r\n");
01179     else if(SDerrorcount > 0)  pc.printf("ERROR 2. reading parameter is failed[%d]\r\n",SDerrorcount);
01180 
01181     pc.printf("kpELE = %f, kiELE = %f, kdELE = %f\r\n", *g_kpELE, *g_kiELE, *g_kdELE);
01182     pc.printf("kpRUD = %f, kiRUD = %f, kdRUD = %f\r\n", *g_kpRUD, *g_kiRUD, *g_kdRUD);
01183     pc.printf("rightloopROLL = %f, rightloopPITCH = %f\r\n", *g_rightloopROLL, *g_rightloopPITCH);
01184     pc.printf("leftloopROLL = %f, g_leftloopPITCH =  %f\r\n", *g_leftloopROLL, *g_leftloopPITCH);
01185     pc.printf("gostraightROLL = %f, g_gostraightPITCH = %f\r\n", *g_gostraightROLL, *g_gostraightPITCH);
01186     pc.printf("g_takeoffTHR = %f, g_loopTHR = %f\r\n", *g_takeoffTHR, *g_loopTHR);
01187     pc.printf("rightloopROLLshort = %f, rightloopPITCHshort = %f\r\n", *g_rightloopROLLshort, *g_rightloopPITCHshort);
01188     pc.printf("leftloopROLLshort = %f, g_leftloopPITCHshort =  %f\r\n", *g_leftloopROLLshort, *g_leftloopPITCHshort);
01189     pc.printf("glideROLL = %f, glidePITCH = %f\r\n", *g_glideloopROLL, *g_glideloopPITCH);
01190     pc.printf("kpAIL = %f,kiAIL = %f,kdAIL = %f\r\n ",*g_kpAIL,*g_kiAIL,*g_kdAIL);
01191     pc.printf("RIGHTLOOPRUD = %d,RIGHTLOOPSHORTRUD = %d\r\n",*g_rightloopRUD,*g_rightloopshortRUD);
01192     pc.printf("LEFTTLOOPRUD = %d,LEFTLOOPSHORTRUD = %d\r\n",*g_leftloopRUD,*g_leftloopshortRUD);
01193     pc.printf("GLIDELOOPRUD = %d\r\n",*g_glideloopRUD);
01194     pc.printf("RIGHTLOOP_ROLL_APPROACH = %f, LEFTLOOP_ROLL_APPROACH= %f\r\n",*g_rightloopROLL_approach,*g_leftloopROLL_approach);
01195     pc.printf("RIGHTLOOP_RUD_APPROACH = %d, LEFTLOOP_RUD_APPROACH = %d\r\n",*g_rightloopRUD_approach,*g_leftloopRUD_approach);
01196     pc.printf("RIGHTLOOP_PITCH_APPROACH = %f, LEFTLOOP_PITCH_APPROACH = %f\r\n",*g_rightloopPITCH_approach,*g_leftloopPITCH_approach);
01197     pc.printf("ASCENDING_PITCH = %f\r\n",*g_ascendingPITCH);
01198     pc.printf("TAKE_OFF_THROTTLE = %d, TAKE_OFF_PITCH = %f\r\n",*g_take_off_THROTTLE,*g_take_off_PITCH);
01199     pc.printf("RIGHTLOOP_THR_RATE = %f, LEFTLOOP_THR_RATE = %f, ASCENDING_THR_RATE = %f\r\n", *g_rightloop_THR_rate, *g_leftloop_THR_rate, *g_ascending_THR_rate);
01200     pc.printf("ASCENDING_ROLL = %f,ASCENDING_RUD = %d\r\n",*g_ascending_ROLL,*g_ascending_RUD);
01201     pc.printf("TRIM1 = %d, TRIM2 = %d, TRIM3 = %d\r\n",*g_trim1,*g_trim2,*g_trim3);
01202     pc.printf("TRIM4 = %d, TRIM5 = %d, TRIM6 = %d\r\n",*g_trim4,*g_trim5,*g_trim6);
01203     pc.printf("TRIM_CHECK = %d\r\n",*g_trim_check);
01204 
01205     return SDerrorcount;
01206 }
01207 
01208 void CalculateControlValue(float targetAngle[3], float controlValue[3])
01209 {
01210 
01211     static int t_last;
01212     int t_now;
01213     float dt;
01214 
01215     t_now = t.read_us();
01216     dt = (float)((t_now - t_last)/1000000.0f) ;
01217     t_last = t_now;
01218 
01219 
01220     //controlValue[ROLL] = pid_RUD.calcPID(nowAngle[ROLL], targetAngle[ROLL], dt);
01221     controlValue[ROLL] = pid_AIL.calcPID(nowAngle[ROLL], targetAngle[ROLL], dt);       //エルロンでロール制御
01222     controlValue[PITCH] = pid_ELE.calcPID(nowAngle[PITCH], targetAngle[PITCH], dt);
01223 
01224 }
01225 
01226 void UpdateAutoPWM(float controlValue[3])
01227 {
01228     NVIC_DisableIRQ(USART1_IRQn);
01229     int16_t addpwm[2]; //-500~500
01230     addpwm[PITCH] = (float)GAIN_CONTROLVALUE_TO_PWM * controlValue[PITCH];    //センサ:機首下げ正    レバー:機首上げ正
01231     addpwm[ROLL] = (float)GAIN_CONTROLVALUE_TO_PWM * controlValue[ROLL];           //センサ:右回転正(8月13日時点;左回転が正!)     レバー:右回転正
01232 
01233     autopwm[ELE] = trimpwm[ELE] + reverce[ELE] * addpwm[PITCH];                 //rewrite
01234     autopwm[AIL_R] = trimpwm[AIL_R] - reverce[AIL_R] * addpwm[ROLL];
01235     //autopwm[THR] = oldTHR;
01236 
01237     autopwm[ELE] = ThresholdMaxMin(autopwm[ELE], maxpwm[ELE], minpwm[ELE]);
01238     autopwm[AIL_R] = ThresholdMaxMin(autopwm[AIL_R], maxpwm[AIL_R], minpwm[AIL_R]);
01239 
01240     NVIC_EnableIRQ(USART1_IRQn);
01241 }
01242 
01243 inline float CalcRatio(float value, float trim, float limit)
01244 {
01245     return  (value - trim) / (limit - trim);
01246 }
01247 
01248 bool CheckSW_Up(Channel ch)
01249 {
01250 
01251     if(SWITCH_CHECK < sbus.manualpwm[ch]) {
01252         return true;
01253     } else {
01254         return false;
01255     }
01256 
01257 }
01258 
01259 int16_t ThresholdMaxMin(int16_t value, int16_t max, int16_t min)
01260 {
01261     if(value > max) return max;
01262     if(value < min) return min;
01263     return value;
01264 }
01265 
01266 inline int16_t SetTHRinRatio(float ratio)
01267 {
01268     return minpwm[THR] + (int16_t)(2 * lengthdivpwm * ratio);
01269 }
01270 
01271 
01272 
01273 /*---SBUS割り込み処理---*/
01274 
01275 //udate_Inputで抽出したpwmデータを整形して各変数に代入する。(マニュアルモード)
01276 //各stabiGylo関数で算出したpwmを各変数に代入する(自動モード)
01277 void Update_PWM()
01278 {
01279     NVIC_DisableIRQ(USART1_IRQn);
01280     static int16_t pwm[6];
01281     static int16_t temppwm[6]= {trimpwm[0],trimpwm[1],trimpwm[2],trimpwm[3],trimpwm[4],trimpwm[5]};
01282     static int16_t FailsafeCounter=0;
01283     static int16_t ResetCounter=0;
01284     static int16_t OKCounter=0;
01285 
01286     if(sbus.flg_ch_update == true) {
01287 
01288         switch(output_status) {   //マニュアルモード,自動モード,自動着陸もモードを切替
01289             case Manual:
01290                 if(OKCounter!=0) break;
01291                 for(uint8_t i=0; i<6; i++) {
01292                     pwm[i] = sbus.manualpwm[i];
01293                 }
01294                 oldTHR = sbus.manualpwm[THR];
01295                 //pc.printf("update_manual\r\n");
01296                 NVIC_EnableIRQ(USART1_IRQn);
01297                 break;
01298 
01299             case Auto:
01300                 if(OKCounter!=0) break;
01301                 pwm[AIL_R] = autopwm[AIL_R];               //sbus.manualpwm[AIL];
01302                 pwm[ELE] = autopwm[ELE];
01303                 pwm[THR] = autopwm[THR];
01304                 pwm[RUD] = autopwm[RUD];
01305                 pwm[DROP] = autopwm[DROP];
01306                 pwm[AIL_L] = autopwm[AIL_L];
01307 
01308                 NVIC_EnableIRQ(USART1_IRQn);
01309                 break;
01310 
01311             default:
01312                 if(OKCounter!=0) break;
01313                 for(uint8_t i=0; i<6; i++) {
01314                     pwm[i] = sbus.manualpwm[i];
01315                 } //pc.printf("update_manual\r\n");
01316                 NVIC_EnableIRQ(USART1_IRQn);
01317                 break;
01318         }
01319 
01320         for(uint8_t i=0; i<6; i++) {
01321             if(pwm[i]<1000 || pwm[i]>2000) pwm[i]=temppwm[i];
01322             temppwm[i]=pwm[i];
01323         }
01324 
01325     }
01326     //else(sbus.flg_ch_update == false) pc.printf("0\r\n");
01327     /* if(sbus.failsafe_status==SBUS_SIGNAL_OK){
01328         pc.printf("OK\r\n");
01329     }
01330     */
01331     //pc.printf("%d\r\n",sbus.failsafe_status);
01332 
01333     if(sbus.failsafe_status==SBUS_SIGNAL_LOST||sbus.failsafe_status==SBUS_SIGNAL_FAILSAFE) FailsafeCounter++;
01334     else ResetCounter++;
01335 
01336     if(ResetCounter>7) {
01337         ResetCounter=0;
01338         FailsafeCounter=0;
01339     }
01340 
01341     if(FailsafeCounter>10) {
01342         ResetCounter=0;
01343         for(uint8_t i=0; i<6; i++) pwm[i] = trimpwm[i];
01344 
01345         if(sbus.failsafe_status==SBUS_SIGNAL_OK&&sbus.flg_ch_update == true) OKCounter++;
01346         else OKCounter=0;
01347 
01348         if(OKCounter>10) {
01349             OKCounter=0;
01350             FailsafeCounter=0;
01351         }
01352         //pc.printf("OKCounter=%d,  FailsafeCounter=%d,  sbus.failsafe_status=%d\r\n",OKCounter,FailsafeCounter,sbus.failsafe_status);
01353     }
01354     //if(sbus.failsafe_status==SBUS_SIGNAL_OK){FailsafeCounter=0;}
01355 
01356 
01357     sbus.flg_ch_update = false;
01358     Output_PWM(pwm);
01359 }
01360 
01361 
01362 
01363 
01364 //pwmをサーボに出力。
01365 void Output_PWM(int16_t pwm[5])
01366 {
01367     NVIC_DisableIRQ(USART1_IRQn);
01368     servo1.pulsewidth_us(pwm[0]);
01369     servo2.pulsewidth_us(pwm[1]);
01370     servo3.pulsewidth_us(pwm[2]);
01371     servo4.pulsewidth_us(pwm[3]);
01372     servo5.pulsewidth_us(pwm[4]);
01373     servo6.pulsewidth_us(pwm[5]);
01374     NVIC_EnableIRQ(USART1_IRQn);
01375 
01376 }
01377 
01378 void ResetTrim()
01379 {
01380     for(uint8_t i=0; i<6; i++) {           //i=4から書き換え_投下サーボは入ってない模様
01381         trimpwm[i] = sbus.manualpwm[i];
01382     }
01383     pc.printf("reset PWM trim\r\n");
01384 }
01385 
01386 
01387 void SensingMPU()
01388 {
01389     //static int16_t deltaT = 0, t_start = 0;
01390     //t_start = t.read_us();
01391 
01392     float rpy[3] = {0}, oldrpy[3] = {0};
01393     static uint16_t count_changeRPY = 0;
01394     static bool flg_checkoutlier = false;
01395     NVIC_DisableIRQ(USART1_IRQn);
01396     NVIC_DisableIRQ(USART2_IRQn);
01397     NVIC_DisableIRQ(TIM5_IRQn);
01398     NVIC_DisableIRQ(EXTI0_IRQn);//MPU割り込み禁止
01399     NVIC_DisableIRQ(EXTI9_5_IRQn);//超音波割り込み禁止
01400 
01401     mpu6050.getRollPitchYaw_Skipper(rpy);
01402 
01403     NVIC_EnableIRQ(USART1_IRQn);
01404     NVIC_EnableIRQ(USART2_IRQn);
01405     NVIC_EnableIRQ(TIM5_IRQn);
01406     NVIC_EnableIRQ(EXTI0_IRQn);
01407     NVIC_EnableIRQ(EXTI9_5_IRQn);
01408 
01409 
01410     //外れ値対策
01411     for(uint8_t i=0; i<3; i++) rpy[i] *= 180.0f/PI;
01412     rpy[ROLL] -= FirstROLL;
01413     rpy[PITCH] -= FirstPITCH;
01414     rpy[YAW] -= FirstYAW;
01415 
01416     for(uint8_t i=0; i<3; i++) {
01417         if(rpy[i] < nowAngle[i]-10 || rpy[i] > nowAngle[i]+10) {
01418             flg_checkoutlier = true;
01419         }
01420     }
01421     if(!flg_checkoutlier || count_changeRPY >= 2) {
01422         for(uint8_t i=0; i<3; i++) {
01423             nowAngle[i] = (rpy[i] + nowAngle[i])/2.0f;  //2つの移動平均
01424         }
01425         count_changeRPY = 0;
01426     } else   count_changeRPY++;
01427     flg_checkoutlier = false;
01428 
01429 }
01430 
01431 float TranslateNewYaw(float beforeYaw,  float newzeroYaw)
01432 {
01433     float newYaw = beforeYaw - newzeroYaw;
01434 
01435     if(newYaw<-180.0f) newYaw += 360.0f;
01436     else if(newYaw>180.0f) newYaw -= 360.0f;
01437     return newYaw;
01438 }
01439 
01440 
01441 void getSF_Serial()
01442 {
01443     //NVIC_DisableIRQ(USART1_IRQn);
01444     //NVIC_DisableIRQ(EXTI0_IRQn);
01445     //NVIC_DisableIRQ(TIM5_IRQn);
01446 
01447 
01448     static char SFbuf[16]= {'Q','Q','Q','Q','Q','Q','Q','Q','Q','Q','Q','Q','Q','Q','Q','Q'};
01449 
01450     static int bufcounter=0;
01451     
01452     float targetyaw = 0;
01453 
01454 
01455 
01456     if(pc.readable()) {    // 受信確認
01457 
01458         SFbuf[bufcounter] = pc.getc();    // 1文字取り出し
01459         if(SFbuf[0]!='S') {
01460             //pc.printf("x");
01461             return;
01462         }
01463 
01464 
01465 
01466         pc.printf("%c",SFbuf[bufcounter]);
01467 
01468         if(SFbuf[0]=='S'&&bufcounter<5)bufcounter++;
01469 
01470         if(bufcounter==5 && SFbuf[4]=='F') {
01471             pc.printf("%s\r\n",SFbuf);
01472             g_landingcommand = SFbuf[1];
01473             //pc.printf("%c",g_landingcommand);
01474             wait_ms(10);
01475             if(g_landingcommand=='Y'){
01476                 targetyaw = ConvertByteintoFloat(SFbuf[2], SFbuf[3]);
01477                 if(targetyaw>=0 && targetyaw<=360){
01478                     g_SerialTargetYAW = ConvertByteintoFloat(SFbuf[2], SFbuf[3]);
01479                 }
01480             }
01481             //if(g_landingcommand=='Y')g_SerialTargetYAW =0.0f;
01482             bufcounter = 0;
01483             memset(SFbuf, 0, sizeof(SFbuf));
01484             NVIC_ClearPendingIRQ(USART2_IRQn);
01485             //pc.printf("command = %c, commandYAW = %f\r\n", g_landingcommand, g_SerialTargetYAW);
01486         }
01487 
01488         else if(bufcounter>=5) {
01489             //pc.printf("Communication Falsed.\r\n");
01490             memset(SFbuf, 0, sizeof(SFbuf));
01491             bufcounter = 0;
01492             NVIC_ClearPendingIRQ(USART2_IRQn);
01493         }
01494     }
01495 
01496     //NVIC_EnableIRQ(TIM5_IRQn);
01497     //NVIC_EnableIRQ(EXTI0_IRQn);
01498     //NVIC_EnableIRQ(USART1_IRQn);
01499 }
01500 
01501 float ConvertByteintoFloat(char high, char low)
01502 {
01503 
01504     //int16_t intvalue = (int16_t)high*256 + (int16_t)low;
01505     int16_t intvalue = (int16_t)(((int16_t)high << 8) | low);  // Turn the MSB and LSB into a signed 16-bit value
01506     float floatvalue = (float)intvalue-256;
01507     return floatvalue;
01508 }
01509 
01510 
01511 //超音波割り込み
01512 
01513 void UpdateDist()
01514 {
01515     g_distance = usensor.get_dist_cm();
01516     usensor.start();
01517 }
01518 
01519 //8の字旋回
01520 void UpdateTargetAngle_Moebius(float targetAngle[3])
01521 {
01522     static uint8_t RotateCounter=0;
01523     static bool flg_setInStartAuto = false;
01524     static float FirstYAW_Moebius = 0.0;
01525     float newYaw_Moebius;
01526 
01527     if(!flg_setInStartAuto && CheckSW_Up(Ch7)) {
01528         FirstYAW_Moebius = nowAngle[YAW];
01529         RotateCounter = 0;
01530         flg_setInStartAuto = true;
01531     } else if(!CheckSW_Up(Ch7)) {
01532         flg_setInStartAuto = false;
01533         led4 = 0;
01534     }
01535     autopwm[THR]=oldTHR;
01536 
01537     newYaw_Moebius = TranslateNewYaw(nowAngle[YAW], FirstYAW_Moebius);
01538 
01539     if(RotateCounter == 0 && newYaw_Moebius >90.0 && newYaw_Moebius < 180.0)    {
01540         RotateCounter++;
01541         led4 = 1;
01542         pc.printf("Rotate 90\r\n");
01543     }
01544     if(RotateCounter == 1 && newYaw_Moebius >-180.0 && newYaw_Moebius < -90.0)  {
01545         RotateCounter++;
01546         led4 = 0;
01547         pc.printf("Rotate 180\r\n");
01548     }
01549     if(RotateCounter == 2 && newYaw_Moebius >-90.0 && newYaw_Moebius <-20.0)   {
01550         RotateCounter++;
01551         led4 = 1;
01552         pc.printf("Rotate 270\r\n");
01553     }
01554     if(RotateCounter == 3 && newYaw_Moebius >-10.0 && newYaw_Moebius < 90.0)     {
01555         RotateCounter++;
01556         led4 = 0;
01557         pc.printf("Change Rotate direction\r\n");
01558     }
01559 
01560 
01561     if(RotateCounter <= 3) UpdateTargetAngle_Rightloop(targetAngle);
01562     else UpdateTargetAngle_Leftloop(targetAngle);   //左旋回
01563 
01564 }
01565 
01566 
01567 
01568 //離陸-投下-着陸一連
01569 void Take_off_and_landing(float targetAngle[3])
01570 {
01571 
01572     if(!CheckSW_Up(Ch7)) bombing_mode = Takeoff;
01573 
01574     switch(bombing_mode) {
01575         case Takeoff:
01576             static bool flg_setFirstYaw = false;
01577             static int TakeoffCount = 0;
01578 
01579             if(!flg_setFirstYaw && CheckSW_Up(Ch7)) {
01580                 FirstYAW = nowAngle[YAW];
01581                 flg_setFirstYaw = true;
01582             } else if(flg_setFirstYaw && !CheckSW_Up(Ch7)) {
01583                 flg_setFirstYaw = false;
01584             }
01585 
01586             UpdateTargetAngle_Takeoff(targetAngle);
01587             NVIC_DisableIRQ(EXTI9_5_IRQn);
01588             
01589             
01590              //if(g_distance>120) TakeoffCount++;
01591 //            else TakeoffCount = 0;
01592 //             if(TakeoffCount>3) Chicken_Drop();
01593 
01594             //if(g_distance>180)TakeoffCount++;
01595             //else TakeoffCount = 0;
01596             
01597             //if(TakeoffCount>2)Chicken_Drop();
01598 
01599             
01600             //if(g_distance>210)Chicken_Drop();
01601             
01602             
01603             
01604             if(g_distance>120) TakeoffCount++;
01605             else TakeoffCount = 0;
01606             //Chicken_Drop();
01607             NVIC_EnableIRQ(EXTI9_5_IRQn);
01608             if(g_landingcommand == 'B'){
01609                 Chicken_Drop();
01610             }
01611             if(TakeoffCount>5) {
01612 
01613                 //autopwm[THR] = SetTHRinRatio(0.3);
01614                 autopwm[THR] = 1700;//g_take_off_THROTTLE;//1180+320*2*0.3;
01615                 targetAngle[PITCH]=g_gostraightPITCH;
01616                 autopwm[RUD]=1370;//trimpwm[RUD];
01617                 targetAngle[ROLL]=g_gostraightROLL;
01618                 Chicken_Drop();
01619                 if(autopwm[AIL_R]<trimpwm[AIL_R]){                                                                                  //エルロン上がりやすさ調節
01620                     autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;  //エルロンサーボ二つ使用時
01621                 }
01622                 else autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;
01623         
01624                 //pc.printf("Now go to Approach mode!!");
01625                 bombing_mode = Approach;
01626                 g_landingcommand = 'T';
01627             }
01628             
01629              
01630              
01631             break;
01632 
01633         //case Chicken:
01634         //break;
01635         /*
01636         case Transition:
01637             static int ApproachCount = 0;
01638             targetAngle[YAW]=180.0;
01639             int Judge = Rotate(targetAngle, g_SerialTargetYAW);
01640 
01641             if(Judge==0) ApproachCount++;
01642             if(ApproachCount>5) bombing_mode = Approach;
01643             break;
01644             */
01645         case Approach:
01646 
01647             //autopwm[THR] = SetTHRinRatio(g_loopTHR); //0.7;スロットルの割合
01648             autopwm[THR] = minpwm[THR];//1180+320*2*0.3;
01649             if(g_Finflag == true){
01650                 autopwm[THR] = minpwm[THR];
01651                 autopwm[ELE] = minpwm[ELE];
01652                 autopwm[RUD]=trimpwm[RUD];
01653                 autopwm[AIL_R] = minpwm[AIL_R];
01654                 autopwm[AIL_L]= maxpwm[AIL_L];
01655                 targetAngle[PITCH] = -80;
01656                 targetAngle[ROLL] = -80;
01657             }else{
01658                 UpdateTargetAngle_Approach(targetAngle);
01659             }
01660 
01661             break;
01662 
01663         default:
01664             bombing_mode = Takeoff;
01665             break;
01666     }
01667 
01668 }
01669 
01670 //離陸モード
01671 void UpdateTargetAngle_Takeoff(float targetAngle[3])
01672 {
01673     //pc.printf("%d \r\n",g_distance);
01674     static int tELE_start = 0;
01675     static bool flg_ELEup = false;
01676     int t_def = 0;
01677 
01678     autopwm[RUD] = 1390;//trimpwm[RUD];
01679     targetAngle[ROLL]=g_gostraightROLL;
01680                 
01681     if(autopwm[AIL_R]<trimpwm[AIL_R]){                                                                                  //エルロン上がりやすさ調節
01682         autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;  //エルロンサーボ二つ使用時
01683     }
01684     else autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;
01685 
01686 
01687     if(!flg_ELEup && CheckSW_Up(Ch7)) {
01688         tELE_start = t.read_ms();
01689         flg_ELEup = true;
01690         pc.printf("timer start!!!!\r\n");
01691     } else if(!CheckSW_Up(Ch7)) {
01692         tELE_start = 0;
01693         flg_ELEup = false;
01694         //pc.printf("lost!!!!\r\n");
01695     }
01696     if(flg_ELEup) {
01697         t_def = t.read_ms() - tELE_start;
01698 
01699         //1.5秒経過すればELE上げ舵へ
01700         if(t_def>500) targetAngle[PITCH]= g_take_off_PITCH;
01701         else {
01702             t_def = 0;
01703             targetAngle[PITCH]=g_gostraightPITCH;
01704         }
01705     }
01706     targetAngle[ROLL] = g_gostraightROLL;
01707     //targetAngle[PITCH] = g_loopTHR;
01708     autopwm[THR] = g_take_off_THROTTLE;//SetTHRinRatio(g_takeoffTHR); //0.7;スロットルの割合
01709 }
01710 
01711 
01712 //ヨーを目標値にして許容角度になるまで水平旋回
01713 int Rotate(float targetAngle[3], float TargetYAW)
01714 {
01715     float diffYaw = TranslateNewYaw(TargetYAW, nowAngle[YAW]);
01716 
01717     if(diffYaw > LIMIT_STRAIGHT_YAW) {
01718         
01719         if(diffYaw > THRESHOLD_TURNINGRADIUS_YAW) UpdateTargetAngle_Rightloop_short(targetAngle);
01720         else UpdateTargetAngle_Rightloop(targetAngle);
01721         
01722         //UpdateTargetAngle_Rightloop_short(targetAngle);
01723         return 1;
01724     } else if(diffYaw < -LIMIT_STRAIGHT_YAW) {
01725         
01726         if(diffYaw < -THRESHOLD_TURNINGRADIUS_YAW) UpdateTargetAngle_Leftloop_short(targetAngle);
01727         else UpdateTargetAngle_Leftloop(targetAngle);
01728         
01729         //UpdateTargetAngle_Leftloop_short(targetAngle);
01730         
01731         return 1;
01732     } else {
01733         UpdateTargetAngle_GoStraight(targetAngle);
01734         return 0;
01735     }
01736 }
01737 
01738 int Rotate_zero(float targetAngle[3], float TargetYAW){
01739     float diffYaw = TranslateNewYaw(TargetYAW, nowAngle[YAW]);
01740 
01741     if(diffYaw > LIMIT_STRAIGHT_YAW) {
01742         
01743         /*if(diffYaw > THRESHOLD_TURNINGRADIUS_YAW) UpdateTargetAngle_Rightloop_short(targetAngle);
01744         else UpdateTargetAngle_Rightloop(targetAngle);
01745         */
01746         UpdateTargetAngle_Rightloop_zero(targetAngle);
01747         return 1;
01748     } else if(diffYaw < -LIMIT_STRAIGHT_YAW) {
01749         
01750         /*if(diffYaw < -THRESHOLD_TURNINGRADIUS_YAW) UpdateTargetAngle_Leftloop_short(targetAngle);
01751         else UpdateTargetAngle_Leftloop(targetAngle);
01752         */
01753         UpdateTargetAngle_Leftloop_zero(targetAngle);
01754         
01755         return 1;
01756     } else {
01757         UpdateTargetAngle_GoStraight_zero(targetAngle);
01758         return 0;
01759     }
01760 }
01761 
01762 //チキラー投下
01763 void Chicken_Drop()
01764 {
01765     //if(CheckSW_Up(Ch7)) {
01766         autopwm[DROP] = maxpwm[DROP];
01767         //pc.printf("Bombed!\r\n");
01768         //RerurnChickenServo1.attach(&ReturnChickenServo1, 3);
01769         //operation_mode = Approach;
01770         //buzzer = 0;
01771         //pc.printf("Goto LeftLoop mode\r\n");
01772     //}
01773 }
01774 
01775 void ReturnChickenServo1()
01776 {
01777     autopwm[DROP] = 1344;
01778     pc.printf("first reverse\r\n");
01779     RerurnChickenServo2.attach(&ReturnChickenServo2, 1);
01780 }
01781 
01782 void ReturnChickenServo2()
01783 {
01784     autopwm[DROP] = 1392;
01785     pc.printf("second reverse\r\n");
01786 }
01787 
01788 //着陸モード(PCからの指令に従う)
01789 void UpdateTargetAngle_Approach(float targetAngle[3])
01790 {
01791 
01792     static bool Zeroflag=false;//着陸時のスロットル動作確認用
01793 
01794     NVIC_DisableIRQ(USART2_IRQn);
01795 
01796     if(CheckSW_Up(Ch7)) {
01797         output_status = Auto;
01798         led1 = 1;
01799     } else {
01800         output_status = Manual;
01801         led1 = 0;
01802         Zeroflag=true;
01803         //g_landingcommand='G';
01804     }
01805 
01806     //pc.printf("Zeroflag = %d\r\n",Zeroflag);
01807 
01808     switch(g_landingcommand) {
01809         case 'R':   //右旋回セヨ
01810             NVIC_EnableIRQ(USART2_IRQn);
01811             if(Zeroflag==true){
01812             UpdateTargetAngle_Rightloop_zero(targetAngle);
01813             }
01814             else{
01815                 UpdateTargetAngle_Rightloop(targetAngle);
01816                 /*
01817                 targetAngle[ROLL] = g_rightloopROLL_approach;
01818                 targetAngle[PITCH] = g_rightloopPITCH_approach ;
01819                 autopwm[RUD]=g_rightloopRUD_approach; //RUD固定
01820                 if(autopwm[AIL_R]<trimpwm[AIL_R]){                                                                                  //エルロン上がりやすさ調節
01821                     autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;
01822                 }
01823                 else {autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;
01824                 autopwm[AIL_R]=autopwm[AIL_R]+AIL_R_correctionrightloop;
01825                 */
01826             }
01827 
01828             break;
01829 
01830         case 'L':   //左旋回セヨ
01831             NVIC_EnableIRQ(USART2_IRQn);
01832             if(Zeroflag==true){
01833                 UpdateTargetAngle_Leftloop_zero(targetAngle);
01834                 }else{
01835                 UpdateTargetAngle_Leftloop(targetAngle);
01836                 /*targetAngle[ROLL] = g_leftloopROLL_approach;
01837                 targetAngle[PITCH] = g_leftloopPITCH_approach;
01838                 autopwm[RUD]=g_leftloopRUD_approach;
01839                 if(autopwm[AIL_R]<trimpwm[AIL_R]){
01840                     autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionleftloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;
01841                 }
01842                 else autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionleftloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;
01843                 */
01844             }
01845 
01846             break;
01847 
01848         case 'G':   //直進セヨ
01849             NVIC_EnableIRQ(USART2_IRQn);
01850             if(Zeroflag==true){
01851             UpdateTargetAngle_GoStraight_zero(targetAngle);
01852             }
01853             else{
01854                 UpdateTargetAngle_GoStraight(targetAngle);
01855                 /*
01856                 targetAngle[ROLL] = g_gostraightROLL;
01857                 targetAngle[PITCH] = g_gostraightPITCH;
01858                 */
01859             }
01860 
01861             break;
01862 
01863         case 'Y':   //指定ノヨー方向ニ移動セヨ
01864             NVIC_EnableIRQ(USART2_IRQn);
01865             if(Zeroflag==true){
01866                 Rotate_zero(targetAngle, g_SerialTargetYAW);
01867                 //autopwm[THR]=minpwm[THR];
01868             }else{
01869                 Rotate(targetAngle, g_SerialTargetYAW);
01870                 //autopwm[THR]=SetTHRinRatio(g_loopTHR+0.05);
01871                 }
01872             break;
01873             
01874         case 'T':   //0度ノヨー方向ニ移動セヨ
01875             NVIC_EnableIRQ(USART2_IRQn);
01876             if(Zeroflag==true){
01877                 Rotate_zero(targetAngle, 0);
01878                 //autopwm[THR]=minpwm[THR];
01879             }else{
01880                 Rotate(targetAngle, 0);
01881                 //autopwm[THR]=SetTHRinRatio(g_loopTHR+0.05);
01882                 }
01883             break;    
01884 
01885         case 'U':   //機首ヲ上ゲヨ
01886             NVIC_EnableIRQ(USART2_IRQn);
01887             static int UpCounter=0;
01888             UpCounter++;
01889             if(UpCounter==3) {
01890                 g_Finflag = true;
01891             }
01892 
01893             break;
01894             
01895         case 'Z':   //ヤレバワカル
01896             NVIC_EnableIRQ(USART2_IRQn);
01897             autopwm[THR] = minpwm[THR];
01898             autopwm[ELE] = minpwm[ELE];
01899             autopwm[RUD]=trimpwm[RUD];
01900             autopwm[AIL_R] = minpwm[AIL_R];
01901             autopwm[AIL_L]= maxpwm[AIL_L];
01902             targetAngle[ROLL] = -80;
01903 
01904             break;
01905 
01906         /*case 'B':   //ブザーヲ鳴ラセ
01907             //buzzer = 1;
01908             NVIC_EnableIRQ(USART2_IRQn);
01909             break;*/
01910 
01911         case 'B':   //物資ヲ落トセ
01912             NVIC_EnableIRQ(USART2_IRQn);
01913             Chicken_Drop();
01914             if(Zeroflag==true){
01915                 Rotate_zero(targetAngle, 0);
01916                 //autopwm[THR]=minpwm[THR];
01917             }else{
01918                 Rotate(targetAngle, 0);
01919                 //autopwm[THR]=SetTHRinRatio(g_loopTHR+0.05);
01920                 }
01921 
01922             break;
01923 
01924         case 'C':   //停止セヨ
01925             NVIC_EnableIRQ(USART2_IRQn);
01926             /*targetAngle[ROLL] = g_gostraightROLL;
01927             targetAngle[PITCH] = g_gostraightPITCH;
01928             autopwm[THR] = minpwm[THR];
01929             */
01930             Zeroflag = true;
01931             if(Zeroflag==true){
01932                 Rotate_zero(targetAngle, 0);
01933                 //autopwm[THR]=minpwm[THR];
01934             }else{
01935                 Rotate(targetAngle, 0);
01936                 //autopwm[THR]=SetTHRinRatio(g_loopTHR+0.05);
01937                 }
01938             
01939             break;
01940             
01941         case 'X':   //再起動セヨ
01942             NVIC_EnableIRQ(USART2_IRQn);
01943             /*
01944             targetAngle[ROLL] = g_gostraightROLL;
01945             targetAngle[PITCH] = g_gostraightPITCH;
01946             autopwm[THR] = minpwm[THR];
01947             */
01948             Zeroflag = false;
01949             if(Zeroflag==true){
01950                 Rotate_zero(targetAngle, 0);
01951                 //autopwm[THR]=minpwm[THR];
01952             }else{
01953                 Rotate(targetAngle, 0);
01954                 //autopwm[THR]=SetTHRinRatio(g_loopTHR+0.05);
01955                 }
01956                 
01957             break;
01958 
01959         default :
01960             NVIC_EnableIRQ(USART2_IRQn);
01961             break;
01962 
01963 
01964     }
01965 
01966 }
01967 
01968 void checkHeight(float targetAngle[3])
01969 {
01970 
01971     static int targetHeight = 200;
01972 
01973     NVIC_DisableIRQ(EXTI9_5_IRQn);
01974     if(g_distance < targetHeight + ALLOWHEIGHT) {
01975         UpdateTargetAngle_NoseUP(targetAngle);
01976         if(CheckSW_Up(Ch7)) led2 = 1;
01977     } else if(g_distance > targetHeight - ALLOWHEIGHT) {
01978         UpdateTargetAngle_NoseDOWN(targetAngle);
01979         if(CheckSW_Up(Ch7)) led2 = 1;
01980     } else led2=0;
01981     NVIC_EnableIRQ(EXTI9_5_IRQn);
01982 }
01983 
01984 void UpdateTargetAngle_NoseUP(float targetAngle[3])
01985 {
01986 
01987     //targetAngle[PITCH] += 2.0f;
01988     //if(nowAngle[PITCH]<targetAngle[PITCH]) autopwm[THR] = SetTHRinRatio(0.6);
01989     autopwm[THR] = SetTHRinRatio(g_loopTHR+0.05);
01990     //pc.printf("nose UP");
01991 }
01992 
01993 void UpdateTargetAngle_NoseDOWN(float targetAngle[3])
01994 {
01995 
01996     //targetAngle[PITCH] -= 2.0f;
01997     autopwm[THR] = SetTHRinRatio(g_loopTHR-0.05);
01998     //pc.printf("nose DOWN");
01999 }
02000 
02001 //直進
02002 void UpdateTargetAngle_GoStraight(float targetAngle[3])
02003 {
02004 
02005     autopwm[RUD] = trimpwm[RUD];
02006     targetAngle[ROLL] = g_gostraightROLL;
02007     targetAngle[PITCH] = g_gostraightPITCH;
02008     autopwm[THR] = SetTHRinRatio(g_loopTHR);
02009     
02010     if(autopwm[AIL_R]<trimpwm[AIL_R]){                                                                                  //エルロン上がりやすさ調節
02011             autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;  //エルロンサーボ二つ使用時
02012         }
02013         else autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;
02014     
02015     autopwm[AIL_R]=autopwm[AIL_R]+AIL_R_correctionrightloop;
02016 
02017     //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
02018 }
02019 
02020 //直進(着陸時スロットル0のとき)
02021 void UpdateTargetAngle_GoStraight_zero(float targetAngle[3])
02022 {
02023 
02024     autopwm[RUD] =  trimpwm[RUD];
02025     targetAngle[ROLL] = g_gostraightROLL;
02026     targetAngle[PITCH] = -7.0;//g_gostraightPITCH;
02027     autopwm[THR] = minpwm[THR];
02028     
02029     if(autopwm[AIL_R]<trimpwm[AIL_R]){                                                                                  //エルロン上がりやすさ調節
02030             autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;  //エルロンサーボ二つ使用時
02031         }
02032         else autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;
02033 
02034     //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
02035 }
02036 
02037 //右旋回
02038 void UpdateTargetAngle_Rightloop(float targetAngle[3])  //右旋回
02039 {
02040     targetAngle[ROLL] = g_rightloopROLL;
02041     targetAngle[PITCH] = g_rightloopPITCH;
02042     autopwm[RUD]=g_rightloopRUD;              //RUD固定
02043     autopwm[THR] = SetTHRinRatio(g_rightloop_THR_rate);                  //手動スロットル記憶
02044 
02045     /*
02046     if (nowAngle[ROLL]>20.0||nowAngle[ROLL]<-20.0){
02047         t2.start();
02048         pc.printf("Timer start.");
02049     }
02050     if(0.0<t2.read()<5.0){
02051             //pc.printf("tagetAngle is changed.");
02052             targetAngle[ROLL] = rightloopROLL2;
02053             }
02054     else {
02055         t2.stop();
02056         t2.reset();
02057         pc.printf("Timer stopped.");
02058         targetAngle[ROLL] = g_rightloopROLL;
02059     }
02060     */
02061     if(autopwm[AIL_R]<trimpwm[AIL_R]){                                                                                  //エルロン上がりやすさ調節
02062             autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;  //エルロンサーボ二つ使用時
02063         }
02064         else autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;
02065     
02066     autopwm[AIL_R]=autopwm[AIL_R]+AIL_R_correctionrightloop;
02067 
02068 
02069     //checkHeight(targetAngle);
02070     //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
02071 }
02072 
02073 void UpdateTargetAngle_Rightloop_UP(float targetAngle[3])  //右上昇旋回
02074 { 
02075     //autopwm[ELE]=maxpwm[ELE];
02076     targetAngle[ROLL] = g_ascending_ROLL;
02077     targetAngle[PITCH] = g_ascendingPITCH;
02078     autopwm[RUD]=g_ascending_RUD;              //RUD固定
02079     autopwm[THR] = SetTHRinRatio(g_ascending_THR_rate);                  //手動スロットル記憶
02080 
02081     /*
02082     if (nowAngle[ROLL]>20.0||nowAngle[ROLL]<-20.0){
02083         t2.start();
02084         pc.printf("Timer start.");
02085     }
02086     if(0.0<t2.read()<5.0){
02087             //pc.printf("tagetAngle is changed.");
02088             targetAngle[ROLL] = rightloopROLL2;
02089             }
02090     else {
02091         t2.stop();
02092         t2.reset();
02093         pc.printf("Timer stopped.");
02094         targetAngle[ROLL] = g_rightloopROLL;
02095     }
02096     */
02097     if(autopwm[AIL_R]<trimpwm[AIL_R]){                                                                                  //エルロン上がりやすさ調節
02098             autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;  //エルロンサーボ二つ使用時
02099         }
02100         else autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;
02101     
02102     autopwm[AIL_R]=autopwm[AIL_R]+AIL_R_correctionrightloop;
02103 
02104 
02105     //checkHeight(targetAngle);
02106     //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
02107 }
02108 
02109 //右旋回(着陸時スロットル0の時)
02110 void UpdateTargetAngle_Rightloop_zero(float targetAngle[3])  //右旋回
02111 {
02112     autopwm[THR]=minpwm[THR];
02113     targetAngle[ROLL] = g_rightloopROLL_approach;
02114     targetAngle[PITCH] = g_rightloopPITCH_approach ;
02115     autopwm[RUD]=g_rightloopRUD_approach;              //RUD固定
02116     if(autopwm[AIL_R]<trimpwm[AIL_R]){                                                                                  //エルロン上がりやすさ調節
02117             autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;  //エルロンサーボ二つ使用時
02118         }
02119         else autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;
02120     
02121     autopwm[AIL_R]=autopwm[AIL_R]+AIL_R_correctionrightloop;
02122 
02123     //checkHeight(targetAngle);
02124     //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
02125 }
02126 
02127 void UpdateTargetAngle_Rightloop_short(float targetAngle[3])  //右旋回
02128 {
02129 
02130     targetAngle[ROLL] = g_rightloopROLLshort;
02131     targetAngle[PITCH] = g_rightloopPITCHshort;
02132     autopwm[RUD]=g_rightloopshortRUD;
02133     autopwm[THR] = SetTHRinRatio(g_rightloop_THR_rate);
02134     if(autopwm[AIL_R]<trimpwm[AIL_R]){
02135             autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloopshort+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;
02136             }
02137         else autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionrightloopshort+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;  //エルロンサーボ二つ使用時
02138     
02139     //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
02140 }
02141 
02142 
02143 //左旋回
02144 void UpdateTargetAngle_Leftloop(float targetAngle[3])
02145 {
02146 
02147     targetAngle[ROLL] = g_leftloopROLL;
02148     targetAngle[PITCH] = g_leftloopPITCH;
02149     //autopwm[ELE] = 1700;
02150     autopwm[RUD]=g_leftloopRUD;
02151     autopwm[THR] = SetTHRinRatio(g_leftloop_THR_rate);
02152     if(autopwm[AIL_R]<trimpwm[AIL_R]){
02153             autopwm[AIL_L]=trimpwm[AIL_L]+g_AIL_L_correctionleftloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;
02154             }
02155         else autopwm[AIL_L]=trimpwm[AIL_L]+g_AIL_L_correctionleftloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;  //エルロンサーボ二つ使用時
02156     
02157     //checkHeight(targetAngle);
02158 
02159     //printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[], targetAngle[PITCH], autopwm[THR]);
02160 }
02161 
02162 //左旋回(着陸時スロットル0のとき)
02163 void UpdateTargetAngle_Leftloop_zero(float targetAngle[3])
02164 {
02165 
02166     targetAngle[ROLL] = g_leftloopROLL_approach;
02167     targetAngle[PITCH] = g_leftloopPITCH_approach;
02168     autopwm[RUD]=g_leftloopRUD_approach;
02169     autopwm[THR] = minpwm[THR];
02170     if(autopwm[AIL_R]<trimpwm[AIL_R]){
02171             autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionleftloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;
02172             }
02173         else autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionleftloop+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;  //エルロンサーボ二つ使用時
02174     
02175     //autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionleftloopshort+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_Ratio_leftloop;
02176     //checkHeight(targetAngle);
02177 
02178     //printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[], targetAngle[PITCH], autopwm[THR]);
02179 }
02180 
02181 void UpdateTargetAngle_Leftloop_short(float targetAngle[3])
02182 {
02183 
02184     targetAngle[ROLL] = g_leftloopROLLshort;
02185     targetAngle[PITCH] = g_leftloopPITCHshort;
02186     autopwm[RUD]=g_leftloopRUD;
02187     autopwm[THR] = SetTHRinRatio(g_leftloop_THR_rate);
02188     if(autopwm[AIL_R]<trimpwm[AIL_R]){
02189             autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionleftloopshort+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioRising;
02190             }
02191         else autopwm[AIL_L]=trimpwm[AIL_L]+AIL_L_correctionleftloopshort+(autopwm[AIL_R]-trimpwm[AIL_R])*AIL_L_RatioDescent;  //エルロンサーボ二つ使用時
02192     
02193     //pc.printf("Roll = %f, PITCH = %f, THR = %d \r\n", targetAngle[ROLL], targetAngle[PITCH], autopwm[THR]);
02194 }
02195 
02196 void Ascending(float targetAngle[3]){
02197     static uint8_t RotateCounter=0;
02198     static bool LapCounter = false;
02199     static bool UpFlag = false;
02200     static bool PressFlag = false;
02201     static float FirstHeight = 0;
02202     static bool flg_setInStartAuto = false;
02203     //static float Time = 0.0;
02204     static float FirstYaw_Ascending = 0;
02205     float newYaw_Ascending;
02206     
02207     //pc.printf("FirstHeight = %f  g_z_comp = %f   g_AscendingFlag = %d\r\n",FirstHeight,g_z_comp,g_AscendingFlag);  
02208     
02209     getBMP280();
02210     
02211     if(!flg_setInStartAuto && CheckSW_Up(Ch7)) {
02212         FirstYaw_Ascending = nowAngle[YAW];
02213         RotateCounter = 0;
02214         flg_setInStartAuto = true;
02215         LapCounter = false;
02216         UpFlag = false;
02217         PressFlag = false;
02218         //tBMP.reset();
02219     } else if(!CheckSW_Up(Ch7)) {
02220         flg_setInStartAuto = false;
02221         led4 = 0;
02222     }
02223     
02224     newYaw_Ascending = TranslateNewYaw(nowAngle[YAW], FirstYaw_Ascending);
02225 
02226     if(RotateCounter == 0 && newYaw_Ascending >90.0 && newYaw_Ascending < 180.0)    {
02227         RotateCounter++;
02228         led4 = 1;
02229         pc.printf("Rotate 90\r\n");
02230     }
02231     if(RotateCounter == 1 && newYaw_Ascending >-180.0 && newYaw_Ascending < -90.0)  {
02232         RotateCounter++;
02233         led4 = 0;
02234         pc.printf("Rotate 180\r\n");
02235     }
02236     if(RotateCounter == 2 && newYaw_Ascending >-90.0 && newYaw_Ascending <-20.0)   {
02237         RotateCounter++;
02238         led4 = 1;
02239         pc.printf("Rotate 270\r\n");
02240     }
02241     if(RotateCounter == 3 && newYaw_Ascending >-10.0 && newYaw_Ascending < 90.0)     {
02242         RotateCounter++;
02243         led4 = 0;
02244         if(LapCounter == false){
02245             RotateCounter = 0;
02246             LapCounter = true;
02247             pc.printf("Lap2\r\n");
02248             }
02249     }
02250     
02251     if(RotateCounter <= 3){
02252         UpdateTargetAngle_Rightloop(targetAngle);
02253     }else if(3 < RotateCounter && UpFlag == false){
02254         if(PressFlag == false){
02255             FirstHeight = g_z_comp;
02256             //tBMP.start();
02257             PressFlag = true;
02258             led4 = 1;
02259             }
02260         //Time = tBMP.read();    
02261         if(g_z_comp > FirstHeight+3000){
02262             UpFlag = true;
02263             led4 = 0;
02264             }
02265         UpdateTargetAngle_Rightloop_UP(targetAngle);
02266         }else{
02267      UpdateTargetAngle_Rightloop(targetAngle);
02268      }
02269          
02270     
02271 }    
02272 
02273 void Sbusprintf() 
02274 {
02275 
02276     for(uint8_t i=0; i<8; i++) pc.printf("ch.%d = %d ",i+1,sbus.manualpwm[i]);
02277     pc.printf("\r\n");
02278 
02279 }
02280 
02281 
02282 //---sensing---
02283 //センサーの値を読み込み、各種フィルタをかける(認知)
02284 void sensing()
02285 {
02286     // If intPin goes high, all data registers have new data
02287     if(mpu9250.readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) {  // On interrupt, check if data ready interrupt
02288 
02289         mpu9250.readAccelData(accelCount);  // Read the x/y/z adc values   
02290         // Now we'll calculate the accleration value into actual g's
02291         ax = (float)accelCount[0]*aRes - accelBias[0];  // get actual g value, this depends on scale being set
02292         ay = (float)accelCount[1]*aRes - accelBias[1];   
02293         az = (float)accelCount[2]*aRes - accelBias[2];  
02294    
02295         mpu9250.readGyroData(gyroCount);  // Read the x/y/z adc values
02296         // Calculate the gyro value into actual degrees per second
02297         gx = (float)gyroCount[0]*gRes - gyroBias[0];  // get actual gyro value, this depends on scale being set
02298         gy = (float)gyroCount[1]*gRes - gyroBias[1];  
02299         gz = (float)gyroCount[2]*gRes - gyroBias[2];   
02300   
02301         mpu9250.readMagData(magCount);  // Read the x/y/z adc values   
02302         // Calculate the magnetometer values in milliGauss
02303         // Include factory calibration per data sheet and user environmental corrections
02304         mx = (float)magCount[0]*mRes*magCalibration[0] - magbias[0];  // get actual magnetometer value, this depends on scale being set
02305         my = (float)magCount[1]*mRes*magCalibration[1] - magbias[1];  
02306         mz = (float)magCount[2]*mRes*magCalibration[2] - magbias[2];   
02307     }
02308    
02309     Now = t.read_us();
02310     deltat = (float)((Now - lastUpdate)/1000000.0f) ; // set integration time by time elapsed since last filter update
02311     lastUpdate = Now;
02312     
02313     g_sum += deltat;
02314     g_sumCount++;
02315     
02316 //  if(lastUpdate - firstUpdate > 10000000.0f) {
02317 //      beta = 0.04;  // decrease filter gain after stabilized
02318 //      zeta = 0.015; // increasey bias drift gain after stabilized
02319 //  }
02320     
02321    // Pass gyro rate as rad/s
02322     mpu9250.MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f,  mx,  my, mz);
02323    // mpu9250.MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f,  my,  mx, mz);
02324     
02325     mpu9250.MahonyQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f, mx, my, mz);
02326    // mpu9250.MahonyQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f, my, mx, mz);
02327 
02328     /*  Auto_Loop()で50ms待ってるから要らないと思う
02329     // Serial print and/or display at 0.5 s rate independent of data rates
02330     delt_t = t.read_ms() - count;
02331     if (delt_t > 500) { // update LCD once per half-second independent of read rate
02332     */
02333 
02334     //pc.printf("ax = %f", 1000*ax); 
02335     //pc.printf(" ay = %f", 1000*ay); 
02336     //pc.printf(" az = %f  mg\n\r", 1000*az); 
02337 
02338     //pc.printf("gx = %f", gx); 
02339     //pc.printf(" gy = %f", gy); 
02340     //pc.printf(" gz = %f  deg/s\n\r", gz); 
02341     
02342     //pc.printf("mx = %f,", mx); 
02343     //pc.printf(" my = %f,", my); 
02344     //pc.printf(" mz = %f  mG\n\r", mz); 
02345     
02346     tempCount = mpu9250.readTempData();  // Read the adc values
02347     temperature = ((float) tempCount) / 333.87f + 21.0f; // Temperature in degrees Centigrade
02348     //pc.printf(" temperature = %f  C\n\r", temperature); 
02349     
02350     //pc.printf("q0 = %f\n\r", q[0]);
02351     //pc.printf("q1 = %f\n\r", q[1]);
02352     //pc.printf("q2 = %f\n\r", q[2]);
02353     //pc.printf("q3 = %f\n\r", q[3]);      
02354     
02355       
02356   // Define output variables from updated quaternion---these are Tait-Bryan angles, commonly used in aircraft orientation.
02357   // In this coordinate system, the positive z-axis is down toward Earth. 
02358   // Yaw is the angle between Sensor x-axis and Earth magnetic North (or true North if corrected for local declination, looking down on the sensor positive yaw is counterclockwise.
02359   // Pitch is angle between sensor x-axis and Earth ground plane, toward the Earth is positive, up toward the sky is negative.
02360   // Roll is angle between sensor y-axis and Earth ground plane, y-axis up is positive roll.
02361   // These arise from the definition of the homogeneous rotation matrix constructed from quaternions.
02362   // Tait-Bryan angles as well as Euler angles are non-commutative; that is, the get the correct orientation the rotations must be
02363   // applied in the correct order which for this configuration is yaw, pitch, and then roll.
02364   // For more see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles which has additional links.
02365     yaw   = atan2(2.0f * (q[1] * q[2] + q[0] * q[3]), q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3]);   
02366     roll = -asin(2.0f * (q[1] * q[3] - q[0] * q[2]));
02367     pitch  = atan2(2.0f * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3]);
02368     pitch *= 180.0f / PI;
02369     yaw   *= 180.0f / PI; 
02370     yaw   -= 13.8f; // Declination at Danville, California is 13 degrees 48 minutes and 47 seconds on 2014-04-04
02371     roll  *= 180.0f / PI;
02372 
02373     //pc.printf("$%d %d %d;",(int)(yaw*100),(int)(pitch*100),(int)(roll*100));
02374     //pc.printf("Yaw: %f  Pitch:%f  Roll:%f\n\r",  yaw,   pitch,   roll);
02375     //pc.printf("average rate = %f\n\r", (float) sumCount/sum);
02376  
02377     count = t.read_ms(); 
02378     g_sum = 0;
02379     g_sumCount = 0; 
02380     //}           
02381 }
02382 
02383 void SetupBMP280(){
02384     bmp.initialize(BMP280::INDOOR_NAVIGATION);
02385     
02386     for(int sn = 0; sn < 100; sn++){
02387         g_press = bmp.getPressure();
02388         if(sn > 0){
02389             g_InitPress[sn] = g_press;
02390             g_InitPressAve += g_InitPress[sn];
02391             float press_ratio = g_st_press / g_press;
02392             g_InitBMPHeight[sn] = ((powf(press_ratio, 0.19) - 1) * 298.15 * 1000) / 0.0065;
02393             g_InitBMPHeightAve += g_InitBMPHeight[sn];
02394 
02395         }
02396         pc.printf("%f,%f\r\n", g_InitBMPHeight[sn],g_InitPress[sn]);
02397         wait(0.05);
02398     }
02399     
02400     g_InitPressAve /= 100.0;
02401 
02402     g_InitBMPHeightAve /= 100.0;
02403     
02404     pc.printf("\r\n%f,%f\r\n\r\n", g_InitBMPHeightAve,g_InitPressAve);
02405         
02406     pc.printf("bmp280 initialized\r\n");    
02407     
02408     g_BMPheight = g_InitBMPHeightAve;
02409     
02410     tBMP.start();//dtを計測
02411    
02412     sensing();//最初だけ空回し
02413     
02414     g_tempaz[0] = az * g_grav * 1000;
02415     
02416 }
02417 
02418 void getBMP280(){
02419         float z_angle, gyro_ver, z_angle_prev;
02420         static float press_rel_coef = 0.03;
02421         float press_ratio = g_st_press / g_press;
02422         
02423         g_z_PressHeight = g_BMPheight;
02424         
02425         z_angle = atan2(sqrt(ax * ax + ay * ay), az);
02426         gyro_ver = cos(z_angle);   //垂直方向の加速度
02427         
02428         g_dt = tBMP.read_us();
02429         g_dt /= 1000000;
02430         tBMP.reset();
02431         tBMP.start();
02432         
02433         
02434         g_z_AccelHeight = g_z_prev - g_v_prev * g_dt - (az - gyro_ver) * g_grav *1000* g_dt * g_dt / 2;
02435             
02436         g_z_comp = g_z_PressHeight* press_rel_coef + g_z_AccelHeight* (1 - press_rel_coef);//係数は足して1になるように適当に設定,単位はmm
02437         
02438         //pc.printf("%f\r\n",g_z_comp/1000);
02439         
02440         g_BMPheight_int = g_z_comp;
02441         
02442         g_press = bmp.getPressure();
02443     
02444         g_BMPheight = ((powf(press_ratio, 0.19) - 1) * 298.15 *1000) / 0.0065 - g_InitBMPHeightAve;
02445               
02446         NVIC_DisableIRQ(USART1_IRQn);
02447         NVIC_DisableIRQ(USART2_IRQn);
02448         NVIC_DisableIRQ(TIM5_IRQn);
02449         NVIC_DisableIRQ(EXTI0_IRQn);//MPU割り込み禁止
02450         NVIC_DisableIRQ(EXTI9_5_IRQn);//超音波割り込み禁止
02451         sensing();      
02452         NVIC_EnableIRQ(USART1_IRQn);
02453         NVIC_EnableIRQ(USART2_IRQn);
02454         NVIC_EnableIRQ(TIM5_IRQn);
02455         NVIC_EnableIRQ(EXTI0_IRQn);
02456         NVIC_EnableIRQ(EXTI9_5_IRQn);
02457         
02458         g_v_prev = (g_z_comp - g_z_prev) / g_dt / 1000000;
02459         
02460         g_z_prev = g_z_comp;
02461         
02462         
02463         //wait_ms(1.0);
02464         
02465 }
02466 
02467 
02468 
02469 //デバッグ用=
02470 void DebugPrint()
02471 {
02472  /*
02473     static int16_t deltaT = 0, t_start = 0;
02474     //deltaT = t.read_u2s() - t_start;
02475     pc.printf("t:%d us, ",deltaT);
02476     pc.printf("\r\n");
02477     t_start = t.read_us();
02478     
02479     for(uint8_t i=0; i<6; i++) pc.printf("sbus.manualpwm[%d]:%d ",i,sbus.manualpwm[i]);
02480     if(g_trim_check){
02481         for(uint8_t i=0; i<6; i++) pc.printf("sbus.manualpwm[%d]:%d ",i,sbus.manualpwm[i]);
02482         pc.printf("\r\n");
02483         }
02484  */
02485     //pc.printf("trimpwm[AIL_R]:%d ELE:%d THR:%d RUD:%d 4:%d AIL_L:%d\n",trimpwm[AIL_R],trimpwm[ELE],trimpwm[THR],trimpwm[RUD],trimpwm[4],trimpwm[AIL_L]);
02486     //for(uint8_t i=0; i<8; i++) pc.printf("sbus.manualpwm[%d]:%d ",i,sbus.manualpwm[i]);
02487     /*for(uint8_t i=1; i<4; i++) pc.printf("sbus.manualpwm[%d]:%d ",i,sbus.manualpwm[i]);
02488     pc.printf("\r\n");
02489     for(uint8_t i=0; i<3; i++) pc.printf("nowangle[%d]:%3.2f\t",i,nowAngle[i]);
02490     for(uint8_t i=0; i<2; i++) pc.printf("nowangle[%d]:%3.2f\t",i,nowAngle[i]); //ロール、ピッチのみ 小数点以下2ケタ
02491     pc.printf("nowangle[pitch]:%3.2f\t\r\n",nowAngle[2]);
02492     pc.printf("autopwm[ELE]:%d\t\r\n",autopwm[ELE]);
02493     pc.printf("autpwm[RUD]:%d\t",autopwm[RUD]);*/
02494     //NVIC_DisableIRQ(EXTI9_5_IRQn);
02495     pc.printf("g_distance:%d\t",g_distance);
02496     //NVIC_EnableIRQ(EXTI9_5_IRQn);
02497     /*pc.printf("Mode: %c: ",g_buf[0]);
02498     if(g_buf[0] == 'Y') pc.printf(" %3.1f",g_SerialTargetYAW);
02499     pc.printf("%f",g_z_comp);
02500     pc.printf("\r\n%f,%f\r\n", g_InitBMPHeightAve,g_InitPressAve);*/
02501     pc.printf("\r\n");
02502     
02503 }