[[2010b]]

#contents

*課題2の内容とルール [#r45faa9e]

各チームで次のようなコースを作成し、コースを2周するロボットを製作せよ。

-黒い線の幅は15〜25mmの範囲で一定にすること

-交差点が3箇所以上あること

-直角のコーナーを2箇所以上設置すること

-近道を2箇所 (直角のコーナーをショートカットしてもよい)

-スタート地点にはコースに直角に横5cmのラインを描く

ただし、

-速さと正確さを追求すること

-2周目はスタート地点の直前で自動的に止まること

-近道を選択するプログラムとそうでないプログラムを2人で分担して作成すること


*メンバー紹介 [#nfd81916]

-松澤

-水野

*ロボットの紹介 [#wc013992]

**機体の構造 [#v16d2593]

これがロボットの外見です。小回りが利くように全体的に小型化しました。

#ref(./CA3C0260.JPG,100%,ロボット)

**工夫した点 [#l8131040]

***その1 [#j2d6bbbf]

写真のように、光センサー、回転センサーを機体に装着しました。

黄色の四角で囲ったのが光センサー、赤の四角で囲ったのが回転センサーです。

#ref(./CA3C0261.JPG,100%,ロボットその2)

コースの黒線を光センサーが挟む形になります。なので、次の4つのパターンが発生します。

(左のセンサー,右のセンサー)

(白,白) まっすぐ進みます。

(白,黒) 左に寄ります。

(黒,白) 右に寄ります。

(黒,黒) 交差点の判定をします。

***その2 [#ib9d94d2]

最初は両方のモーターに直接タイヤをつけていたので、スピードが早く光センサーが反応しても制御がうまくできませんでした。

そこで16枚ギアをモーターに取り付けました。スピードが遅くなりセンサーがうまく反応するようになりました。下はその写真です。

#ref(./CA3C0265.JPG,100%,ロボットその3)

*コースの紹介 [#ma49512d]

赤の矢印が共通のコースです。黄色の矢印が近道のコースです。

#ref(./CA3C0264.JPG,100%,コース)

*プログラムと作成図 [#y66ecd3d]

-松澤(近道Ver)

--プログラム

 #define turn_left(t) OnRev(OUT_A);OnFwd(OUT_C);Wait(t);OnFwd(OUT_C)	//tの時間左に回る
 #define turn_right(t) OnRev(OUT_C);OnFwd(OUT_A);Wait(t);OnFwd(OUT_A)	//tの時間右に回る
 #define THRESHOLD 40						//しきい値
 #define Do  1047							//soundの周波数を定義
 #define Do2  2093
 #define Do3  4186
 #define Re  1175
 #define Re2  2349
 #define Mi2  1319
 #define Mi3  2637
 #define Mif  1245
 #define Mif2  2489
 #define Fa  1397
 #define Fa2  2794
 #define Faf  659
 #define Faf2  1319
 #define Sol 784
 #define Sol2 1568
 #define Sol3 3136
 #define Laf 1661
 #define Laf2 3322
 #define Sif 932
 #define Sif2 1865
 #define Sif3 3729
 
 task main()
 {
 	SetSensor(SENSOR_1,SENSOR_LIGHT);	//光センサー1定義
 	SetSensor(SENSOR_2,SENSOR_ROTATION);	//回転センサー2定義
 	SetSensor(SENSOR_3,SENSOR_LIGHT);	//光センサー3定義
 	ClearSensor(SENSOR_2);			//回転センサをリセット
 	int cycle=0;					//周回を数える変数
 	int cross=0;					//交差点を数える変数
 	
 	while(cycle!=2){				//2周にならない間、繰り返す(2周したら繰り返しを止める)
 		OnFwd(OUT_A+OUT_C);				//発進
 		if(cross % 12 == 1){		//1周目または2周目の1回目の近道を曲がる
 			if(cross==13){		//2周目のときは斜めに交差点に入ってしまうので修正
 				turn_left(20);
 				OnFwd(OUT_A+OUT_C);
 			}
 			Wait(60);						//↓近道に入る命令
 			turn_right(40);
 			Off(OUT_A+OUT_C);Wait(50);
 			OnFwd(OUT_A+OUT_C);Wait(40);
 			turn_right(10);
 			Off(OUT_A+OUT_C);Wait(50);
 			OnFwd(OUT_A+OUT_C);
 			cross++;				//これをしないともう一度上のプログラムを繰り替えしてしまう
 		}
 		if(cross % 12 == 3){		//1番目の近道の終わり
 			OnRev(OUT_A+OUT_C);Wait(10);			//↓近道から出る命令
 			turn_right(60);
 			Off(OUT_A+OUT_C);Wait(50);
 			OnFwd(OUT_A+OUT_C);
 			cross++;				//これをしないともう一度上のプログラムを繰り替えしてしまう
 		}
 		if(cross % 12 == 7){		//2番目の1周目または2周目の近道を曲がる
 			repeat(3){PlaySound(SOUND_CLICK) ;}
 			turn_right(20);					//↓近道に入る命令
 			OnFwd(OUT_A+OUT_C);Wait(10);
 			Off(OUT_A+OUT_C);Wait(50);
 			OnFwd(OUT_A+OUT_C);
 			cross++;				//これをしないともう一度上のプログラムを繰り替えしてしまう
 		}
 		if(cross % 12 == 9){		//2番目の近道の終わり
 			OnRev(OUT_A+OUT_C);Wait(10);			//↓近道から出る命令
 			turn_right(60);
 			Off(OUT_A+OUT_C);Wait(50);
 			OnFwd(OUT_A+OUT_C);
 			cross++;				//これをしないともう一度上のプログラムを繰り替えしてしまう
 		}
 		if((abs(SENSOR_2) == 336) || (abs(SENSOR_2) == 720)){
 			OnFwd(OUT_A+OUT_C);Wait(20);			//少し進む(回転センサーSENSOR_2の値を増やすため)
 			Off(OUT_A+OUT_C);Wait(100);			//	↑↑をしないともう1度プログラムを繰り替えしてしまう
 			PlayTone(Mi2,12); Wait(10);			//sound 1UP
 			PlayTone(Sol2,12); Wait(10);
 			PlayTone(Mi3,12); Wait(10);
 			PlayTone(Do,12); Wait(10); 
 			PlayTone(Re,12); Wait(10);
 			PlayTone(Sol3,12); Wait(10);
 			cycle++;						//1周をインクリメント
 			OnFwd(OUT_A+OUT_C);
 		}
 		if((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD)){		//左右が白の時
 			OnFwd(OUT_A+OUT_C);					//そのまま進む
 		}else if((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD)){	//左が黒、右が白の時
 			turn_left(5);					//左に回転
 		}else if((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD)){	//左が白、右が黒の時
 			turn_right(5);					//右に回転
 		}else if((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD)){	//左右が黒の時
 			OnFwd(OUT_A+OUT_C);Wait(20);			//少し進む
 			cross++;						//交差点数をインクリメント
 			PlaySound(SOUND_CLICK) ;
 		}
 		Wait(1);
 	}
 	Off(OUT_A+OUT_C);					// 止まる
 	PlayTone(Sol,14); Wait(10);			//sound couse_clear
 	PlayTone(Do,14); Wait(10);
 	PlayTone(Mi2,14); Wait(10);
 	PlayTone(Sol2,14); Wait(10);
 	PlayTone(Do2,14); Wait(10);
 	PlayTone(Mi3,14); Wait(10);
 	PlayTone(Sol2,40); Wait(10);
 	PlayTone(Mi3,40); Wait(10);
 	PlayTone(Faf,14); Wait(10);
 	PlayTone(Do,14); Wait(10);
 	PlayTone(Mif,14); Wait(10);
 	PlayTone(Laf,14); Wait(10);
 	PlayTone(Do2,14); Wait(10);
 	PlayTone(Mif2,14); Wait(10);
 	PlayTone(Laf2,40); Wait(10);
 	PlayTone(Mif2,40); Wait(10);
 	PlayTone(Sif,14); Wait(10);
 	PlayTone(Re,14); Wait(10);
 	PlayTone(Fa,14); Wait(10);
 	PlayTone(Sif2,14); Wait(10);
 	PlayTone(Re2,14); Wait(10);
 	PlayTone(Fa2,14); Wait(10);
 	PlayTone(Sif3,30); Wait(20);
 	PlayTone(Sif3,8); Wait(15);
 	PlayTone(Sif3,8); Wait(15);
 	PlayTone(Sif3,8); Wait(15);
 	PlayTone(Do3,160); Wait(10);
 }

交差点を数える変数と、回転センサーを使って近道を通るようにしました。サウンドを鳴らすことに凝ったため、その部分が長くなってしまいました。

-水野(直角を通る道Ver)

--プログラム

 #define THRESHOLD 45   // 閾値
 #define RUN_TIME 30   // トレースする時間(単位 1/10 秒)
 int i; //変数値をiと定義
 task main ()
 {
     SetSensor(SENSOR_1, SENSOR_LIGHT); //センサー1を光センサーと認識
     SetSensor(SENSOR_2,SENSOR_ROTATION); //センサー2は回転センサと認識
     SetSensor(SENSOR_3, SENSOR_LIGHT); //センサー3を光センサーと認識
     SetPower(OUT_A,2); //Aギアの出力を2と設定
     SetPower(OUT_C,1); //Cギアの出力を2と設定
     ClearTimer(0); //Timer(0) をリセット
     i=0; //変数iをリセット
     while (i<22) {
        if(abs(SENSOR_2)>40){
                    i=i+1;
                    ClearSensor(SENSOR_2); //回転センサをリセット
                            }
        else{
         if(SENSOR_1>THRESHOLD) { //センサー1が白を認知
                     if(SENSOR_3>THRESHOLD) { //センサー3も白を認知
                                   OnFwd(OUT_A+OUT_C); Wait(1);
                                }
                     else { //センサー3は黒を認知
                                   OnRev(OUT_C); OnFwd(OUT_A); Wait(1);
                                   ClearSensor(SENSOR_2); //回転センサーをリセット
                           }
                                }
         else { //センサー1が黒を認知
                     if(SENSOR_3>THRESHOLD) { //センサー3は白を認知
                                   OnRev(OUT_A); OnFwd(OUT_C); Wait(1);
                                   ClearSensor(SENSOR_2); //回転センサをリセット
                                            }
                     else { //センサー3も黒を認知
                         if((i==1)||(i==7)||(i==8)||(i==12)||(i==18)||(i==19)){
                                   Off(OUT_A+OUT_C); Wait(100);
                                   OnFwd(OUT_C); Off(OUT_A);
                                   Wait(80);
                                   ClearSensor(SENSOR_2); //回転センサをリセット
                                   i=i+1;
                                         }
                         else {
                            if(i==11) {
                                   Off(OUT_A+OUT_C); Wait(100);
                                   OnFwd(OUT_C); Off(OUT_A);
                                   Wait(40);
                                   ClearSensor(SENSOR_2); //回転センサをリセット
                                   i=i+1;
                                                }
                            else {
                                   Off(OUT_A+OUT_C); Wait(10);
                                   OnFwd(OUT_A+OUT_C); Wait(25);
                                   ClearSensor(SENSOR_2); //回転センサをリセット
                                   i=i+1;
                                         }
                                      }
                                 }
                   }
                 }
     ClearTimer(0); //Timer(0) をリセット
                       }
    while(Timer(0)<=RUN_TIME) { // タイマー0がRUN_TIME(3秒)以下の時に繰り返す
            if(SENSOR_1>THRESHOLD) { //センサー1が白を認知
                        if(SENSOR_3>THRESHOLD) { //センサー3も白を認知
                                   OnFwd(OUT_A+OUT_C); Wait(1);
                                                           }
                        else { //センサー3は黒を認知
                                   OnFwd(OUT_A); OnRev(OUT_C); Wait(1);
                                    }
                                      }
            else { //センサー1が黒を認知
                        if(SENSOR_3>THRESHOLD) { //センサー3は白を認知
                                   OnFwd(OUT_C); OnRev(OUT_A); Wait(1);
                                                           }
                     }
                                      }
    Off(OUT_A+OUT_C);                         
 }
 

自分のプログラムで工夫した点は以下の通りです。
●変数を使って交差点判定の条件を判断させる。→近道、ゴール、交差点の判別を行う
●回転センサーを使い、点線で交差点を判断しなかった時、変数に1を加える。→点線の場所で交差点判定をしなかった時、自動的に変数に1を加えるようにしました。
●タイマーを使ってのゴール地点→変数が上限を越えた時、タイマーをリセットをして何秒後に止まるかを指定しました。


*反省・感想 [#v4bada11]

-松澤

今回の課題のプログラミングはとても難しかったです。最初は点線のところをRUN_TIMEで操作しようとしましたが、プログラムが長くなってしまう等なかなかうまくいきませんでした。そこで回転センサーを活用しました。回転センサーを使うことで位置をほぼ正確に把握することができます。1周する回転数を計ってプログラミングしました。しかしそれでも点線の判定が交差点の判定になってしまう、1周で終了してしまう等のミスがあり、何度も試行錯誤をして細かく修正しました。そのためプログラムが少し長くなってしまいました。しかし、今回の課題でプログラミングの理解が深まってよかったです。

-水野

今回はロボ製作は簡単でしたが、プログラムの難易度が大幅に上がった。ポイントは●コースから外れない●交差点や近道の判別だったと思う。また、何度試行しても結果が変わったりして正確なプログラムはできなかった。コース離脱や思わぬハプニングが起こったりしたが、その時に役にたったのが回転センサーだった。直角は90°で曲げたかったが変数指定すると直線の部分で判定が起こったりして上手くいかなかったのが悔しい。HPも任せきりにしてしまい反省でたくさんの課題になってしまった。

*コメントをお願いします [#dc304afe]
- ロボットの説明、コースの分析をさらに詳細にすると良いと思います -- [[TAKA]] &new{2010-12-24 (金) 16:30:55};
- 書くべき点は書けていると思います。あとは、二人目のプログラムで何の変数かの説明を入れたりするなど細かい点に気を配ってみてください。過去の優れたホームページを参考にして、選り優れたホームページを目指してください。 -- [[FI]] &new{2011-01-08 (土) 02:47:06};

#comment

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