2009a

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

メンバー/ ピーチクパーチク
       バビロン
       ライス

ロボット

ディファレンシャル・ギア

d_gear01.jpeg
この特殊なギアは、内部に含まれるギアを使うことで、一つだけのモーターで左右回転・直進を可能にする優れたものである。
しかし今回は仕様上、直進機能を除き、ラチェットを使うことで左右回転だけが可能なロボットを作成した。
見れば分かるように、ディファレンシャルギアの近くに車軸がある。
これを利用して、ディファレンシャルギアに触れるか触れないかほどに、留め具をつけた。これで車軸のぶれが抑えられるのである。

車体

main01.jpeg main02.jpeg
説明書のトップシークレット、先生に頂いたヒント、先輩の作成したロボットを元に作成。
モーターからディファレンシャルギアへ力を伝えるためのギアが噛み合わなくて苦労した。
そのため、ギアボックスの広さを1ブロック分空け、パーツを詰めてギアを噛み合わせられるようにした。
ラチェットのぶれ幅も一工夫。最初のうちはギアを多く取り付けて、後ろに伸びたギアボックスの内側にラチェットを搭載しようとしていたが、トルクが小さくなってロボが動かなくなってしまったのでやめた。結局、このような形に落ち着いた。


main_s01.jpeg

初期は前輪を装着するつもりだったが、予想外に摩擦力がかかるので、
タイヤの代わりに支え棒(半球)をふたつ装着。摩擦がほどよく小さくなった。
タイヤのブレ防止と車軸にかかる力を落とすためにフレームを増強。

ブロック投射機

line01.jpegline02.jpeg
先輩の作ったレールガンのようなものに惹かれ作成。
先輩のものとほぼ同じようなものだが……

改造点
・砲芯の長さを延長
・速度上昇のためギア比を変更
・撃鉄までの長さを延長
これらの改造は、すべてホイールの投射速度・範囲と威力を上げるためのものである。
投射能力の向上に必要なのは「遠心力(加速度)」。回転運動が描く円の半径を大きくすればいいのである。
強度は弱い。しかしホイールを投げるだけなら十分なのでこれで完成。

l_wall00.jpeg
前方にずれたバランスを整えるため、車体についていた支え棒はこちらに装着。
また、光センサも内包した投射機となった。
簡単に分離でき、接続強度も十分な「ユニット」としての完成をみる。

調整

l_wall02.jpegl_wall01.jpeg
光センサの感度を左右でおおきく変えるため、光センサの間、投射機にカベのようなものを作成。
壁を作ることで、左右どちらのほうが明るいかを比較的正確に判断できるようになる。
先生が説明していたが、壁がなかったとして、横側から光を当てても、小型ロボの左右のセンサの距離では、光の強さはほぼ変わらないということが壁作成の指針となっている。

完成

comp01.jpeg
まるで戦車砲のようだ。かっこいい。

プログラム

1・全方向から懐中電灯の方向を探しだし、懐中電灯を狙ってブロックを投げる

作成者:バビロン

しきい値を60としてプログラムを作成した。

task main()
{
SetSensor(SENSOR_1,SENSOR_LIGHT);
while(true){
       if(SENSOR_<60){ //センサーが光を見つけていないとき
       OnFwd(OUT_B); //その場で回転
       }
       if(SENSOR_1>60){ //センサーが光を見つけたとき
       Off(OUT_B); //停止
       OnRev(OUT_A); //投げる
       Wait(18);
       Off(OUT_A);
       break; //while終了、プログラム停止
       }
}
}

''改良プログラム''
相談したところ、ピーチクパーチクさんのサブルーチンがそのまま使用できそうなので貰い、こっちの課題にあうよう改造しました。
それを所々説明を付け加えたりしました。

一回転するうちに光の最大値を探し、今度は逆向きに回転することで光の方向を向くことの出来るプログラムです。

変数の定義
int tmax = 0; //周囲の「光の最大値」を見つけるまでの時間
int lmax = 0; //センサーが見つけた「光の最大値」 

メインタスク

task main(){
ClearTimer(0); //タイマーセット
SetPower(OUT_B,4);
OnFwd(OUT_B);      //最初の一回転
while ( FastTimer(0) < 300) { //三秒間、回転している間、下のことを繰り返す    
 	if (SENSOR_3> tmax){ //回転中常に光の大きさを検索
		lmax = SENSOR_3;
		tmax = FastTimer(0); //光の最大値と、そのときの時間を記録する
		}
	}
	SetPower(OUT_B,7);
	OnRev(OUT_B); //光の方向を向くための逆回転
	Wait(300 -  tmax); //回転時間=3秒-光の最大値を見つけた時間
	Off(OUT_B);  //停止する

 	SetPower(OUT_A,7); //Aの力を最大に
	OnRev(OUT_A);
	Wait(70);  //ブロックを投げる
	Float(OUT_A+OUT_B); //モーターを止める。
}

