2020_TeamA / Mbed 2 deprecated somaomuni2

Dependencies:   mbed YKNCT_Movement SBDBT BNO055 YKNCT_MD YKNCT_I2C

Revision:
2:ec149525ec2a
Parent:
1:b9f698be841c
Child:
3:b77f51108bf1
--- a/main.cpp	Sat Mar 14 05:29:14 2020 +0000
+++ b/main.cpp	Tue Mar 17 05:17:59 2020 +0000
@@ -17,6 +17,8 @@
 ROCATION NowAcc;
 /* ロボットの座標 */
 ROCATION NowLoc;
+/* ロボットの目標座標 */
+ROCATION Target;
 
 /* 定数定義 ------------------------------------------------------------------*/
 /* マクロ定義 ----------------------------------------------------------------*/
@@ -28,6 +30,9 @@
 /* 自己位置推定処理 */
 void LocEstimate(void);
 
+/* P制御値代入 */
+void Pro_control(int tar_x, int tar_y, int tar_rev);
+
 
 /* 変数定義 ------------------------------------------------------------------*/
 
@@ -41,7 +46,7 @@
 double EncoderDeg[EncoderMAX] = {0};
 
 /* 足回り値保存変数 */
-int MovMotor[4]={0};
+int MovMotor[4]= {0};
 
 /* 自動yaw補整目標角度 */
 double TarTheta=0;
@@ -57,6 +62,9 @@
 /* gyro用タイマ */
 Timer yawCnt;
 
+/* P制御終了タイマ */
+Timer P_fin;
+
 /* UART (Tx,Rx) */
 Serial telemetry(USBTX, USBRX, 115200);
 
