2009b


課題3:懐中電灯に向かってブロックを投げるロボット

作成者:SHIMA,kata,PuKKu

 インストの「top secret」を参考にして、白いホイールを(2個以上)連射するロボットを作成し、以下の動きをするようにプログラムを作成せよ。 (重複しないように一人一つ以上のプログラムを作成すること)

  1. 全方向から懐中電灯の方向を探しだし、懐中電灯を狙ってブロックを投げる。方向を定めたのち、懐中電灯の30cm以内に近づかない範囲で必要な距離を移動してもよい。懐中電灯は動かさないが、いろいろな距離や方向にある懐中電灯に対応できるロボットにすること。(SHIMA)
  2. 懐中電灯をゆっくり動かしたとき懐中電灯に向かって進み、懐中電灯の動きを止めれば一定の距離(懐中電灯から30cm以上離れた距離)まで近づいて懐中電灯を狙ってブロックを投げる。(PuKKu)
  3. 懐中電灯を動かしたとき懐中電灯に向かって進み、見失った時には再び全方向から懐中電灯を探しだす。7秒以上追尾できたら懐中電灯に向かってブロックを投げる。(kata)

 懐中電灯の代わりに携帯のライトなどを利用してもよい。モータ、光センサ、タッチセンサはそれぞれ2個まで使用可。ただし、平面的な方向だけでなく懐中電灯の高さまで含めた方向を探す場合にはモータを3個使用してもよい。

(2009b/練習問題より抜粋)

目次

ロボットの作成

方針

台車

 モーターは今回の課題では2つしか使ってはいけないので、1つのモーターで左右に曲がれる機構を作らなければならなかった。ディファレンシャルギアという特別なパーツが必要となった。

アーム

 始めはアームにホイールをセットし、投げる構造にしていたが、きわめて大掛かりで、安定して投げることができなかった。方針を変え、打ち出すことにした。

IMG_02172.jpg
当初の予定(黄色の矢印の方向へアームを動かして投げる)

作成手順

台車

IMG_01972.jpg

 今回は使用できるモーターが一つだけなので、課題3のヒントを参考にして、ディファレンシャルギアを用いて左右のタイヤをそれぞれ一方ずつ動くようにした。そのために、左右のタイヤがそれぞれ後転するときには下図のようにストッパーを用いて回転しないようにして、左右に動くようにした。そして、モーターが一つなので力不足にならないようにするために、ギア比を調節し力不足にならないようにした。

左側                右側
IMG_01982.jpg     IMG_01992.jpg

アーム

IMG_02051.jpg
IMG_02092.jpg

 発射の方法は、レール(2本の棒)上にセットされたホイールをレールの間(2本の棒の間)を通過するアームに当てて発射させます。
 一つのホイールが発射されると次のホイールが落下して、再度、レール上にセットされます。これを4回繰り返すことにより連射が可能になります。

IMG_02032.jpg

 発射される以外のホイールが置かれているところ(マガジン)は、初めレールに沿って斜め上に装着されていましたが、たまにホイールが落下しないことがあったので、レールに沿って垂直にセッティングしました。
 ホイールの中心に軸を通す穴があったので、これに棒を通し、マガジンにホイールを待機させます。なので、棒の長さによっては、何発でも装填可能です。

光センサー

light2.jpg

 光センサーの配置は特に工夫はしなかったが、前回のライントレースのときとは違い、センサー同士の間についたてを立てた。これにより、2つの値の差が大きくなるので、より光を追いやすくなった。

改良前の作品

IMG_01811.jpg

 時々、ホイールがレール上にうまくセットされないことがあり、安定性がなかった。また、台車のギアがよく外れてしまい、動かなくなった。

完成

IMG_01951.jpg

 以前より、安定性が増し、課題をうまく行えるようなロボットになった。

工夫した点・苦労した点など

  • 車体に取り付けられたギアが、回転しているうちに徐々に外れていまい苦労しましたが、なんとか外れにくいように工夫しました。(今でもたまに外れます。)また、ストッパーの取り付けも試行錯誤を繰り返して、理想のストッパーができたと思います。
    タイヤは、小回りできるように小型の2輪タイプにしました。
  • アームは、作成手順に書いたように二度の改良で割と遠くまで飛ばせるようになりました。ごく稀にホイールが落下しないこともあるのが難点です。また、次に装填されるホイールの落下位置を安定させるため左右に黒い棒を2本ずつ取り付けました。
  • センサーの部分に取り付けられた黒い角は左右のセンサーに当てられた光を区別するためです。また、センサー自体は、軽量化のためシンプルにそのまま取り付けました。

問題点

  • 3つ目のモーターは投げる角度を調節するのには使ってもよかったが、うまく利用できなかった。
  • 走行中にギアが時々外れてしまう。
  • ホイールをマガジンにセットするのが難しい。

プログラム

SHIMAのプログラム(1)

#define T 900                                //一周旋回する時間
#define right_turn OnFwd(OUT_C);       //右回りに旋回するプログラム
#define arm OnFwd(OUT_A);Wait(20);Off(OUT_A);//球を発射するプログラム

task main ()
 {
  SetSensor(SENSOR_1,SENSOR_LIGHT);     //センサー1は光センサー
  SetSensor(SENSOR_3,SENSOR_LIGHT);     //センサー3は光センサー
  ClearTimer(0);
  int light_max;               //光の明るさの最大値の定義
  light_max=0;
    
  while(FastTimer(0)<T)          //時間T以内なら以下のプログラムを行う
        {right_turn             //右回りに旋回する
           if(SENSOR_1>light_max)      //センサー1が光の最大値を更新
             {light_max=SENSOR_1;}
         }
  right_turn                                 //以上のプログラムが終わったら
  until(SENSOR_1>=light_max);        //もっとも明るい方向へ右旋回する
  Float(OUT_C);                              //停止
  repeat(4){arm Wait(100);}         //”arm”というプログラムを4回行う
 }

~SHIMAのプログラム解説~
 このプログラムは、9秒間、ロボットを旋回させ、その間に光の明るさの最大値を更新させて、9秒経過したら一番明るかった方向へ再度旋回させ、ホイールを4連射させるものです。初め、光のセンサーは2個使用しましたが、このプログラムの場合、センサーを1個にした方が効率が良い(簡単なプログラム)だろうと思い、減らしました。また、過去の人が作成した光の最大値を更新するプログラムを参考にしたり、チーム内の方々に作成の手伝いやアドバイスをしてもらいました。みなさん、大変お世話になりましたm(_ _)m

PuKKuのプログラム(2)

#define EYE_L SENSOR_1				//左の光センサー
#define EYE_R SENSOR_3				//右の光センサー
#define LIGHT 65				//懐中電灯に30cmぐらい近づいた明るさ
#define ON_A SetOutput(OUT_A,OUT_ON);		//モーターAに電源を入れる
#define ON_C SetOutput(OUT_C,OUT_ON);		//モーターAに電源を入れる
#define OFF_A SetOutput(OUT_A,OUT_OFF);		//モーターAをOffで止める
#define FLOAT_C SetOutput(OUT_C,OUT_FLOAT);	//モーターCをFloatで止める
#define FWD_C SetDirection(OUT_C,OUT_FWD);	//モーターCを回転させ、左のタイヤが前進
#define REV_C SetDirection(OUT_C,OUT_REV);	//モーターCを回転させ、右のタイヤが前進
#define FWD_A SetDirection(OUT_A,OUT_FWD);	//モーターAを回転させ、ホイールを投げる



task main(){
	SetSensor(EYE_L, SENSOR_LIGHT);				//光センサー(左)
	SetSensor(EYE_R, SENSOR_LIGHT);				//光センサー(右)
	int brightness=0;					//明るさの記録

	
	while((EYE_L<LIGHT) || (EYE_R<LIGHT)){			//左右の明るさが共にLIGHTより暗い間
		ON_C;						//モーターCに電源を入れる
		if(EYE_L<EYE_R){				//右が左より明るいとき(右に曲がる)
			brightness=EYE_L;			//左の明るさを記録
			FWD_C;					//左のタイヤを前進
			until(EYE_L>brightness);		//左の明るさが記録した値より大きくなるまで
		}else if(EYE_L>EYE_R){				//左が右より明るいとき(左に曲がる)
			brightness=EYE_R;			//右の明るさを記録
			REV_C;					//右のタイヤを前進
			until(EYE_R>brightness);		//右の明るさが記録した値より大きくなるまで
		}else{						//その他(前進)
			FWD_C;					//左のタイヤが前進
			Wait(100);
			REV_C;					//右のタイヤが前進
			Wait(100);
		}
	}
	FLOAT_C;						//モーターCをFloatで止める(車体停止)
	
	Wait(100);						//休憩
	
	
	repeat(4){						//ホイールを4発投げる
		ON_A;						//モーターAに電源を入れる
		FWD_A;						//ホイールを発射
		Wait(20);
		OFF_A;						//モーターAの電源を切る
		Wait(100);
	}
}

〜PuKKuのプログラム〜
 このプログラムは右と左の光センサーのそれぞれの値を比べて高い(明るい)方に向かって進んで懐中電灯の光に追いかけ、懐中電灯の光がある一定以上の明るさになると、ホイールを4発発射させるようになっている。

〜苦労した点など〜
 懐中電灯が遠くにあるときの左と右の明るさの差を判断させることが改良前のロボットでは、難しいところだったが、ロボットを改良したことでこの問題を解決することができた。また、なるべく早く懐中電灯の方を向くようにそれぞれのタイヤを動かす時間を少し前より明るくなった時までとした。これにより、余分に回りすぎないようになった。

kataのプログラム(3)