2・動く懐中電灯に向かって進み、懐中電灯が止まったらブロックを投げる

作成者:ライス

int Tmax = 0; //光の最大値を見つけるまでの時間
int Lmax = 0; //光の最大値 
//ピーチクパーチクさんに貰った光を見つけるプログラム
sub serch(){  //サブルーチン「光の最大値を見つける」
ClearTimer(0); //タイマーセット
SetPower(OUT_B,4);
OnFwd(OUT_B);      //3秒間回転(一回転)
while ( FastTimer(0) < 300) {    
 	if (SENSOR_3> Tmax){ //回転中常に光の大きさを検索
		Lmax = SENSOR_3;
		Tmax = FastTimer(0); //光の最大値と、そのときの時間を検索
		}
	}
	SetPower(OUT_B,7);
	OnRev(OUT_B); //逆回転
	Wait(300 -  Tmax); //回転時間=3秒-光の最大値を見つけた時間
	Off(OUT_B);
	}
task main(){
SetSensor(SENSOR_1, SENSOR_LIGHT);
SetSensor(SENSOR_3, SENSOR_LIGHT); //センサー定義
	serch(); //光を見つけるサブルーチン
	ClearTimer(1); //タイマーのリセット

	while(Timer(1) < 100){ //タイマーが10秒以内の時、以下の動作を続ける
		if(SENSOR_1 > SENSOR_3){ //左の光がおおきい
			OnRev(OUT_B);
			Wait(20);  //左を向く
			ClearTimer(1); //タイマーのリセット
		} if (SENSOR_3 > SENSOR_1){ //右の光がおおきい
			OnFwd(OUT_B);
			Wait(20);  //右を向く
			ClearTimer(1); //タイマーのリセット
		} if ((SENSOR_3<40)&&(SENSOR_1<40)){ //光を見失ったとき
			ClearTimer(1); //タイマーのリセット
			serch(); //サブルーチン「光の最大値を見つける」実行
			ClearTimer(1); //タイマーのリセット、サブルーチンで6秒ほど使うため
		}if ((SENSOR_3>70)||(SENSOR_1>70)){ //光に近づきすぎたとき
			Off(OUT_B); //止まる
		}else { //光の値がそれ以外の時
			ClearTimer(1); //タイマーのリセット
			OnFwd(OUT_B);
		 	Wait(5); //ほんの少しだけ右を向く
		}

	}//懐中電灯が止まっているなら、このロボも30cmくらいで停止していることになる。
		//ロボが5秒以上止まっている=懐中電灯が止まっているなら、下の動作に移る

	ClearTimer(2); //次のタイマーをリセット
	while(Timer(2)<5){ //0.5秒間向きを調整する
		if(SENSOR_1 > SENSOR_3){ //左の光がおおきい
			OnRev(OUT_B); //左を向く
		} if (SENSOR_3 > SENSOR_1){ //右の光がおおきい
			OnFwd(OUT_B); //右を向く
		}
	}
	Off(OUT_B);
 	SetPower(OUT_A,7);
	OnRev(OUT_A);
	Wait(70);  //ブロックを投げる
	Float(OUT_A+OUT_B); //プログラムここまで。
}

3・7秒間懐中電灯を追尾して、最後にブロックを投げるロボット

作成者:ピーチクパーチク
プログラム概要
1:一回転して、懐中電灯(光の最大値)の位置を探る
2:懐中電灯を追う、見失ったらもう一度位置を探る、近づきすぎたら止まる
3:投げる

int Tmax = 0; //光の最大値を見つけるまでの時間
int Lmax = 0; //光の最大値 

sub serch(){  //サブルーチン「光の最大値を見つける」
ClearTimer(0); //タイマーセット
SetPower(OUT_B,4);
OnFwd(OUT_B);      //3秒間回転(一回転)
while ( FastTimer(0) < 300) {    
 	if (SENSOR_3> Tmax){ //回転中常に光の大きさを検索
 		Lmax = SENSOR_3;
		Tmax = FastTimer(0); //光の最大値と、そのときの時間を検索
		}
	}
	SetPower(OUT_B,7);
	OnRev(OUT_B); //逆回転
	Wait(300 -  Tmax); //回転時間=3秒-光の最大値を見つけた時間
	Off(OUT_B);
	}

