2015b/Member

目次

課題内容

課題は、ボールを離れた場所から缶に当てるロボットとボールを回収するロボットの制作です。

課題

ロボットAについて

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

ロボット全体図

↑ロボット全体図

ボールを掴む・弾く動作

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

このロボットが完成するまで、様々な改良を加えていきました。最終的に完成させたロボットでも、動きに問題は無かったですが、ギア比等をもっとしっかり考えておくべきだったと思います。

動作説明

↑ギア側面図

ロボットBについて

ロボットBは、缶に当たったボールを回収する動作をします。このロボットには、モーター3つと、光センサを1つ使用しています。モーターのうち2つは車輪に、残り1つは、ボール回収動作を行うために使っています。光センサは、ライントレースをするために使用しています。

制作初期は、缶に当たったボールを探すことを目標としていましたが、光センサでボールを探すことが難しいと判断したため、コース内に止まったボールを、手当り次第回収するという、成功率の高い方法をとりました。

ロボット全体図

↑ロボット全体図

ボールを回収する動作

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

このロボットは、制作が発表当日に完了したということもあり、まだまだ、改良の余地はあったと思われますが、結果としてはこれで良かったのかもしれません。

動作説明

↑ギア側面図

プログラム

プログラムは、同チームの2人が中心になって作成してくれました。ざっくりとした説明になってしまいますので、詳細は同チームの人のページを確認してください。

ロボットA用

ロボット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用

ロボット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);
}

結果

結果は、全4チーム中一番という結果でしたが、これには、多かれ少なかれ、運が絡んでいます。まず、ロボットAの角度センサを利用した、ボールの位置特定が、正確に特定できない時があります。赤ボールに関しては、悪くない確率で成功させられますが、青ボールに関しては、めったにできないので、諦めていたところでした。ロボットBについても、ボールの停止位置に左右される作りになっていますので、運が良かったとしか言えません。私自身は運がいい方ではないので、この結果は、チームのみんながもたらした、結果なのかもしれません。

感想

終わりよければすべて良しというわけではありませんが、結果だけをみれば満足のいくものでした。今回の課題では、チーム一丸となって取り組んだものだったので、なお喜ばしいものになりました。このゼミを通して、私自身沢山のことを学ばせてもらいました。素直に楽しかったです。


添付ファイル: file2015b-mission3.png 108件 [詳細] fileDSC_0251.JPG 81件 [詳細] fileDSC_0250.JPG 93件 [詳細] fileDSC_0249.JPG 89件 [詳細] fileDSC_0248.JPG 93件 [詳細] fileDSC_0246.JPG 53件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-02-15 (月) 22:28:23 (1281d)