Bot Furukawa / Mbed 2 deprecated Estrela_v12

Dependencies:   BMP280 mbed

Revision:
0:248f3186c666
diff -r 000000000000 -r 248f3186c666 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat May 20 10:05:35 2017 +0000
@@ -0,0 +1,951 @@
+#include "mbed.h"
+//#include "rtos.h"
+#include "MPU9250.h"
+#include "BMP280.h"
+#include "SkipperSv2.h"
+#include "Estrela.h"
+//#include "stm32f4xx_hal_iwdg.h"
+
+
+#define UPD_MANUAL  0
+#define UPD_AUTO    1
+#define UPD_LANDING 2
+
+#define SBUS_SIGNAL_OK          0x00
+#define SBUS_SIGNAL_LOST        0x01
+#define SBUS_SIGNAL_FAILSAFE    0x03
+
+//Serial pc(TX, RX);
+RawSerial sbus_(PA_9, PA_10); //SBUS
+
+PwmOut servo1(PC_6); // TIM3_CH1
+PwmOut servo2(PC_7); // TIM3_CH2    //PC_7
+PwmOut servo3(PB_0); // TIM3_CH3
+PwmOut servo4(PB_1); // TIM3_CH4
+PwmOut servo5(PB_6); // TIM4_CH1
+PwmOut servo6(PB_7); // TIM4_CH2
+PwmOut servo7(PB_8); // TIM4_CH3    //PB_8
+PwmOut servo8(PB_9); // TIM4_CH4
+
+RawSerial pc(PA_2, PA_3);
+
+DigitalOut led1(PA_0);  //緑
+DigitalOut led2(PA_1);  //赤
+DigitalOut led3(PB_4);  //赤外線
+DigitalOut led4(PB_5);
+
+volatile uint8_t buf_sbus[25]; 
+volatile int cnt_sbus = 0;
+static int16_t channels[18];
+uint8_t  failsafe_status = SBUS_SIGNAL_FAILSAFE;
+static bool flg_ch_update = false;
+//uint8_t i,j,k;
+uint8_t update_mode = 0;
+static uint16_t pwm[8];
+static uint16_t oldTHL;
+
+//9軸センサー関連
+float sum = 0;
+uint32_t sumCount = 0;
+MPU9250 mpu9250;
+Timer t;
+
+/*
+float g_BefGyro[3] = {0,0,0};
+double g_HpfGyro[3] = {0,0,0};
+double g_HpfGyro1[3] = {0,0,0};
+double g_LpfAccel[3] = {0,0,0};
+*/
+
+static int jj = 0;
+
+//IWDG_HandleTypeDef hiwdg;
+
+void disp_clock(){
+    pc.printf("System Clock = %d[MHz]\r\n", HAL_RCC_GetSysClockFreq()/1000000);
+    pc.printf("HCLK Clock   = %d[MHz]\r\n", HAL_RCC_GetHCLKFreq()/1000000);
+    pc.printf("PCLK1 Clock  = %d[MHz]\r\n", HAL_RCC_GetPCLK1Freq()/1000000);
+    pc.printf("PCLK2 Clock  = %d[MHz]\r\n", HAL_RCC_GetPCLK2Freq()/1000000);
+    pc.printf("\r\n");
+    }
+
+//サーボ初期化関数
+void init_Servo()
+{
+    uint8_t j = 0;
+    
+    servo1.period_ms(14);
+    servo1.pulsewidth_us(1500);
+    
+    servo2.period_ms(14);
+    servo2.pulsewidth_us(1500);
+    
+    servo3.period_ms(14);
+    servo3.pulsewidth_us(1000);
+    
+    servo4.period_ms(14);
+    servo4.pulsewidth_us(1500);
+    
+    servo5.period_ms(14);
+    servo5.pulsewidth_us(1500);
+    
+    servo6.period_ms(14);
+    servo6.pulsewidth_us(1500);
+    
+    servo7.period_ms(14);
+    servo7.pulsewidth_us(1500);
+    
+    servo8.period_ms(14);
+    servo8.pulsewidth_us(1500);
+    
+    for (j=0; j<8; j++) {pwm[j] = 1500;}
+    pc.printf("servo initialized\r\n");
+}
+
+//---setall_servo---
+//pwmをサーボに出力する関数。
+void setall_servo()
+{
+    uint8_t j = 0;
+    
+    //if(failsafe_status == SBUS_SIGNAL_OK){
+    servo1.pulsewidth_us(pwm[0]);
+    servo2.pulsewidth_us(pwm[1]);
+    servo3.pulsewidth_us(pwm[2]);
+    servo4.pulsewidth_us(pwm[3]);
+    servo5.pulsewidth_us(pwm[4]);
+    servo6.pulsewidth_us(pwm[5]);
+    servo7.pulsewidth_us(pwm[6]);
+    servo8.pulsewidth_us(pwm[7]);   
+      /*  }else{
+        servo1.pulsewidth_us(1000);
+        servo2.pulsewidth_us(1000);
+        servo3.pulsewidth_us(1000);
+        servo4.pulsewidth_us(1000);
+        servo5.pulsewidth_us(1000);
+        servo6.pulsewidth_us(1000);
+        servo7.pulsewidth_us(1000);
+        servo8.pulsewidth_us(1000);
+    }*/
+
+    for(j=0;j<8;j++){
+        pc.printf("ch%d=%d ", j+1, pwm[j]);
+    }
+    //pc.printf("time = %d", frq.read_ms()); 
+    pc.printf("\r\n");
+
+    //frq.reset();
+
+}
+
+
+//---update_pwm---
+//udate_Inputで抽出したpwmデータを整形して各変数に代入する。(マニュアルモード)
+//各stabiGylo関数で算出したpwmを各変数に代入する(自動モード)
+void update_pwm()
+{
+    uint8_t j = 0;
+    
+    if(flg_ch_update == true){
+    switch(update_mode){    //マニュアルモード,自動モード,自動着陸もモードを切替
+        case UPD_MANUAL:    //マニュアルモード
+            for(j=0;j<8;j++){
+                pwm[j] = (channels[j]>>1) + 1000;
+            }
+            oldTHL = pwm[2];
+            jj=0;
+            //pc.printf("update_manual\r\n");
+            break;
+        
+        case UPD_AUTO:      //自動モード
+            pwm[0] = (channels[0]>>1) + 1000;
+            pwm[1] = Auto_ELE;
+            pwm[2] = Auto_THR;
+            pwm[3] = Auto_RUD;
+            pwm[4] = (channels[4]>>1) + 1000;
+            pwm[5] = (channels[5]>>1) + 1000;
+            pwm[6] = (channels[6]>>1) + 1000;
+            pwm[7] = (channels[7]>>1) + 1000;
+ 
+            //pc.printf("update_auto\r\n");
+            break;
+        
+        case UPD_LANDING:   //自動着陸モード
+            pwm[0] = (channels[0]>>1) + 1000;
+            pwm[1] = Auto_ELE;
+            pwm[2] = (channels[2]>>1) + 1000;
+            pwm[3] = (channels[3]>>1) + 1000;
+            pwm[4] = (channels[4]>>1) + 1000;
+            pwm[5] = (channels[5]>>1) + 1000;
+            pwm[6] = (channels[6]>>1) + 1000;
+            pwm[7] = (channels[7]>>1) + 1000;
+            break;
+            
+        default:            //デフォはマニュアルモード
+            for(j=0;j<8;j++){
+                pwm[j] = (channels[j]>>1) + 1000;
+            }
+
+            jj=0;
+            //pc.printf("update_manual\r\n");
+            break;
+    }
+    }else{
+        pc.printf("0\r\n");
+    }
+    flg_ch_update = false;
+    ///oldTHL = pwm[2]; 
+          setall_servo();  
+}
+
+/*void update_auto()
+{
+    pwm[0] = (channels[0]>>1) + 1000;
+    pwm[1] = Auto_ELE;
+    pwm[2] = Auto_THR;
+    pwm[3] = Auto_RUD;
+    pwm[4] = (channels[4]>>1) + 1000;
+    pwm[5] = (channels[5]>>1) + 1000;
+    pwm[6] = (channels[6]>>1) + 1000;
+    pwm[7] = (channels[7]>>1) + 1000;
+    
+    setall_servo();
+    //pc.printf("update_auto\r\n");
+}*/
+
+//---update_Input---
+//catch_sbusで取得したSbusの生データから各チャンネルのpwmを抽出する。
+void update_Input()
+{     
+    uint8_t i = 0;
+
+/*  for (i=0; i<25; i++){
+        pc.printf("%x ", buf_sbus[i]);
+        }pc.printf("\n"); 
+*/
+    // clear channels[]
+    for (i=0; i<18; i++) {channels[i] = 0;}
+
+    // reset counters
+    uint8_t byte_in_sbus = 1;
+    uint8_t bit_in_sbus = 0;
+    uint8_t ch = 0;
+    uint8_t bit_in_channel = 0;
+
+    // process actual sbus data
+    for (i=0; i<176; i++) {
+        if (buf_sbus[byte_in_sbus] & (1<<bit_in_sbus)) {
+            channels[ch] |= (1<<bit_in_channel);
+        }
+        bit_in_sbus++;
+        bit_in_channel++;
+
+        if (bit_in_sbus == 8) {
+            bit_in_sbus =0;
+            byte_in_sbus++;
+        }
+        if (bit_in_channel == 11) {
+            bit_in_channel =0;
+            ch++;
+        }
+    }
+    // DigiChannel 1
+    if (buf_sbus[23] & (1<<0)) {
+        channels[16] = 1;
+    }else{
+        channels[16] = 0;
+    }
+    // DigiChannel 2
+    if (buf_sbus[23] & (1<<1)) {
+        channels[17] = 1;
+    }else{
+        channels[17] = 0;
+    }
+    // Failsafe
+    failsafe_status = SBUS_SIGNAL_OK;
+    if (buf_sbus[23] & (1<<2)) {
+        failsafe_status = SBUS_SIGNAL_LOST;
+    }
+    if (buf_sbus[23] & (1<<3)) {
+        failsafe_status = SBUS_SIGNAL_FAILSAFE;
+    }
+    //channels[i] = channels[i]>>1;
+    for (i=0; i<25; i++) {buf_sbus[i] = 0;}
+    cnt_sbus = 0;
+    flg_ch_update = true;
+    
+    update_pwm();
+        
+
+}
+
+//---catch_sbus---
+//受信機から送られてくるSBus信号(シリアル)を取得する関数
+void catch_sbus()
+{
+    buf_sbus[cnt_sbus] = sbus_.getc();
+    if(buf_sbus[0] == 0x0f)
+        {
+            cnt_sbus ++;
+        }
+    if(cnt_sbus >=25){  
+        if(buf_sbus[24] == 0x00){
+            update_Input();     //update_Input実行
+        }else{
+            cnt_sbus = 0;
+        }
+    }
+return;
+}
+
+//---init_sbus---
+//Sbusを初期化する関数
+void init_sbus(){
+    // Set Baudrate
+    sbus_.baud(100000);
+    // Set Datalenght & Frame
+    sbus_.format(8, Serial::Even, 2);
+    //start sbus irq
+    sbus_.attach(&catch_sbus, RawSerial::RxIrq);
+    }
+
+//---CheckSW_up---
+//プロポのスイッチがonかoffか返す関数
+//ch 1~8
+bool CheckSW_up(int8_t ch)
+{
+    uint16_t checkpwm;
+    checkpwm = (channels[ch-1]>>1) + 1000;
+    //pc.printf("ch%d=%d ", ch, checkpwm);
+    if(SWITCH_CHECK > checkpwm){
+        return true;
+    }else{
+        return false;
+    }
+}
+
+
+        
+//---sensing---
+//センサーの値を読み込み、各種フィルタをかける(認知)
+void sensing()
+{
+    // If intPin goes high, all data registers have new data
+    if(mpu9250.readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) {  // On interrupt, check if data ready interrupt
+
+        mpu9250.readAccelData(accelCount);  // Read the x/y/z adc values   
+        // Now we'll calculate the accleration value into actual g's
+        ax = (float)accelCount[0]*aRes - accelBias[0];  // get actual g value, this depends on scale being set
+        ay = (float)accelCount[1]*aRes - accelBias[1];   
+        az = (float)accelCount[2]*aRes - accelBias[2];  
+   
+        mpu9250.readGyroData(gyroCount);  // Read the x/y/z adc values
+        // Calculate the gyro value into actual degrees per second
+        gx = (float)gyroCount[0]*gRes - gyroBias[0];  // get actual gyro value, this depends on scale being set
+        gy = (float)gyroCount[1]*gRes - gyroBias[1];  
+        gz = (float)gyroCount[2]*gRes - gyroBias[2];   
+  
+        mpu9250.readMagData(magCount);  // Read the x/y/z adc values   
+        // Calculate the magnetometer values in milliGauss
+        // Include factory calibration per data sheet and user environmental corrections
+        mx = (float)magCount[0]*mRes*magCalibration[0] - magbias[0];  // get actual magnetometer value, this depends on scale being set
+        my = (float)magCount[1]*mRes*magCalibration[1] - magbias[1];  
+        mz = (float)magCount[2]*mRes*magCalibration[2] - magbias[2];   
+    }
+   
+    Now = t.read_us();
+    deltat = (float)((Now - lastUpdate)/1000000.0f) ; // set integration time by time elapsed since last filter update
+    lastUpdate = Now;
+    
+    sum += deltat;
+    sumCount++;
+    
+//  if(lastUpdate - firstUpdate > 10000000.0f) {
+//      beta = 0.04;  // decrease filter gain after stabilized
+//      zeta = 0.015; // increasey bias drift gain after stabilized
+//  }
+    
+   // Pass gyro rate as rad/s
+    mpu9250.MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f,  my,  mx, mz);
+    mpu9250.MahonyQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f, my, mx, mz);
+
+    /*  Auto_Loop()で50ms待ってるから要らないと思う
+    // Serial print and/or display at 0.5 s rate independent of data rates
+    delt_t = t.read_ms() - count;
+    if (delt_t > 500) { // update LCD once per half-second independent of read rate
+    */
+
+    //pc.printf("ax = %f", 1000*ax); 
+    //pc.printf(" ay = %f", 1000*ay); 
+    //pc.printf(" az = %f  mg\n\r", 1000*az); 
+
+    //pc.printf("gx = %f", gx); 
+    //pc.printf(" gy = %f", gy); 
+    //pc.printf(" gz = %f  deg/s\n\r", gz); 
+    
+    //pc.printf("mx = %f,", mx); 
+    //pc.printf(" my = %f,", my); 
+    //pc.printf(" mz = %f  mG\n\r", mz); 
+    
+    tempCount = mpu9250.readTempData();  // Read the adc values
+    temperature = ((float) tempCount) / 333.87f + 21.0f; // Temperature in degrees Centigrade
+    //pc.printf(" temperature = %f  C\n\r", temperature); 
+    
+    //pc.printf("q0 = %f\n\r", q[0]);
+    //pc.printf("q1 = %f\n\r", q[1]);
+    //pc.printf("q2 = %f\n\r", q[2]);
+    //pc.printf("q3 = %f\n\r", q[3]);      
+    
+      
+  // Define output variables from updated quaternion---these are Tait-Bryan angles, commonly used in aircraft orientation.
+  // In this coordinate system, the positive z-axis is down toward Earth. 
+  // 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.
+  // Pitch is angle between sensor x-axis and Earth ground plane, toward the Earth is positive, up toward the sky is negative.
+  // Roll is angle between sensor y-axis and Earth ground plane, y-axis up is positive roll.
+  // These arise from the definition of the homogeneous rotation matrix constructed from quaternions.
+  // Tait-Bryan angles as well as Euler angles are non-commutative; that is, the get the correct orientation the rotations must be
+  // applied in the correct order which for this configuration is yaw, pitch, and then roll.
+  // For more see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles which has additional links.
+    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]);   
+    roll = -asin(2.0f * (q[1] * q[3] - q[0] * q[2]));
+    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]);
+    pitch *= 180.0f / PI;
+    yaw   *= 180.0f / PI; 
+    yaw   -= 13.8f; // Declination at Danville, California is 13 degrees 48 minutes and 47 seconds on 2014-04-04
+    roll  *= 180.0f / PI;
+
+    //pc.printf("$%d %d %d;",(int)(yaw*100),(int)(pitch*100),(int)(roll*100));
+    //pc.printf("Yaw: %f  Pitch:%f  Roll:%f\n\r",  yaw,   pitch,   roll);
+    //pc.printf("average rate = %f\n\r", (float) sumCount/sum);
+ 
+    count = t.read_ms(); 
+    sum = 0;
+    sumCount = 0; 
+    //}           
+}
+
+
+//---CalibrateCompass---
+//グラウンドチェック時にスイッチ7だけをonにしておくことで実行 リポ抜いたらやり直ししなくてはならない
+//使わない予定
+void CalibrateCompass(void)
+{
+    led1 = 1;
+    sensing();
+    uint8_t ii;
+    float mxMAX=mx, mxMIN=mx;
+    float myMAX=my, myMIN=my;
+    magbias[0] = 0;    //初期化
+    magbias[1] = 0;
+    //magbias[2] = 0;   
+    ii=0;
+    while(1){   //キャリブレーション実行   led2が点滅時に機体を一回転させる xy方向のみ
+        sensing();
+        if(mxMAX < mx) mxMAX = mx;
+        if(mxMIN > mx) mxMIN = mx;
+        if(myMAX < my) myMAX = my;
+        if(myMIN > my) myMIN = my;
+        led2 = !led2;
+        ++ii;
+        wait(50);
+        
+        if(!CheckSW_up(7)) break;   //スイッチ7を下げて終了
+    }
+    led2 = 0;
+    if(ii<20){  //チャンネル7をすぐ切った場合 元に戻す
+        magbias[0] = MAGBIASX;
+        magbias[1] = MAGBIASY;
+    }else{  //しっかりと値を入れた場合
+        magbias[0] = (mxMAX+mxMIN)/2;
+        magbias[1] = (myMAX+myMIN)/2;
+    }
+    led1 = 0;
+    t.reset();  //タイマーをリセットして終了
+}  
+
+    
+//---StabiGyro---
+//水平旋回のためのラダー、エレベーターの角度(要はpwm)を計算する。(判断)
+//右旋回
+void StabiGyro()
+{   
+    if(0  /*oldTHL < 1200*/){  //機体審査用
+        Auto_RUD = RUD_N + -65 + int((-12-roll)*RUDDER_GN-gy*RUD_DGN);
+        Auto_ELE = ELE_N + -50 + int((-15 - pitch)*ELEVATOR_GN - gx*ELE_DGN);
+        Auto_THR = 1500;
+        }else{
+            if(jj<=0){     //旋回し始め  15  
+                Auto_RUD = RUD_N + -65 + int((-12 -roll)*RUDDER_GN - gy*RUD_DGN);    //*0.75);   //roll -> gy        3.5
+                Auto_ELE = ELE_N + -65 + int((-16 - pitch)*ELEVATOR_GN - gx*ELE_DGN);     //pitch  -> -gx
+                Auto_THR = oldTHL + 30;     
+                //pc.printf("first%d\r\n",jj);
+                jj++;
+            }else{          //旋回中
+                Auto_RUD = RUD_N + -65 + int((-12-roll)*RUDDER_GN - gy*RUD_DGN);    //*0.75); 
+                Auto_ELE = ELE_N + -65 + int((-16 - pitch)*ELEVATOR_GN - gx*ELE_DGN);
+                Auto_THR = oldTHL ;
+            }
+        }
+    
+    //pwmの値が最小値と最大値の間に入ってなかったら、強制的に最大値or最小値にする
+    if(Auto_RUD > RUD_MAX){
+        Auto_RUD = RUD_MAX;
+    }else if(Auto_RUD < RUD_MIN){
+        Auto_RUD = RUD_MIN;
+    }
+    if(Auto_ELE > ELE_MAX){
+        Auto_ELE = ELE_MAX;
+    }else if(Auto_ELE < ELE_MIN){
+        Auto_ELE = ELE_MIN;
+    }
+    
+
+        
+    //pc.printf("rud %d\tele %5d\r\n", Auto_RUD, Auto_ELE);
+    //Thread::wait(G_MS);
+}
+
+//---StabiGyro_Mobius---
+//8の字旋回のためのラダー、エレベーターの角度(要はpwm)を計算する。(判断)
+void StabiGyro_Mobius()
+{
+    if(jj<=15){     //右旋回導入
+        Auto_RUD = RUD_N + -65 + int((-12-roll)*RUDDER_GN - (gy + 130)*0.75);    //*0.75);   //roll -> gy        3.5
+        Auto_ELE = ELE_N + -65 + int((-16 - pitch)*ELEVATOR_GN - (gx + 30)*0.8);     //pitch  -> -gx
+        Auto_THR = oldTHL;       
+        //pc.printf("first%d\r\n",jj);
+        jj++;
+    }else if((15<jj) && (jj<=70)){     //右旋回途中
+        Auto_RUD = RUD_N + -65 + int((-12-roll)*RUDDER_GN - gy*RUD_DGN);    //*0.75); 
+        Auto_ELE = ELE_N + -65 + int((-16 - pitch)*ELEVATOR_GN - gx*ELE_DGN);
+        Auto_THR = oldTHL;
+        jj++;
+    }else if((70<jj) && (jj<=75)){    //旋回遷移1
+        Auto_RUD = RUD_N + 100 + int((16 -roll)*RUDDER_GN - (gy-100)*0.75);  
+        Auto_ELE = ELE_N + 20 + int((0 -pitch)*ELEVATOR_GN - (gx + 0)*0.6);   
+        Auto_THR = THR_N - 100;      
+        //pc.printf("first%d\r\n",jj);
+        jj++;
+    }else if((75<jj) && (jj<=90)){    //旋回遷移2
+        Auto_RUD = RUD_N + 65 + int((12-roll)*RUDDER_GN - (gy-100)*0.75);    // 105 30 
+        Auto_ELE = ELE_N + -15 + int((-5 - pitch)*ELEVATOR_GN - (gx+30)*0.6);   //-75 -15
+        Auto_THR = oldTHL - 20;     //-20
+        jj++;
+    }else{                              //左旋回途中
+        Auto_RUD = RUD_N + 65 + int((12-roll)*RUDDER_GN - gy*RUD_DGN);  
+        Auto_ELE = ELE_N + -65 + int((-16 - pitch)*ELEVATOR_GN - gx*ELE_DGN);   
+        Auto_THR = oldTHL;   
+    }
+        
+    if(Auto_RUD > RUD_MAX){
+        Auto_RUD = RUD_MAX;
+    }else if(Auto_RUD < RUD_MIN){
+        Auto_RUD = RUD_MIN;
+    }
+    if(Auto_ELE > ELE_MAX){
+        Auto_ELE = ELE_MAX;
+    }else if(Auto_ELE < ELE_MIN){
+        Auto_ELE = ELE_MIN;
+    }
+        
+    //pc.printf("rud %d\tele %5d\r\n", Auto_RUD, Auto_ELE);
+    //Thread::wait(G_MS);
+}
+
+//---StabiGyro_Climb---
+//上昇旋回のためのラダー、エレベーターの角度(要はpwm)を計算する。(判断)
+void StabiGyro_Climb()
+{
+    if(jj<=15){     //右旋回導入
+        Auto_RUD = RUD_N + -65 + int((-12-roll)*RUDDER_GN - (gy+130)*RUD_DGN);    //*0.75);   //roll -> gy        3.5
+        Auto_ELE = ELE_N + -65 + int((-16 - pitch)*ELEVATOR_GN - (gx+30)*ELE_DGN);     //pitch  -> -gx
+        Auto_THR = oldTHL;            
+        //pc.printf("first%d\r\n",jj);
+        jj++;
+    }else if((15<jj) && (jj<=136)){     //右旋回途中
+        Auto_RUD = RUD_N + -65 + int((-12-roll)*RUDDER_GN - gy*RUD_DGN);    //*0.75); 
+        Auto_ELE = ELE_N + -65 + int((-16 - pitch)*ELEVATOR_GN - gx*ELE_DGN);
+        Auto_THR = oldTHL;
+        jj++;
+    /*}else if((136<jj) && (jj<=146)){    //上昇遷移
+        Auto_RUD = RUD_N + -65 - int((-12-roll)*RUDDER_GN - gy*0);
+        Auto_ELE = ELE_N + -80 + int((-22-pitch)*ELEVATOR_GN - gx*0);
+        Auto_THR = THR_N + 100;     
+        //pc.printf("first%d\r\n",jj);
+        jj++;*/
+    }else if((136<jj) && (jj<=200)){    //上昇中
+        Auto_RUD = RUD_N + -65 + int((-12-roll)*RUDDER_GN - gy*RUD_DGN);    //*0.75); 
+        Auto_ELE = ELE_N + -140 + int((-25 - pitch)*ELEVATOR_GN - gx*ELE_DGN);
+        Auto_THR = oldTHL + 220;
+        jj++;
+    }else{                              //水平旋回
+        Auto_RUD = RUD_N + -65 + int((-12-roll)*RUDDER_GN - gy*RUD_DGN);    //*0.75); 
+        Auto_ELE = ELE_N + -65 + int((-16 - pitch)*ELEVATOR_GN - gx*ELE_DGN);
+        Auto_THR = oldTHL;
+    }
+        
+    if(Auto_RUD > RUD_MAX){
+        Auto_RUD = RUD_MAX;
+    }else if(Auto_RUD < RUD_MIN){
+        Auto_RUD = RUD_MIN;
+    }
+    if(Auto_ELE > ELE_MAX){
+        Auto_ELE = ELE_MAX;
+    }else if(Auto_ELE < ELE_MIN){
+        Auto_ELE = ELE_MIN;
+    }
+        
+    //pc.printf("rud %d\tele %5d\r\n", Auto_RUD, Auto_ELE);
+    //Thread::wait(G_MS);
+}
+
+//---StabiGyro_Glide---
+//自動滑空のためのラダー、エレベーターの角度(要はpwm)を計算する。(判断)
+void StabiGyro_Glide()
+{
+    if(jj<=15){
+        Auto_RUD = RUD_N;
+        Auto_ELE = ELE_N + -5 + int (( - pitch)*ELEVATOR_GN - gx*0);
+        Auto_THR = 1000;
+        //pc.printf("first%d\r\n",jj);
+        jj++;
+    }else{
+        Auto_RUD = RUD_N + -30 + int((-8 - roll)*RUDDER_GN - gy*RUD_DGN);    
+        Auto_ELE = ELE_N + -25 + int((-5- pitch)*ELEVATOR_GN - gx*ELE_DGN);
+        Auto_THR = 1000;    //スロットルoff
+    }
+    if(Auto_RUD > RUD_MAX){
+        Auto_RUD = RUD_MAX;
+    }else if(Auto_RUD < RUD_MIN){
+        Auto_RUD = RUD_MIN;
+    }
+    if(Auto_ELE > ELE_MAX){
+        Auto_ELE = ELE_MAX;
+    }else if(Auto_ELE < ELE_MIN){
+        Auto_ELE = ELE_MIN;
+    }
+        
+    //pc.printf("rud %d\tele %5d\r\n", Auto_RUD, Auto_ELE);
+    //Thread::wait(G_MS);
+}
+
+void StabiGyro_Landing()
+{
+    if(pwm[0]<1300){
+        Auto_ELE = ELE_N + -10 + int((-5 - pitch)*ELEVATOR_GN - gx*ELE_DGN);
+        Auto_THR = oldTHL;
+    }else if((1300<=pwm[0])&&(pwm[0]<1800)){
+        Auto_ELE = ELE_N + -15 + int((-8 - pitch)*ELEVATOR_GN - gx*ELE_DGN);
+        Auto_THR = oldTHL - 30;
+    }else if(1800<=pwm[0]){
+        Auto_ELE = ELE_N + -25 + int((-12 - pitch)*ELEVATOR_GN - gx*ELE_DGN);
+        Auto_THR = 1000;
+    }
+}
+
+void Auto_Loop()
+{
+    //while(true){
+    //for(k=0;k<100;++k){
+        //sensing();      //センサーの値を読み込む(認知)
+        StabiGyro();    //水平旋回のためのラダー、エレベーターのpwmを計算(判断)
+        update_mode = UPD_AUTO;     //オートモード
+        //StabiAccel();
+        //Auto_ELE+=145;
+        //Auto_RUD-=80;
+        //Servos.Auto2Servo();
+        //Thread::wait(50);
+    /*
+        if(!CheckSW_up(7)){
+            pc.printf("go to manual\n");
+            break;
+        }*/
+        //wait_ms(50);        
+    //}   
+    //k=0; //for debug
+    //pwm[6]=1000;
+}
+
+void Auto_Mobius()
+{
+    //sensing();
+    StabiGyro_Mobius();
+    update_mode = UPD_AUTO;
+    //wait_ms(50);
+}
+
+void Auto_Climb()
+{
+    //sensing();
+    StabiGyro_Climb();
+    update_mode = UPD_AUTO;
+    //wait_ms(50);   
+}
+
+void Auto_Glide()
+{
+    //sensing();
+    StabiGyro_Glide();
+    update_mode = UPD_AUTO;
+    //wait_ms(50);
+}
+
+void Auto_Landing()
+{   
+    //sensing();
+    StabiGyro_Landing();
+    update_mode = UPD_MANUAL;
+    //wait_ms(50);
+}
+
+int main()
+{
+    //初期化開始
+    led1 = 1;
+    led2 = 1;
+    led3 = 0;
+    led4 = 0;
+    
+    //SBus用バッファ初期化
+    int count_initsbus;
+    for (count_initsbus = 0; count_initsbus < 25; count_initsbus++) {buf_sbus[count_initsbus] = 0;}
+    
+    //pc.baud(115200);    //パソコン通信用シリアルのボードレート
+           
+    //frq.start();     
+    init_Servo();
+    init_sbus();    
+    disp_clock();
+   
+    //---9軸センサー(MPU9250)初期化--- 
+    
+    //Set up I2C
+    i2c.frequency(400000);  // use fast (400 kHz) I2C  
+    pc.printf("CPU SystemCoreClock is %d Hz\r\n", SystemCoreClock);   
+    t.start();
+    
+    // Read the WHO_AM_I register, this is a good test of communication
+    uint8_t whoami = mpu9250.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250);  // Read WHO_AM_I register for MPU-9250
+    pc.printf("I AM 0x%x\n\r", whoami); pc.printf("I SHOULD BE 0x71\n\r");
+  
+    if (whoami == 0x71){ // WHO_AM_I should always be 0x68
+        pc.printf("MPU9250 is online...\n\r");
+        //wait(1);
+     
+        mpu9250.resetMPU9250(); // Reset registers to default in preparation for device calibration
+        mpu9250.calibrateMPU9250(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers  
+        //pc.printf("x gyro bias = %f\n\r", gyroBias[0]);
+        //pc.printf("y gyro bias = %f\n\r", gyroBias[1]);
+        //pc.printf("z gyro bias = %f\n\r", gyroBias[2]);
+        //pc.printf("x accel bias = %f\n\r", accelBias[0]);
+        //pc.printf("y accel bias = %f\n\r", accelBias[1]);
+        //pc.printf("z accel bias = %f\n\r", accelBias[2]);
+        wait(1);
+        
+        mpu9250.initMPU9250(); 
+        pc.printf("MPU9250 initialized for active data mode....\n\r"); // Initialize device for active mode read of acclerometer, gyroscope, and temperature
+        mpu9250.initAK8963(magCalibration);
+        pc.printf("AK8963 initialized for active data mode....\n\r"); // Initialize device for active mode read of magnetometer
+        pc.printf("Accelerometer full-scale range = %f  g\n\r", 2.0f*(float)(1<<Ascale));
+        pc.printf("Gyroscope full-scale range = %f  deg/s\n\r", 250.0f*(float)(1<<Gscale));
+        if(Mscale == 0) pc.printf("Magnetometer resolution = 14  bits\n\r");
+        if(Mscale == 1) pc.printf("Magnetometer resolution = 16  bits\n\r");
+        if(Mmode == 2) pc.printf("Magnetometer ODR = 8 Hz\n\r");
+        if(Mmode == 6) pc.printf("Magnetometer ODR = 100 Hz\n\r");
+        wait(1);
+    
+    }else{
+        pc.printf("Could not connect to MPU9250: \n\r");
+        pc.printf("%#x \n",  whoami); 
+        while(1) ; // Loop forever if communication doesn't happen
+    }
+
+    mpu9250.getAres(); // Get accelerometer sensitivity
+    mpu9250.getGres(); // Get gyro sensitivity
+    mpu9250.getMres(); // Get magnetometer sensitivity
+    //pc.printf("Accelerometer sensitivity is %f LSB/g \n\r", 1.0f/aRes);
+    //pc.printf("Gyroscope sensitivity is %f LSB/deg/s \n\r", 1.0f/gRes);
+    //pc.printf("Magnetometer sensitivity is %f LSB/G \n\r", 1.0f/mRes);
+    magbias[0] = MAGBIASX;       //+470.;  // User environmental x-axis correction in milliGauss, should be automatically calculated
+    magbias[1] = MAGBIASY;       //+120.;  // User environmental y-axis correction in milliGauss
+    magbias[2] = MAGBIASZ;       //+125.;  // User environmental z-axis correction in milliGauss
+    
+    t.start();
+    pc.printf("mpu9250 initialized\r\n");
+    
+    //---9軸センサー(MPU9250)初期化終わり---   
+          
+    led1 = 0;
+    led2 = 0;
+    led3 = 0;
+    led4 = 0;
+    
+    pc.printf("All initialized\r\n");
+    
+
+    while (true) {      //無限ループ
+        //for(i=0;i<8;i++){
+        //pc.printf("%x ", buf_sbus[i]);
+        //pc.printf("ch%d=%d ", i+1, channels[i]);
+        //}
+        //pc.printf("\n");
+        sensing();
+        wait_ms(50);
+
+        
+        switch(OperationMode){      //変数OperationModeの値で場合分け
+            case GROUNDCHECK:   //グラウンドチェック(スイッチが2つ初期値にちゃんとなってたら水平旋回モードに移行)
+                if(!CheckSW_up(7)&&!CheckSW_up(8)){     //チャンネル7,8が両方offなら
+                    OperationMode=AUTOLOOP;             //変数OperationModeにAUTOLOOP(定数なので2(SkipperS.hで定義))を代入
+                    pc.printf("go to autoloop\r\n");
+                    led1 = 0;
+                    led2 = 0;
+                }else{
+                    led1 = 1;
+                    led2 = 1;
+                }
+                //変数update_modeはSBus(=プロポ=操縦者)からのpwmをそのまま垂れ流すか、自動制御で計算したpwmをサーボに流すかを切り替えるための変数
+                update_mode = UPD_MANUAL;   //マニュアルモード(そのまま垂れ流す)
+               // pc.printf("groundcheck mode\r\n");
+                
+                break;
+            case AUTOLOOP:      //水平旋回モード
+                //t.reset();
+                if(CheckSW_up(7)){  //チャンネル7がonなら
+                    //t.reset();
+                    Auto_Loop();    //関数Auto_Loop実行
+                    led1 = 1;
+                    led2 = 0;
+                    //Auto_Loop();
+                    //pc.printf("Auto Loop Now\r\n");
+                    //autoloop.set_priority(osPriorityAboveNormal);
+                    /*
+                    while(true){
+                        if(!CheckSW_up(7)){
+                            autoloop.terminate();
+                            break;
+                        }
+                    }
+                    */     
+                }else{
+                    update_mode = UPD_MANUAL;
+                    //pc.printf("manual Now\r\n");
+                    led1 = 0;
+                    led2 = 0;
+                    
+                    /*debug*/
+                    //k++;
+                    //wait(50);
+                    //if(k>100) pwm[6]=2000;    
+                }  
+                
+                if(!CheckSW_up(7)&&CheckSW_up(8)){  //チャンネル7がoff、8がonなら
+                    OperationMode=AUTOMOBIUS;
+                    pc.printf("go to auto8\r\n");
+                }
+                break;
+            case AUTOMOBIUS:    //8の字旋回モード
+                if(CheckSW_up(7)){
+                    Auto_Mobius();
+                    led1 = 1;
+                    led2 = 1;
+                    //pc.printf("Auto Mobius Now\r\n");                    
+                }else{
+                    update_mode = UPD_MANUAL;
+                    //pc.printf("manual Now\r\n");
+                    led1 = 0;
+                    led2 = 1;
+                }  
+                
+                if(!CheckSW_up(7)&&!CheckSW_up(8)){
+                    OperationMode=AUTOCLIMB;
+                    pc.printf("go to autoclimb\r\n");
+                }
+                break;
+            case AUTOCLIMB:     //上昇旋回モード
+                if(CheckSW_up(7)){
+                    Auto_Climb();
+                    led1 = 1;
+                    led2 = 0;
+                    //pc.printf("Auto Climb Now\r\n");                    
+                }else{
+                    update_mode = UPD_MANUAL;
+                    //pc.printf("manual Now\r\n");
+                    led1 = 0;
+                    led2 = 0;
+                }  
+                
+                if(!CheckSW_up(7)&&CheckSW_up(8)){
+                    OperationMode=AUTOGLIDE;
+                    pc.printf("go to manual\r\n");
+                }
+                break;
+            
+            case AUTOGLIDE:     //自動滑空モード
+                if(CheckSW_up(7)){
+                    Auto_Glide();
+                    led1 = 1;
+                    led2 = 1;
+                    //pc.printf("Auto Glide Now\r\n");                    
+                }else{
+                    update_mode = UPD_MANUAL;
+                    //pc.printf("manual Now\r\n");
+                    led1 = 0;
+                    led2 = 1;
+                }  
+                
+                if(!CheckSW_up(7)&&!CheckSW_up(8)){
+                    OperationMode=AUTOLANDING;
+                    pc.printf("go to autoloop\r\n");
+                }
+                break;
+            
+            case AUTOLANDING:
+                led3 = 1;
+                led4 = 1; //赤外線
+                if(CheckSW_up(7)){
+                    Auto_Landing();
+                    led1 = 1;
+                    led2 = 0;
+                    //pc.printf("Auto Landing Now\r\n");                    
+                }else{
+                    update_mode = UPD_MANUAL;
+                    //pc.printf("manual Now\r\n");
+                    led1 = 0;
+                    led2 = 0;
+                }  
+                
+                if(!CheckSW_up(7)&&CheckSW_up(8)){
+                    OperationMode=AUTOLOOP;
+                    //pc.printf("go to manualmade\r\n");
+                }
+                break;
+            
+            case MANUALMODE:
+                update_mode = UPD_MANUAL;
+                led1 = 0;
+                led2 = 1;
+                led4 = 1; 
+                
+                if(!CheckSW_up(7)&&!CheckSW_up(8)){
+                    OperationMode=AUTOLANDING;
+                    pc.printf("go to autolanding\r\n");
+                }
+                break;
+            
+        }
+                
+            
+             
+                
+     /*
+    if(CheckSW_up(7)){
+        pc.printf("true\r\n");
+        Auto_loop();
+        
+    }else{
+        pc.printf("false\r\n");
+        update_manual();
+    }*/
+    }
+}