task main(){ //メインタスク

SetSensor(SENSOR_1, SENSOR_LIGHT);
SetSensor(SENSOR_3, SENSOR_LIGHT);
	serch(); //サブルーチン「光の最大値を見つける」
	ClearTimer(1);
	OnFwd(OUT_B);
	while (Timer(1) <= 70){ //タイマー(1)が70になるまで=7秒間
		SetPower(OUT_B,4); //以下、左右に少しずつ回転することで前に進むプログラム
		Wait(3);
		SetPower(OUT_B,7);
		OnRev(OUT_B);
		Wait(3);     //ここまで
		if(SENSOR_1 > SENSOR_3){ //左の方が光が強いとき
			OnRev(OUT_B);
			Wait(20);  //左を向く
		} if (SENSOR_3 > SENSOR_1){ //右の方が光が強いとき
			OnFwd(OUT_B);
			Wait(20);  //右を向く
		} if ((SENSOR_3<40)&&(SENSOR_1<40)){ //光を見失ったとき
			ClearTimer(1);
			serch(); //サブルーチン「光の最大値を見つける」実行
			ClearTimer(1); //サブルーチンで数秒使うので、タイマーをリセットする
		}if ((SENSOR_3>80)||(SENSOR_1>80)){ //光に近づきすぎたとき
			Off(OUT_B); //止まる
		}else{ //光センサの値が、上以外の時に実行
			OnFwd(OUT_B); //少しだけ右回転
			Wait(5);}
		
	}  //7秒間、以上の動作を繰り返した後
	Off(OUT_B); //止まる
 	SetPower(OUT_A,7);
	OnRev(OUT_A);
	Wait(70);  //ホイールを投げる
	Float(OUT_A+OUT_B); //ロボット停止、プログラム終了。
} 

コメント

コメントをどうぞ

  • 松本先生曰く、今回の課題は絶対的に明るい方向を探すのではなく、変数を用いて相対的に最も明るい方向を探す課題だそうです。また、ifを使うときは場合分けにもれがないように注意した方がいいです。めったにはありませんが、右と左の光センサが同じ値を認識したときにロボットはどう動くのでしょうか。 -- FI? 2009-08-08 (土) 05:16:00
  • プログラム、ロボットの説明を更新しました。''ロボットの説明は太字で書かれているところが更新した部分です。''バビロンさんのプログラムは、今までのプログラムの下に乗せてあります。ifの条件漏れについては、elseでif以外の時を全部まとめてみました。 -- ピーチクパーチク? 2009-08-08 (土) 14:32:42
  • 全員のプログラムに共通することとして、光を探す部分では、SetPower(OUT_B,4);とOnFwd(OUT_B);をループ内に入れる必要はないと思います。ライスさんのプログラム、「//ロボが5秒以上止まっている=懐中電灯が止まっているなら、下の動作に移る」とのことですが、どこでそれを判断しているのでしょうか?また、ピーチクパーチクさんのプログラムでは、7秒間の途中で光を見失った場合でも投げてしまうような気がします。 -- こさか? 2009-08-10 (月) 00:37:53
  • プログラムを更新しました。こさかさんの言われたとおり、setpower、onfwdをwhileから抜き出しました。ライスさんのプログラムもミスだそうで、4個目のif「近づきすぎたとき」にタイマーをリセットしないようにしています。こうすることで、ロボットが停止している間はタイマーがクリアされることがなく、次の動作に移ることが出来るはずです。少し無理があるかな……? 最後に私のプログラムですが、光を見失ったら、タイマーをクリアしてからサブルーチンを実行することにしました。このあたり課題の説明では曖昧なのですが、「光を見失ったらそこからまた7秒間光を追う」という解釈で作り直してみた結果がこれです。 -- ピーチクパーチク? 2009-08-11 (火) 03:28:29


添付ファイル: filemain_s01.jpeg 213件 [詳細] filemain02.jpeg 218件 [詳細] filemain01.jpeg 247件 [詳細] fileline02.jpeg 223件 [詳細] fileline01.jpeg 215件 [詳細] filel_wall02.jpeg 225件 [詳細] filel_wall01.jpeg 211件 [詳細] filel_wall00.jpeg 217件 [詳細] filel_s01.jpeg 131件 [詳細] filed_gear01.jpeg 238件 [詳細] filecomp01.jpeg 226件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-08-11 (火) 03:31:46 (3661d)