#author("2019-12-22T11:50:34+09:00","takaki","takaki")
#author("2019-12-22T12:10:15+09:00","takaki","takaki")
**目次 [#r53d533a]
#contents

*課題2 [#md26d522]
ライントレースし、ボールを目的地まで運ぶロボット
#ref(2019b/Member/takaki/Mission2/2019b-mission2.png,100%,コース)
+A地点から出発
+J
+H (直進)
+I (ボール or キューボイドをつかんでUターン)
+H (右折)
+G (一時停止の後、直進)
+D (右折)
+E, F 通過
+G (一時停止の後、直進)
+C (一時停止の後、左折)
+B (一時停止)
+A地点に入る(ゴール)
*ロボットの説明 [#aa666193]

#ref(2019b/Member/takaki/Mission2/IMG_1989.jpg,100%,ロボット全体)
前のロボットの欠点をふまえ、垂直な線が描けるよう、x,y座標を動かす部分を別にした。
#ref(2019b/Member/takaki/Mission1/IMG_1991.jpg,100%,ロボット前)
特徴として、縦方向には車の部分、横方向にはペンを取り付けたマジックアームが動くようになっている。
#ref(2019b/Member/takaki/Mission1/IMG_1990.jpg,100%,ロボット後)
このロボットを作るにあたって、いかにマジックアームが動く土台となる棒がなめらかであるかが問題になった。最初、土台の部分を長めのブロックで作ったが、移動部分が長いために、どうしても継ぎはぎにしなければならなかった。そこで、極力アームが動く部分に継ぎ目が来ないようにした。結果として、継ぎ目が多かった時よりも若干スムーズには動いた。しかし、プログラムで動作を連続で行わないようにするなどの工夫は必要となった。
#ref(2019b/Member/takaki/Mission2/IMG_2103.jpg,100%,ロボット全体)
#ref(2019b/Member/takaki/Mission2/IMG_2104.jpg,100%,ロボット前)
#ref(2019b/Member/takaki/Mission2/IMG_2105.jpg,100%,ロボット上)

*プログラムの説明 [#x8aae064]
 #define A_SPEED 20
 #define B_SPEED 17
 #define BLACK 45
 #define B_GRAY 53
 #define GRAY 61
 #define W_GRAY 69
 #define WHITE 75
 #define SPEED 30
 #define r_rot OnFwd(OUT_C,SPEED);Off(OUT_B);
 #define l_rot OnFwd(OUT_B,SPEED);Off(OUT_C);
 #define r_turn OnFwd(OUT_C,SPEED);OnRev(OUT_B,SPEED);
 #define l_turn OnFwd(OUT_B,SPEED);OnRev(OUT_C,SPEED);
 #define up RotateMotor(OUT_A,10,-40); 
 
 void pu()
 void line_follow_r(long tmin = 0,long tmax = 60000)
 {
     RotateMotor(OUT_C,10,-15);
     Wait(1000);
     long t0 = CurrentTick();
     long t = CurrentTick();
     SetSensorLight(S1);
     
     while(CurrentTick() - t0 < 110)
     {
      if(SENSOR_1 <= BLACK)
      {
       l_rot;
      }
      else 
      {
       if(SENSOR_1 <= B_GRAY)
       {
        l_turn;
       }
       else if(SENSOR_1 <= GRAY)
       {
        OnFwd(OUT_BC,SPEED);
       }
       else if(SENSOR_1 <= W_GRAY)
       {
        r_turn;
       }
       else
       {
        r_rot;
       }
 
        t0 = CurrentTick();
      }
     }
 
     Off(OUT_BC);
 }
 
 void pd()
 void line_follow_l(long tmin = 0,long tmax = 60000)
 {
     RotateMotor(OUT_C,10,15);
     Wait(1000);
     long t0 = CurrentTick();
     long t = CurrentTick();
     SetSensorLight(S1);
     
     while(CurrentTick() - t0 < 110)
     {
       if(SENSOR_1 <= BLACK) 
      {
       r_rot;
      }
       else 
      {
        if(SENSOR_1 <= B_GRAY)
       {
        r_turn;
       }
        else if(SENSOR_1 <= GRAY)
       {
        OnFwd(OUT_BC,SPEED);
       }
        else if(SENSOR_1 <= W_GRAY)
       {
        l_turn;
       }
        else
       {
        l_rot;
       }
 
        t0 = CurrentTick();
      }
     }
 
     Off(OUT_BC);
 }
 
 void rmot_a(int k)
 void fetch_ball(long tmax = 10000)
 {
     RotateMotor(OUT_A,A_SPEED,k);
     Wait(1000);
 }
     SetSensorLowspeed(S2);
     long t0 = CurrentTick();
 
 void rmot_b(int k)
 {
     RotateMotor(OUT_B,B_SPEED,k);
     Wait(1000);
      while(1)
     {
       if(CurrentTick() - t0 <= tmax)
      {
        if(SensorUS(S2) >= 4)
       {
        OnFwd(OUT_BC,15);
       }
        else
       {
        up;
        l_rot;
        Wait(1000);
        break;
       }
      }
       else
      {
       l_rot;
       Wait(1000);
       break;
      }
     }
 }
 
 task main()
 {
     line_follow_r(0,60000);
     Wait(1000);
     
     rmot_a(80);
     rmot_b(15);
     rmot_a(-80);
     rmot_a(-15);
 
     pu();
     rmot_b(5);
     rmot_a(10);
 
     pd();
     rmot_b(5);
     pu();
     rmot_b(5);
     pd();
     rmot_b(5);
 
     pu();
     rmot_a(15);
     rmot_b(-7);
     pd();
     rmot_a(30);
     rmot_a(5);
     pu();
     OnFwd(OUT_C,SPEED);
     Off(OUT_B);
     Wait(100);
     fetch_ball(10000);
     line_follow_l(0,1000);
     r_turn;
     Wait(1000);
     line_follow_l(0,1000);
     r_turn;
     Wait(1000);
     line_follow_l(0,10000);
     OnFwd(OUT_BC,SPEED);
     Wait(1000);
     line_follow_r(0,10000);
 }

車の部分と、マジックアームの部分のモータの速さが違ったため、#defineで定義した。
 #define BLACK 45
 #define B_GRAY 53
 #define GRAY 61
 #define W_GRAY 69
 #define WHITE 75
 #define SPEED 30
 #define r_rot OnFwd(OUT_C,SPEED);Off(OUT_B);
 #define l_rot OnFwd(OUT_B,SPEED);Off(OUT_C);
 #define r_turn OnFwd(OUT_C,SPEED);OnRev(OUT_B,SPEED);
 #define l_turn OnFwd(OUT_B,SPEED);OnRev(OUT_C,SPEED);
 #define up RotateMotor(OUT_A,10,-40); 

モータAで車、Bでアーム、Cでペンを動かした。
 void pu()
 void line_follow_r(long tmin = 0,long tmax = 60000)
 {
     RotateMotor(OUT_C,10,-15);
     Wait(1000);
     long t0 = CurrentTick();
     long t = CurrentTick();
     SetSensorLight(S1);
     
     while(CurrentTick() - t0 < 110)
     {
      if(SENSOR_1 <= BLACK)
      {
       l_rot;
      }
      else 
      {
       if(SENSOR_1 <= B_GRAY)
       {
        l_turn;
       }
       else if(SENSOR_1 <= GRAY)
       {
        OnFwd(OUT_BC,SPEED);
       }
       else if(SENSOR_1 <= W_GRAY)
       {
        r_turn;
       }
       else
       {
        r_rot;
       }
 
        t0 = CurrentTick();
      }
     }
 
     Off(OUT_BC);
 }
 
 void pd()
 void line_follow_l(long tmin = 0,long tmax = 60000)
 {
     RotateMotor(OUT_C,10,15);
     Wait(1000);
     long t0 = CurrentTick();
     long t = CurrentTick();
     SetSensorLight(S1);
     
     while(CurrentTick() - t0 < 110)
     {
       if(SENSOR_1 <= BLACK) 
      {
       r_rot;
      }
       else 
      {
        if(SENSOR_1 <= B_GRAY)
       {
        r_turn;
       }
        else if(SENSOR_1 <= GRAY)
       {
        OnFwd(OUT_BC,SPEED);
       }
        else if(SENSOR_1 <= W_GRAY)
       {
        l_turn;
       }
        else
       {
        l_rot;
       }
 
        t0 = CurrentTick();
      }
     }
 
     Off(OUT_BC);
 }
ペンの上げ下げを関数として定義した。また、
 void rmot_a(int k)

 void fetch_ball(long tmax = 10000)
 {
     RotateMotor(OUT_A,A_SPEED,k);
     Wait(1000);
 }
     SetSensorLowspeed(S2);
     long t0 = CurrentTick();
 
 void rmot_b(int k)
 {
     RotateMotor(OUT_B,B_SPEED,k);
     Wait(1000);
      while(1)
     {
       if(CurrentTick() - t0 <= tmax)
      {
        if(SensorUS(S2) >= 4)
       {
        OnFwd(OUT_BC,15);
       }
        else
       {
        up;
        l_rot;
        Wait(1000);
        break;
       }
      }
       else
      {
       l_rot;
       Wait(1000);
       break;
      }
     }
 }
車の部分とアームの部分も関数にした。引数kによって、どれだけ回転させるかを決める。また、アームの部分は非常に繊細なので、動作をさせるときは1テンポ置くようにした。

*感想と反省 [#sc4824a3]
#ref(2019b/Member/takaki/Mission1/IMG_1992.jpg,100%,ロボット全体)
今回、うまく似顔絵をかくことができなかった。理由としては、マジックアームの不安定さにあると思う。マジックアームのモーターに、ペンをとりつけたモーターという、非常に重いものを移動させるには、トルクが足りないと感じた。また、アームが片方にしかついていないということもあり、非常にバランスが悪かった。マジックアームを作る部分は比較的簡単だったが、プログラムの面で挫折してしまった。今回のロボットから、ハードウェアを作成するうえで、非常に重要なことが分かった気がする。次の課題では、ハードウェアとソフトウェアの関連性や、ロボットに無理をさせないような作りにしたい。


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS