[[2018a/Member]]
*課題 [#ebae0cfb]
下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットを作成せよ。
#ref(./課題2 コースの図.png,70%,コースの図)
[ミッション]
次のいずれかのコースで黒い線に沿って動き、350mlの空き缶(黄色で表示)を移動させるロボットを製作せよ。
[コース1]
��Aをスタート
��Bを直進
��Cで一時停止の後、直進
��Dで一時停止の後、Xの空き缶をキャッチしてD地点に戻る
��DからEに向かい、Eを直進
��Fを左折
��Gで一時停止の後、左折
��Hで一時停止の後、右折
��Iで一時停止の後、右折
��Lを直進
��Kを直進
��Jで一時停止の後、空き缶をYに置きてJに戻りBに向かう
��Bで一時停止の後、左折
��Aで停止
(一時停止の指定がある場所は、1秒間停止すること)
[コース2]
��Aをスタート
��Bを右折
��Jで一時停止の後、Yの空き缶をキャッチしてJに戻る
��JからKに向かい、Kを直進
��Lを直進
��Iを左折
��Hで一時停止の後、左折
��Gで一時停止の後、右折
��Fで一時停止の後、右折
��Eを直進
��Dで一時停止の後、空き缶をXに置いてDに戻り、Cに向かう
��Cで一時停止の後、直進
��Bを直進
��Aで停止
(一時停止の指定がある場所は、1秒間停止する)
※私はコース2を選択した
*ロボット本体の説明 [#m397acd1]
#ref(./IMG_8116.jpg,20%,ロボットの写真)
ロボットの全体像である。シンプルなつくりとなっている。光センサーは前輪の間に設置されている。
#ref(./IMG_8117.JPG,20%,ロボットの写真)
缶を操作する機構である。大きさの異なるギアを組み合わせることで動きの速さを制御した。また、ギアの高さをそろえるために2つ重ねた。
*プログラミングの説明 [#i3ca63fc]
**定義 [#f16699a2]
#define cross_stop Off(OUT_AC);Wait(100);//交差点で止まる
#define TURN_RIGHT(t) OnFwd(OUT_A);OnRev(OUT_C);Wait(t);Off(OUT_AC);//右にt秒曲がる
#define TURN_LEFT(t) OnFwd(OUT_C);OnRev(OUT_A);Wait(t);Off(OUT_AC);//左にt秒曲がる
#define go_straight(t) OnFwd(OUT_AC);Wait(t);Off(OUT_AC);//まっすぐt秒進む
#define hold_can OnFwd(OUT_B);//缶をつかむ
#define releace_can OnRev(OUT_B);//缶を放す
**サブルーチン [#e681841b]
基本のライントレースは線の左右それぞれで分けてサブルーチンを作成した。
線の左側では、白(≧52)のとき右折し、薄い白(≧48)のとき右旋回し、薄い黒(≧43)のとき左旋回し、黒(≧41)のとき左折する。
線の右側では、白(≧52)のとき左折し、薄い白(≧48)のとき左旋回し、薄い黒(≧43)のとき右旋回し、黒(≧41)のとき右折する。
sub Line_Left()//左側のライントレース
{
SetSensor(SENSOR_2,SENSOR_LIGHT);
ClearTimer(0);
while(FastTimer(0)<=30){
if(SENSOR_2>=52){
OnFwd(OUT_A);
OnRev(OUT_C);
Wait(5);
Off(OUT_A);
ClearTimer(0);
}else if(SENSOR_2>=48){
OnFwd(OUT_A);
Wait(5);
Off(OUT_A);
ClearTimer(0);
}else if(SENSOR_2>=43){
OnFwd(OUT_C);
Wait(5);
Off(OUT_C);
ClearTimer(0);
}else if(SENSOR_2>=41){
OnFwd(OUT_C);
OnRev(OUT_A);
Wait(5);
Off(OUT_AC);
}
}
Off(OUT_AC);
}
sub Line_Right()//右側のライントレース
{
SetSensor(SENSOR_2,SENSOR_LIGHT);
ClearTimer(0);
while(FastTimer(0)<=30){
if(SENSOR_2>=52){
OnFwd(OUT_C);
OnRev(OUT_A);
Wait(5);
Off(OUT_AC);
ClearTimer(0);
}else if(SENSOR_2>=48){
OnFwd(OUT_C);
Wait(5);
Off(OUT_C);
ClearTimer(0);
}else if(SENSOR_2>=43){
OnFwd(OUT_A);
Wait(5);
Off(OUT_A);
ClearTimer(0);
}else if(SENSOR_2>=41){
OnFwd(OUT_A);
OnRev(OUT_C);
Wait(5);
Off(OUT_AC);
}
}
Off(OUT_AC);
}
円上をライントレースする場合、基本のライントレースでは内輪差の関係で交差点の認識ができないため、円の部分だけ、別のサブルーチンを作成した。
線の左側では、薄い白(≧48)のとき右旋回し、薄い黒(≧43)のとき左旋回する。
線の右側では、薄い白(≧48)のとき左旋回し、薄い黒(≧43)のとき右旋回する。
sub Line_Lefts()//左側のライントレース
{
SetSensor(SENSOR_2,SENSOR_LIGHT);
ClearTimer(0);
while(FastTimer(0)<=20){
if(SENSOR_2>=48){
OnFwd(OUT_A);
Wait(5);
Off(OUT_A);
ClearTimer(0);
}else if(SENSOR_2>=43){
OnFwd(OUT_C);
Wait(5);
Off(OUT_C);
}
}
Off(OUT_AC);
}
sub Line_Rights()//右側のライントレース
{
SetSensor(SENSOR_2,SENSOR_LIGHT);
ClearTimer(0);
while(FastTimer(0)<=20){
if(SENSOR_2>=48){
OnFwd(OUT_C);
Wait(5);
Off(OUT_C);
ClearTimer(0);
}else if(SENSOR_2>=43){
OnFwd(OUT_A);
Wait(5);
Off(OUT_A);
}
}
Off(OUT_AC);
}
***交差点判断 [#udcc6df4]
円上以外のライントレースにおいて、通常であれば黒(≧41)を認識したら旋回し、黒でない部分に移動するはずだが、交差点においては黒い部分の時間が増える。そのため、while文の中に(FastTimer(0)<=30)を入れると、0.3秒より多くの時間同じ色を認識したらライントレースをやめるプログラムとなり、交差点を認識し止まることができる。&br;
円上のライントレースでも同様に薄い黒(≧43)を認識したら旋回し、薄い黒でない部分に移動するはずだが、交差点においては薄い黒の部分の時間が増える。そのため、while文の中に(FastTimer(0)<=20)を入れると、0.2秒より多くの時間同じ色を認識したらライントレースをやめるプログラムとなり、交差点を認識し止まることができる。
円上以外のライントレースにおいて、通常であれば黒(≧41)を認識したら旋回し、黒でない部分に移動するはずだが、交差点においては黒い部分の時間が増える。そのため、while文の中に(FastTimer(0)<=30)を入れ、黒以外の色のif文にClearTimer(0);を入れることで、0.3秒より多くの時間黒を認識したらライントレースをやめるプログラムとなり、交差点を認識し止まることができる。&br;
円上のライントレースでも同様に薄い黒(≧43)を認識したら旋回し、薄い黒でない部分に移動するはずだが、交差点においては薄い黒の部分の時間が増える。そのため、while文の中に(FastTimer(0)<=20)を入れ、薄い白のif文にのみClearTimer(0);を入れることで、0.2秒より多くの時間薄い黒を認識したらライントレースをやめるプログラムとなり、交差点を認識し止まることができる。
**メインプログラム [#ca9db545]
#ref(./IMG_8135.jpg,70%,コースの図)
※Line_Left→黄色、Line_Right→赤色、 Line_Lefts→緑色、Line_Rights→青色
センサーが前輪の間にある関係で、90°に曲がるときは一度前進してから曲がることで正確に曲がることができる
地点H〜Gにかけての曲線は途中まで線の右側をトレースし、途中から線の左側をトレースすることで確実にライントレースできる。
・AからB
Line_Right();
cross_stop;
go_straight(30);
TURN_RIGHT(65);
・BからJ
Line_Right();
cross_stop;
hold_can;
TURN_LEFT(50);
・JからK
Line_Lefts();
cross_stop;
・KからL
go_straight(30);
Line_Lefts();
cross_stop;
・LからI
go_straight(30);
Line_Lefts();
cross_stop;
・IからH
go_straight(30);
TURN_LEFT(50);
Line_Left();
cross_stop;
go_straight(60);
TURN_LEFT(65);
・HからG
Line_Right();
cross_stop;
go_straight(30);
Line_Left();
cross_stop;
go_straight(30);
TURN_LEFT(65);
Line_Left();
cross_stop;
go_straight(30);
TURN_RIGHT(65);
・GからF
Line_Left();
cross_stop;
TURN_RIGHT(50);
・FからD
Line_Rights();
cross_stop;
go_straight(30);
Line_Rights();
cross_stop;
TURN_LEFT(65);
releace_can;
TURN_RIGHT(130);
・DからC
Line_Right();
cross_stop;
go_straight(30);
TURN_RIGHT(65);
Line_Right();
cross_stop;
・CからA
go_straight(30);
Line_Right();
Off(OUT_ABC);
*まとめ [#ocdabd54]
**課題 [#leb45e01]
光センサーの位置が前輪の間にあったために、しっかり線を追うことはできたものの、動きの誤差が生じてしまったため、プログラミングが簡潔なものにならなかったように思う。設計がいかに重要であるかが分かった。
**感想 [#b7394c33]
今回もギリギリであったが、完成することができてよかった。こうやって完成することができたのも、まわり方々の手助けがあったからだと強く思う。次回の課題3では少しでもチームに貢献できるように努力したい。