#contents
*Mission2 [#h3f38c94]
&ref(./mission2 siryou.png,100%,ライントレースのコース図);

自分が走らせたコースは第二コースで,課題はYにおいてある空き缶を次のコースをライントレースしながらXへ届けるというものだった.
-第二コース
+Aをスタート
+Bを右折
+Jで一時停止の後、Yの空き缶をキャッチしてJに戻る
+JからKに向かい、Kを直進
+Lを直進
+Iを左折
+Hで一時停止の後、左折
+Gで一時停止の後、右折
+Fで一時停止の後、右折
+Eを直進
+Dで一時停止の後、空き缶をXに置いてDに戻り、Cに向かう
+Cで一時停止の後、直進
+Bを直進
+Aで停止

*ロボット本体の説明 [#r7197748]
**本体について [#ye297acf]
&ref(./IMG_hontai.jpg,100%,ロボット本体);

今回のミッションでは,ラインのカーブを走るために左右にモータを取り付け缶回収のために前に人布モータを取り付けた.後に説明があるが,缶回収の簡略化のためアームを本体の前に取り付けたため少し前のめりになってしまった.
**アームについて [#s775da3b]
&ref(./IMG_arm.jpg,100%,ろっぼとのアーム);

アームは本体の進む方向の目の前につけた.そして,できるだけ前につけることで缶を取るとき本体を缶に近づけることなく缶を回収できるようにした.アームにタッチセンサーを付けるという考えもあったが取り付ける場所が取りづらく前がさらに重くなるのでこのようなつくりにした.

*プログラムについて [#bee864c5]
**定義文について [#y747fbf0]
 #define BLACK 48                 //黒の定義
 #define WHITE 50                 //白の定義
 #define tyokushin OnFwd(OUT_AC);Wait(2);                   //前に少し進む
 #define hidarimagaru OnFwd(OUT_C);Wait(2);                 //左に少し進む
 #define migimagaru OnFwd(OUT_A);Wait(2);                   //右に少し進む
 #define hidarisenkai OnFwd(OUT_C);OnRev(OUT_A);Wait(2);    //左旋回する
 #define migisenkai OnFwd(OUT_A);OnRev(OUT_C);Wait(2);      //右旋回する
 #define JudgeTime 80               //交差点を判断するための時間
 #define TEISI Off(OUT_AC);Wait(100);                 //一時停止
 #define STOP Off(OUT_AC);Wait(1);                    //モータの回転の切り替えのための停止
 #define BACK OnRev(OUT_AC);                //後ろに下がる
 #define kaishuu OnFwd(OUT_B);Wait(10);Off(OUT_B);            //缶の回収
 #define hanasu OnRev(OUT_B);Wait(10);Off(OUT_B);             //缶を放す
 #define START OnFwd(OUT_AC);Wait(100);Off(OUT_AC);               //Aから出る
 #define END OnFwd(OUT_AC);Wait(100);Off(OUT_AC);                 //Aに戻る
 #define kurosen_oudan OnFwd(OUT_AC);Wait(30);Off(OUT_AC);    //黒線を横断する
 #define tyokkaku_migi_magaru OnFwd(OUT_A);OnRev(OUT_C);Wait(50);Off(OUT_AC);//交差点を直角に右に曲がる
 #define tyokkaku_hidari_magaru OnFwd(OUT_C);OnRev(OUT_A);Wait(50);Off(OUT_AC);//交差点を直角に左に曲がる
プログラムに定義されているSTARTやENDなどは最初はサブルーチンで明るさセンサーを用意てwhile分で書いていたがそうするとうまくAをこえることができなかったので,最初と最後以外使わないプログラミングだったので定義文で表した.定義文ではmigisenkaiとhidarisenkaiを定義しているが実際は使っていない.この定義文は急なカーブに備えて作ったものだが,曲がるときに外側の線に沿って進めばこの定義文を使う必要がなかったので結局使わなかった.
**変数について [#k17680aa]
     int limittime=0;        //ライン上を動く時間
この変数はサブルーチンのtomarazu_migisen_susumuとtomarazu_hidarisen_susumuに使うためのものでライン上を動く時間を設定している.
**サブルーチンについて [#a9a7acb4]
***線をトレースするプログラミング [#h03db3c6]

 sub migisen_susumu()        //右側線に沿って進む
 {
     ClearTimer(0);
     while (FastTimer(0)<JudgeTime) {
       if (SENSOR_1 > WHITE) {       //黒線の外に出ているとき
           hidarimagaru;             //左に曲がる
           STOP;
           ClearTimer(0);            //時間リセット
        } else if (SENSOR_1 > BLACK) {     //黒線と白の間にいるとき
           tyokushin;                      //直進
           STOP;
           ClearTimer(0);                  //時間をリセット
        } else if (SENSOR_1 > 40) {            //黒線上にいるとき
           migimagaru;                         //右曲がる
           STOP;
        }
     }
 } 

 sub hidarisen_susumu()        //左側線に沿って進む
 {
     ClearTimer(0);
     while (FastTimer(0)<JudgeTime){
       if (SENSOR_1 > WHITE) {       //黒線の外に出ているとき
           migimagaru;               //右に曲がる
           STOP;
           ClearTimer(0);            //時間をリセット
        } else if (SENSOR_1 > BLACK) {       //黒線と白の間にいるとき
           tyokushin;                        //直進
           STOP;
           ClearTimer(0);                    //時間をリセット
        } else if (SENSOR_1 > 40) {                   //黒線上にいるとき
           hidarimagaru;                              //左に曲がる
           STOP;
        }
     }
 } 

-下の図は直線の黒線をトレースするロボットの軌跡を表す.
赤い矢印が進む方向で,黄色い丸がロボット本体

&ref(./rainn.png,70%,直線のトレースの説明図);

-下の図は交差点を判断するときのロボットの軌跡を表す.
青い丸の時に,黒線に連続でいた時間>一定時間となり線をトレースするプログラムが役目を果たし,taskmainでは次の命令に行くようになる.

&ref(./kousatenn.png,70%,交差点のトレースの説明図);


***トレースする線を変更するためのプログラム [#sf063edf]

 sub hidari_kara_migi()        //左側線から右側線へ移動
 {
     while(SENSOR_1 < BLACK){
        migimagaru;
     }
     STOP;
     while(SENSOR_1 > WHITE){
        migimagaru;
     } 
     OnRev(OUT_C);
     OnFwd(OUT_A);
     Wait(20);
     STOP;
 }

 sub migi_kara_hidari()        //右側線から左側線へ移動
 {
 
     STOP;
     while(SENSOR_1 > WHITE){
         hidarimagaru;
     } 
     OnFwd(OUT_C);
     OnRev(OUT_A);
     Wait(40);
     STOP;
 }

このプログラムは急なカーブを前に述べた線をトレースするプログラムで曲がれるようにするという目的と単純にトレースする線の左右を変更する目的で作られた.下の図のようにカーブの時,内側を走ると線をトレースするプログラムでは黒線に入る時間が増えて次の命令に行ってしまうという問題があるが外側を走ればその問題については解決される.よって,カーブの時は常に外側を走る必要があるのでこのプログラムを書いた.

&ref(./curve.png,70%,カーブでの問題点1);

-上の図の説明.緑の丸がカーブの内側を走るロボットの軌跡で黄色の丸が外側,青丸は黒線に連続でいた時間>一定時間となった時を表す.
***線をトレースする際の補助的なプログラム [#y65339bc]

 sub tomarazu_hidarisen_susumu()        //左側線に沿って一定時間進む
 {
     ClearTimer(0);
     while (FastTimer(0)<limittime){
       if (SENSOR_1 > WHITE) {
           migimagaru;
           STOP;
           ClearTimer(0);
        } else if (SENSOR_1 > BLACK) {
           tyokushin;
           STOP;
           ClearTimer(0);
        } else if (SENSOR_1 > 40) { 
           hidarimagaru;
           STOP;
        } 
     }
 }

 sub tomarazu_migisen_susumu()        //右側線に沿って一定時間進む
 {
     ClearTimer(0);
     while (FastTimer(0)<limittime) {
       if (SENSOR_1 > WHITE) {
           hidarimagaru;
           STOP;
           ClearTimer(0);
        } else if (SENSOR_1 > BLACK) {
           tyokushin;
           STOP;
           ClearTimer(0);
        } else if (SENSOR_1 > 40) { 
           migimagaru;
           STOP;
        } 
     }
 }
ライントレース中時々線上を進むプログラムが意図しないところで条件を満たし流れてしまうことがあった.そこで,流れやすいところをトレースするときにこのプログラムを使うことでその問題を解決した.
**タスクメインについて [#rc16b993]
 task main ()
 {
     START;                         //AからBへ直進して進む
     migisen_susumu();              //Bの交差点につく
     tyokkaku_migi_magaru;          //交差点を右曲がる
     migisen_susumu();              //BからJへ
     TEISI;                         //一時停止
     kaishuu;                       //缶回収
     migi_kara_hidari();            //円の外側に移る
     hidarisen_susumu();            //Kまで進む
     OnRev(OUT_C);
     OnFwd(OUT_A);
     Wait(20);
     Off(OUT_AC);                   //調節
     kurosen_oudan;                 //前の黒線無視して進む
     hidarisen_susumu();            //KからLへ進む
     OnRev(OUT_C);
     OnFwd(OUT_A);
     Wait(20);
     Off(OUT_AC);
     Off(OUT_AC);                   //調整
     kurosen_oudan;                 //前の黒線無視して進む
     hidarisen_susumu();            //LからI進む
     tyokkaku_hidari_magaru;        //Iの交差点を左に曲がる
     hidarisen_susumu();            //IからH
     TEISI;                         //一時停止
     tyokkaku_hidari_magaru;        //Hの交差点を左に曲がる
 
     hidarisen_susumu();            //Hからカーブまで
     kurosen_oudan;                 //逆側の線上に移動
     limittime=200;
     tomarazu_migisen_susumu();     
     migisen_susumu();              //Gへ行く
     TEISI;                         //確認
     tyokkaku_migi_magaru;          //Gの交差点を右曲がる
     migisen_susumu();              //GからF
     TEISI;                         //一時停止
     migisen_susumu();              //FからE
     OnRev(OUT_C);
     OnFwd(OUT_A);
     Wait(20);
     Off(OUT_AC);                   //調節    
     kurosen_oudan;                 //前の黒線無視して進む
     migisen_susumu();              //EからD
     TEISI;                         //一時停止
     OnRev(OUT_C);
     OnFwd(OUT_A);
     Wait(100);
     Off(OUT_AC);                   //調節   
     hanasu;                        //缶を放す
     OnRev(OUT_C);
     OnFwd(OUT_A);
     Wait(100);
     Off(OUT_AC);                   //調節  
     migisen_susumu();              //DからC
     tyokkaku_migi_magaru;          //DからCまでの直角カーブを右曲がる
     migisen_susumu();              //Cまで進む
     TEISI;                         //一時停止
     OnRev(OUT_C);
     OnFwd(OUT_A);
     Wait(20);
     Off(OUT_AC);                   //調節
     kurosen_oudan;                 //前の黒線無視して進む
     migisen_susumu();              //CからA
     END;
 }

*** [#a6dcbce8]
*** [#d8212c0f]
task mainでは,サブルーチンや定義文のみの構成にしてわかりやすくしたかったが,うまくいかず調整という形でズレを修正していった.
*反省・課題 [#c15ddc0f]
サブルーチンを使うことによってtask mainが単純化できてよかったと思う.だが,線を進むプログラムは黒線を一定時間進むことで交差点の有無を判断していたので交差点と判断するのに黒線を左右どちらかに進みすぎなければいけなかった.それがズレとなりtask mainで調整という形で書く必要があった.また,線を進むプログラムはモータの調子によって意図しないところで流れたりしてしまうことが多かった.これはモータが悪いというわけではなく,モータの調子にかかわらず走るプログラムを書くことができない自分の力不足だと考える.線を進むプログラムに関してandやorを使ったプログラムを書いてはみたが,自分の意図した動きを作ることができず時間的にも余裕がなかったことから不完全なプログラムになってしまった.次のmissionではこの反省を活かして時間に余裕を持つために前々の行動に心がける.

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