Mission2

ライントレースのコース図

自分が走らせたコースは第二コースで,課題はYにおいてある空き缶を次のコースをライントレースしながらXへ届けるというものだった.

  • 第二コース
  1. Aをスタート
  2. Bを右折
  3. Jで一時停止の後、Yの空き缶をキャッチしてJに戻る
  4. JからKに向かい、Kを直進
  5. Lを直進
  6. Iを左折
  7. Hで一時停止の後、左折
  8. Gで一時停止の後、右折
  9. Fで一時停止の後、右折
  10. Eを直進
  11. Dで一時停止の後、空き缶をXに置いてDに戻り、Cに向かう
  12. Cで一時停止の後、直進
  13. Bを直進
  14. Aで停止

ロボット本体の説明

本体について

ロボット本体

今回のミッションでは,ラインのカーブを走るために左右にモータを取り付け缶回収のために前に人布モータを取り付けた.後に説明があるが,缶回収の簡略化のためアームを本体の前に取り付けたため少し前のめりになってしまった.

アームについて

ろっぼとのアーム

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

プログラムについて

定義文について

#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を定義しているが実際は使っていない.この定義文は急なカーブに備えて作ったものだが,曲がるときに外側の線に沿って進めばこの定義文を使う必要がなかったので結局使わなかった.

変数について

    int limittime=0;        //ライン上を動く時間

この変数はサブルーチンのtomarazu_migisen_susumuとtomarazu_hidarisen_susumuに使うためのものでライン上を動く時間を設定している.

サブルーチンについて

線をトレースするプログラミング

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;
       }
    }
} 
  • 下の図は直線の黒線をトレースするロボットの軌跡を表す. 赤い矢印が進む方向で,黄色い丸がロボット本体

直線のトレースの説明図

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

交差点のトレースの説明図

トレースする線を変更するためのプログラム

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;
}

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

カーブでの問題点1

  • 上の図の説明.緑の丸がカーブの内側を走るロボットの軌跡で黄色の丸が外側,青丸は黒線に連続でいた時間>一定時間となった時を表す.

線をトレースする際の補助的なプログラム

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;
       } 
    }
}

ライントレース中時々線上を進むプログラムが意図しないところで条件を満たし流れてしまうことがあった.そこで,流れやすいところをトレースするときにこのプログラムを使うことでその問題を解決した.

タスクメインについて

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);                   //調整
    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;
}

task mainでは,サブルーチンや定義文のみの構成にしてわかりやすくしたかったが,うまくいかず調整という形でズレを修正していった.

反省・課題

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


添付ファイル: filecurve.png 23件 [詳細] filekousatenn.png 18件 [詳細] filerainn.png 19件 [詳細] fileIMG_hontai.jpg 16件 [詳細] fileIMG_arm.jpg 18件 [詳細] filemission2 siryou.png 19件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-07-19 (木) 09:33:19