#contents
 

*課題2 [#ob5b84f5]
 課題の内容は、[[2019a/Mission2]]を参照。

**コース [#h87b58c8]
 私は、下側から上の方向に動く第2コースにした。

*ロボットの説明 [#xfdfaf6f]
 今回は、黒い線を認識するための光センサーが必要であった。

**全体像 [#xc3bae14]
 あまり大きくなりすぎないようにした。大きくなることでカーブの際に細かい動きができなくなる可能性があったため小さくすることを意識した。

"&ref("IMG_0410 (3).JPG");"

**光センサー [#ma6055fc]
 光センサーは、近すぎたり遠すぎるとミスする可能性が高くなるためちょうどいい距離にする必要があった。光センサーが少しタイヤよりも後ろにあるところを直すことができたらよかった。

"&ref("IMG_0412.JPG");"

**アーム [#fc3728b1]
 一つの動力で二つのものを動かすことができなかったので少しボールの位置を高くすることで対応しようと考えた。高い位置にあるボールなら一つの動力で救うことができるため、そのような設定にしようとした。
  
*プログラムの説明 [#ic1bed64]

**定義したプログラム [#p5c2fbc0]
 何回も同じプログラムを書くことは無駄であるため定義した。

 まず、簡単にできるものを定義した。
 #define left_2 OnFwd(OUT_B,20);OnRev(OUT_C,20);   //左旋回
 #define left_1 OnFwd(OUT_B,20);Off(OUT_c);        //左折
 #define right_2 OnFwd(OUT_C,20);OnRev(OUT_B,20);  //右旋回
 #define right_1 OnFwd(OUT_C,20);Off(OUT_B);       //右折
 #define straight OnFwd(OUT_BC,30);                //直進
 #define all_off Off(OUT_BC);                      //一度停止
 #define stopp Wait(1000);                         //1秒間続ける

**サブルーチン [#z32cc74e]
 ライントレースや交差点で止まった後に直進するためのプログラムなどは上のように定義できないためサブルーチンとして定義する。

***ライントレース [#d2ec3812]
 void futu()
 {
     SetSensorLight(S1);
     long t0;                       //long型のt0を定義
     t0=CurrentTick();                  //t0は現在の時間である
     while(CurrentTick()-t0<100)        //今からt0になるまで0.1秒立つまでの間プログラムを続ける
     {
         if(SENSOR_1>60){               //もし光センサーで60以上の値(白)が測定されると
             right_2;                   //右旋回もし光センサーで
             right_2;                   //右旋回
             t0=CurrentTick();          //t0を更新する
         }else if(SENSOR_1>56){         //もし光センサーで56〜59の値(白灰)が測定されると
             right_1;                   //右折
             t0=CurrentTick();          //t0を更新する
         }else if(SENSOR_1>48){         //もし光センサーで48〜55の値(灰)が測定されると
             straight;                  //直進
             t0=CurrentTick();     //t0を更新する
         }else if(SENSOR_1>36){     //もし光センサーで36〜47の値(黒灰)が測定されると
             left_1;          //左折
             t0=CurrentTick();     //t0を更新する
         }else{             //もし光センサーで35以下を測定されると
             left_2;          //左旋回
         }
      }
 }


 上のサブルーチンは光センサーが感知する値を5段階に分けてロボットが線の境界線に沿って進むプログラムである。完全に白色を測定すると線の上に戻るように動かしたり、境界線にいるときはまっすぐ進むようにするプログラムを作った。

 交差点では、黒を観測し左旋回をする。普通であればまた黒灰、灰色を観測しラインとレースを続けるが、その部分では左旋回しても黒が0.1秒以上観測されることになる。。t0が0.1秒になるまでしか上のプログラムは続かないので、0.1秒立つとその部分で止まることになる。

&ref("ライントレース.png");

***交差点で直進するプログラム [#s0af67d6]

 void tixyokusen_1()
 {
    right_2;   //右旋回
    Wait(60);  //0.06秒続ける
    straight;  //直進
    Waut(300); //0.3秒続ける
 } 
  
 このプログラムは、交差点で止まった後に直進することが必要であり機体が左方向に向いているため、旋回をしてから直進する。


***急カーブでも止まらないプログラム [#add6ccfd]

 急カーブでは、ライントレースのプログラムだと交差点と間違えて止まるため止まらないプログラムを作る必要があった。


 void carve()
 {
     SetSensorLight(S1);
     long t1;               //long型のt1を定義
     t1=CurrentTick();        //t1は現在の時間である
     while(CurrentTick()-t1<20000){ //今からt1が20秒立つまでの間プログラムを繰り返す
         if(SENSOR_1>60){      //もし光センサーが60以上の値(白)が測定されると
             right_2;        //右旋回
         }else if(SENSOR_1>56){   //もし光センサーが56〜59の値(白灰)が測定されると
             right_1;        //右折
         }else if(SENSOR_1>48){   //もし光センサーが48〜55の値(灰)が測定されると
             straight;        //直進
         }else if(SENSOR_1>36){   //もし光センサーが36〜47の値(黒灰)が測定されると
             left_1;         //左折
         }else{           //もし光センサーが35以下の値(黒)が測定されると
             left_2;         //左旋回
         }
     }
 } 
 

 このプログラムで交差点と間違えることなく急カーブを曲がれるようになる。


 これで何回も使用するプログラムをすべて定義することができた。



**メインプログラム [#j7e427ac]
 メインプログラムは、定義したものを組み合わせる。
  
 交差点では1秒停止させる必要がある。

 task main()
 {
     straight;         //直進
     Wait(2000);    //2秒続ける 
     futu();      //ライントレース
     all_off;     //停止
     carve();     //急カーブをライントレース
     all_off;     //停止
     futu();      //ライントレース
     all_off;     //停止
     stopp;      //1秒止まる
     tixyokusen_1();  //Kの交差点を直進
     straight;     //直進
     stopp;      //1秒続ける
     OnRev(OUT_A,30); //ボールを持ち上げる
     Wait(100);    //0.1秒続ける
     right_2;     //右旋回
     Wait(60);     //0.06秒続ける
     straight;     //直進
     stopp;      //1秒続ける
     all_off;     //停止
     stopp;      //1秒止まる
     right_1:     //右折
     Wait(200);    //0.2秒続ける
     all_off;     //停止
     futu();      //ライントレース
     all_off;     //停止 (Jの交差点)
     stopp;      //1秒止まる
     futu();      //ライントレース
     all_off;     //停止
     stopp;      //1秒止まる
     tixyokusen_1();  //Iの交差点を直進する
     futu();      //ライントレース
     all_off;     //停止
     stopp;      //1秒止まる
     tixyokusen_1();  //Hの交差点を直進する
     futu();      //ライントレース
     all_off;     //停止 (Gの交差点)
     stopp;      //1秒止まる
     futu();      //ライントレース
     all_off;     //停止 (Fの直角)
     futu();      //ライントレース
   all_off;     //停止 (Eの直角)
   futu();      //ライントレース
   all_off;     //停止
   stopp;      //1秒止まる
   tixyokusen_1();  //Dの交差点を直進する
   futu();      //ライントレース
   all_off;     //停止
     stopp;      //1秒止まる
   tixyokusen_1();  //Cの交差点を直進する
   futu();      //ライントレース
     all_off;     //停止 (Bの交差点)
     stopp;      //1秒止まる
   right_2;     //右旋回
   Wait(60);     //0.06秒続ける
   OnFwd(OUT_A,30); //ボールを転がす (シュート)
   Wait(100);    //0.1秒続ける
   straight;     //直進する
   stopp;      //1秒続ける
   all_off;     //停止
 }


*まとめ [#pa829e5f]
**感想 [#nf6b4137]
 自分の思った通りに機体が動いてくれない部分が多くて、課題ができたとは言うことができない状態で終わってしまうのが悔しいと感じた。ロボットを作ったり、プログラムを組むことは難しいと再度感じさせられることになった。さらにロボットに大した工夫をすることができなかった。

**反省点 [#jcc9f95e]
・上でも挙げた通り課題を達成したとはいいがたい状態になってしまったのは、センサーの位置がタイヤよりも少し後ろに設置したのも一つの原因であることが考えられる。さらに、二つのタイヤの幅が広すぎることもあって少し小回りが利きにくいこともあった。

・アームの部分で一つの動力で二つの部分を動かす方法を考えて、うまくボールを挟めるようにする必要もあった。

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS