[[2018a/Member]]
*目次 [#z6c42f96]
#contents
*課題2 [#pd053fea]
製作したコースをライントレースし、缶を移動させるロボットの製作
*ロボの説明 [#x1cf7e1f]
二つのモータACが左右のタイヤを回す。またモータBは缶を運ぶ機構に用いた。
#ref(全体像.jpg)
ロボットの前方には、ライントレースを行うための光センサがついている。
#ref(前.jpg)
缶を運ぶ機構は虫取り網をもとに製作した。
網をかぶせるようにすることで掴めないというミスを減らすことが出来る。
網のふちを大きめに作ったことで誤差があっても缶を掴むことができるようになっている。さらに、缶を離す時も網のふちが大きいため缶に当たらず、倒れることがない。
また、網の高さをパーツを組み合わせて調節したことで常に缶を押していても缶が倒れることなく運ぶことが出来る。
#ref(上から.jpg)
#ref(横から.jpg)
*プログラムの説明 [#cd5339dc]
今回は第二コースを走るプログラムを書いた。内容は以下の通りである。
1.Aをスタート
2.Bを右折
3.Jで一時停止の後、Yの空き缶をキャッチしてJに戻る
4.JからKに向かい、Kを直進
5.Lを直進
6.Iを左折
7.Hで一時停止の後、左折
8.Gで一時停止の後、右折
9.Fで一時停止の後、右折
10.Eを直進
11.Dで一時停止の後、空き缶をXに置いてDに戻り、Cに向かう
12.Cで一時停止の後、直進
13.Bを直進
14.Aで停止
#ref(レースコース.png)
***defineの説明[#e93143b6]
今回は右折・左折・右旋回・左旋回と、しきい値、直進・停止、右に曲がる・左に曲がるをdefineで用意した。
最初の5つはサブルーチン用。
残りの4つはプログラム用で分けてある。
特に、旋回については数値がプログラムの中で変わるので、サブルーチンに支障が出ないように分けている。
#define USETSU OnFwd(OUT_A);Off(OUT_C); //右折
#define SASETSU OnFwd(OUT_C);Off(OUT_A); //左折
#define MIGI_SEN OnFwd(OUT_A);OnRev(OUT_C); //右旋回
#define HIDARI_SEN OnFwd(OUT_C);OnRev(OUT_A); //左旋回
#define SIKII 45 //しきい値
#define TEISI Off(OUT_AC);Wait(100);PlaySound(SOUND_DOUBLE_BEEP); //停止後に音が鳴る
#define ZENSIN OnFwd(OUT_AC); //前進
#define MAGARU_R OnFwd(OUT_A);OnRev(OUT_C);Wait(60);Off(OUT_C); //右に曲がる
#define MAGARU_L OnFwd(OUT_C);OnRev(OUT_A);Wait(60);Off(OUT_C); //左に曲がる
***サブルーチンの説明 [#n7b916e2]
サブのプログラムは3つあり、ライントレース・缶を取る・缶を置くの3つである。
ライントレースのプログラム
しきい値45をdefineで用意したことにより、プラスマイナスを付けて数値を簡単に変えられるようにした。
右トレースなので、しきい値+5で左旋回、しきい値+3で左折、しきい値と同じで直進、‐3で右折、それ以下で右旋回して停止となっている。
sub trace(){
SetSensor(SENSOR_1, SENSOR_LIGHT);
ClearTimer(0);
while(FastTimer(0)<=25){
if(SENSOR_1 > SIKII+5){
HIDARI_SEN //左旋回する
ClearTimer(0); // timerを0にする
}else if(SENSOR_1 > SIKII+3){
SASETSU //左折する
ClearTimer(0); // timerを0にする
}else if(SENSOR_1 > SIKII){
OnFwd(OUT_AC); //前進
ClearTimer(0); // timerを0にする
}else if(SENSOR_1 > SIKII-3){
USETSU //右折する
ClearTimer(0); //timerを0にする
}else{
MIGI_SEN //右旋回する
}
Off(OUT_AC); //止まる
}
}
缶を持ち上げるプログラム
sub kan_toru(){
OnFwd(OUT_AC); //前進
Wait(0);
Off(OUT_AC); //止まる
OnFwd(OUT_B); //アームを動かす
Wait(25); //缶を取る
Off(OUT_B); //アームを止める
OnRev(OUT_AC); //後進
Wait(0);
Off(OUT_AC); //止まる
}
缶を置くプログラム
sub kan_oku(){
OnFwd(OUT_AC); //前進
Wait(0);
Off(OUT_AC); //止まる
OnRev(OUT_B); //アームを上げる
Wait(25); //缶を置く
Off(OUT_B); //アームを止める
OnRev(OUT_AC); //後進
Wait(0);
Off(OUT_AC); //止まる
}
***交差点の検出 [#y25f9415]
サブルーチンのプログラムより、交差点(T字路も含む)に到着するまでトレースを続ける。黒いラインの上に光センサが乗ることでセンサの値が小さくなり右旋回を始める。while文の中に(FastTimer(0)<=25)を入力してある。
もし直線や曲線をトレースしていれば(FastTimer(0)<=25)の秒間内に曲がることでき車体の角度の修正が可能となり、黒い線の上にずっといるということはない。しかし、交差点では右旋回を続けても右側に線が続く(これはコースの形を見れば明らかである)ので(FastTimer(0)<=25)の秒間内に黒い線の上から抜け出せない。このためタイムオーバーにより停止する。
つまり、この値になるまで右旋回し、かつその間ずっと黒が続くのは交差点なのでwhile文により停止する。
よって、交差点を検出し止まることができるようになっている。
***メインプログラム [#p066acb1]
メインプログラムは次の通りである。
task main(){
trace(); //Aをスタート
OnFwd(OUT_AC); //切り返す
Wait(50);
MAGARU_R; //Bを右折
trace();
TEISI; //Jで一時停止
kan_toru(); //缶を取る
ZENSIN;
Wait(10);
MAGARU_L; //Jを左折
ClearTimer(1);
while(FastTimer(1) <= 2400){
trace();
}
OnFwd(OUT_AC); //切り返す
Wait(30);
MAGARU_L; //Iを左折
trace();
TEISI; //Hで一時停止
OnFwd(OUT_AC); //切り返す
Wait(30);
MAGARU_L; //Hで左折
trace();
TEISI; //Gで一時停止
OnFwd(OUT_AC); //切り返す
Wait(30);
MAGARU_R; //Gを右折
trace();
TEISI; //Fで一時停止
MAGARU_R; //Fを右折
trace();
ZENSIN; //Eを通過
trace();
TEISI; //Dで一時停止
MAGARU_L; //Dで左折
Wait(30);
kan_oku(); //缶を置く
MAGARU_L; //Dを回れ左
Wait(120);
trace();
OnFwd(OUT_AC); //切り返す
Wait(30);
trace();
TEISI; //Cで一時停止
ZENSIN;
trace();
ZENSIN; //ゴール!
}
*結果 [#o6aa08b1]
細かいカーブを曲がりきることができなかった。これは、左右のタイヤの幅が大きすぎたため小回りが利かなかったと考えられる。
また、線の右側と左側のトレースを使い分けるプログラムは大変だと思い、常に線の右側をトレースするようにしたのだが、うまく走れない箇所が多く、かえって難しくなってしまった。