&size(20){目次};
#contents
*課題について [#m065738c]
**課題の内容 [#g83bcdda]
#ref(./2017a-mission2.jpg,100%,misson2)
「経路を黒い線にそって動くロボットを作成せよ」という課題である。

課題の内容に関して詳しくはこちら[[課題2>2017a/Mission2]]
私の選んだコースは【E地点右折コース】である
私の選んだコースは&color(#bf00df){【E地点右折コース】};である

*ロボット本体について [#c15a6c7d]
ロボット本体に関しては、なるべく小型化し、センサーとタイヤの位置が絶妙になるよう試行錯誤した。~
できるだけシンプルで小型にすることで小回りがきくようになった。
できるだけシンプルで小型にすることで、急なカーブも一回で曲がることができた。
**ロボット本体の写真 [#zc7d91de]
#ref(./20170706_100455.jpg,50%,本体(横))
本体横の写真である。無駄な部分を省き、ライントレースができる最小限の大きさにした。
#ref(./20170706_100533.jpg,50%,本体(後ろ))
本体後ろの写真である。大きさを小さくするため後ろに小さなタイヤのようなものをつけた。~
しかし、右左折や旋回するときに横に引きずって音を立てていたが走行に影響はなかった。
#ref(./20170706_103424.jpg,50%,センサー部分)
プログラムだけで完璧にすることは大変であったので、ロボットの構造を簡単に変えられる部分を作った。~
やはりセンサーとタイヤの位置関係は大切であり、位置関係を変えることで大幅に改善することがあったので、ブロックの取り外しを簡単にできるように工夫した。~
写真の通りブロックの取り外しをすることで、センサーとタイヤの距離を容易に変更できる。

*プログラムについて [#j87a8741]
プログラムについてはだれが見てもわかりやすく、できるだけシンプルにするよう心掛けた。
プログラムについてはだれが見てもわかりやすく、できるだけシンプルにするよう心掛けた。~
黒い部分と白い部分の境目をトレースさせた。しきい値によって基準を決め、その値よりも大きいか小さいかで線を判別させた。

**define、sub、voidなどの説明 [#uf19c654]
右左折や旋回などの基本的な動き、基本的な値には%%%define%%%を用いた。~
ラインをたどるなどの小さなプログラムのかたまりには%%%sub%%%を用い、引数を使う場合には%%%void%%%を使用した。~
この3つを使い分けることによって、シンプルなプログラムにすることができた。
この3つを使い分けることによって、シンプルなプログラムにすることができた。~
それぞれの役割はコメント文に書いた通りである。
***define [#c6937f6a]
   #define LS_THRESHOLD 45 //光センサのしきい値
   #define LINE_TIME 30 //交差点の感知時間

光センサーのしきい値は&color(#008000){45};、交差点の感知時間は&color(#008000){30};を基準とし、定義した。

   #define senkai_right OnFwd(OUT_A);OnRev(OUT_C);//右旋回
   #define senkai_left OnFwd(OUT_C);OnRev(OUT_A); //左旋回
   #define turn_right OnFwd(OUT_A);Off(OUT_C);//右折
   #define turn_left Off(OUT_A);OnFwd(OUT_C);//左折
   #define fwd OnFwd(OUT_AC);//直進

***void [#x6265257]
   void LINE_right(int time)   //線の右側を走る
      {
       ClearTimer(0);
        while(FastTimer(0) < time){
           if(SENSOR_2 > LS_THRESHOLD) {
             turn_left;
             ClearTimer(0);
           }else{
             turn_right;
            } 
           Wait(1); }
      Off(OUT_AC);
      ClearTimer(0);
       }

   void LINE_left(int time) //線の左側を走る
      {
       ClearTimer(0);
        while(FastTimer(0) < time){
           if(SENSOR_2 > LS_THRESHOLD) {
             turn_right;
             ClearTimer(0);
           }else{
             turn_left;
            } 
           Wait(1); }
      Off(OUT_AC);
      ClearTimer(0);
       }

黒線の右側をトレースさせるか左側をトレースさせるかは、場合によって使い分けた。~
交差点の判断方法としてはTimerを用いた。交差点の判断時間を&color(#008000){30};と定義し、光センサーが黒い部分を0.3秒以上たどっていると感知したときに交差点として判断するようにしている。

***sub [#j88ab527]
   sub SEARCH_LINE_turnright()  //センサーが線を見つけるまで右に曲がる
      {
         while(SENSOR_2 > LS_THRESHOLD) {
            turn_right;
            Wait(1);
         }
      }

   sub SEARCH_LINE_turnleft()  //センサーが線を見つけるまで左に曲がる
      {
         while(SENSOR_2 > LS_THRESHOLD) {
            turn_left;
            Wait(1);
         }
      }

   sub SEARCH_WHITE_turnright()  //線から出るまで右に曲がる
      {
         while(SENSOR_2 < LS_THRESHOLD) {
            turn_right;
            Wait(1);
         }
      }

   sub SEARCH_WHITE_turnleft()  //線から出るまで左に曲がる
      {
         while(SENSOR_2 < LS_THRESHOLD) {
            turn_left;
            Wait(1);
         }
      }

   sub SEARCH_WHITE_forward()  //線から出るまで直進
      {
         while(SENSOR_2 < LS_THRESHOLD) {
            fwd;
            Wait(1);
         }
      }

   sub Stop()   //交差点で音を鳴らして一時停止
      {
         PlaySound(SOUND_DOWN);
         Wait(100);
      }


**ライントレースのプログラム [#o8968fa1]
ライントレースをする本体のプログラムは、交差点のアルファベットと順番を随時メモしていくことで途中にわかりずらくなることを防いだ。シンプルかつ分かりやすいプログラムになったので満足だった。
   task main()
   {
      SetSensor(SENSOR_2, SENSOR_LIGHT);
      SetPower(OUT_AC,3); 
      
      LINE_right(LINE_TIME);  //1
      PlaySound(SOUND_UP);//E
   
      SEARCH_WHITE_forward(); //2
      SEARCH_LINE_turnright();
      LINE_left(LINE_TIME);  
      Stop(); //P
      SEARCH_WHITE_forward();
      SEARCH_LINE_turnleft();
      SEARCH_WHITE_turnleft();
   
      LINE_left(LINE_TIME); //3
      PlaySound(SOUND_UP);//Q
      SEARCH_WHITE_turnright();
    
      LINE_left(LINE_TIME);//4
      PlaySound(SOUND_UP);//R
      SEARCH_WHITE_forward();
    
      LINE_right(LINE_TIME);//5
      Stop(); //T
      SEARCH_WHITE_forward();
      
      LINE_right(LINE_TIME); //6
      Stop(); //T
      SEARCH_WHITE_forward();
   
      LINE_right(LINE_TIME); //7
      PlaySound(SOUND_UP); //H
      SEARCH_WHITE_forward();
      SEARCH_LINE_turnright();
      
      //8
      ClearTimer(0); while(FastTimer(0) < (LINE_TIME * 3)) {
         if(SENSOR_2 < LS_THRESHOLD) { turn_right; ClearTimer(0); }
         else{ turn_left; }
         Wait(1);
      }
      SEARCH_LINE_turnleft();
      ClearTimer(0); while(FastTimer(0) < (LINE_TIME * 3)) {
         if(SENSOR_2 < LS_THRESHOLD) { turn_left;  ClearTimer(0);}
         else{ turn_right; }
         Wait(1);
      }
      SEARCH_LINE_turnright();
      SEARCH_WHITE_turnright();
      LINE_right(LINE_TIME);
      PlaySound(SOUND_UP); //G
      SEARCH_WHITE_forward();
      SEARCH_LINE_turnright();
   
      LINE_left(LINE_TIME); //9
      Stop(); //S
      SEARCH_WHITE_forward();
      SEARCH_LINE_turnleft();
      SEARCH_WHITE_turnleft();
      
      LINE_left(LINE_TIME); //10
      PlaySound(SOUND_UP); //P
      SEARCH_WHITE_turnright();
      
      LINE_left(LINE_TIME); //10
      PlaySound(SOUND_UP); //Q
      SEARCH_WHITE_forward();
      SEARCH_LINE_turnleft();
      
      LINE_right(LINE_TIME); //11
      PlaySound(SOUND_UP); //F
      SEARCH_WHITE_forward();
      SEARCH_LINE_turnright();
      SEARCH_WHITE_turnright();
   
      LINE_right(LINE_TIME); //12,E
      Stop(); //A
   }

定義やsub、voidを使い全体のプログラムを書いた。うまくいかない箇所には追加でプログラムを書いた。~
コメント文にあるアルファベット、数字はそれぞれ課題にあった交差点やカーブ名と交差点やカーブの順番である。
*結果 [#mcade650]
完成したプログラムを用いてロボットを実際に動かした動画については下のURLを参照してください。~
最初のうちはできるときとできない時があったりと確実性に欠けたが、完璧になるよう何度も繰り返したため、何度やってもゴールにたどり着くまでの確実性を手に入れた。~
自分の思い通りになったため大変満足であった。

完成したプログラムを用いてロボットを実際に動かした動画については下のURLを参照願いたい。~

↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓~
https://youtu.be/C5nUh8Q5C4A

*まとめ [#uac0b444]
**苦労した点 [#yeb97ad7]
苦労した点としては、基準となる最適な値を見つけることと、交差点をうまく認識してくれなかったことである。90度カーブであれば認識してくれるのだが、特にQ地点は斜めになった状態から黒い部分に入っていくためかなり難しかった。ほかのカーブでも認識されないことがまれにあったため、何度も試行錯誤した。~
ほかには、カーブを認識させるときにはカーブの内側を通らせなければならなかったり、急なカーブが曲がり切れなかったりしたため、線の右と左を状況に応じて交互にトレースさせた。反対方向にトレースを切り替えるタイミングはどうするかなどの多くの問題点が生じたため、自分なりに最適なタイミングを見つけるよう努力した。
**感想 [#w2cbaf12]
Misson2ではMisson1よりもハイレベルなプログラム技術が要求された。どうすれば簡潔で分かりやすいプログラムになるのか、どうすれば適切な動き方をするのかを常に考えながらプログラムを作った。完成にはかなりの時間を費やしたが、費やした時間が無駄になったとは思わない。~
さらなる高みを目指すためにも常に好奇心と探求心を持ち続け、自分が納得のいくものを作り上げたいと思う。そしてMisson3ではチームの仲間との協力し、さらに高度な技術を身に付けたい。


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