[[2015b/Member]]

目次
#contents
*課題内容 [#g9939cd0]
*ロボットの説明 [#wd0d1857]
**ロボットA [#k3ee3c7c]
**ロボットB [#afae0e3e]
課題は、ボールを離れた場所から缶に当てるロボットとボールを回収するロボットの制作です。

#ref(./2015b-mission3.png,60%,課題)

*ロボットAについて [#k3ee3c7c]
ロボットAは、ボールを掴んで缶に当てる動作を行います。このロボットには、モーターを3つと、光センサを2つ、角度センサを1つ使用しています。モーターのうち2つは車輪に使い、残りの1つは、ボールを掴む・弾く動作のために使っています。光センサは、ライントレース用と、缶の位置を探す用に分けて使っています。角度センサは、主に距離を測るために使っています。

#ref(./DSC_0248.JPG,60%,ロボット全体図)
↑ロボット全体図

**ボールを掴む・弾く動作 [#v79a51aa]

今回の課題では、ボールを缶に当てる動作が必要になるので、どうやってボールをとばすかということが、初めに考えられました。ボールを正確に掴むため、クワガタのようなアームにし車体を利用して、体当たりのような形で押し出す方法が考えられましたが、それではあまりに不格好だと思い、掴む・押し出すを綺麗な形で行える方法を考えました。その結果、爪のようなものを軸回転させるという方法になりました。これにより、ボール回収後も、車体から飛び出すことなく安定して運べますし、なにより、ボールを無駄な動きなく飛ばすことができます。

このロボットが完成するまで、様々な改良を加えていきました。最終的に完成させたロボットでも、動きに問題は無かったですが、ギア比等をもっとしっかり考えておくべきだったと思います。
#ref(./DSC_0250.JPG,60%,動作説明)
↑ギア側面図
*ロボットBについて [#afae0e3e]
ロボットBは、缶に当たったボールを回収する動作をします。このロボットには、モーター3つと、光センサを1つ使用しています。モーターのうち2つは車輪に、残り1つは、ボール回収動作を行うために使っています。光センサは、ライントレースをするために使用しています。

制作初期は、缶に当たったボールを探すことを目標としていましたが、光センサでボールを探すことが難しいと判断したため、コース内に止まったボールを、手当り次第回収するという、成功率の高い方法をとりました。
#ref(./DSC_0249.JPG,60%,ロボット全体図)
↑ロボット全体図

**ボールを回収する動作 [#rd0d793d]
ロボットBのボール回収動作は、RCXのキャタピラパーツを4つ使用して、それを常に車体中心に向かって回転するようにして、ボールを回収していくことができます。万が一、ボールが外に飛び出さないよう、柔らかい透明なパーツを車体の両サイドに取り付けています。もう一つ、このパーツを利用したことに、ロボットのキャタピラパーツが捉えられない位置にあるボールを前にはじき出し、運良く回収できるということが挙げらます。こちらの方が、本来の目的であったりします。

このロボットは、制作が発表当日に完了したということもあり、まだまだ、改良の余地はあったと思われますが、結果としてはこれで良かったのかもしれません。
#ref(./DSC_0251.JPG,60%,動作説明)
↑ギア側面図

*プログラム [#we877882]
プログラムは、同チームの2人が中心になって作成してくれました。ざっくりとした説明になってしまいますので、詳細は同チームの人のページを確認してください。
**ロボットA用 [#daa1aaa3]
ロボットAの基本戦略は、ボールの位置を角度センサにより正確に計測し、その場に到達したら掴む動作を行い、缶に近い場所まで移動、光センサを利用し缶の位置を特定し、ボールを弾くというような形になります。

所々、ライントレースをしたり、角度センサを利用して走行したりするため、プログラムをサブルーチンで複数組んであります。
 //black = 43 < 48 < white = 52
 //SENSOR_2 トレース
 //SENSOR_3 物体探索
 //TIMER(0) トレース
 //TIMER(1) 光探索


 /*共通機構*/
 #define power(s) SetPower(OUT_A+OUT_C,s);

 /*ライントレース用*/
 #define shiki 48

 #define tomaru(t) Off(OUT_AC);Wait(t);
 #define FWD OnFwd(OUT_AC);
 #define BACK OnRev(OUT_AC);
 #define LEFT_t OnRev(OUT_A); OnFwd(OUT_C);
 #define LEFT Off(OUT_A); OnFwd(OUT_C);
 #define RIGHT_t OnRev(OUT_C); OnFwd(OUT_A); 
 #define RIGHT Off(OUT_C); OnFwd(OUT_A);
 #define TMAX 20

 /*ロボコン独自機構*/
 #define open(t) OnFwd(OUT_B);Wait(t);//玉を扱う機構
 #define close(t) OnRev(OUT_B);Wait(t);Off(OUT_B);
 #define stop_B Off(OUT_B);
 #define SUN 50//ランタンの輝度を表す数値
 #define shoot power(2);open(15);Wait(10);close(15);

 /*赤球迄のトレース*/
 sub trace_0()
 {
	power(2);
	ClearSensor(SENSOR_1);
	while(1){
                if (SENSOR_2 < shiki -7){
			LEFT_t;
		} else if (SENSOR_2 < shiki -4){
			LEFT;
		} else if (SENSOR_2 < shiki){
			FWD;
		} else if(SENSOR_2 < shiki +4){
			RIGHT;
		} else {
			RIGHT_t;
		} 
		if(SENSOR_1 > 335){
			power(3);
			close(50);
			ClearSensor(SENSOR_1);
			break;
		}
	}
 }

 /*赤球を放つ手前*/
 sub trace_1()
 {
	ClearSensor(SENSOR_1);
	close(10);
	Off(OUT_B);
	power(2);
	while(1){
                if (SENSOR_2 < shiki -7){
			LEFT_t;
		} else if (SENSOR_2 < shiki -4){
			LEFT;
		} else if (SENSOR_2 < shiki){
			FWD;
		} else if(SENSOR_2 < shiki +4){
			RIGHT;
		} else {
			RIGHT_t;
		} 
                if(SENSOR_1 > 62){
		tomaru(10);
		break;
		}
	}
 }

 sub trace_2()
 {
	power(1);
	ClearSensor(SENSOR_1);
	while(1){
                if (SENSOR_2 < shiki -7){
			RIGHT_t;
		} else if (SENSOR_2 < shiki -4){
			RIGHT;
		} else if (SENSOR_2 < shiki){
			FWD;
		} else if(SENSOR_2 < shiki +4){
			LEFT;
		} else {
			LEFT_t;
		} 
		if(SENSOR_1 > 44){
			power(3);
			close(50);
			ClearSensor(SENSOR_1);
			break;
		}
	}
 }

 sub trace_3()
 {
	power(2);
	ClearSensor(SENSOR_1);
	while(1){
		close(1);
		Off(OUT_B);
		if (SENSOR_2 < shiki -7){
			RIGHT_t;
		} else if (SENSOR_2 < shiki -4){
			RIGHT;
		} else if (SENSOR_2 < shiki){
			FWD;
		} else if(SENSOR_2 < shiki +4){
			LEFT;
		} else {
			LEFT_t;
		} 
		if(SENSOR_1 > 110){
			power(3);
			close(50);
			ClearSensor(SENSOR_1);
			break;
		}
	}
 }

 /*光源を探す*/
 sub LIGHT()
 {	
	
	PlaySound(SOUND_UP);
	int sun_MAX = 0;
	int sensor_MAX = 0;
	close(20);
	ClearSensor(SENSOR_1);
	power(1);
	while(SENSOR_1 < 85){
		RIGHT_t;
		if(SENSOR_3 > sun_MAX){
			sun_MAX = SENSOR_3;
			sensor_MAX = SENSOR_1;
		}
	}
	tomaru(10);
	LEFT_t;
	until(SENSOR_1 < sensor_MAX);
	tomaru(10);
 }

 task main()
 {
	/*回転センサ*/
	SetSensor(SENSOR_1,SENSOR_ROTATION);
	/*トレース用センサ*/
	SetSensor(SENSOR_2,SENSOR_LIGHT);
	/*探索用センサ*/
	SetSensor(SENSOR_3,SENSOR_LIGHT);
        FWD;Wait(150);
	trace_0();//向かう
	tomaru(50);
        trace_1();//赤玉持ち
	LIGHT();
	shoot;
	tomaru(20);
	ClearSensor(SENSOR_1);
	RIGHT_t;
	until(SENSOR_1 > 28);
	tomaru(10);
	ClearSensor(SENSOR_1);
	FWD;
	until(SENSOR_1 > 26);
	Off(OUT_B);
	FWD;
	until(SENSOR_2 < 48);
	open(7);
	Off(OUT_B);
	trace_2();
	tomaru(10);
	FWD;Wait(100);
	trace_3();
	tomaru(10);
	LIGHT();
	shoot;
	trace_1();
 }
**ロボットB用 [#rdc01f14]
ロボットBの基本戦略は、ライントレースする中でボールを回収していくことになります。プログラムは、課題2で組んだプログラムに、回収動作や、ロボットAと動作が被らないように停止する動作等を加えてあります。
 /*
 37 black
 53 white
 */

 int startime=300;

 #define CHECKCROSSTIME 25

 #define fwd(OUT) Off(OUT);OnFwd(OUT)
 #define rev(OUT) Off(OUT);OnRev(OUT)

 #define TURNLEFT fwd(OUT_AC)
 #define LEFT Off(OUT_C);fwd(OUT_A)

 #define TURNRIGHT rev(OUT_AC)
 #define RIGHT Off(OUT_A);rev(OUT_C)

 #define STRAIGHT rev(OUT_C);fwd(OUT_A)
 #define BACK fwd(OUT_C);rev(OUT_A)

 #define ISNOTCROSS FastTimer(0) <= CHECKCROSSTIME || FastTimer(1) <= startime

 #define RELEASE rev(OUT_B);
 #define LOADING fwd(OUT_B);

 sub trace(){
	ClearTimer(0);
	while(ISNOTCROSS){
		if(FastTimer(1) < startime){
			ClearTimer(0);
		}
		if(52 <= SENSOR_1){
			TURNRIGHT;
		}else if(50 <= SENSOR_1){
			RIGHT;
		}else if(41 <= SENSOR_1){
			STRAIGHT;
		}else if(39 <= SENSOR_1){
			LEFT;
		}else {
			TURNLEFT;
		}
		if(39 <= SENSOR_1) ClearTimer(0);
	}
	Off(OUT_AC);
	ClearTimer(0);
	Wait(100);
 }

 /* 直進する */
 sub go_straight(){
	STRAIGHT;
	Wait(30);
	ClearTimer(1);
 }

 /* 左折する */
 sub turn_left(){
	ClearTimer(1);
	ClearTimer(0);
 }

 /* 右折する */
 sub turn_right(){
	ClearTimer(1);
	while(ISNOTCROSS){
		if(FastTimer(1) >= startime){
			ClearTimer(0);
			ClearTimer(1);
			break;
		}
		if(53 <= SENSOR_1){
			TURNLEFT;
		}else if(50 <= SENSOR_1){
			LEFT;
		}else if(47 <= SENSOR_1){
			STRAIGHT;
		}else if(44 <= SENSOR_1){
			RIGHT;
		}else {
			TURNRIGHT;
		}
	}
	TURNLEFT;
	Wait(10);
	Off(OUT_AC);
	ClearTimer(0);
	ClearTimer(1);
 } 

 task main(){
	SetSensor(SENSOR_1,SENSOR_LIGHT);
	ClearTimer(0);
	LOADING;
	go_straight();
	trace();
	go_straight();
	Off(OUT_AC);
	Wait(2300);
	ClearTimer(1);
	startime=900;
	trace();
	startime=300;
	//turn_left();//
	//trace();
	go_straight();
	trace();
	go_straight();
	//turn_left();
	trace();
	go_straight();
	startime=1400;
	trace();
	startime=300;
         TURNRIGHT;
	Wait(10);
	Off(OUT_AC);
	RELEASE;
	Wait(300);
	BACK;
	Wait(100);
	TURNRIGHT;
	Wait(40);
         LOADING;
	ClearTimer(0);
	trace();
	turn_left();
	startime=900;
	trace();
	startime=300;
	//turn_left();//
	//trace();
	go_straight();
	trace();
	go_straight();
	trace();
	go_straight();
	startime=1400;
	trace();
	startime=300;
         TURNRIGHT;
	Wait(10);
	Off(OUT_AC);
	RELEASE;
	Wait(300);
	go_straight();
	Wait(10);
	Off(OUT_ABC);
 }
*結果[#s55739b0]
結果は、全4チーム中一番という結果でしたが、これには、多かれ少なかれ、運が絡んでいます。まず、ロボットAの角度センサを利用した、ボールの位置特定が、正確に特定できない時があります。赤ボールに関しては、悪くない確率で成功させられますが、青ボールに関しては、めったにできないので、諦めていたところでした。ロボットBについても、ボールの停止位置に左右される作りになっていますので、運が良かったとしか言えません。私自身は運がいい方ではないので、この結果は、チームのみんながもたらした、結果なのかもしれません。
*感想 [#nf94c7f1]
終わりよければすべて良しというわけではありませんが、結果だけをみれば満足のいくものでした。今回の課題では、チーム一丸となって取り組んだものだったので、なお喜ばしいものになりました。このゼミを通して、私自身沢山のことを学ばせてもらいました。素直に楽しかったです。


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