- 追加された行はこの色です。
- 削除された行はこの色です。
[[2018a/Member]]
#contents
* 課題[#w3f30b24]
**ライントレースロボットの製作 [#v30a912c]
幅2ミリの黒線をトレースするロボットを作る
**以下のコースを進み,課題を達成させる [#u99b98ee]
#ref(./コース.png,70%,コース)
**以下のコースを進み,課題を達成させる(課題としてはAコース) [#u99b98ee]
#ref(./コース.png,70%,コース)
1. Aをスタート
2. Bを直進
3. Cで一時停止の後、直進
4. Dで一時停止の後、Xの空き缶をキャッチしてD地点に戻る
5. DからEに向かい、Eを直進
6. Fを左折
7. Gで一時停止の後、左折
8. Hで一時停止の後、右折
9. Iで一時停止の後、右折
10. Lを直進
11. Kを直進
12. Jで一時停止の後、空き缶をYに置きてJに戻りBに向かう
13. Bで一時停止の後、左折
14. Aで停止
(一時停止の指定がある場所は、1秒間停止すること)
* 製作したロボット[#wbc0bea6]
小回りを利かせるために2輪ローバーにした.また,そのためのバランサーの先に光センサーを取り付けた.缶をつかむ機構はクワガタのような型にした.開閉にはラックを前後させ,2本の角に支点を設けることで動かす機構を採用した.
#ref(./)
小回りを利かせるために2輪ローバーにした.また,そのためのバランサーの先に光センサーを取り付けた.光センサーの高さは床から3mm程の位置になるよう調整した.缶をつかむ機構はクワガタのような型にした.開閉にはラックを前後させ,2本の角に支点を設けることで動かす機構を採用した.
**全体像 [#k59e399b]
#ref(./全体像.jpg,50%,全体像)
**車体下部 [#nd75eca7]
#ref(./車体下.jpg,40%,車体下部)
**上から見た車体 [#yf0066e9]
#ref(./車体上.jpg,40%,車体上)
**つかみ部のラック [#i5815de7]
#ref(./つかみ部.jpg,40%,つかみ部)
**つかみ部の動き方 [#ie2da74d]
&ref(./アーム1.png,70%,作動前);
&ref(./アーム2.png,70%,作動後);
* 製作したプログラム[#i91f01f2]
A端子が左車輪,B端子がつかみ部の開閉,C端子が右車輪を制御する.また,2番端子に光センサーを接続している.
**ライントレースプログラムの仕組み [#sf71d29d]
光センサーは赤色光を照射し,その反射光を検知し,明るいほど高い数値を表す.ライントレースのプログラムはそれを利用して,黒い部分と白い部分の中間をたどるように閾値を設定し,それぞれの明るさに応じた行動をとらせる.また,機体の向きを修正する時間がある値以上(FastTimer(0)<=55/2)になったらそこを交差点と判断するようにする.(これは直線や曲線ではこの時間以内に次の動作に入りFastTimer(0)がリセットされるが,交差点ではこの時間以内に次の動作に入らず,FastTimer(0)がリセットされないからである.)今回は光センサーの値が45となるところを基準とし,+ー7以上で急旋回,+−5以上で曲がり,−5から+5の間で直進するように設定している.また,急旋回する向き・曲がる向きは,右側トレースの時は+5以上で左,−5以下で右に,左側トレースの時は+5以上で右,−5以上で左となる.
**使用したマクロ [#ce259723]
#define x 45 //閾値の設定
#define r 65 //90度の旋回時間(roll time)
#define g 35 //缶をつかみに・離しに行くまでの時間(go time)
**サブルーチン・右側トレース [#qb0298bf]
sub line2()
{
ClearTimer(0);
while(FastTimer(0)<=55/2){ //交差点を判断する値
if(SENSOR_2>x+7){ //光センサーの値が閾値+7以上だったら左に急旋回
OnRev(OUT_A);
OnFwd(OUT_C);
ClearTimer(0);
}else if(SENSOR_2>=x+5){ //光センサーの値が閾値+5以上だったら左に曲がる
Off(OUT_A);
OnFwd(OUT_C);
ClearTimer(0);
}else if(SENSOR_2>x){ //光センサーの値が閾値より大きかったら直進
OnFwd(OUT_AC);
ClearTimer(0);
}else if(SENSOR_2>=x-5){ //光センサーの値が閾値-5以上だったら右に曲がる
Off(OUT_C);
OnFwd(OUT_A);
ClearTimer(0);
}else{ //それ以外だったら右に急旋回
OnRev(OUT_C);
OnFwd(OUT_A);
}
}
Off(OUT_AC); //交差点が来たらとまれ
PlaySound(SOUND_DOUBLE_BEEP); //停止と同時に音を出せ
}
**サブルーチン・左側トレース(基本) [#eb284728]
sub line()
{
ClearTimer(0);
while(FastTimer(0)<=55/2){ //交差点を判断する値
if(SENSOR_2>x+7){ //光センサーの値が閾値+7以上だったら右に急旋回
OnRev(OUT_C);
OnFwd(OUT_A);
ClearTimer(0);
}else if(SENSOR_2>=x+5){ //光センサーの値が閾値+5以上だったら右に曲がる
Off(OUT_C);
OnFwd(OUT_A);
ClearTimer(0);
}else if(SENSOR_2>x){ //光センサーの値が閾値より大きかったら直進
OnFwd(OUT_AC);
ClearTimer(0);
}else if(SENSOR_2>=x-5){ //光センサーの値が閾値-5以上だったら左に曲がる
Off(OUT_A);
OnFwd(OUT_C);
ClearTimer(0);
}else{ //それ以外だったら右に急旋回
OnRev(OUT_A);
OnFwd(OUT_C);
}
}
Off(OUT_AC); //交差点が来たらとまれ
PlaySound(SOUND_DOUBLE_BEEP); //停止と同時に音を出せ
}
**サブルーチン・離すプログラム [#of5668e3]
sub release()
{
OnFwd(OUT_C); //左に曲がる
OnRev(OUT_A);
Wait(r);
Off(OUT_AC);
OnFwd(OUT_AC); //前進
Wait(g);
Off(OUT_AC);
OnRev(OUT_B); //腕を開く
Wait(10);
Off(OUT_B);
OnRev(OUT_AC); //後退
Wait(g);
Off(OUT_AC);
OnRev(OUT_C);180度旋回
OnFwd(OUT_A);
Wait(r*2);`
Off(OUT_AC);
}
**サブルーチン・掴むプログラム [#ab92bbb8]
sub cat()
{
OnFwd(OUT_AC); //前進
Wait(g);
Off(OUT_AC);
OnFwd(OUT_B); //腕を閉じる
Wait(10);
Off(OUT_B);
OnRev(OUT_AC); //後退
Wait(g);
Off(OUT_AC);
}
**メインプログラム [#fcaf5452]
task main()
{
SetSensor(SENSOR_2,SENSOR_LIGHT); //光センサーを定義
OnFwd(OUT_AC);
OnFwd(OUT_AC); //最初の黒線を乗り越える
Wait(30);
Off(OUT_AC);
line();
line();
Wait(100); //until C
OnFwd(OUT_AC);
OnFwd(OUT_AC); //Cの黒線を乗り越える
Wait(70);
Off(OUT_AC);
line();
Wait(100); //until D
cat();
cat(); //缶をつかむ
Wait(100); //Dで停止
OnFwd(OUT_C); //D turn
OnRev(OUT_A);
Wait(r);
Off(OUT_AC);
Wait(100);
line(); //until E
line(); //until G
OnFwd(OUT_C); //Gで曲がる
OnRev(OUT_A);
Wait(r);
Off(OUT_AC);
Wait(100);
line();
line();
Wait(100); //until H
OnFwd(OUT_C); //Hで曲がる
Off(OUT_C);
Wait(r);
Off(OUT_AC);
line();
Wait(100); //until I
OnFwd(OUT_A); //Iで曲がる
Off(OUT_C);
Wait(r/2);
Off(OUT_AC);
line2(); //ここから右トレース
Wait(100); //until L
line2();
Wait(100); //until K
line2();
Wait(100); //until J
release();
release(); //缶を離す
line();
line(); //ここから左トレース
Wait(100); //until B
OnFwd(OUT_C);
OnRev(OUT_A);
Wait(r);
Off(OUT_AC); //Bで曲がる
line(); //until A
OnFwd(OUT_AC); /枠内へ
Wait(300);
Off(OUT_AC); //停止
}
* まとめ[#wf4cffdf]
**車体について [#i6fc5bfb]
センサーやタイヤの劣化による誤差によって1回1回の結果が変わってしまった.また,つかむ機構が走行中にゆるんでしまい,缶が途中でこぼれてしまうことがあった.劣化のほうはどうにもならないが,ゆるんでしまうのはモーター側のトルクを大きくすることで改善できると思う.次に,缶をつかみに行く際に,最初はタッチセンサーを使用しようと考えていたが,缶が軽すぎて反応しなかった.そのため,タッチセンサーを反応しやすくする必要があるが,その場合車体の振動で反応してしまうことが考えられる.そのため,タッチセンサー以外の使用が望ましい.しかしそれ以外の面ではおおむね良好であったと思う.
**プログラムについて [#ca2ee730]
ライントレースのサブルーチンを右側トレース・左側トレースの二つを作ることにより,場所に応じて好ましいほうを選択できるようになり,片側だけでは突破の難しかったところを突破できた.この時の閾値の調整に手間取った.しかし直線の途中で止まってしまうことがあったが,同じプログラムを重ねることで解決した.そのほかには特に問題はなく,しっかりと動いてくれたので良かった.