MPU6050のサンプルプログラム2

Dependencies:   ConfigFile SDFileSystem mbed

Fork of LAURUS_program by LAURUS

Revision:
15:d14d385d37e2
Parent:
14:f85cb5340cb8
Child:
16:174daf81eea0
Child:
17:03b45055ca05
--- a/main.cpp	Fri Jun 19 15:56:52 2015 +0000
+++ b/main.cpp	Sat Jun 20 16:39:11 2015 +0000
@@ -16,6 +16,10 @@
 #define TRUE    1
 #define FALSE   0
 
+#define RULE1
+//#define RULE2
+//#define RULE3
+
 const float dt              = 0.01f;        // 割り込み周期(s)
 const float ServoMax        = 0.0023f;      // サーボの最大パルス長(s)
 const float ServoMin        = 0.0006f;      // サーボの最小パルス長(s)
@@ -26,7 +30,9 @@
 const int   BorderParafoil  = 0;            // 物理スイッチのOFF出力
 const int   MaxCount        = 3;            // 投下シグナルを何回連続で検知したら投下と判断するか(×0.2[s])
 const int   WaitTime        = 1;            // 投下後、安定するまで何秒滑空するか
-const float Alpha           = 30.0f;        // 目標方向と自分の進行方向との差の閾値(制御則1の定数
+const float Alpha           = 30.0f;        // 目標方向と自分の進行方向との差の閾値(deg)(制御則1&2&3の定数
+const float Beta            = 60.0f;        // 目標方向と自分の進行方向との間に取るべき角度差(deg)(制御則3の定数
+const float BorderDistance  = 10.0f;        // 落下制御に入るための目標値との距離の閾値(m)(制御則2の定数
 
 /****************************** private macro     ******************************/
 /****************************** private typedef   ******************************/
@@ -92,7 +98,7 @@
 char    data[512] = {};         // 送信データ用配列
 
 /** config.txt **
-* #から始めるのはコメント行 
+* #から始めるのはコメント行
 * #イコールの前後に空白を入れない
 * target_x=111.222
 * target_y=33.444
@@ -137,27 +143,29 @@
 void    toString(Matrix& m);                // デバッグ用
 void    toString(Vector& v);                // デバッグ用
 
-inline float min(float a, float b) {
+inline float min(float a, float b)
+{
     return ((a > b) ? b : a);
 }
 
 /******************************   main function   ******************************/
 
-int main() {
-    
+int main()
+{
+
     i2c.frequency(400000);                  // I2Cの通信速度を400kHzに設定
-    
+
     if(!mpu.init()) AbortWithMsg("mpu6050 Initialize Error !!");        // mpu6050初期化
     if(!hmc.init()) AbortWithMsg("hmc5883l Initialize Error !!");       // hmc5883l初期化
-    
+
     //Config読み取り
     LoadConfig();
-    
+
     //SDカード初期化
     FILE *fp;
     char filename[15];
     int n = Find_last();
-    if(n < 0){
+    if(n < 0) {
         pc.printf("Could not read a SD Card.\n");
         return 0;
     }
@@ -165,20 +173,20 @@
     fp = fopen(filename, "w");
     fprintf(fp, "log data\r\n");
     xbee.printf("log data\r\n");
-    
+
     servoL.period(0.020f);                  // サーボの信号の周期は20ms
     servoR.period(0.020f);
-    
+
     //カルマンフィルタ初期化
     KalmanInit();
-    
+
     INT_timer.attach(&INT_func, dt);        // 割り込み有効化(Freq = 0.01fなので、10msおきの割り込み)
-    
+
     //重力ベクトルの初期化
     raw_g.SetComp(1, 0.0f);
     raw_g.SetComp(2, 0.0f);
     raw_g.SetComp(3, 1.0f);
-    
+
     // 機体に固定されたベクトルの初期化
     b_f.SetComp(1, 0.0f);
     b_f.SetComp(2, 0.0f);
@@ -187,97 +195,91 @@
     b_u.SetComp(2, 0.0f);
     b_u.SetComp(3, 0.0f);
     b_l = Cross(b_u, b_f);
-    
+
     // 目標座標をベクトルに代入
     target_p.SetComp(1, target_x * DEG_TO_RAD);
     target_p.SetComp(2, target_y * DEG_TO_RAD);
-    
+
     /* ------------------------------ ↓↓↓ ここからメインループ ↓↓↓ ------------------------------ */
     while(1) {
         timer.stop();
         timer.reset();
         timer.start();
         myled = 1;                                          // LED is ON
-        
-        
+
+
         /******************************* データ処理 *******************************/
         {
             INT_flag = FALSE;                               // 割り込みによる変数書き換えを阻止
             gms.read();                                     // GPSデータ取得
             UTC_t = (int)gms.time;
-            
-            
-            
+
+
+
             // 参照座標系の基底を求める
             r_u = g;
             r_f = geomag.GetPerpCompTo(g).Normalize();
             r_l = Cross(r_u, r_f);
-            
+
             // 回転行列を経由してオイラー角を求める
             // オイラー角はヨー・ピッチ・ロールの順に回転したものとする
             // 各オイラー角を求めるのに回転行列の全成分は要らないので、一部だけ計算する。
-            
+
             float R_11 = r_f * b_f;                         // 回転行列の(1,1)成分
             float R_12 = r_f * b_l;                         // 回転行列の(1,2)成分
             float R_13 = r_f * b_u;                         // 回転行列の(1,3)成分
             float R_23 = r_l * b_u;                         // 回転行列の(2,3)成分
             float R_33 = r_u * b_u;                         // 回転行列の(3,3)成分
-            
-            yaw = atan2(-R_12, R_11) * RAD_TO_DEG - MAG_DECLINATION;
+
+#ifdef RULE3
+            yaw = atan2(-R_12, R_11) * RAD_TO_DEG + MAG_DECLINATION - Beta;
+#else
+            yaw = atan2(-R_12, R_11) * RAD_TO_DEG + MAG_DECLINATION;
+#endif
             roll = atan2(-R_23, R_33) * RAD_TO_DEG;
             pitch = asin(R_13) * RAD_TO_DEG;
-            
+
             if(yaw < -180.0f) yaw += 360.0f;                // ヨー角を[-π, π]に補正
-            
-            
-            
+            if(yaw > 180.0f) yaw -= 360.0f;                 // ヨー角を[-π, π]に補正
+
+
+
             if(UTC_t - pre_UTC_t >= 1) {                    // GPSデータが更新されていたら
                 p.SetComp(1, gms.longitude * DEG_TO_RAD);
                 p.SetComp(2, gms.latitude * DEG_TO_RAD);
-                
+
             } else {                                        // 更新されていなかったら
                 // GPSの補完処理を追加予定
             }
-            
+
             pre_p = p;
             pre_UTC_t = UTC_t;
-        
+
             float sv = (float)servoVcc.read_u16() * ADC_LSB_TO_V * 2.0f;    // サーボ電源電圧
             float lv = (float)logicVcc.read_u16() * ADC_LSB_TO_V * 2.0f;    // ロジック電源電圧
-            
+
             // データをmicroSDに保存し、XBeeでPCへ送信する
-            sprintf(data, "%.3f,%.3f,%.3f, %.3f,%.3f,%.3f, %.3f,%.3f,%.3f, %.3f,%d\r\n", 
-                    yaw, pitch, roll, 
-                    press, gms.longitude, gms.latitude, 
-                    sv, lv, vrt_acc, 
+            sprintf(data, "%.3f,%.3f,%.3f, %.3f,%.3f,%.3f, %.3f,%.3f,%.3f, %.3f,%d\r\n",
+                    yaw, pitch, roll,
+                    press, gms.longitude, gms.latitude,
+                    sv, lv, vrt_acc,
                     Distance(target_p, p), optSensor.read_u16());
             fprintf(fp, data);
             fflush(fp);
             xbee.printf(data);
-            
+
             INT_flag = TRUE;            // 割り込み許可
         }
-        
-        
+
+
         /******************************* 制御ルーチン *******************************/
         {
-            
-            if(fabs(roll) > BorderSpiral) {
-                // スパイラル回避行動
-                if(roll > 0) {
-                    pull_L = PullMax;
-                    pull_R = 0;
-                } else {
-                    pull_L = 0;
-                    pull_R = PullMax;
-                }
-            } else {
-                
-                switch(step){
-                
-                // 投下検出
-                case '0':
-                    if(thrown() || count != 0){
+
+            switch(step) {
+
+                // 投下&安定滑空シーケンス
+                case 0:
+                    if(thrown() || count != 0) {
                         count++;
                         // 投下直後に紐を引く場合はコメントアウトをはずす
                         // pull_L = 15;
@@ -288,114 +290,141 @@
                             step = 1;
                         }
                     }
-                break;
-                
-                // 制御ルーチン
-                case '1':
-                    /* いずれも地球を完全球体と仮定 */
-                    float target_lng = target_x * DEG_TO_RAD;
-                    float target_lat = target_y * DEG_TO_RAD;
-                    /* 北から西回りで目標方向の角度を出力 */
-                    float targetY = cos( target_lat ) * sin( target_lng - p.GetComp(1) );
-                    float targetX = cos( p.GetComp(2) ) * sin( target_lat ) - sin( p.GetComp(2) ) * cos( target_lat ) * cos( target_lng - p.GetComp(1) );
-                    float theta = -atan2f( targetY, targetX ); 
-                    float delta_theta = 0.0f;
-                    
-                    if(yaw >= 0.0f) {
-                        if(theta >= 0.0f) {
-                            if(theta - yaw > Alpha) dir = 0;
-                            else if(theta - yaw < -Alpha) dir = 1;
+                    break;
+
+                // 制御シーケンス
+                case 1:
+                    if(fabs(roll) > BorderSpiral) {
+                        // スパイラル回避行動
+                        if(roll > 0) {
+                            pull_L = PullMax;
+                            pull_R = 0;
                         } else {
-                            theta += 360.0f;
-                            delta_theta = fabs(theta - yaw);
-                            if(delta_theta < 180.0f) {
-                                if(delta_theta > Alpha) dir = 0;
-                            } else {
-                                if(360.0f - delta_theta > Alpha) dir = 1;
-                            }
+                            pull_L = 0;
+                            pull_R = PullMax;
                         }
                     } else {
-                        if(theta <= 0.0f) {
-                            if(theta - yaw > Alpha) dir = 0;
-                            else if(theta - yaw < -Alpha) dir = 1;
-                        } else {
-                            theta -= 360.0f;
-                            delta_theta = fabs(theta - yaw);
-                            if(delta_theta < 180.0f) {
-                                if(delta_theta > Alpha) dir = 1;
-                            } else {
-                                if(360.0f - delta_theta > Alpha) dir = 0;
+
+                        /* いずれも地球を完全球体と仮定 */
+                        float target_lng = target_x * DEG_TO_RAD;
+                        float target_lat = target_y * DEG_TO_RAD;
+                        /* 北から西回りで目標方向の角度を出力 */
+                        float targetY = cos( target_lat ) * sin( target_lng - p.GetComp(1) );
+                        float targetX = cos( p.GetComp(2) ) * sin( target_lat ) - sin( p.GetComp(2) ) * cos( target_lat ) * cos( target_lng - p.GetComp(1) );
+                        float theta = -atan2f( targetY, targetX );
+                        float delta_theta = 0.0f;
+
+                        if(yaw >= 0.0f) {                                       // ヨー角が正
+                            if(theta >= 0.0f) {                                 // 目標角も正ならば、
+                                if(theta - yaw > Alpha) dir = 0;                // 単純に差を取って閾値αと比べる
+                                else if(theta - yaw < -Alpha) dir = 1;
+                            } else {                                            // 目標角が負であれば
+                                theta += 360.0f;                                // 360°足して正の値に変換してから
+                                delta_theta = theta - yaw;                      // 差を取る(yawから左回りに見たthetaとの差分)
+                                if(delta_theta < 180.0f) {                      // 差が180°より小さければ左旋回
+                                    if(delta_theta > Alpha) dir = 0;
+                                } else {                                        // 180°より大きければ右旋回
+                                    if(360.0f - delta_theta > Alpha) dir = 1;
+                                }
                             }
+                        } else {                                                // ヨー角が負
+                            if(theta <= 0.0f) {                                 // 目標角も負ならば、
+                                if(theta - yaw > Alpha) dir = 0;                // 単純に差を取って閾値αと比べる
+                                else if(theta - yaw < -Alpha) dir = 1;
+                            } else {                                            // 目標角が正であれば、
+                                delta_theta = theta - yaw;                      // 差を取る(yawから左回りに見たthetaとの差分)
+                                if(delta_theta < 180.0f) {                      // 差が180°より小さければ左旋回
+                                    if(delta_theta > Alpha) dir = 0;
+                                } else {                                        // 180°より大きければ右旋回
+                                    if(360.0f - delta_theta > Alpha) dir = 1;
+                                }
+                            }
+                        }
+
+                        if(dir == 0) {           //目標は左方向
+
+                            pull_L = 20;
+                            pull_R = 0;
+
+                        } else if (dir == 1) {   //目標は右方向
+
+                            pull_L = 0;
+                            pull_R = 20;
+
                         }
                     }
-                    
-             
-                    if(dir == 0) {           //目標は左方向
-             
-                        pull_L = 20;
-                        pull_R = 0;
-             
-                    } else if (dir == 1) {   //目標は右方向
-             
-                        pull_L = 0;
-                        pull_R = 20;
-             
-                    }
-                    
-                break;
-                }
-                
+
+#ifdef RULE2
+                    // 目標地点との距離が閾値以下だった場合、落下シーケンスへと移行する
+                    if(Distance(target_p, p) < BorderDistance) step = 2;
+#endif
+
+                    break;
+
+#ifdef RULE2
+                // 落下シーケンス
+                case 2:
+                    pull_L = 25;
+                    pull_R = 0;
+
+                    // もし落下中に目標値から離れてしまった場合は、体勢を立て直して再び滑空
+                    // 境界で制御が不安定にならないよう閾値にマージンを取る
+                    if(Distance(target_p, p) > BorderDistance+5.0f) step = 1;
+                    break;
+#endif
             }
-                    
+
             // 指定された引っ張り量だけ紐を引っ張る
             if(pull_L < 0) pull_L = 0;
             else if(pull_L > PullMax) pull_L = PullMax;
             if(pull_R < 0) pull_R = 0;
             else if(pull_R > PullMax) pull_R = PullMax;
-            
+
             servoL.pulsewidth((ServoMax - ServoMin) * pull_L / PullMax + ServoMin);
             servoR.pulsewidth((ServoMax - ServoMin) * pull_R / PullMax + ServoMin);
-            
-            
-            
+
+
+
         }
-        
+
         myled = 0; // LED is OFF
-        
+
         // ループはきっかり0.2秒ごと
         while(timer.read_ms() < 200);
-        
-        
+
+
     }
-    
+
     /* ------------------------------ ↑↑↑ ここまでメインループ ↑↑↑ ------------------------------ */
 }
 
-void LoadConfig(){
+void LoadConfig()
+{
     char value[20];
     //Read a configuration file from a mbed.
-    if (!cfg.read("/sd/config.txt")){
+    if (!cfg.read("/sd/config.txt")) {
         pc.printf("Config file does not exist\n");
-    }else{    
+    } else {
         //Get values
         if (cfg.getValue("target_x", &value[0], sizeof(value))) target_x = atof(value);
-        else{
+        else {
             pc.printf("Failed to get value for target_x\n");
         }
         if (cfg.getValue("target_y", &value[0], sizeof(value))) target_y = atof(value);
-        else{
+        else {
             pc.printf("Failed to get value for target_y\n");
         }
     }
 }
 
-int Find_last() {
+int Find_last()
+{
     int i, n = 0;
     char c;
     DIR *dp;
     struct dirent *dirst;
     dp = opendir("/sd/");
-    if (!dp){
+    if (!dp) {
         pc.printf("Could not open directry.\n");
         return -1;
     }
@@ -408,7 +437,8 @@
     return n;
 }
 
-void KalmanInit() {
+void KalmanInit()
+{
     // 重力
     {
         // 誤差共分散行列の値を決める(対角成分のみ)
@@ -416,17 +446,17 @@
         float alpha_Q2 = 0.5f;
         R2 *= alpha_R2;
         Q2 *= alpha_Q2;
-        
+
         // 観測方程式のヤコビアンの値を設定(時間変化無し)
         float h2[15] = {
             1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-            0.0f, 1.0f, 0.0f, 0.0f, 0.0f,  
+            0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
             0.0f, 0.0f, 1.0f, 0.0f, 0.0f
         };
-        
+
         H2.SetComps(h2);
     }
-    
+
     // 地磁気
     {
         // 誤差共分散行列の値を決める(対角成分のみ)
@@ -434,49 +464,50 @@
         float alpha_Q1 = 0.5f;
         R1 *= alpha_R1;
         Q1 *= alpha_Q1;
-        
+
         // 観測方程式のヤコビアンの値を設定(時間変化無し)
         float h1[21] = {
             1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
             0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
             0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f
         };
-        
+
         H1.SetComps(h1);
     }
 }
 
-void KalmanUpdate() {
+void KalmanUpdate()
+{
     // 重力
-    
+
     {
         // ヤコビアンの更新
         float f2[25] = {
-            1.0f, (raw_gyro.GetComp(3) - post_x1.GetComp(7))*dt, -(raw_gyro.GetComp(2) - post_x2.GetComp(5))*dt, 0.0f, post_x2.GetComp(3)*dt, 
-            -(raw_gyro.GetComp(3) - post_x1.GetComp(7))*dt, 1.0f, (raw_gyro.GetComp(1) - post_x2.GetComp(4))*dt, -post_x2.GetComp(3)*dt, 0.0f, 
-            (raw_gyro.GetComp(2) - post_x2.GetComp(5))*dt, -(raw_gyro.GetComp(1) - post_x2.GetComp(4))*dt, 1.0f, post_x2.GetComp(2)*dt, -post_x2.GetComp(1)*dt, 
-            0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 
+            1.0f, (raw_gyro.GetComp(3) - post_x1.GetComp(7))*dt, -(raw_gyro.GetComp(2) - post_x2.GetComp(5))*dt, 0.0f, post_x2.GetComp(3)*dt,
+            -(raw_gyro.GetComp(3) - post_x1.GetComp(7))*dt, 1.0f, (raw_gyro.GetComp(1) - post_x2.GetComp(4))*dt, -post_x2.GetComp(3)*dt, 0.0f,
+            (raw_gyro.GetComp(2) - post_x2.GetComp(5))*dt, -(raw_gyro.GetComp(1) - post_x2.GetComp(4))*dt, 1.0f, post_x2.GetComp(2)*dt, -post_x2.GetComp(1)*dt,
+            0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
             0.0f, 0.0f, 0.0f, 0.0f, 1.0f
         };
-        
+
         F2.SetComps(f2);
-        
+
         // 事前推定値の更新
         //pri_x2 = F2 * post_x2;
-        
+
         float pri_x2_vals[5] = {
-            post_x2.GetComp(1) + post_x2.GetComp(2) * (raw_gyro.GetComp(3) - post_x1.GetComp(7)) * dt - post_x2.GetComp(3) * (raw_gyro.GetComp(2) - post_x2.GetComp(5)) * dt, 
-            post_x2.GetComp(2) + post_x2.GetComp(3) * (raw_gyro.GetComp(1) - post_x2.GetComp(4)) * dt - post_x2.GetComp(1) * (raw_gyro.GetComp(3) - post_x1.GetComp(7)) * dt, 
-            post_x2.GetComp(3) + post_x2.GetComp(1) * (raw_gyro.GetComp(2) - post_x2.GetComp(5)) * dt - post_x2.GetComp(2) * (raw_gyro.GetComp(1) - post_x2.GetComp(4)) * dt, 
-            post_x2.GetComp(4), 
+            post_x2.GetComp(1) + post_x2.GetComp(2) * (raw_gyro.GetComp(3) - post_x1.GetComp(7)) * dt - post_x2.GetComp(3) * (raw_gyro.GetComp(2) - post_x2.GetComp(5)) * dt,
+            post_x2.GetComp(2) + post_x2.GetComp(3) * (raw_gyro.GetComp(1) - post_x2.GetComp(4)) * dt - post_x2.GetComp(1) * (raw_gyro.GetComp(3) - post_x1.GetComp(7)) * dt,
+            post_x2.GetComp(3) + post_x2.GetComp(1) * (raw_gyro.GetComp(2) - post_x2.GetComp(5)) * dt - post_x2.GetComp(2) * (raw_gyro.GetComp(1) - post_x2.GetComp(4)) * dt,
+            post_x2.GetComp(4),
             post_x2.GetComp(5)
         };
-        
+
         pri_x2.SetComps(pri_x2_vals);
-        
+
         // 事前誤差分散行列の更新
         pri_P2 = F2 * post_P2 * F2.Transpose() + R2;
-        
+
         // カルマンゲインの計算
         S2 = Q2 + H2 * pri_P2 * H2.Transpose();
         static float det;
@@ -484,47 +515,47 @@
             pc.printf("E:%.3f\r\n", det);
             return;     // 万が一、逆行列が見つからなかった場合は前回の推定値を保持して終了
         }
-        K2 = pri_P2 * H2.Transpose() * S_inv2;    
-        
+        K2 = pri_P2 * H2.Transpose() * S_inv2;
+
         // 事後推定値の更新
         post_x2 = pri_x2 + K2 * (raw_acc - H2 * pri_x2);
         // 事後誤差分散行列の更新
         post_P2 = (I2 - K2 * H2) * pri_P2;
     }
-    
-    
+
+
     // 地磁気
     {
         // ヤコビアンの更新
         float f1[49] = {
-            1.0f, (raw_gyro.GetComp(3) - post_x1.GetComp(7))*dt, -(raw_gyro.GetComp(2) - post_x2.GetComp(5))*dt, 0.0f, 0.0f, 0.0f, -post_x1.GetComp(2) * dt, 
-            -(raw_gyro.GetComp(3) - post_x1.GetComp(7))*dt, 1.0f, (raw_gyro.GetComp(1) - post_x2.GetComp(4))*dt, 0.0f, 0.0f, 0.0f, post_x1.GetComp(1) * dt, 
-            (raw_gyro.GetComp(2) - post_x2.GetComp(5))*dt, -(raw_gyro.GetComp(1) - post_x2.GetComp(4))*dt, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 
-            0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 
-            0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,  
-            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,  
+            1.0f, (raw_gyro.GetComp(3) - post_x1.GetComp(7))*dt, -(raw_gyro.GetComp(2) - post_x2.GetComp(5))*dt, 0.0f, 0.0f, 0.0f, -post_x1.GetComp(2) * dt,
+            -(raw_gyro.GetComp(3) - post_x1.GetComp(7))*dt, 1.0f, (raw_gyro.GetComp(1) - post_x2.GetComp(4))*dt, 0.0f, 0.0f, 0.0f, post_x1.GetComp(1) * dt,
+            (raw_gyro.GetComp(2) - post_x2.GetComp(5))*dt, -(raw_gyro.GetComp(1) - post_x2.GetComp(4))*dt, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+            0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
+            0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
             0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
         };
-        
+
         F1.SetComps(f1);
-        
+
         // 事前推定値の更新
         //pri_x1 = F1 * post_x1;
         float pri_x1_vals[7] = {
-            post_x1.GetComp(1) + post_x1.GetComp(2) * (raw_gyro.GetComp(3) - post_x1.GetComp(7)) * dt - post_x1.GetComp(3) * (raw_gyro.GetComp(2) - post_x2.GetComp(5)) * dt, 
-            post_x1.GetComp(2) + post_x1.GetComp(3) * (raw_gyro.GetComp(1) - post_x2.GetComp(4)) * dt - post_x1.GetComp(1) * (raw_gyro.GetComp(3) - post_x1.GetComp(7)) * dt, 
-            post_x1.GetComp(3) + post_x1.GetComp(1) * (raw_gyro.GetComp(2) - post_x2.GetComp(5)) * dt - post_x1.GetComp(2) * (raw_gyro.GetComp(1) - post_x2.GetComp(4)) * dt, 
-            post_x1.GetComp(4), 
-            post_x1.GetComp(5), 
-            post_x1.GetComp(6), 
+            post_x1.GetComp(1) + post_x1.GetComp(2) * (raw_gyro.GetComp(3) - post_x1.GetComp(7)) * dt - post_x1.GetComp(3) * (raw_gyro.GetComp(2) - post_x2.GetComp(5)) * dt,
+            post_x1.GetComp(2) + post_x1.GetComp(3) * (raw_gyro.GetComp(1) - post_x2.GetComp(4)) * dt - post_x1.GetComp(1) * (raw_gyro.GetComp(3) - post_x1.GetComp(7)) * dt,
+            post_x1.GetComp(3) + post_x1.GetComp(1) * (raw_gyro.GetComp(2) - post_x2.GetComp(5)) * dt - post_x1.GetComp(2) * (raw_gyro.GetComp(1) - post_x2.GetComp(4)) * dt,
+            post_x1.GetComp(4),
+            post_x1.GetComp(5),
+            post_x1.GetComp(6),
             post_x1.GetComp(7)
         };
-        
+
         pri_x1.SetComps(pri_x1_vals);
-        
+
         // 事前誤差分散行列の更新
         pri_P1 = F1 * post_P1 * F1.Transpose() + R1;
-        
+
         // カルマンゲインの計算
         S1 = Q1 + H1 * pri_P1 * H1.Transpose();
         static float det;
@@ -532,8 +563,8 @@
             pc.printf("E:%.3f\r\n", det);
             return;     // 万が一、逆行列が見つからなかった場合は前回の推定値を保持して終了
         }
-        K1 = pri_P1 * H1.Transpose() * S_inv1;    
-        
+        K1 = pri_P1 * H1.Transpose() * S_inv1;
+
         // 事後推定値の更新
         post_x1 = pri_x1 + K1 * (raw_geomag - H1 * pri_x1);
         // 地磁気ベクトルの大きさに拘束条件を与える
@@ -542,9 +573,9 @@
             gm.SetComp(1, post_x1.GetComp(1));
             gm.SetComp(2, post_x1.GetComp(2));
             gm.SetComp(3, post_x1.GetComp(3));
-            
+
             gm = MAG_MAGNITUDE * gm.Normalize();
-            
+
             post_x1.SetComp(1, gm.GetComp(1));
             post_x1.SetComp(2, gm.GetComp(2));
             post_x1.SetComp(3, gm.GetComp(3));
@@ -554,9 +585,10 @@
     }
 }
 
-float Distance(Vector p1, Vector p2) {
+float Distance(Vector p1, Vector p2)
+{
     if(p1.GetDim() != p2.GetDim()) return 0.0f;
-    
+
     static float mu_y = (p1.GetComp(2) + p2.GetComp(2)) * 0.5f;
     static float s_mu_y = sin(mu_y);
     static float w = sqrt(1 - GPS_SQ_E * s_mu_y * s_mu_y);
@@ -564,60 +596,62 @@
     static float n = GPS_A / w;
     static float d1 = m * (p1.GetComp(2) - p2.GetComp(2));
     static float d2 = n * cos(mu_y) * (p1.GetComp(1) - p2.GetComp(1));
-    
+
     return sqrt(d1 * d1 + d2 * d2);
 }
 
 /** 投下を検知する関数
- * 
+ *
  * @return 投下されたかどうか(true=投下 false=未投下
- * 
+ *
 */
-bool thrown() {
+bool thrown()
+{
     static int opt_count = 0;
     static int g_count = 0;
     static int para_count = 0;
-    
+
     if(optSensor.read_u16() > BorderOpt) opt_count++;
     else opt_count = 0;
     if(vrt_acc < BorderGravity) g_count++;
     else g_count = 0;
     if((int)paraSensor == BorderParafoil) para_count++;
     else para_count = 0;
-    
+
     if(opt_count >= MaxCount || g_count >= MaxCount || para_count >= MaxCount) {
         return true;
     }
-    
+
     return false;
-    
+
 }
 
 /* ------------------------------ 割り込み関数 ------------------------------ */
 
-void INT_func() {
+void INT_func()
+{
     // センサーの値を更新
     mpu.read();
     hmc.read();
-    
+
     for(int i=0; i<3; i++) {
         raw_acc.SetComp(i+1, (float)mpu.data.value.acc[i] * ACC_LSB_TO_G);
         raw_gyro.SetComp(i+1, (float)mpu.data.value.gyro[i] * GYRO_LSB_TO_DEG * DEG_TO_RAD);
         raw_geomag.SetComp(i+1, (float)hmc.data.value[i] * MAG_LSB_TO_GAUSS);
     }
-        
+
     Vector delta_g = Cross(raw_gyro, raw_g);                              // Δg = ω × g
     raw_g = 0.9f * (raw_g - delta_g * dt) + 0.1f * raw_acc.Normalize();   // 相補フィルタ
     raw_g = raw_g.Normalize();
-       
+
     KalmanUpdate();
-        
+
     // LPS25Hによる気圧の取得は10Hz
     lps_cnt = (lps_cnt+1)%10;
     if(lps_cnt == 0) {
         raw_press = (float)lps.pressure() * PRES_LSB_TO_HPA;
     }
-    
+
     if(INT_flag != FALSE) {
         g = raw_g;
         for(int i=0; i<3; i++) {
@@ -626,30 +660,32 @@
         acc = raw_acc;
         gyro = raw_gyro;
         press = raw_press;
-        
+
         vrt_acc = raw_acc * raw_g;
-        
+
     }
 }
 
 /* ------------------------------ デバッグ用関数 ------------------------------ */
 
-void toString(Matrix& m) {
-    
+void toString(Matrix& m)
+{
+
     for(int i=0; i<m.GetRow(); i++) {
         for(int j=0; j<m.GetCol(); j++) {
             pc.printf("%.6f\t", m.GetComp(i+1, j+1));
         }
         pc.printf("\r\n");
     }
-    
+
 }
 
-void toString(Vector& v) {
-    
+void toString(Vector& v)
+{
+
     for(int i=0; i<v.GetDim(); i++) {
         pc.printf("%.6f\t", v.GetComp(i+1));
     }
     pc.printf("\r\n");
-    
+
 }
\ No newline at end of file