・目次
#contents
*課題内容 [#zcba08a0]
#ref(IMG_1181.PNG,,80%)
~今回の課題の内容は
「A地点を出発し、次のいずれかの経路を黒い線にそって動くロボットを作成する (他のメンバーとは別の経路になるようにする)。

1:A地点から出発 → B → C(直進) → D(一時停止の後、直進) → E → F → G(一時停止の後、右折) → H → I → J(右折) → K(左折) → L(ピンポン玉をつかむ) → K(直進) → M(一時停止) → シュート→ A地点に入る(ゴール)

2:A地点から出発 → M → K(直進) → L(ピンポン玉をつかむ) → K(右折) → J(一時停止の後、左折) → I(直進) → H(直進) → G(左折) → F → E → D(一時停止の後、直進) → C(直進) → B(一時停止) → シュート→ A地点に入る(ゴール)
交差点では1秒間停止し、丁字路では直角方向に進入する時のみ一時停止すること。」

というものである。
私が挑んだコースは1番のコースである。
*ロボットについて [#v51a31f2]
**全体像 [#tc9239e9]
#ref(IMG_1183.JPG,,30%)
上のようなロボットをつくった。基本構造としては、説明書とほぼ同じ機体にした。改善すべき点としてはもっと光センサーとタイヤとの距離を短くするべきであった。
**ボールを掴む機構 [#tcd08375]
#ref(IMG_1182.JPG,,30%)
ボールをつかみ、シュートする機構は上のようにした。アームは、ボールにかぶさるようにして、ボールを掴むようにした。工夫した点としては、つかむ部分を斜めにすることによって、ボールを離すだけで、シュートを打てるようにした。
*プログラムについて [#u8502922]
**ライントレース [#w4e6f68c]
黒い線に沿って動かすためにライントレースというプログラムを作る。ライントレースのプログラムは光センサーを用いて、「完全な黒」、「黒よりの灰色」、「灰色」、「白よりの灰色」、「完全な白」の5つの段階の明るさを判別して、それぞれの明るさで別々の動きをさせる。5つの測定した値は以下のものである。
       段階 完全な黒 黒よりの灰色 灰色 白よりの灰色 完全な白 
              値   32          42        45       55           60
である。また、それぞれの値でのときの動作のプログラムは次のように定義した。  
 #define SPEED 20
 #define turn_left  OnFwd(OUT_B,SPEED);Off(OUT_C);            //左に曲がる
 #define turn_right Off(OUT_B);OnFwd(OUT_C,SPEED);            //右に曲がる
 #define right_senkai OnRev(OUT_B,SPEED);OnFwd(OUT_C,SPEED);  //右に旋回
 #define left_senkai OnFwd(OUT_B,SPEED);OnRev(OUT_C,SPEED);   //左に旋回
***線の左端を走るライントレース [#j159b223]
線の左端を走るライントレースのプログラムは次のようになる。
 sub follow_line(){SetSensorLight(S3);
                  long t0=CurrentTick();
                  while(CurrentTick()-t0<100){    //0.1秒未満の時
                  if(SENSOR_3>=60){               //白なら    
                  right_senkai;                   //右に旋回
                  t0=CurrentTick();               //時間をリセットする
                  }else if(SENSOR_3>=55){         //白よりの灰色なら
                  turn_right;                     //右に曲がる
                  t0=CurrentTick();
                  }else if(SENSOR_3>=45){         //灰色なら
                  OnFwd(OUT_BC,SPEED);            //速さ20で直進
                  t0=CurrentTick();
                  }else if(SENSOR_3>=42){         //黒よりの灰色なら
                  turn_left;                      //左に曲がる
                  t0=CurrentTick();
                  }else if(SENSOR_3>=32){         //黒なら 
                  left_senkai;                    //左に旋回
                   long t0=CurrentTick();
                 
                    while(CurrentTick()-t0<100){        //0.1秒未満の時
                     if(SENSOR_3>=60){                  //白なら    
                        right_senkai;                   //右に旋回
                        t0=CurrentTick();               //時間をリセットする
                     }else if(SENSOR_3>=55){            //白よりの灰色なら
                        turn_right;                     //右に曲がる
                        t0=CurrentTick();
                     }else if(SENSOR_3>=45){            //灰色なら
                        OnFwd(OUT_BC,SPEED);            //速さ20で直進
                        t0=CurrentTick();
                     }else if(SENSOR_3>=42){            //黒よりの灰色なら
                        turn_left;                      //左に曲がる
                        t0=CurrentTick();
                     }else if(SENSOR_3>=32){            //黒なら 
                        left_senkai;                    //左に旋回
                     }
                  } Off(OUT_BC);}                 //停止
                   } Off(OUT_BC);                       //停止
                  }                 
***線の右端を走るライントレース [#wa9a35a4]
線の右端を走るライントレースのプログラムは次のようになる
 sub line_trace(){SetSensorLight(S3);
                  long t0=CurrentTick();
                  while(CurrentTick()-t0<100){
                  if(SENSOR_3>=60){
                  left_senkai; 
                  t0=CurrentTick();  
                  }else if(SENSOR_3>=55){
                  turn_left;
                  t0=CurrentTick();
                  }else if(SENSOR_3>=45){
                  OnFwd(OUT_BC,SPEED);
                  t0=CurrentTick();
                  }else if(SENSOR_3>=42){
                  turn_right;
                  t0=CurrentTick();
                  }else if(SENSOR_3>=32){
                  right_senkai;
 sub line_trace(){ SetSensorLight(S3);
                   long t0=CurrentTick();
                 
                    while(CurrentTick()-t0<100){
                     if(SENSOR_3>=60){
                        left_senkai; 
                        t0=CurrentTick();  
                     }else if(SENSOR_3>=55){
                        turn_left;
                        t0=CurrentTick();
                     }else if(SENSOR_3>=45){
                        OnFwd(OUT_BC,SPEED);
                        t0=CurrentTick();
                     }else if(SENSOR_3>=42){
                        turn_right;
                        t0=CurrentTick();
                     }else if(SENSOR_3>=32){
                        right_senkai;
                     }
                  } Off(OUT_BC);}
                  } Off(OUT_BC);
                 }
このプログラムの内容はfollow_lineでのプログラムとほぼ同じため省略する。
これらのプログラムは黒い線に沿って進み、交差点で止まるようになっている。
**交差点の判断 [#l045e418]
交差点かどうかを判断するのにはライントレース中の真っ黒である時間で認識させる。交差点では、直線を走るときよりも、真っ黒の時間を走っている時間が長くなるので、そのターンにかかる時間が一定の時間を超えたときにロボットが止まるようにする。私が作ったロボットでは0.1秒が適切であった。以下に交差点時の様子を図で示す。
**交差点の認識 [#l045e418]
交差点かどうかを判断するのにはライントレース中の真っ黒である時間で認識させる。交差点では、直線を走るときよりも、真っ黒の時間を走っている時間が長くなるので、そのターンにかかる時間が一定の時間を超えたときにロボットが止まるようにする。これを行うために、時間変数t0を用いた。toを基準の時間と設定して、この時刻と現在の時刻との差を計算することによって、時間がどれくらいたったのかを計算させる。なお、現在の時刻はlong t0=CurrentTick()で得られる。私が作ったロボットでは交差点でターンするのに0.1秒かかった。ゆえに、基準の時刻と現在の時刻との差CurrentTick-t0が0.1より大きいとき、機体が止まるようにする。また、ifやelse ifの中にto=CurrentTickをいれることによって、基準の時刻と現在の時刻との差を0にすることで、CurrebtTickの値が増え続けることを防ぐ。
~以下に交差点時の様子を図で示す。
#ref(交差点判断.png,,80%)
**交差点を通過する [#ya635dae]
交差点を通過するプログラムは次のようになる。
 sub cross_line(){turn_right;            //右に曲がる
                  Wait(1000);            //1秒間
                  Off(OUT_C);            //停止
                  OnFwd(OUT_BC,SPEED);   //速さ20で直進する
                  Wait(1000);            //1秒間
                  Off(OUT_BC);           //停止
                 }
**全体のプログラム [#f716e665]
全体のプログラムは次のようになる。
  task main()
 {  follow_line(); 
    Wait(1000);                //D地点の交差点で1秒間停止
    cross_line();              //D地点の交差点を通過
    line_trace();
    Wait(1000);                //H地点の交差点で1秒間停止
    turn_left;                 //ロボットをまっすぐに
    Wait(500);                 
    Off(OUT_BC);               
    OnFwd(OUT_BC,SPEED);       //H地点の交差点を通過
    Wait(500);                 
    Off(OUT_BC);               //停止
    line_trace();
    Wait(1000);                //I地点の交差点で1秒間停止
    turn_left;                 //ロボットをまっすぐに
    Wait(500);                 
    Off(OUT_BC);               
    OnFwd(OUT_BC,SPEED);       //I地点の交差点を通過
    Wait(500);                 
    Off(OUT_BC);               //停止
    follow_line();              
    Wait(1000);                //K地点で1秒間停止
    OnFwd(OUT_BC,SPEED);       //L地点へ直進
    Wait(3000);                
    Off(OUT_BC);               //停止                
    OnFwd(OUT_A,SPEED);        //ボールをつかむ
    Wait(1000);                
    Off(OUT_BC);               //停止
    follow_line;
    Wait(1000);                //M地点で停止
    OnRev(OUT_A,SPEED);        //ボールをシュート
    Wait(2000);                
    Off(OUT_A);                //停止
 )
*まとめ [#y629d111]
 ただ単にライントレースをすることだけはうまくできた。しかし、交差点を通過するなどは非常に困難であった。これは、車輪とセンサーの位置が離れてしまったことが原因だと考察します。また、車輪とセンサーの位置が少し離れてしまったがために、うまくできるときとできないときができてしまい、安定して動かすことができなかった。課題3で、もし光センサーを使うことがあれば、今回の反省を生かして、ロボットを組み立てたい。


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