- 追加された行はこの色です。
- 削除された行はこの色です。
[[2015b/Member]]
目次
#contents
*課題内容 [#w3767585]
・ライントレースカーの作成
#ref(./2015b-mission2.png,60%)
上の図が課題のコースです。
私は、A地点からB地点へ行くプログラムを作成しました。具体的には、A地点→P直進→Q直進→Q右折→P右折→Q左折→P左折→B地点の順です。
*ロボット本体 [#f282aa06]
&ref(./robo.png,40%);
&ref(./robo1.png,34%);
上の写真がロボットの全体です。赤い丸が付いているのが光センサーです。今回の課題はラインに沿て走行するものです。なので、光センサーを使用しました。光センサーは自ら光を出し、光量の測定もします。黒と白では反射する光量が異なります。それにより、線上か否かを判断します。
*トレースの方法 [#f25e7892]
私は黒と白の間を基準に走行する方法で行いました。線は左から判断します。
明るさを5段階に分けました。理由としては、滑らかな動きをさせることにより時間を短縮させることができるからです。
分け方は、最も暗いときはその場で左回転、暗いときは斜め左前へ、中間のときは前進、明るいときは斜め右前へ、最も明るいときはその場で右回転の分け方です。
1,2回目の交差点では斜め左前に進みます。理由はモータの力の加減で線の右に行くことがあるからです。
3,4回目は左奥に進みます。こうすることで線を左から処理することができます。
線がきれいではないため途中で交差点の処理をすることがあります。その為、タイマーを使い処理をさせないようにもしています。
*プログラム [#z455f13e]
同じ動作が多いため先にマクロで定義しました。光量の中間値は、黒と白の光量を調べその中間値を定義しました。音は、交差点をしっかり判断しているか調べるために定義しました。
#define go(p) Off(OUT_BC);OnFwd(OUT_BC,p); //前進
#define right(p,P) Off(OUT_BC);OnFwd(OUT_C,p);OnFwd(OUT_B,P); //右移動
#define left(p,P) Off(OUT_BC);OnFwd(OUT_B,p);OnFwd(OUT_C,P); //左移動
#define THE 53 //光量の中間値
#define tmax 115 //交差点の判断
#define Mu PlaySound(SOUND_CLICK); //音
・交差点でない場合のプログラム
task main()
{
SetSensorLight(S1); //光センサー
long t0=0,t=0; //変数の宣言と初期化
int c=0,x=0,y=0;
t0=CurrentTick();
t=CurrentTick();
int c=0,x=0,y=0; //交差点処理に使用
t0=CurrentTick(); //交差点判断での時間
t=CurrentTick(); //処理を行わない時間
while(true){ //繰り返し
while(CurrentTick()-t0<tmax){ //交差点か否かの判断
if(SENSOR_1<THE){ //黒の場合
if(SENSOR_1>35){ //白よりの黒の場合
left(45,10);
t0=CurrentTick();} //交差点でないため時間(t0)を初期化
else if(SENSOR_1<35){ //最も黒い場合
left(35,-40);
}
}
else if(SENSOR_1>THE){ //白の場合
if(SENSOR_1<65){ //黒よりの白の場合
right(45,10);
t0=CurrentTick();}
else if(SENSOR_1>65){ //最も白い場合
right(40,-40);
t0=CurrentTick();}
else{
go(50);t0=CurrentTick();} //中間値の場合
}}
・交差点かどうか判断するプログラム
if(c<=1){ //交差点を直進
Mu;Off(OUT_BC);Wait(1000);right(30,50);
・交差点かどうか判断するプログラム。
交差点の処理をするとカウントが増えていく。cはPとQを直進したときに、xはPとQを右折したときに、yは最後のPを左折したときにカウントされる。
if(c<=1){ //交差点を直進 2回行う
Mu;Off(OUT_BC);Wait(1000);right(30,50); //音を鳴らし交差点を直進
Wait(300);c++;x++;y++;t0=CurrentTick();,t=CurrentTick();}
タイマーも条件式に加えている理由は、コースがあまりきれいに描けなかったので円の中で交差点の処理を時々してしまうためです。上のプログラムで時間(t)を初期化しているのは、円の中を走行する時間をはかだけにすることで、設定が容易になるからです。
else if(x==2&&CurrentTick()-t>6500){ //交差点を右折 1回目
Mu;Off(OUT_BC);Wait(1000);right(40,-50);
Wait(300);go(30);
Wait(500);x++;y++;t0=CurrentTick();}
else if(y==3){ //交差点を右折 2回目
Mu;Off(OUT_BC);Wait(1000);right(50,-20);Wait(400);go(30);
else if(x==2&&CurrentTick()-t>6500){ //xのカウントが2で円内時間が6.5秒以下の
Mu;Off(OUT_BC);Wait(1000); //時、処理を行う。交差点を右折
right(40,-50);Wait(300);go(30);Wait(500); //音を鳴らし交差点を右折
x++;y++;t0=CurrentTick();}
else if(y==3){ //yのカウントが3の時処理を行う。交差点
Mu;Off(OUT_BC);Wait(1000); //を右折
right(50,-20);Wait(400);go(30); //音を鳴らし交差点を右折
Wait(500);y++;t0=CurrentTick();}
上のプログラムだけでは、最後の交差点Pを判断しないのでPを交差点だと処理させるプログラム。
else if(y==4&&CurrentTick()-t>20000){Mu;Off(OUT_BC);
Wait(1000);t0=CurrentTick();y++;}
else if(y==4&&CurrentTick()-t>20000){ //yのカウントが4で最後の交差点を抜けてか
Mu;Off(OUT_BC); //らの時間が20秒以下の時、処理を行う。
Wait(1000);t0=CurrentTick();y++;} //音を鳴らし交差点を左折
交差点だと判断しないプログラム
else{t0=CurrentTick();}
}}
*工夫点 [#kb29c14f]
線がきれいに描けなかったため円の中などの交差点以外の急な曲がり角で交差点の処理をしてしまいます。その為処理をさせないようにタイマーで制限をしました。
一つの定義の分で左右のタイヤを同時に動かせるようにすることで、細かい調整を可能とさせました。
*反省・感想 [#n1d85cd1]
工夫点としては、円の中などの交差点以外の急な曲がり角で交差点の処理をさせないためにタイマーを利用したことや、回転の移動で左右のタイヤを一文で処理させることにより柔軟性を持たせたことです。
反省点は、帰ってくるときのQを交差点として判断できなかったことです。Qの交差点は曲がりが急ではないので交差点の処理ができなかったと考えています。
今回の課題は書道ロボットと違いロボット自身が判断するプログラムを作らなければいけないためとても大変でした。更に、書道ロボットはロボットのできでもプログラムを安易にできました。私は機械関係なので主に機器を作る側になると思います。なので、できる限りプログラムを安易にできるような機器を作るよう心掛けていきたいです。