#define eye_L SENSOR_1                   //eye_Lを定義
#define eye_R SENSOR_3                   //eye_Rを定義
#define cont 45                          //contを45と定義
#define time 50                          //timeを50と定義
task main ()
{
	SetSensor(eye_L, SENSOR_LIGHT);                 //左の光センサー
	SetSensor(eye_R, SENSOR_LIGHT);                 //右の光センサー
	int i=0;                                        //変数を使用 0から
	Wait(100);                                      //一秒待ってからスタート
	while(i<4)                                      //変数が4になるまで繰り返す
	{
	if ((eye_L >= cont ) && (eye_R >= cont ))       //センサーが両方反応したとき
		{
		if (FastTimer(0) <  700){               
			PlaySound(SOUND_FAST_UP) ;}    //search_light後七秒経っていないなら、音を一回鳴らす
		else{
		PlaySound(SOUND_DOUBLE_BEEP) ;}       //search_light後七秒経っているなら、音を二回鳴らす
		OnFwd(OUT_C); Wait(time); Off(OUT_C); Wait(10);
		OnRev(OUT_C); Wait(time); Off(OUT_C); Wait(10);
			if (FastTimer(0) >=  700){    //七秒経っているなら、ブロックを投げるプログラム
			OnFwd(OUT_A); Wait(20);
			Off(OUT_A);
			Wait(100);
			i++;                          //変数に1を足してプログラムは上に戻る
			}
		}
	else if ((eye_L >= cont ) && (eye_R  <= cont ))       //左のセンサーが反応しているとき、左に曲がる
		{
		PlayTone(349,50) ;
		OnRev(OUT_C); Wait(time); Off(OUT_C); Wait(10);}    
	else if ((eye_L <= cont ) && (eye_R >= cont ))        //右のセンサーが反応しているとき、右に曲がる
		{
		PlayTone(440,50) ;
		OnFwd(OUT_C); Wait(time); Off(OUT_C); Wait(10);}
	else {                                                //センサーが反応していないとき、search_lightをスタート
		
		search_light();}
	}
}
sub search_light()                  //右回りし続けて光を探すプログラム
{
	OnFwd(OUT_C); Wait(50);
	Off(OUT_C); Wait(20);
	PlayTone(330,50) ;
	ClearTimer(0);               //search_lightを実行するたびにタイマーをリセット&スタートする
}

〜プログラムについて〜  始めは変数を使わずWhile(true)やrepeatを使っていたが、これだと途中で違うプログラムを使えなかったり、無視してしまったりした。変数の使い方を学べた。

感想

~SHIMA~
 ホイールを発射する仕組みは何とかなったが、下の車体は難しすぎてよくわからなかった。また、プログラムの製作は、手助けが必要でした。ロボット自体は、満足できる結果が得られたと思う。

~kata~
 ライトを7秒追うことはできたが、30センチの距離はうまくとれなかった。土台のディファレンシャルギアの利用に苦労した。

~PuKKu~
 今回は、アームを軽くし、台車にあまり負担をかけないようにすることが大変であった。また、走行中にギアが外れてしまうことが悩みの種であった。そして、今回ロボットの重心を考えることがとても重要だということがよく実感できた。プログラムでは、センサーによって得られた光の明るさの値をどのように利用して、ロボットをコントロールして30センチの距離まで近づくことが大変でした。そして、懐中電灯の光を動かすこともなかなか難しかった。

コメント

  • ロボットの説明もプログラムの説明も頑張っています。一つ目・二つ目のプログラムに関しては、反応が起きる範囲に幅を持たせた方が良いと思います。例えば、1周目で求めた光の最大値以上のとき投げるとするよりも、ちょっとした加減で感知する光の強さは変わるので、+−5くらいの幅を持たせた方が実際的かもしれません。 3つ目のプログラムに関して言えば、連射するだけならrepeatを使った方が、すぐ上のelseに組み込めばif (FastTimer(0) >= 700)はいらないかもしれません。-- FI? 2010-01-27 (水) 01:39:13
  • ロボットの説明が大変よくできています。写真だけでなく図を利用している点がとてもよいです。プログラムについては、制作の過程で自分で使い方を学ぶという姿勢が高評価です。while(true)+break、while(...)、repeatのような同じ動作をする構文は、一番スマートに(シンプルに)書けるものが一番適しているので、場面ごとに最適なものを選べるようにしましょう。 -- こさか? 2010-02-10 (水) 15:56:09


添付ファイル: fileIMG_02092.jpg 186件 [詳細] fileIMG_02032.jpg 201件 [詳細] filelight2.jpg 191件 [詳細] fileIMG_01992.jpg 197件 [詳細] fileIMG_01982.jpg 193件 [詳細] fileIMG_01972.jpg 181件 [詳細] fileIMG_02172.jpg 194件 [詳細] fileIMG_02051.jpg 205件 [詳細] fileIMG_01991.jpg 100件 [詳細] fileIMG_01981.jpg 108件 [詳細] fileIMG_01971.jpg 97件 [詳細] fileIMG_01951.jpg 217件 [詳細] fileIMG_01811.jpg 184件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-02-13 (土) 23:40:51 (3480d)