- 追加された行はこの色です。
- 削除された行はこの色です。
[[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]
終わりよければすべて良しというわけではありませんが、結果だけをみれば満足のいくものでした。今回の課題では、チーム一丸となって取り組んだものだったので、なお喜ばしいものになりました。このゼミを通して、私自身沢山のことを学ばせてもらいました。素直に楽しかったです。