[[2016a/Member]]
#contents
*今回の課題 [#vb924856]
今回の課題は下の画像の黒線の上を走ることでした
#ref(課題2.png)
私は画像の赤線で塗られている部分を走りました。~
言葉で説明すると~
C地点からA地点へ ~
C地点 → S左折 → P左折 → Q直進 → Q直進 → R右折 → P左折 → A地点~
また交差点では一秒静止し、音を鳴らすのがルールでした。~
私のルートでは交差点が6つありました。
*ロボットについて [#p47f6cd6]
今回のロボットは、前回の似顔絵ロボットを元に作成をしました。~
#ref(ライン2.JPG)
赤丸で囲んであるところに元はペンを上げ下げする機械があったのですが、そこに光センサーを置きました。~


#ref(ライン6.5.jpg)
前から見るとこんな感じになります。~
この機械の工夫したところは、歯車をかませスピードを落としたところです。
それにより、交差点などではスピードが出すぎて、交差点だと認識せずに曲がってしまうことがありませんでした。

*光センサーについて [#bae899bc]
光センサーは色の濃さを数値化し私たちに教えてくれるものです。~
今回では、数字が大きいほど白く、数字が小さいほど黒くなります。~

*プログラムについて [#y391940d]
今回のプログラムは多くの定義とサブルーチンを駆使していかにメインのタスクを見やすくするかをがんばりました。~
今回私は、黒と白の中間の値を設定し、ロボはその値よりも大きいか小さいかすると中間の場所に戻るようにプログラムしました。~
・定義したプログラム~


 #define THRESHOLD 45      //この値は中間の色です
 #define BRACK 37           //黒です
 #define DARK 36           //さらに暗い黒です
 #define WHITE 47          //白です
 #define left Off(OUT_A); OnFwd(OUT_C);    //左に曲がります
 #define right OnFwd(OUT_A); Off(OUT_C);    //右へ曲がります
 #define go_long OnFwd(OUT_AC);Wait(800);Off(OUT_AC);    //前に進みます(長い時間)
 #define go OnFwd(OUT_AC);Wait(200);Off(OUT_AC);       //前に進みます(短い時間)
 #define right_senkai OnFwd(OUT_C); OnRev(OUT_A);      //右への旋回です
 #define left_senkai OnFwd(OUT_A);OnRev(OUT_C);       //左への旋回です
 #define STEP 1                 //0.01秒の間隔でロボが値を測定してタスクを行います
 #define short_break Off(OUT_AC);Wait(100);      //交差点で止まるときのです

・サブルーチン~
・ラインの右側をトレースをするためのサブルーチン

 sub line_followR()
 {
 int zk=0;      //交差点を確認したときに数が増えるカウンター
   
 SetSensor(SENSOR_3,  SENSOR_LIGHT);
    ClearTimer(0);
 
    while(zk==0) {          //カウンターが0の時この中身を繰り返します
       while(FastTimer(0)>100);   //1秒以上感知するタイマー感知すると下のif文を行う
       while(FastTimer(0)>100);   //タイマーで1秒以上感知すると下のif文を行うはずだった
            if (SENSOR_3 < DARK){   //黒を1秒以上感知すると交差点と見なす
                 short_break;
        PlaySound(SOUND_DOUBLE_BEEP);   //1秒停止し音を鳴らす
          zk=1;          //カウンターが1の時このサブルーチンを終わり次の動作へ移ります
        }else if (SENSOR_3<BRACK){
                  right_senkai;         //センサーが37以下を感知したとき右旋回
                  ClearTimer(0);       //毎回タイマーをリセットするため必要
            }else if (SENSOR_3 < THRESHOLD){
                 left;             // センサーが45以下を感知したとき左へ
                 ClearTimer(0);
            }else if(SENSOR_3> THRESHOLD) {
                 right;             //センサーが45以上を感知したとき右へ
                   ClearTimer(0);
              }
            Wait(STEP);
         }
     }

最初にカウンター(zk)を設置していなかったため次の動作に移りませんでした。~
ただサブルーチンをつなげただけでは次の動作に進まないということがわかった。
ただサブルーチンをつなげただけでは次の動作に進まないということがわかった。~
しかもこのプログラムはミスがあり、タイマーが作動していませんでした。~
 
・ラインの左側をトレースするサブルーチン

 sub line_followL()
 {
 int zk=0;
   
 SetSensor(SENSOR_3,  SENSOR_LIGHT);
    ClearTimer(0);
 
    while(zk==0) {
       while(FastTimer(0)>100);
            if (SENSOR_3 < DARK){
                 short_break;
        PlaySound(SOUND_DOUBLE_BEEP);
          zk=1;         
        }else if (SENSOR_3>WHITE){
                  right_senkai;
                  ClearTimer(0);
            }else if (SENSOR_3 < THRESHOLD){
                  right;
                 ClearTimer(0);
            }else if(SENSOR_3> THRESHOLD) {
                 left;
                   ClearTimer(0);
              }
            Wait(STEP);
         }
     }

1つめのサブルーチンを逆にしただけです。~
ここでは中間の値より大きいと左へ、小さいと右へ進ませています。~
右側のライントレースと同様タイマーが作動していません。~

・交差点で左折するサブルーチン
 sub cross_left()
 {
      go;
      OnFwd(OUT_A); 
      OnRev(OUT_C);     
      Wait(280);
      Off(OUT_AC);
 }
・交差点で右折するサブルーチン~

 sub cross_right()
 {
       go;
      OnFwd(OUT_C);
      OnRev(OUT_A);     
      Wait(250);
      Off(OUT_AC);
 }
・斜めに動くサブルーチン~

 sub cross_nanameL()
 {
     OnFwd(OUT_A); 
      Off(OUT_C);     
      Wait(230);
      Off(OUT_A);
 }
・左へ旋回するだけのサブルーチン~
 sub cross_leftshort()
 {
      go;
      OnFwd(OUT_A); 
      OnRev(OUT_C);     
      Wait(220);
      Off(OUT_AC);
 }


・最終的なタスク~


 task main()
 {
 line_followR();  //C→S交差点へ(最初のライントレースは右)
 cross_left();   //S交差点を左折 
 line_followR();  //S→P交差点へ
 cross_left();   //P交差点を左折
 line_followR();  //P→Q交差点へ
 go;        //直進
 line_followR();  //Q交差点から円を描いてQ交差点へ
 cross_nanameL(); //ライントレースの切り替えのため斜め移動
 line_followL();  //Q→R交差点へ(ライントレースは左へ変化)
 cross_right();  //R交差点を右折
 line_followL();  //R→P交差点へ
 cross_leftshort(); //P交差点を左折
 line_followR();  //P→A地点へ(ライントレースは右へ変化)
 go_long ;      //ゴールの中に入る為の直進
 PlaySound(SOUND_UP);  //勝利のサウンド
 }
*ロボットの最終的な動き方 [#f42e1d23]
このプログラムの説明だけでは不明な点が多くあると思いますのでそこを説明していきます。
なぜライントレースの左右が存在するかというと、私は最初に、ラインの右側だけをロボに動かさせていました。しかしこのプログラムでは交差点Q→Rへ向かうときの半径5センチのカーブで1秒以上黒を認識してしまい、交差点と勘違いしていました。そこで交差点Qでロボを斜めにうごかせ、ライントレースを左へと移行させました。このように、常に円の中ではなく外側をライントレースすることにより、カーブにおける勘違いをなくしました。
なぜライントレースの左右が存在するかというと、私は最初に、ラインの右側だけをロボに動かさせていました。しかしこのプログラムでは交差点Q→Rへ向かうときの半径5センチのカーブで1秒以上黒を認識してしまい、交差点と勘違いしていました。そこで交差点Qでロボを斜めにうごかせ、ライントレースを左へと移行させました。このように、常に円の中ではなく外側をライントレースすることにより、カーブにおける勘違いをなくしました。~
次になぜタイマーが作動していないのにゴールをすることができたのかを説明します。~
あのプログラムではタイマーが作動していないためロボットはDRAK(値36)を確認したときに交差点だと認識しています。これでは普通ゴールできません。特に半径5�僂離�ーブを交差点だと誤認してしまうでしょう。(10�僂留澆歪未譴泙靴拭砲靴�し私は常にカーブの外側を通るプログラムを書いたため円の内側をとおることがなくしたため運良くゴールすることができました。この方法を用いるためにはDARKの値をしっかり考える必要がありますが今回はたまたま決めた値が上手くはまったようです。
*まとめ・感想 [#k4553ca3]
ロボットのところでも書いたように、前回の似顔絵ロボットのをそのまま用いたため、C→Aまでのライントレースで5分9秒という時間がかかり、スピードがあまり出ませんでした。もちろんそれによる利点もありますが、少し落としすぎたのかもしれません。スピードを求めるならモーターの回転がそのまま伝わるように改良するべきだったかもしれません。~
プログラムについては交差点で旋回するだけでは、ライントレースする場所が逆になってしますので少し前進させてから旋回しなければいけなかったりと、様々な私のイメージとは違う点がありました。

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