@@ -87,105 +95,105 @@
 /*----------------------------------- main ----------------------------------*/
 int main()
 {
-  telemetry.printf("\n\rMainStart");
+    telemetry.printf("\n\rMainStart");
 
-  /* 割り込みの設定
-   * IT_CallBack関数を0.1msで割り込み */
-  flipper.attach_us(&IT_CallBack, 100);
+    /* 割り込みの設定
+     * IT_CallBack関数を0.1msで割り込み */
+    flipper.attach_us(&IT_CallBack, 100);
 
-  /* ジャイロの設定 */
-  bno.setmode(OPERATION_MODE_IMUPLUS);
+    /* ジャイロの設定 */
+    bno.setmode(OPERATION_MODE_IMUPLUS);
 
-  /* I2CMDの設定 */
-  MD.Init(0,MD_SMB);
-  MD.Init(1,MD_SMB);
-  MD.Init(2,MD_SMB);
-  MD.Init(3,MD_SMB);
+    /* I2CMDの設定 */
+    MD.Init(0,MD_SMB);
+    MD.Init(1,MD_SMB);
+    MD.Init(2,MD_SMB);
+    MD.Init(3,MD_SMB);
 
-  telemetry.printf("\n\rMainLoopStart");
-  /* メインループ --------------------------------------------------------------*/
-  while(1) {
-    /* オンボードLED点滅 */
-    led=!led;
+    telemetry.printf("\n\rMainLoopStart");
+    /* メインループ --------------------------------------------------------------*/
+    while(1) {
+        /* オンボードLED点滅 */
+        led=!led;
 
-    /* 表示改行 */
-    telemetry.printf("\n\r");
+        /* 表示改行 */
+        telemetry.printf("\n\r");
 
-    /* 自動処理関連テレメトリ */
-    telemetry.printf("ope:%d ",operate);
-    /* 座標テレメトリ */
-    telemetry.printf("X:%4.0f Y:%4.0f T:%4.0f ",NowLoc.X,NowLoc.Y,NowLoc.theta);
+        /* 自動処理関連テレメトリ */
+        telemetry.printf("ope:%d ",operate);
+        /* 座標テレメトリ */
+        telemetry.printf("X:%4.0f Y:%4.0f T:%4.0f ",NowLoc.X,NowLoc.Y,NowLoc.theta);
 
-    /* 自己位置推定更新 */
-    LocEstimate();
+        /* 自己位置推定更新 */
+        LocEstimate();
 
-    /* I2CMD実行 */
-    MD.Exe();
-    
-    /* タイマ-スタート */
-    yawCnt.start();
-    /* タイマーリセット */
-    yawCnt.reset();
+        /* I2CMD実行 */
+        MD.Exe();
+
+        /* タイマ-スタート */
+        yawCnt.start();
+        /* タイマーリセット */
+        yawCnt.reset();
 
 
-    /* 操縦権変更 ×停止 △手動 〇自動 */
-    if(DS3.CROSS)     operate=0;
-    if(DS3.TRIANGLE)  operate=1;
-    if(DS3.CIRCLE)    operate=2;
+        /* 操縦権変更 ×停止 △手動 〇自動 */
+        if(DS3.CROSS)     operate=0;
+        if(DS3.TRIANGLE)  operate=1;
+        if(DS3.CIRCLE)    operate=2;
 
-    /* 操縦権:なし 停止動作 */
-    if(operate==0){
-      /* 足回り停止 */
-      omuni.XmarkOmni_Move(0,0,0);
-      for (int i = 0; i < 4; i++) {
+        /* 操縦権:なし 停止動作 */
+        if(operate==0) {
+            /* 足回り停止 */
+            omuni.XmarkOmni_Move(0,0,0);
+            for (int i = 0; i < 4; i++) {
                 MD.Set(i,MovMotor[i]);
             }
 
-    }
-    /* 操縦権:手動 */
-    else if(operate==1){
-      /* 足回り手動動作 */
-      int x_val = (double)(DS3.LX-64)*100/64;
-      int y_val = (double)(64-DS3.LY)*100/64;
-      int r_val = (double)(DS3.RX-64)*100/64;
+        }
+        /* 操縦権:手動 */
+        else if(operate==1) {
+            /* 足回り手動動作 */
+            int x_val = (double)(DS3.LX-64)*100/64;
+            int y_val = (double)(64-DS3.LY)*100/64;
+            int r_val = (double)(DS3.RX-64)*100/64;
 
-      /* 目標角更新 */
-      if(DS3.RX!=64) yawCnt.reset(); 
-      if(yawCnt.read_ms()<1000) TarTheta=NowLoc.theta;
-      
-      /* gyro値による補正 */
-      r_val += (TarTheta-NowLoc.theta)*cor;
-       
-      omuni.XmarkOmni_Move(x_val,y_val,r_val);
-      for (int i = 0; i < 4; i++) {
+            /* 目標角更新 */
+            if(DS3.RX!=64) yawCnt.reset();
+            if(yawCnt.read_ms()<1000) TarTheta=NowLoc.theta;
+
+            /* gyro値による補正 */
+            r_val += (TarTheta-NowLoc.theta)*cor;
+
+            omuni.XmarkOmni_Move(x_val,y_val,r_val);
+            for (int i = 0; i < 4; i++) {
                 MD.Set(i,MovMotor[i]);
             }
 
-    }
-    /* 操縦権:自動 */
-    else if(operate==2){
-      switch(auto_mode){
-        /* スタート待機処理 */
-        case 0:
-          /* オンボードSWで次のステップに */
-          if(UB) auto_mode++;
-        break;
+        }
+        /* 操縦権:自動 */
+        else if(operate==2) {
+            switch(auto_mode) {
+                /* スタート待機処理 */
+                case 0:
+                    /* オンボードSWで次のステップに */
+                    if(UB) auto_mode++;
+                    break;
 
-        /* 〇〇の処理 */
-        case 1:
-          /* 〇〇の時次のステップに */
-          if(1) auto_mode++;
-        break;
+                /* 〇〇の処理 */
+                case 1:
+                    /* 〇〇の時次のステップに */
+                    if(1) auto_mode++;
+                    break;
 
-        /* 終了処理 */
-        default:
-          auto_mode=0;
-          operate=0;
-        break;
-      }
+                /* 終了処理 */
+                default:
+                    auto_mode=0;
+                    operate=0;
+                    break;
+            }
+        }
+
     }
-    
-  }
 }
 
 
@@ -194,37 +202,38 @@
 * @引数   なし
 * @返り値 なし
 *******************************************************************************/
-void LocEstimate(void){
-  static double GyroDeg[2]={0};
-  static double EncDeg[2][2]={0};
-  static double disp[3]={0};
+void LocEstimate(void)
+{
+    static double GyroDeg[2]= {0};
+    static double EncDeg[2][2]= {0};
+    static double disp[3]= {0};
 
-  /* ジャイロの値取得 */
-  bno.get_angles();
-  GyroDeg[1]=GyroDeg[0];
-  GyroDeg[0]=bno.euler.yaw;
-  if(GyroDeg[0]!=0) {
-    /* 359→0を跨いだ時,前回の値を0から逆回転で負の値で表記 */
-    if(GyroDeg[1]<90 && GyroDeg[0]>270) GyroDeg[1]+=360;
-    /* 0→359を跨いだ時,前回の値を360以上の値で表記 */
-    else if(GyroDeg[1]>270 && GyroDeg[0]<90) GyroDeg[1]-=360;
-    /* 差を求める*/
-    disp[2]=GyroDeg[1]-GyroDeg[0];
-  }
-  /* Enc2つの差分求める */
-  for(int i=0;i<2;i++){
-    EncDeg[i][1]=EncDeg[i][0];
-    EncDeg[i][0]=EncoderDeg[i];
-    disp[i]=EncDeg[i][1]-EncDeg[i][0];
-  }
-  /* 差分を加速度として保存 */
-  NowAcc.theta = disp[2];
-  NowAcc.X =  disp[0] * cos(NowLoc.theta) + disp[1] * sin(NowLoc.theta)+200*disp[2];
-  NowAcc.Y = -disp[0] * sin(NowLoc.theta) + disp[1] * cos(NowLoc.theta)+200*disp[2];
-  /* 差分を累積して現在位置を保存 */
-  NowLoc.X += NowAcc.X;
-  NowLoc.Y += NowAcc.Y;
-  NowLoc.theta += NowAcc.theta;
+    /* ジャイロの値取得 */
+    bno.get_angles();
+    GyroDeg[1]=GyroDeg[0];
+    GyroDeg[0]=bno.euler.yaw;
+    if(GyroDeg[0]!=0) {
+        /* 359→0を跨いだ時,前回の値を0から逆回転で負の値で表記 */
+        if(GyroDeg[1]<90 && GyroDeg[0]>270) GyroDeg[1]+=360;
+        /* 0→359を跨いだ時,前回の値を360以上の値で表記 */
+        else if(GyroDeg[1]>270 && GyroDeg[0]<90) GyroDeg[1]-=360;
+        /* 差を求める*/
+        disp[2]=GyroDeg[1]-GyroDeg[0];
+    }
+    /* Enc2つの差分求める */
+    for(int i=0; i<2; i++) {
+        EncDeg[i][1]=EncDeg[i][0];
+        EncDeg[i][0]=EncoderDeg[i];
+        disp[i]=EncDeg[i][1]-EncDeg[i][0];
+    }
+    /* 差分を加速度として保存 */
+    NowAcc.theta = disp[2];
+    NowAcc.X =  disp[0] * cos(NowLoc.theta) + disp[1] * sin(NowLoc.theta)+200*disp[2];
+    NowAcc.Y = -disp[0] * sin(NowLoc.theta) + disp[1] * cos(NowLoc.theta)+200*disp[2];
+    /* 差分を累積して現在位置を保存 */
+    NowLoc.X += NowAcc.X;
+    NowLoc.Y += NowAcc.Y;
+    NowLoc.theta += NowAcc.theta;
 }
 
 
@@ -233,41 +242,117 @@
 /* 割り込み(100us) *************************************************************/
 void IT_CallBack(void)
 {
-  static int cnt = 0;
-  static int data[EncoderMAX] = {0};
-  static double EncDeg[EncoderMAX][2] = {0};
+    static int cnt = 0;
+    static int data[EncoderMAX] = {0};
+    static double EncDeg[EncoderMAX][2] = {0};
+
+    for(int i=0; i<EncoderMAX; i++)
+        switch(cnt) {
+            /* 最初の処理 */
+            case 0:
+                data[i] = 0;
+                CS[i] = 0;
+                CL[i] = 1;
+                break;
+            /* 最後の処理 */
+            case 25:
+                CS[i]=1;
+                /* 前回の値更新 今回の値更新(エンコーダの値(0~4096)を角度(0~360)に) */
+                EncDeg[i][1] = EncDeg[i][0];
+                EncDeg[i][0] = (double)data[i] * 360.0 / 4096;
+                /* 359→0を跨いだ時,前回の値を0から逆回転で負の値で表記 */
+                if ((270 <= EncDeg[i][1]) && (EncDeg[i][0] < 90))
+                    EncDeg[i][1] -= 360;
+                /* 0→359を跨いだ時,前回の値を360以上の値で表記 */
+                else if ((EncDeg[i][1] < 90) && (270 <= EncDeg[i][0]))
+                    EncDeg[i][1] += 360;
+                /* 差を求める*/
+                EncoderDeg[i] += EncDeg[i][0] - EncDeg[i][1];
+                break;
+            /* 通常の処理 */
+            default:
+                CL[i]=!CL[i];
+                /* 最初でも最後でもなく奇数回で最初以外の時読み取り処理 */
+                if(cnt != 1 && cnt % 2) {
+                    data[i] |= (DO[i]==1);
+                    data[i] = data[i] << 1;
+                }
+                break;
+        }
+    cnt++;
+    cnt%=26;
+}
+
+
+
+
+/*******************************************************************************
+ * @概要   P制御
+ * @引数   tar_x  :目標のx座標
+ * @引数   tar_y  :目標のy座標
+ * @引数   tar_rev: 目標角
+ * @返り値 なし
+*******************************************************************************/
+void Pro_control(int tar_x, int tar_y, int tar_theta)
+{
+    int log_distance = 0;
 
-  for(int i=0;i<EncoderMAX;i++) 
-  switch(cnt){
-    /* 最初の処理 */
-    case 0:
-      data[i] = 0; CS[i] = 0; CL[i] = 1;
-      break;
-    /* 最後の処理 */
-    case 25:
-      CS[i]=1;
-      /* 前回の値更新 今回の値更新(エンコーダの値(0~4096)を角度(0~360)に) */
-      EncDeg[i][1] = EncDeg[i][0];
-      EncDeg[i][0] = (double)data[i] * 360.0 / 4096;
-      /* 359→0を跨いだ時,前回の値を0から逆回転で負の値で表記 */
-      if ((270 <= EncDeg[i][1]) && (EncDeg[i][0] < 90))
-        EncDeg[i][1] -= 360;
-      /* 0→359を跨いだ時,前回の値を360以上の値で表記 */
-      else if ((EncDeg[i][1] < 90) && (270 <= EncDeg[i][0]))
-        EncDeg[i][1] += 360;
-      /* 差を求める*/
-      EncoderDeg[i] += EncDeg[i][0] - EncDeg[i][1];
-      break;
-    /* 通常の処理 */
-    default:
-      CL[i]=!CL[i];
-      /* 最初でも最後でもなく奇数回で最初以外の時読み取り処理 */
-      if(cnt != 1 && cnt % 2){
-        data[i] |= (DO[i]==1);
-        data[i] = data[i] << 1;
-      }
-      break;
-  }
-  cnt++;
-  cnt%=26;
+    /* 現在座標と目標座標との距離を記録しておく */
+    log_distance = (int)sqrt(pow((double)tar_x - NowLoc.X, 2.0) + pow((double)tar_y - NowLoc.Y, 2.0));
+
+    int x_vel = 0;
+    int y_vel = 0;
+    int t_vel = 0;
+
+    double theta_tar=0.0;
+
+    while(1) {
+        x_vel = ABS((tar_x - NowLoc.X) * 0.06);
+        y_vel = ABS((tar_y - NowLoc.Y) * 0.06);
+
+        /* 最低を決める */
+        if (x_vel < 20)
+            x_vel = 20;
+        if (y_vel < 20)
+            y_vel = 20;
+        /* 100以内に収める */
+        x_vel = Rest(x_vel, 100);
+        y_vel = Rest(y_vel, 100);
+
+        /* 正負を決める */
+        if ((tar_x - NowLoc.X) < 0)
+            x_vel *= -1;
+        if ((tar_y - NowLoc.Y) < 0)
+            y_vel *= -1;
+
+        /* 残り距離計算 */
+        int remain = (int)sqrt(pow((double)tar_x - NowLoc.X, 2.0) + pow((double)tar_y - NowLoc.Y, 2.0));
+        /* 移動量に応じたthetaを求める */
+        theta_tar = (((double)log_distance - remain) / log_distance) * (tar_theta - NowLoc.theta) + NowLoc.theta;;
+        /* 合わせるthetaと現在thetaの差分からtheta補整をかける */
+        t_vel = (theta_tar - NowLoc.theta) * 1.5;
+        
+        t_vel = Rest(t_vel, 20);
+
+        omuni.XmarkOmni_Move(x_vel,y_vel,t_vel);
+
+
+        /* 終了処理 */
+        if ((5 > ABS(remain)) && ABS(tar_theta - NowLoc.theta) < 0.1) {
+            x_vel = 0;
+            y_vel = 0;
+        }
+        if (x_vel == 0 && y_vel == 0)
+            P_fin.start();
+        else
+            P_fin.reset();
+
+        if (P_fin.read_ms() > 100) {
+            /* タイマー停止 */
+            P_fin.stop();
+            P_fin.reset();
+            
+            break;
+        }
+    }
 }
\ No newline at end of file