- 追加された行はこの色です。
- 削除された行はこの色です。
目次
#contents
*はじめに [#lfc82429]
今回の課題はライントレースロボットで、図のようなコースを決められた順路を通り、途中においてあるピンポン玉をゴールまで運ぶロボットを作るというものでした。僕はC地点からA地点へ (Q交差点では直進、P三叉路では右折)を通るロボットを作りました。&br;
今回は前回と違い、本体の作成は簡単でしたが、プログラムに時間がかかりました。
#ref(./無題.png,コース)
*ロボット本体 [#n90d2dd9]
**全体 [#s04d8fe6]
#ref(./S__35348483.jpg,around,全体)
#ref(./S__36487170.jpg,around,全体)
基本の車の形のものにアームとセンサーを付けた形になっています。&br;
センサーが車体から遠いと一度の動作でセンサーが動く距離が大きくなり、曲がり切れないところがあったのでなるべく車体から近いところにしました。&br;
#clear
**アーム [#o870d1e6]
#ref(./image.jpg,around,アーム)
モーター1つで開閉ができるようにしました。モーターを直接つなぐと動きが早すぎたのでギア比を考えてゆっくり動くようにしています。&br;
プログラムをこのまま送れるように送受信センサのところには棒が一本しか通らないようにしています。アームとセンサはまとめて本体から簡単に取り外しができるようにもしています。
#clear
*プログラム [#y060cbef]
#define turnleft OnFwd(OUT_C);OnRev(OUT_A); //左旋回
#define left OnFwd(OUT_C);Off(OUT_A); //左に曲がる
#define right OnFwd(OUT_A);Off(OUT_C); //右に曲がる
#define turnright OnFwd(OUT_A);OnRev(OUT_C); //右旋回
#define stop2sec Off(OUT_AC);Wait(200); //2秒止まる
//ライントレース用の関数
void linetrase(int t){
ClearTimer(0);
while(FastTimer(0)<t){
if(SENSOR_3<36){
turnright;
}else if(SENSOR_3<39){
right;
Wait(2);
}else{
if(SENSOR_3<47){
OnFwd(OUT_AC);
Wait(3);
}else if(SENSOR_3<50){
left;
Wait(2);
}else{
turnleft;
}
ClearTimer(0);
}
}
}
task main ()
{
SetSensor(SENSOR_3,SENSOR_LIGHT);
int count=0;
ClearTimer(1);
while(count <= 1){
linetrase(28);
if(FastTimer(1)>500||count==0){
count++;
}
ClearTimer(1);
}
stop2sec;
left;
OnFwd(OUT_B);
Wait(20);
Off(OUT_C);
Wait(100);
Off(OUT_B);
linetrase(21);
stop2sec;
linetrase(28);
Off(OUT_AC);
OnRev(OUT_A);
Wait(30);
Off(OUT_A);
OnRev(OUT_B);
Wait(50);
Off(OUT_B);
OnFwd(OUT_AC);
Wait(60);
OnRev(OUT_AC);
Wait(60);
Off(OUT_AC);
}
*説明 [#h2bcbc39]
**定義 [#e8076282]
まずは以下の通り全方向に動くための定義をしました。
#define turnleft OnFwd(OUT_C);OnRev(OUT_A); //左旋回
#define left OnFwd(OUT_C);Off(OUT_A); //左に曲がる
#define right OnFwd(OUT_A);Off(OUT_C); //右に曲がる
#define turnright OnFwd(OUT_A);OnRev(OUT_C); //右旋回
#define stop2sec Off(OUT_AC);Wait(200); //2秒止まる
さらに交差点で2秒止まるための定義をしました。
#define stop2sec Off(OUT_AC);Wait(200); //2秒止まる
そして、交差点までライントレースするプログラムを関数で書きました。引数を入れたかったのでサブルーチンではなく関数を使っています。引数は一度にどれだけ右に曲がったら交差点と判断するのかを入れられるようにしています。これにより、様々な曲がり角に対応できるようになりました。&br;
Wait関数を少し入れることでなるべく滑らかに動くようにしています。
void linetrase(int t){
ClearTimer(0);
while(FastTimer(0)<t){
if(SENSOR_3<36){
turnright;
}else if(SENSOR_3<39){
right;
Wait(2);
}else{
if(SENSOR_3<47){
OnFwd(OUT_AC);
Wait(3);
}else if(SENSOR_3<50){
left;
Wait(2);
}else{
turnleft;
}
ClearTimer(0);
}
}
}
**動作 [#ef62e8b7]
#ref(./コース.png,around,right,コース)
右の図の様にライントレースしました。&br;
+右に大きく曲がる場所が交差点までに一度あるので、一度目の大きく曲がるところはスルーするようになっています。曲がる時間が長く、二度認識してしまうことがあったので、50秒以内には二度目を認識しないようにしました。
int count=0;
ClearTimer(1);
while(count <= 1){
linetrase(28);
if(FastTimer(1)>500||count==0){
count++;
}
ClearTimer(1);
}
+2度目の大きく曲がるところを認識したら、2秒間止まってから線を越えます。そのあとはアームでピンポン玉をはさみます。
stop2sec;
left;
OnFwd(OUT_B); //アームを閉じる
Wait(20);
Off(OUT_C);
Wait(100);
Off(OUT_B);
+ライントレースを再び初めて、角を認識したら2秒間止まる。
linetrase(21);
stop2sec;
+ライントレースを再び始め、角を認識したら後ろに下がり、アームを開いてシュートする。
linetrase(28);
Off(OUT_AC);
OnRev(OUT_A); //後ろに下がる
Wait(30);
Off(OUT_A);
OnRev(OUT_B); //アームを開く
Wait(50);
Off(OUT_B);
OnFwd(OUT_AC); //シュートする
Wait(60);
OnRev(OUT_AC);
Wait(60);
Off(OUT_AC);
#clear
*結果・感想 [#x983fbb1]
前回の課題の時より慣れていたためかすぐに完成させることができました。&br;
実際のロボット動きは動画にしたので見ていただきたいです。[[動画はこちら:https://www.youtube.com/watch?v=vz3ReqVNWz8]]&br;
グループで製作ということで、3人で相談しあいながらなんとか形にできたのは大きな達成感を得ることになりました。&br;