目次
#contents

*課題1 [#fa670487]
下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットを作成せよ。
#ref(コース.png,,100%)
**ミッション [#y8cc62e2]
次のいずれかのコースで黒い線に沿って動き、途中でボールをゴール付近に立てた350mlの空き缶(黄色で表示)に当てるロボットを製作せよ。 (相棒と違うコースを選ぶこと)
第1.第2コースがあるが、私は第1コースを選択した。
***第1コース [#hef0ce1d]
1:ロボットを長方形X内におき、Aをスタート

2:Bを右折

3:Kで一時停止して左折

4:Jを直進

5:Iを直進

6:Hを左折

7:Gで一時停止して左折

8:Eで一時停止して右折

9:Lを経て正方形Y内に入って停止

(一時停止の指定がある場所は、1秒間停止すること)

ボールはロボットが弧KJIH上にある時にQ地点の空き缶に当てる

*ロボットの説明 [#fc515f1f]
移動するための車の部分の基本的な構造は付属の冊子を参考に作成した。
ロボット作成において最も苦戦したのはボールを投げる機構だった。最終的にはボールをつかんで移動し、投げる際に離して本体で押し出すような仕組みとなった。

ロボット作成において最も苦戦したのはボールを投げる機構だった。

最終的にはボールをつかんで移動し、投げる際に離して本体で押し出すような仕組みとなった。

#ref(robotto3.jpg,,50%)
ロボットの全体像

基本的な構造は付属の冊子を参考にした。特に考えたのがボールを掴む機構であるが、結論から言うと、この機構はあまり良いものとは言えなかった。

#ref(robotto2.jpg,,50%)
ラインを感知するセンサー

付属の冊子に記載されている通りに作ると紙の盛り上がりなどで、値がまばらになることがあったため、少しだけ低く設置するように変更した。

#ref(robotto1.jpg,,50%)
ボールを掴むロボット
この装置でボールを掴んだまま進み、投げるときは手を開きながら前進する。

*プログラムの説明 [#if36ed0f]
**基本的なライントレースのプログラム [#he2d7f7e]
void line_trace()     //センサーが捉えたラインの明るさを判断して移動する
{
    SetSensorLight(S1);
    long t0,t1;
    t1=100;
    t0=CurrentTick();
    while(CurrentTick()-t0<t1){
        if(SENSOR_1>55){       //明るさ55以上だと判断した際はその場で右旋回
        turn_r1;
        t0=CurrentTick();
        }else if(SENSOR_1>45){       //明るさ55以上だと判断した際は右に曲がる
        turn_r0;
        t0=CurrentTick();
        }else if(SENSOR_1>40){       //明るさ40以上だと判断した際は直進
        go_s;
        t0=CurrentTick();
        }else if(SENSOR_1>30){       //明るさ30以上だと判断した際は左に曲がる
        turn_l0;
        t0=CurrentTick();
        }else{
        turn_l1;       //明るさ30以下だと判断した際はその場で左旋回
        }
    }
}

**AB間を走るプログラム [#aa3ef991]
void line_trace_AB()      //AB間全体の中で唯一ラインの右側を走るため、基本のプログラムを逆転させている
{
    SetSensorLight(S1);
    OnFwd(OUT_BC,SPEED_SLOW);
    Wait(1000);
    long t0,t1;
    t1=100;
    t0=CurrentTick();
    while(CurrentTick()-t0<t1){
        if(SENSOR_1>55){       //明るさ55以上だと判断した際はその場で左旋回
        turn_l1;
        t0=CurrentTick();
        }else if(SENSOR_1>45){       //明るさ55以上だと判断した際は左に曲がる
        turn_l0;
        t0=CurrentTick();
        }else if(SENSOR_1>40){       //明るさ40以上だと判断した際は直進
        go_s;
        t0=CurrentTick();
        }else if(SENSOR_1>30){       //明るさ30以上だと判断した際は右に曲がる
        turn_r0;
        t0=CurrentTick();
        }else{
        turn_r1;       //明るさ30以下だと判断した際はその場で右旋回
        }
    }
    OnFwd(OUT_BC,30);    //ここまではラインの右側を走っているため、ここで左側に変更する
    Wait(500);
    while(SENSOR_1>55){
        turn_r1;
        }
}

**BK間を走るプログラム [#ye964d7c]
void line_trace_BK()
{
    line_trace();
    sleep;     ・一時停止
}

**KJ間を走るプログラム [#x7583b08]
void line_trace_KJ()
{
    while(SENSOR_1>55){
        turn_l0;
    }
    line_trace();
    OnFwd(OUT_BC,SPEED_SLOW);    //基本の往路グラムだと交差点に惑わされて、左折してしまうため、交差点を直進するためのプログラム
    Wait(300);
    while(SENSOR_1<55){
        turn_r0;
    }
}

**JI間を走るプログラム [#c4499021]
void line_trace_JI()
{
    line_trace();
}

**缶を探すプログラム [#q1b1e45f]
void fwdDist(float d)   //距離 d cm 前進
{
    long angle;
    angle = d/(diameter*pi)*360.0;  //角度を計算する
    RotateMotorEx(OUT_BC, SPEED_SLOW, angle, 0, true, true);
}

void turnAng(long ang)   //角度 ang 度の時計回りの旋回
{
    long angle;
    angle = track/diameter * ang;
    RotateMotorEx(OUT_BC, SPEED_SLOW, angle, 100,true, true);
}

int searchDirection(long ang)  //現在の方向を中心に ang 度の範囲で探し
                                    //障害物までの距離を返す
{
    long angle,tacho_min=0, tacho_corr ;
    int d_min;

    d_min=300;       //仮の最小値

    angle = (track/diameter)*ang;  //旋回角度からタイヤの回転を計算
    turnAng(ang/2);                //指定された角度の半分を旋回
    ResetTachoCount(OUT_BC);      //角度計算をリセット

    OnFwdSync(OUT_BC,SPEED_SLOW,-100);  //半時計回りに旋回
    while(MotorTachoCount(OUT_B)<=angle){
        if (SensorUS(S4)<d_min){
            d_min=SensorUS(S4);        //仮の最小値を更新
            tacho_min=MotorTachoCount(OUT_B);
        }
    }
    OnFwdSyncEx(OUT_BC,SPEED_SLOW,100,RESET_NONE);
    until(MotorTachoCount(OUT_B)<=tacho_min||SensorUS(S4)<=d_min);

    Wait(14);            //微調整
    Off(OUT_BC);Wait(500);
    return d_min;
}


**ボールを放つプログラム [#x01719f2]
void throw_a_ball()
{
    OnFwd(OUT_BC,70);OnFwd(OUT_A,20);   //腕を開きながら前進してボールを押し出す
    Wait(750);
    OnRev(OUT_A,20);
    Wait(750);
    OnRev(OUT_BC,70);       //元の位置に戻る
    Wait(750);
    while(SENSOR_1<55){    //進路に戻る
        turn_r0;
    }
}

**IH間を走るプログラム [#u616d3db]
void line_trace_IH()
{
    line_trace();
}

**HG間を走るプログラム [#of059791]
void line_trace_HG()
{
    line_trace();
    sleep;     //一時停止
}

**GF間を走るプログラム [#qdf65753]
void line_trace_GF(long min_t)    //この区間は急なカーブがあるため、ロボットが交差点と誤認してしまう。そのため、Gを発ってから10秒間は交差点と認識しても止まらないようなプログラムを作る
{
    SetSensorLight(S1);
    long t0,t1,t2;
    t2=CurrentTick();
    t1=1000;
    t0=CurrentTick();
    while(CurrentTick()-t0<t1 ||CurrentTick()-t2<min_t){
        if(SENSOR_1>55){
        turn_r1;
        t0=CurrentTick();
        }else if(SENSOR_1>48){
        turn_r0;
        t0=CurrentTick();
        }else if(SENSOR_1>42){
        go_s;
        t0=CurrentTick();
        }else if(SENSOR_1>33){
        turn_l0;
        t0=CurrentTick();
        }else{
        turn_l1;
        }
    }

}

**FE間を走るプログラム [#r744bc26]
void line_trace_FE()
{
    line_trace();
    sleep;       //一時停止
    while(SENSOR_1<55){;    //基本の往路グラムだと交差点に惑わされて、左折してしまうため、交差点を直進するためのプログラム
        turn_l1;
    }
}
**EL間を走るプログラム [#kbe92727]
void line_trace_EL()
{
    line_trace();
}
**LY間を走るプログラム [#i43f6da8]
void line_trace_LY()
{
    OnFwd(OUT_BC,30);    /最後は前進してゴール
    Wait(750);
    Off(OUT_BC);
}

**プログラムを書く際の工夫 [#ae12b55e]
線を追うプログラムは、今までの学習で作ったプログラムを編集して作成した。ラインと白い部分の境界を進むプログラムで、光センサーの捉える明るさを5段階に分けて処理をする。光センサーが標準の明るさだと判断した場合はロボットを直進。少し暗いと判断した場合は左に曲がり、少し明るいと判断した場合は右に曲がる。最も暗いと判断した場合はその場で左旋回し、最も明るいと判断した場合はその場で右旋回する。センサーが交差点に到着した場合、センサーは線の内部を感知することになるため、最も暗いと判断する。したがってその場で左旋回することができるので、このプログラムだけで交差点を曲がることもできる。このようにすることによって、光センサーは線と余白の境界を往復しながら線をを追うことができる。しかし、このプログラムは左旋回はできても交差点を右に曲がることができないため、指定されたようにコースを移動するためにはこのプログラムを改変する必要があった。まず最初に行ったのが、各交差点を認識して、それぞれのルートに応じた進み方にすることだ。まず初めに、今までのプログラムだと線の左側を進んでいたためAB間を進んだとき交差点Bを感知することができなかった。そのためAB間のみに限りプログラムの処理を逆にして線の右側を進むようにした。次に、このプログラムどおりに進むと、交差点J.I.Eでは進行したい方向と異なる道に進んでしまう。これを改善するためにそれぞれ適切なプログラムを追加して、元のラインに戻ってくるように調整した。最後に、交差点GF間の線を追う際に必ずどちらかのカーブの内側を通ることにるが、ロボット本体にある程度の大きさがあり、曲がり切れずに交差点だと判断してしまうケースが多々あった。この問題の解決策としては、交差点Gを出発してから数秒の間はたとえセンサーが交差点に到着したと判断しても、無視して今までのプログラムを継続するようにプログラムすることで解決した。

*問題点とその改善案 [#oad796f8]
・超音波センサーを設置した位置が少し高かったため、たまに缶を感知できない時があった。もう少し設置位置を調整するべきだった。

・ボールを投げる仕組みをロボット全体で押し出すように設計したため、プログラムの政策が難しくなってしまった。発表を見た後に周りのグループがうまく作っていたため、もっと考察するべきだったようにかんじた。


*感想 [#w2832c85]
ボールを投げる機構に苦戦したため、本体やセンサー類にあまり時間をとることができなかった。これをもう少しシンプルで操作しやすいものにできるようにしたかったが、周りのグループの作成したロボットを見て、まだまだ改善の余地があったと感じた。


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