[[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]
ライントレースのサブルーチンを右側トレース・左側トレースの二つを作ることにより,場所に応じて好ましいほうを選択できるようになり,片側だけでは突破の難しかったところを突破できた.この時の閾値の調整に手間取った.しかし直線の途中で止まってしまうことがあったが,同じプログラムを重ねることで解決した.そのほかには特に問題はなく,しっかりと動いてくれたので良かった.


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS