[[2018a/Member]]
目次
#contents

*課題2 [#xd5191b6]
下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットを作成せよ。 &br;
黒い線に沿って動き、350mlの空き缶(黄色で表示)を移動させるロボットを製作せよ。&br;
二つのコースがあり、自分はコース1を選択して作成した。&br;
下の図で青→緑→黄色の矢印の順で動き、緑の矢印上は空き缶を運んでいる。また、停止と書かれた交差点では、一時停止をしなければならない。&br;
課題について詳しくは[[こちら>2018a/Mission2]]。
#ref(./コース.png,70%,コース)


*ロボットの説明 [#wccbcd36]
**全体像 [#cded12c3]
レゴのクラフトガイドの作り方を参考に車輪、光センサーの取り付けをした。&br;
缶をつかむ機構は虫取り網の要領で囲って運ぶようにした。
#ref(./全体像.jpg,70%,全体像)

**つかむ機構 [#u0706100]
始めはモーターの動力を直でつないでアームを制御をしていたが、動きが早すぎて制御が難しいためモーターとアームとの軸の間に大きい歯車を入れて制御しやすくした。
#ref(./つかむところ.png,70%,つかむとこ)

*プログラムの説明 [#see65286]
**ライントレースの仕組み [#qfe27031]
コースの関係上左側のふちをライントレースするようにした。&br;
ライントレースをするうえで重要なのは光センサーである。黒の線上でも光センサーでは違う値を検出するため、検出された値に対応した動作をさせることでライントレースができる。&br;
私たちは白と黒の間の値を基準として、そのプラスマイナスで制御をおこなった。
#ref(./閾値.png,70%,閾値)
下の表にその値で行う動作を示す。
#ref(./動作表.png,80%,動作表)
***ライントレースのプログラム [#yd12d976]
上の表で整理した動作をマクロとして以下のように定義した。
 #define MIGISENKAI OnFwd(OUT_A);OnRev(OUT_C); //右旋回
 #define MIGIMAGARI OnFwd(OUT_A);Off(OUT_C); //右曲がり
 #define HIDARISENKAI OnFwd(OUT_C);OnRev(OUT_A); //左旋回
 #define HIDARIMAGARI OnFwd(OUT_C);Off(OUT_A); //左曲がり
 #define middle 45 //白と黒の境目の値

下にライントレースで使用したサブプログラムを記載する。
 sub Line() //ライントレース
 {
 SetSensor(SENSOR_1,SENSOR_LIGHT);
 ClearTimer(0);
 while(FastTimer(0)<=28) //左旋回が0.28秒以内の場合はループしなさい
 	{
 	if(SENSOR_1>middle+8)
 		{
 		MIGISENKAI
 		ClearTimer(0); //白だったら右旋回しなさい
 		}
 	else if(SENSOR_1>middle+6)
 		{
 		MIGIMAGARI
 		ClearTimer(0); //白っぽいなら右に曲がりなさい
 		}
 	else if(SENSOR_1>middle)
 		{
 		OnFwd(OUT_AC);
 		ClearTimer(0); //中間なら直進しなさい
 		}
 	else if(SENSOR_1>middle-4)
 		{
 		HIDARIMAGARI
 		ClearTimer(0); //黒っぽいなら左に曲がりなさい
 		}
 	else
 		{
 		HIDARIMAGARI //黒なら旋回しなさい←変更点!
 		}
 	}
 Off(OUT_AC); //とまれ
 }
このプログラムをよく見てもらうと真っ黒と感知したときの動作が上の表とは違い黒を感知したときの動作になっている。これは次に説明する交差点の判断で誤動作を減らすために変更したためである。また、whileでタイマーの値を使っているのも交差点の判断に必要なためである。


**交差点の判断 [#v748f15f]
交差点を認識させるにはライントレース中の真っ黒である時間によって認識させる。交差点に差し掛かると直線よりも真っ黒の時の時間が増加する。このターンにかかる時間が一定以上になった時にライントレースのプログラムを抜け次に対応する動作につなげる。私の作った機体では0.28秒が適正だった。以下に交差点時の様子を図で示している。
#ref(./交差点.png,40%,交差点)
ここでなぜライントレースのプログラムを変更したのか説明する。それは交差点の感知ができなかったためである。主な原因は二つだと考えられる。&br;
-タイヤの出力が大きいこと&br;
→交差点でもすぐに回転しトレースし続けてしまう。
-センサーの位置が車体から離れていること&br;
→交差点に対して車体が斜めに入ってしまいターンにかかる時間が減少してしまう。&br;
わかりずらいと思うので下の図にて補足する。
#ref(./光センサー問題.png,70%,問題)
#ref(./光センサー問題2.png,60%,問題点)
上の写真は実際の機体部の様子である。
**マクロ [#xf2cd6df]
ライントレースで使った以外に以下のマクロを定義した。
 #define go(time) OnFwd(OUT_AC);Wait(time);Off(OUT_AC); //time秒前進
 #define back(time) OnRev(OUT_AC);Wait(time);Off(OUT_AC); //time秒後退
 #define LEFT(angle) OnFwd(OUT_C);OnRev(OUT_A);Wait(angle);Off(OUT_AC); //angle度左折
 #define RIGHT(angle) OnFwd(OUT_A);OnRev(OUT_C);Wait(angle);Off(OUT_AC); //angle度右折
交差点を渡る時間や缶を取りに行く時間をその時々で調節できるようにした。

**サブプログラム [#efb4f59d]
ライントレースで使用したサブプログラムのほかに以下のプログラムを用意した。&br;
下のサブプログラムはGからH間のライントレースで使用するプログラムで、25秒間交差点の判断をしないでライントレースをするというプログラムである。GからH間は半径の小さいカーブが多く交差点と判断してしまうことが多いためこのようにして対処した。
 sub Line2() //特殊ライントレース
 {
 SetSensor(SENSOR_1,SENSOR_LIGHT);
 ClearTimer(0);
 while(FastTimer(0)<=2500) //GからH間のライントレース
 	{
 	if(SENSOR_1>middle+8)
 		{
 		MIGISENKAI //白だったら右旋回しなさい
 		}
 	else if(SENSOR_1>middle+6)
 		{
 		MIGIMAGARI //白っぽいなら右に曲がりなさい
 		}
 	else if(SENSOR_1>middle)
 		{
 		OnFwd(OUT_AC); //中間なら直進しなさい
 		}
 	else if(SENSOR_1>middle-4)
 		{
 		HIDARIMAGARI //黒っぽいなら左に曲がりなさい
 		}
 	else
 		{
 		HIDARISENKAI //黒なら旋回しなさい
 		}
 	}
 Off(OUT_AC);
 }

次のプログラムは真っ白を検知するまで左回転するプログラムである。これは交差点を感知してからライントレースのプログラムに入る際、真っ黒の範囲から出られず再び交差点と判断することを防ぐためである。下の図でも軽く説明する。

 sub TURN_LEFT() //白感知左曲がり
 {
 SetSensor(SENSOR_1,SENSOR_LIGHT);
 OnFwd(OUT_C);
 OnRev(OUT_A);
 until(SENSOR_1>=58); //真っ白を感知するまで待つ
 Off(OUT_AC); //停止
 }
#ref(./ライントレース開始.png,50%,ライントレース開始)

次のプログラムは缶をつかむプログラムと、離すプログラムである。

 sub CATCH() //つかむ
 {
 OnFwd(OUT_B);
 Wait(30);
 Off(OUT_B); 
 }


 sub RELEASE() //離す
 {
 OnFwd(OUT_B);
 Wait(30);
 Off(OUT_B);
 }



**メインプログラム [#t9cdc219]
 task main()
 {
 Line(); //A-C
 
 Wait(100); //停止地点
 
 go(40) //Cの交差点を渡りきるための直進
 
 Line(); //Cから
 
 GO_WHITE(); //C-Dの交差点
 
 LEFT(15) //白のとこまで回転させる。
 
 Line(); //白の値からライントレースを開始し、Dの交差点を感知する
 
 Wait(100); //停止位置
 
 go(10) //缶をつかむため所定の位置まで前進する。
 
 CATCH(); //つかむ
 
 Wait(100); //アームを下げ安定させるための時間
 
 back(28) //戻る<ここの値は前進時よりも大きい値でないと定位置に戻らなくなってしまう>
 
 Wait(40); //速く動き出すと誤作動するので少し時間を空ける
 
 TURN_LEFT();

実際にうまくいったのはここまでである。
次のライントレースから交差点でないのに停止してしまう問題が生じる。
 Line(); //D-E
 
 go(40) //E
 
 Line(); //E-F
 
 TURN_LEFT(); //白を感知させる
 
 Line(); //F-G
 
 Wait(100); //停止位置
 
 TURN_LEFT(); //白を感知させる
 
 Line2(); //G-H'<曲線の連続部分>
 
 Line(); //H'-H<曲線エリアから抜け出してHの交差点を感知>
 
 Wait(100); //停止位置
 
 RIGHT(90) //90度
 
 Line(); //H-I
 
 Wait(100); //停止位置
 
 Line(); //I-L
 
 go(40)
 
 Line(); //L-K
 
 go(40)
 
 Line(); //K-J
 
 Wait(100); //停止位置
 
 LEFT(90) //90度
 
 go(80) //所定の位置へ
 
 RELEASE(); //はなす
 
 back(80) //Jに戻る
 
 LEFT(90) //180度
 
 Line(); //J-B
 
 Wait(100); 
 
 go(30) //2cm+A
 
 TURN_LEFT();
 
 Line(); //B-A
 
 }


*まとめ [#q80da23d]
前回の課題1に比べ様々な問題に直面した。機体に関するトラブルが多くプログラムでそれをカバーするように努力した。結果として課題2を達成することはできなかったが、修正する能力が身についたと思う。
前回の課題1に比べ様々な問題に直面した。機体に関するトラブルが多くプログラムでそれをカバーするように努力した。結果として課題2を達成することはできなかったが、修正する能力が身についたと思う。&br;
今回の課題の制御は時間で調整しようとするとトラブルが多くなってしまう。光センサーによってより細かい制御を行えたら課題を達成できたかもしれない。特に缶をキャッチしに行くときの機体の角度が円の中心に向かっていなかった。これを解決するために真っ黒を感知するまで回転するといった制御が必要だったのかもしれないと思った。&br;
次の課題が最後なのでこれまで学んだことを生かして課題をクリアさせたい。

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS