目次
#contents
*課題について [#p32e005d]
今回の課題は指定された黒い線に沿ってロボットを動かす。私が選んだコースはE地点直進コースである。
詳しい内容については[[課題2>2017a/Mission2]]より。
*ロボット本体について [#we65960b]
ロボット本体を横からみた写真である。センサーとタイヤをできるだけ近づけ、ロボットの回転半径をできるだけ小さくした。
#ref(2017a/Member/rock/Mission2/zenntai.JPG,50%);
今回の課題は、光センサーを使っているため照明や人影で読み取る値に差が生まれ、動きが変わることがあったため、センサーを床に近づけて周りの状況によらないようにした。
#ref(2017a/Member/rock/Mission2/sensor.JPG,50%);
ロボット本体の後ろ側にタイヤをつけると自由に動くようにしなければいけないが、今回は球状になっているブロックを使い摩擦を小さくしている。
#ref(2017a/Member/rock/Mission2/usiro.JPG,50%);
*プログラミングについて [#lf910492]
 前回の課題ではメインのプログラムが長々となってしまったため、今回はサブルーチンを使うなどしてコンパクトになるべくしようとした。
**defineについて [#v9c94d32]
 基本的な色の値と右左折、直進を定義した。
&br; 最後の2つの定義は線を左側から右側へ行くプログラムとその逆のプログラムである。本当はサブルーチンにしたかったが、数に制限がありdefineで定義した。
 #define white 49
 #define white_gray 48
 #define gray 40
 #define black_gray 38
 #define black 35
  
 #define go_forward OnFwd(OUT_AC);              //直進
 #define turn_left0 Off(OUT_A);OnFwd(OUT_C);    //左折
 #define turn_left1 OnRev(OUT_A);OnFwd(OUT_C);  //左旋回
 #define turn_right0 OnFwd(OUT_A);Off(OUT_C);   //右折
 #define turn_right1 OnFwd(OUT_A);OnRev(OUT_C); //右旋回
 
 #define migigawa turn_right0;Wait(20);Off(OUT_A);turn_right1;Wait(60);Off(OUT_AC); //右側に移動
 #define hidarigawa turn_left0;Wait(20);Off(OUT_C);turn_left1;Wait(60);Off(OUT_AC); //左側に移動
**サブルーチンについて [#s470c00b]
 最初と最後、交差点で状況に適した動きができるようなプログラムを、サブルーチンにより定義した。ライントレースをしているときに黒の線上から白の紙に光センサーが0.2秒で移れなかった場合に交差点またはT字路と判断する。道順は決まっているため、次に何をするかはタスクメインで指令した。
&br;  line_go()では、黒線の左側をトレースする。光センサーが白色(49以上)と判断すれば右旋回(左タイヤを前進、右タイヤを後進)を、白色より黒線に近い色(48より上)と判断すれば右折(左タイヤだけを前進)を、白色と黒色の境目上の色(40より上)と判断すれば直進(左右タイヤを前進)を、白色と黒色の境目から黒線の中心に近い色(38より上)と判断すれば左折(右タイヤだけを前進)を、これ以外の色つまり黒線上になれば左旋回(左タイヤ後進、右タイヤを前進)をする。また、白色から白色と黒色の境目から黒線の中心に近い色の時は、タイマーをリセットし、黒線上に0.2秒以上いる時は交差点と判断して止まる。line_go2()は左側をトレースするがline_go()と右左折、右左旋回が逆の動きをする。
 sub hajime()                       //Aからスタート
 {
      OnFwd(OUT_AC);
      Wait(60);
      Off(OUT_AC);
 }
  
 sub owari()                        //最後の直線からAに入る
 {
      OnFwd(OUT_AC);
      Wait(180);
      Off(OUT_AC);
      PlaySound(SOUND_DOWN);
 }
  
 sub line_go()                      //線の左側をトレースし走行
 {
      SetSensor(SENSOR_2,SENSOR_LIGHT);
      ClearTimer(0);
      
      while(FastTimer(0)<20){
          if(SENSOR_2>=white){
              turn_right1;
              ClearTimer(0);
             }else if(SENSOR_2>white_gray){
                  turn_right0;
                  ClearTimer(0);
                 }else if(SENSOR_2>gray){
                      go_forward;
                      ClearTimer(0);
                     }else if(SENSOR_2>black_gray){
                          turn_left0;
                          ClearTimer(0);
                         }else{
                              turn_left1;
                                 }
       }
          }else if(SENSOR_2>white_gray){
              turn_right0;
              ClearTimer(0);
          }else if(SENSOR_2>gray){
              go_forward;
              ClearTimer(0);
          }else if(SENSOR_2>black_gray){
              turn_left0;
              ClearTimer(0);
          }else{
              turn_left1;
          }
      }
      Off(OUT_AC);
 }
  
 sub line_go2()                     //線の右側をトレースし走行
 {
      SetSensor(SENSOR_2,SENSOR_LIGHT);
      ClearTimer(0);
      
      while(FastTimer(0)<20){
          if(SENSOR_2>=white){
              turn_left1;
              ClearTimer(0);
             }else if(SENSOR_2>white_gray){
                  turn_left0;
                  ClearTimer(0);
                 }else if(SENSOR_2>gray){
                      go_forward;
                      ClearTimer(0);
                     }else if(SENSOR_2>black_gray){
                          turn_right0;
                          ClearTimer(0);
                         }else{
                              turn_right1;
                                 }
       }
          }else if(SENSOR_2>white_gray){
              turn_left0;
              ClearTimer(0);
          }else if(SENSOR_2>gray){
              go_forward;
              ClearTimer(0);
          }else if(SENSOR_2>black_gray){
              turn_right0;
              ClearTimer(0);
          }else{
              turn_right1;
          }
      }
      Off(OUT_AC);
 }
  
 sub tyokusinn_sound()          //交差点で音を鳴らし直進する
 {
      PlaySound(SOUND_UP);
      OnFwd(OUT_AC);
      Wait(40);
      Off(OUT_AC);
 }
  
 sub sasetu_sound()             //交差点で音を鳴らし左折する
 {
      PlaySound(SOUND_UP);
      turn_left0;
      Wait(90);
      turn_left1;
      Wait(50);
      Off(OUT_AC);
 }
  
 sub ichijiteisi_tyokusinn()    //交差点で音を鳴らし一時停止し直進する
 {
      PlaySound(SOUND_DOWN);
      Off(OUT_AC);
      Wait(100);
      Off(OUT_AC);
      OnFwd(OUT_AC);
      Wait(40);
      Off(OUT_AC);
 }
  
 sub ichijiteisi_sasetu()       //交差点で音を鳴らし一時停止し左折する
 {
      PlaySound(SOUND_DOWN);
      Off(OUT_AC);
      Wait(100);
      Off(OUT_AC);
      turn_left0;
      Wait(90);
      turn_left1;
      Wait(40);
      Off(OUT_AC);
 }
  
**ライントレースのプログラム [#u8bf72e8]
 サブルーチンひとつで状況に適した曲がり方をできるようにしたため、メインのプログラムが比較的簡潔になったのではないかと思う。
 task main()
 {
      hajime();                 //Aから出て線をトレースし始める
      line_go();
      sasetu_sound();           //Fで左折
      line_go();
      ichijiteisi_sasetu();     //Qで一時停止、左折
      line_go(); 
      tyokusinn_sound();        //Rで直進
      line_go();
      sasetu_sound();           //Sで左折
      line_go();
      sasetu_sound();           //Gで左折
      line_go();
      migigawa;
      line_go2();
      hidarigawa;
      line_go();
      sasetu_sound();           //Hで左折
      line_go();
      ichijiteisi_tyokusinn();  //T一回目、一時停止、直進
      line_go();
      ichijiteisi_tyokusinn();  //T二回目、一時停止、直進
      line_go();
      ichijiteisi_sasetu();     //Rで一時停止、左折
      line_go();
      tyokusinn_sound();        //Sで直進
      line_go();
      sasetu_sound();           //Pで左折
      line_go();
      ichijiteisi_sasetu();     //Eで一時停止、左折
      line_go();
      owari();                  //Aに入る
 }
*まとめ [#g0d650f9]
 前回のプログラムが長くなってしまった反省を活かして、サブルーチンをできるだけ活用してプログラムを短くした。また、そのおかげで試行錯誤している時に、どこを変えればいいかが格段にわかりやすくなった。その上、同じ動きで交差点を曲がる時にプログラミングが簡単であった。
&br; 交差点Qで、交差点判定するプログラムがなかなかできずに苦労した。交差点判定をするまでの時間を短くしすぎると、急なカーブで誤作動が起きるため、そこをうまいことプログラムするのが難しいため、急なカーブでカーブの外側を走ることにすることでこの問題を解決することに成功した。
&br; 課題1ではどちらかというとロボットの組み立てにも苦戦をしたが、今回の課題2ではプログラムがさらに難しくなり苦戦したが、プログラムを前回より簡潔にできたのは大きな成果ではないかと思う。


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