2017a/Member

目次

課題

今回の課題は2cm幅の線に沿って走るロボットの作成だ。

詳しくはこちら

私は点Eで右折するルートを選択した。

相方のページはこちら

機体

ロボット

ロボットはセンサーの取り付け位置以外、説明書と同じ構造にした。

aa.png

工夫した点

光センサーの位置を説明書のものよりも本体に近くした。これのおかげでより急カーブを曲がりやすくなった。

light2.png

プログラム

ライントレイス

私達の機体の光センサーは白いところでは63、黒いところでは35という値をだした。この範囲を35<=X<39(黒),39<=X<45(暗い灰色),45<=X<53(灰色),53<=X<59(明るい灰色), 59<=X<63(白)の5つに分けた。

点Eで右折するコースでは、常に線の右側もしくは、常に左側を走行するプログラムにすると上手に曲がれないところが出てくる。そのため線の右側、左側の両方のライントレースできるように両方のプログラムを作った。

右側ライントレイス

機体が「黒」と判別したとき、その場で右回りに回転とする。

機体が「暗い灰色」と判別したとき、右にカーブする。

機体が「灰色」と判別したとき、直進する。

機体が「明るい灰色」と判別したとき、左にカーブする。

機体が「白」と判別したとき、その場で左回りに回転する。

左側ライントレイス

右側ライントレイスの回転する方向を逆にしただけである。

機体が「黒」と判別したとき、その場で左回りに回転とする。

機体が「暗い灰色」と判別したとき、左にカーブする。

機体が「灰色」と判別したとき、直進する。

機体が「明るい灰色」と判別したとき、右にカーブする。

機体が「白」と判別したとき、その場で右回りに回転する。

直角と急カーブの見分け方

点Hから点Gまで移動するとき、20秒間は黒い部分に長時間のっていても止まらないよにした。こうしなければ私のプログラムでは急カーブでも直角でも止まってしまう。しかし、止まらないようにすることによって急カーブを通過しやすくなる、また急カーブでは止まらないが直角では止まるようになる。

交差点の判別方法

ライントレイスをしているときには機体の先端(光センサー)が左右に振られている。これは光センサーが黒を判別したら線の外側へ、白を判別したら線の内側へと機体を進めようとするからだ。そして、交差点に侵入した時機体の先端を何度か回転させても0.18秒以上連続で黒と判別されるとき、この機体は自分が交差点上にいると判断する。

定義

#define speedH 30   //直進、後退時の速度
#define speedL 20   //曲がるときの速度
#define OnRL(speedr,speedl) OnFwd(OUT_B,speedr);OnFwd(OUT_C,speedl);
#define go_forward OnRL(speedH,speedH);    //直進
#define go_back OnRL(-speedH,-speedH);    //後退
#define spin_left OnRL (speedL,-speedL);    //左旋回
#define turn_left OnRL (speedL,0);    // 左折
#define turn_right OnRL (0,speedL);    //右折
#define spin_right OnRL (-speedL,speedL);    //右旋回
#define wait Wait(1000);
#define off Off(OUT_BC)

サブルーチン

線の上を走行時

線の右側を走行する。

sub R()
{
    SetSensorLight(S1);
    long t0 = CurrentTick();
    long tmax = 180;
    while (CurrentTick()-t0<=tmax) {
        if (SENSOR_1 >= 59){
            spin_left;
            t0 = CurrentTick();
        } else if (SENSOR_1 >= 53) {
            turn_left;
            t0 = CurrentTick();
        } else if (SENSOR_1 >= 45) {
            go_forward;
            t0 = CurrentTick();
        } else if (SENSOR_1 >= 39) {
            turn_right;
        } else {
            spin_right;
         }
      Wait(1);
    }
    off;
}

線の左側を走行する。仕組みは右側を走行するときと同じである。

sub L()   //
{ 
    SetSensorLight(S1);
    long t0 = CurrentTick();
    long tmax = 180;
    while (CurrentTick()-t0<=tmax) {
        if (SENSOR_1 >= 59){
            spin_right;
            t0 = CurrentTick();
        } else if (SENSOR_1 >= 53) {
            turn_right;
            t0 = CurrentTick();
        } else if (SENSOR_1 >= 45) {
            go_forward;
            t0 = CurrentTick();
        } else if (SENSOR_1 >= 39) {
            turn_left;
        } else {
            spin_left;
         }
      Wait(1);
    }
   off;
} 

点Hから点Gまで移動するときに使う。ヘアピンカーブと直角カーブを間違えないように20秒間は黒い部分に長時間のっていても止まらないようにした。

sub HtoG()
{
    SetSensorLight(S1);
    long t0 = CurrentTick();
    long t1 = 20000;
    long tmax = 180;
    while (CurrentTick()-t0 <= t1) {
        if (SENSOR_1 >= 59){
            spin_left;
        } else if (SENSOR_1 >= 53) {
            turn_left;
        } else if (SENSOR_1 >= 45) {
            go_forward;
        } else if (SENSOR_1 >= 39) {
            turn_right;
        } else {
            spin_right; 
        }
    Wait(1);
    }
    t0 = CurrentTick();
    while (CurrentTick()-t0<=tmax) {
        if (SENSOR_1 >= 59){
            spin_left;
            t0 = CurrentTick();
        } else if (SENSOR_1 >= 53) {
            turn_left;
            t0 = CurrentTick();
        } else if (SENSOR_1 >= 45) {
            go_forward;
            t0 = CurrentTick();
        } else if (SENSOR_1 >= 39) {
            turn_right;
        } else {
            spin_right;
         }
      Wait(1);
    }
    off;
} 

各地点での方向転換、

点E,Q,R,G,P(二回目),Qでの方向転換、直進

sub EQRGPQ()
{  
    PlaySound(SOUND_UP);
    go_forward;
    Wait(350);
    off; 
} 

点P(1回目),Sでの左折

sub PS()
{    
    PlaySound(SOUND_DOWN);
    wait;
    go_back;
    Wait(600);
    turn_left;
    Wait(100);
    go_forward;
    Wait(500);
}

点Tを通過する

sub TT()
{
    PlaySound(SOUND_DOWN);
    wait;
    go_forward;
    Wait(350);
    off; 
} 

点H,Fの直角コーナーを右折

sub HF()
{
    PlaySound(SOUND_UP);
    go_back;
    Wait(500);
    turn_right;
    Wait(1700);
    go_forward;
    Wait(500);
    off;
}

タスクメイン

task main()
{
    R();
    EQRGPQ();
    L();
    PS();
    L();
    EQRGPQ();
    L();
    EQRGPQ();
    R();
    TT();
    R();
    TT();
    R();
    HF();
    HtoG();
    EQRGPQ();
    R();
    PS();
    L();
    EQRGPQ();
    L();
    EQRGPQ();
    R();
    HF();
    R();
}

感想

今回の課題はなかなか進行しなかったが、光センサーを本体に近づけることで急にうまくいった。今回、プログラミングに苦戦した。プログラミングの概形ができても細かな調整が必要だった。その中で同じ動きをする場所をみつけて、1つのサブルーチンにまとめることで少しは楽になったと思う。

次回はプログラミングの改良だけでなく、ハード面の改良もしながら課題を進めていきたい。


添付ファイル: fileaa.png 58件 [詳細] filezenntai.xcf 27件 [詳細] filezenntaizou.png 24件 [詳細] filelight2.png 53件 [詳細] filelight.png 29件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-08-12 (土) 22:11:15