[[2011a]]

*課題2 黒い線上を動くロボットを作成せよ!! [#v522a89f]
次のような周回コース(黒い線)を動くロボットを作成せよ。

- 通常の交差点が2箇所以上ある
- ロータリー型の交差点が1箇所以上ある (ロータリーでは反時計まわりに進む)
- 直角に曲がるコーナーおよびそのコーナーをショートカットするコース(点線)が存在する
- 急なヘアピンカーブが1箇所以上ある
- スタート地点に目印がある
- 黒い線の幅は15〜20mm程度

センサー、モーターはいくつ使ってもよい。プログラムは次の2つを作成すること。

1. 直角のコーナーを通る~
2. 直角のコーナーを通らない(近道する)

ただし互いに逆方向に周回すること。
#contents


*メンバー [#jefdde39]
ばば~
中島


*製作過程 [#y2884bab]
**コース [#v375c6ed]
僕たちのチームは先生の考えたコースをもとにして、近道の部分は直角にしました。~
以下の写真が今回用いたコースです。~
#ref(kadai2_6.png)
このコースでセンサーが読み取るのは以下の4種類だけである。~
(センサー1、センサー3)~
1.(白、白)→黒い線を2つのセンサーがまたいでいるとき ⇒直進~
2.(白、黒)→センサー3(右)が黒を認識 ⇒右に修正~
3.(黒、白)→センサー1(左)が黒を認識 ⇒左に修正~
4.(黒、黒)→交差点(ロータリー)に差し掛かった ⇒直進or右に修正~

**ロボット本体 [#q967b082]
ロボット本体は、重々しいのが嫌だったのでシンプルにしました。

そして今回のポイントとなる光センサーも2人で違う形として使うために簡単に作りました。~
センサー間は3.0mmのです。~
#ref(kadai2_1.png)~
これを車体前方につけて~
#ref(kadai2_2.png)~
こうしてできた、今回のロボットはこちら↓~
#ref(kadai2_3.png)





*プログラム [#b55dc97c]
**ばば・作(左からSTART、直角コース) [#ocd393e1]
使用コース~
#ref(kadai2_4.png)~
 #define THRESHOLD 40                                 //閾値
 sub except_a_crossing()                //サブルーチンを定義
 { if((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD))     //(白、白):直進
   { OnFwd(OUT_A+OUT_C); }
   if((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD))   //(黒、白):左に修正
   { Off(OUT_A);
     OnFwd(OUT_C); }
   if((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD))   //(白、黒):右に修正
   { OnFwd(OUT_A);
     Off(OUT_C); }
 }
 task main()
 { 
   SetSensor(SENSOR_1,SENSOR_LIGHT);         //センサー1は光センサー
   SetSensor(SENSOR_3,SENSOR_LIGHT);         //センサー3は光センサー
   ClearTimer(0);                   //タイマーをリセット
   while(FastTimer(0)<=1200)             //12秒以下でwhile内を繰り返し
   { except_a_crossing();
     if((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD))  //(黒、黒):直進
     { OnFwd(OUT_A+OUT_C);
       PlaySound(SOUND_CLICK); }           //交差点で音を鳴らす
    }
   ClearTimer(0);                   //タイマーをリセット
   while(FastTimer(0)<=300)              //3秒以下でwhile内を繰り返し
   { except_a_crossing();
     if((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD))  //(黒、黒):右に大きく修正
     { OnFwd(OUT_A);
       OnRev(OUT_C);
       PlaySound(SOUND_CLICK); }           //交差点で音を鳴らす
    }
   ClearTimer(0);                   //タイマーをリセット
   while(FastTimer(0)<=250)              //2.5秒以下でwhile内を繰り返し
   { if((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD))  //(白、白):直進
     { OnFwd(OUT_A+OUT_C); }
     if((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD))  //(黒、白):左に修正
     { Off(OUT_A);
       OnFwd(OUT_C); }
     if((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD))  //(白、黒):直進
     { OnFwd(OUT_A+OUT_C); }
    }
   ClearTimer(0);                   //タイマーをリセット
   while(FastTimer(0)<=200)              //2秒以下でwhile内を繰り返し
   { if((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD))  //(白、白):直進
     { OnFwd(OUT_A+OUT_C); }
     if((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD))  //(白、黒):右に大きく修正
     { OnFwd(OUT_A);
       OnRev(OUT_C); }
    }
   ClearTimer(0);                   //タイマーをリセット
   while(FastTimer(0)<=250)              //2.5秒以下でwhile内を繰り返し
   { if((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD))  //(白、白):直進
     { OnFwd(OUT_A+OUT_C); }
     if((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD))  //(白、黒):右に修正
     { OnFwd(OUT_A);
       Off(OUT_C); }
    }
   ClearTimer(0);                   //タイマーをリセット
   while(FastTimer(0)<=500)              //5秒以下でwhile内を繰り返し
   { if((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD))  //(白、白):直進
     { OnFwd(OUT_A+OUT_C); }
     if((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD))  //(白、黒):右に大きく修正
     { OnFwd(OUT_A);
       OnRev(OUT_C); }
    }
   ClearTimer(0);                   //タイマーをリセット
   while(FastTimer(0)<=200)              //2秒以下でwhile内を繰り返し
   { if((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD))  //(白、白):直進
     { OnFwd(OUT_A+OUT_C); }
     if((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD))  //(黒、白):左に修正
     { Off(OUT_A);
       OnFwd(OUT_C); }
     if((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD))  //(白、黒):右に大きく修正
     { OnFwd(OUT_A);
       OnRev(OUT_C); }
     if((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD))  //(黒、黒):右に大きく修正
     { OnFwd(OUT_A);
       OnRev(OUT_C);
       PlaySound(SOUND_CLICK); }           //交差点で音を鳴らす
    }
   ClearTimer(0);                   //タイマーをリセット
   while(FastTimer(0)<=200)              //2秒内でwhile内を繰り返し
   { if((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD))  //(白、白):直進
     { OnFwd(OUT_A+OUT_C); }
     if((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD))  //(白、黒):右に修正
     { Off(OUT_A);
       OnFwd(OUT_C); }
    }
   ClearTimer(0);                   //タイマーをリセット
   while(FastTimer(0)<=200)              //2秒以下でwhile内を繰り返し
   { if((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD))  //(白、白):直進
     { OnFwd(OUT_A+OUT_C); }
     if((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD))  //(白、黒):右に大きく修正
     { OnFwd(OUT_A);
       OnRev(OUT_C); }
    }
   ClearTimer(0);                   //タイマーをリセット
   while(FastTimer(0)<=1000)             //10秒以下でwhile内を繰り返し
   { if((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD))  //(白、白):直進
     { OnFwd(OUT_A+OUT_C); }
     if((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD))  //(黒、白):左に修正
     { Off(OUT_A);
       OnFwd(OUT_C); }
     if((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD))  //(白、黒):右に修正
     { OnFwd(OUT_A);
       OnRev(OUT_C); }
     if((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD))  //(黒、黒):直進
     { OnFwd(OUT_A+OUT_C);
     PlaySound(SOUND_CLICK); }            //交差点で音を鳴らす
    }
   Off(OUT_A+OUT_C);
   PlaySound(SOUND_DOUBLE_BEEP);           //ゴールしたら音を鳴らす
 }



**中島・作(右からSTART、近道コース) [#m51a3efa]
使用コース~
#ref(kadai2_7.png)
 #define threshold 40  
 #define turn_left(t) OnRev(OUT_A);OnFwd(OUT_C);Wait(t);Float(OUT_A+OUT_C);
 #define turn_right(t) OnRev(OUT_C);OnFwd(OUT_A);Wait(t);Float(OUT_A+OUT_C); 
 #define go_straight(t) OnFwd(OUT_A+OUT_C);Wait(t);Float(OUT_A+OUT_C);
 task main()
 {
 SetSensor(SENSOR_1, SENSOR_LIGHT);       //センサー1は光センサー
 SetSensor(SENSOR_3, SENSOR_LIGHT);       //センサー3は光センサー
 ClearTimer(0);
 while(FastTimer(0) <= 1320)              //急カーブ
 {
  if(SENSOR_3 < threshold)
  { 
  OnFwd(OUT_A);
  Off(OUT_C);
  } 
  if(SENSOR_1 < threshold)
  {                     
  Off(OUT_A);
  OnFwd(OUT_C);
  }
  else  
  {
  OnFwd(OUT_A);
  OnFwd(OUT_C);
   }
 }
 ClearTimer(0);
 while(FastTimer(0) <= 210)               //ロータリー
 { 
  if(FastTimer(0) <= 40)
  {
  turn_right(40);
  }
  if(SENSOR_3 < threshold)
  { 
  OnFwd(OUT_A);
  Off(OUT_C);
  } 
  if(SENSOR_1 < threshold)
  {                     
  Off(OUT_A);
  OnFwd(OUT_C);
  }
  else  
  {
  OnFwd(OUT_A);
  OnFwd(OUT_C);
  }
 }
 ClearTimer(0);
 while(FastTimer(0) <= 260)                 //一つ目無視して進む
 { 
  if(FastTimer(0) <= 100)
  {
  OnFwd(OUT_C);Wait(100);
  }
  if(SENSOR_3 < threshold)
  { 
  OnFwd(OUT_A);
  Off(OUT_C);
  } 
  if(SENSOR_1 < threshold)
  {                     
  Off(OUT_A);
  OnFwd(OUT_C);
  }
  else  
  {
  OnFwd(OUT_A);
  OnFwd(OUT_C);
  }
 }
 ClearTimer(0);
 while(FastTimer(0) <= 425)              //ロータリー1終わり→3.8秒進む
 { 
  if(FastTimer(0) <= 45)
  {
  turn_right(45);
  }
  if(SENSOR_3 < threshold)
  { 
  OnFwd(OUT_A);
  Off(OUT_C);
  } 
  if(SENSOR_1 < threshold)
  {                     
  Off(OUT_A);
  OnFwd(OUT_C);
  }
  else  
  {
  OnFwd(OUT_A);
  OnFwd(OUT_C);
  }
 }
 ClearTimer(0);
 while(FastTimer(0) <= 540)                //近道
 { 
  if(FastTimer(0) <=442)
  {
  turn_left(102);
  go_straight(230);
  turn_left(110);
  }
  if(SENSOR_3 < threshold)
  { 
  OnFwd(OUT_A);
  Off(OUT_C);
  } 
  if(SENSOR_1 < threshold)
  {                     
  Off(OUT_A);
  OnFwd(OUT_C);
  }
  else  
  {
  OnFwd(OUT_A);
  OnFwd(OUT_C);
  }
 }
 ClearTimer(0);
 while(FastTimer(0) <= 200)                 //ロータリー2
 { 
  if(FastTimer(0) <= 40)
  {
  turn_right(40);
  }
  if(SENSOR_3 < threshold)
  { 
  OnFwd(OUT_A);
  Off(OUT_C);
  } 
  if(SENSOR_1 < threshold)
  {                     
  Off(OUT_A);
  OnFwd(OUT_C);
  }
  else  
  {
  OnFwd(OUT_A);
  OnFwd(OUT_C);
  }
 }
 ClearTimer(0);
 while(FastTimer(0) <= 335)                   //一つ目無視
 { 
  if(FastTimer(0) <= 100)
  {
  OnFwd(OUT_C);
  Off(OUT_A);
  Wait(170);
  }
  if(SENSOR_3 < threshold)
  { 
  OnFwd(OUT_A);
  Off(OUT_C);
  } 
  if(SENSOR_1 < threshold)
  {                     
  Off(OUT_A);
  OnFwd(OUT_C);
  }
  else  
  {
  OnFwd(OUT_A);
  OnFwd(OUT_C);
  }
 }
 ClearTimer(0);
 while(FastTimer(0) <= 1400)               //ロータリー2終わり→13秒進む
 { 
  if(FastTimer(0) <= 100)
  {
  turn_right(100);
  }
  if(SENSOR_3 < threshold)
  { 
  OnFwd(OUT_A);
  Off(OUT_C);
  } 
  if(SENSOR_1 < threshold)
  {                     
  Off(OUT_A);
  OnFwd(OUT_C);
  }
  else  
  {
  OnFwd(OUT_A);
  OnFwd(OUT_C);
  }
 }
 ClearTimer(0);
 while(FastTimer(0) <= 250)                  //曲がりきる
 {
 if(FastTimer(0) <= 150)
  {
  OnFwd(OUT_A);
  Off(OUT_C);
  Wait(150);
  }
  if(SENSOR_3 < threshold)
  { 
  OnFwd(OUT_A);
  Off(OUT_C);
  } 
  if(SENSOR_1 < threshold)
  {                     
  Off(OUT_A);
  OnFwd(OUT_C);
  }
  else  
  {
  OnFwd(OUT_A);
  OnFwd(OUT_C);
  }
 }
 Off(OUT_A+OUT_C);                        //終わり
 }

*評価 [#g04be9fb]
**感想 [#mc7b834d]
今回の課題はロボット本体の製作にはあまり手こずらなかったが、その分プログラミングの難易度が高かった。課題1でやった関数やサブルーチンに加え、whileやifなども出てきて大変だった。一番難しかったのは、タイマーとwhileの調節です。この時間内にはこの条件という命令を出すのは厳しかったです。工夫した点は、サブルーチンを使ったところ。交差点以外は基本同じ動きをするので、except_a_crossing というサブルーチンを定義したら、プログラムがすっきりしました。さらに、交差点を通過するたび音を鳴らしたので、プログラムの修正中にちょっとした目印となった。今回の課題ではプログラミング力がついたと思うので、次の課題ではプログラムに工夫点をたくさん組み込んでいきたいです。

**反省 [#oa1b0290]
まずロータリーの仕組みを理解してなかったのはすごく反省しています。一度は完成したプログラムも全て書き直しました。課題そのものをちゃんと理解することが大切だと実感しました。~
前回の最大の反省点である「作業に取り掛かるのが遅すぎた」のは改善されましたが、少ない作業時間をもっと密度の濃いものにしていかないといけないと思った。自宅でタイマーの時間以外のプログラムを終わらせてきて、集まったときに時間調節をしたのは良かったと思うので、次の課題3でも自宅でできることは全部終わらせて集まったときは、その時にしかできないことをやりたいと思います。

*コメント [#k89b316f]
- 中島が使うロボットの写真も載せといて! -- [[ばば]] &new{2011-06-15 (水) 20:53:59};

#comment

----

Today:&counter(today);

Yesterday:&counter(yesterday);

All:&counter(all);

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