[[2017a/Member]]
#contents
*課題3と担当 [#r967ec7c]
**課題3 [#l471b155]
ロボットを2台使い、[[課題2:http://yakushi.shinshu-u.ac.jp/robotics/?2017a%2FMission2]]
で使ったコースを用いてコース上の様々な位置に置かれた缶を指定された位置に入れ、得点を競う。このとき、缶を積み上げると得点が高くなる。詳しくは[[課題3:http://yakushi.shinshu-u.ac.jp/robotics/?2017a%2FMission3]]を参照。
**担当した箇所 [#h06a53a2]
班のメンバーはRyoma、Kawachan、rayonne、kkの4人である。この班はロボット2台を合体させずに、缶を積み上げるロボットと缶を運ぶロボットを作った。Ryoma、Kawachanが積み上げるロボットを、rayonne、私が運ぶロボットを担当した。よって、このページでは、缶を運ぶロボットについて説明する。缶を積み上げるロボットについては、[[Ryoma:http://yakushi.shinshu-u.ac.jp/robotics/?2017a%2FMember%2FRyoma%2FMission3]]、[[Kawachan:http://yakushi.shinshu-u.ac.jp/robotics/?cmd=edit&page=2017a%2FMember%2FKawachan%2FMission3&refer=2017a%2FMember]]を参照。
#ref(./積み上げロボット.JPG,50%,積み上げロボット);
積み上げロボット
#ref(./持ち運びロボット.png,50%,運搬ロボット);
運搬ロボット
*ロボット [#k57b7f1c]
#ref(./持ち運びロボット.png,50%,運搬ロボット);
&br;
#ref(./持ち運びロボット 正面.JPG,50%,運搬ロボット正面);
ライントレースをして缶を取りに行くロボットである。課題2で作ったロボット(詳しくは[[kk:http://yakushi.shinshu-u.ac.jp/robotics/?2017a%2FMember%2Fkk%2FMission2]])を基本に、缶をいれるアームを取り付けた。缶を1つ取るごとに地点Tに運ぶので、アームは缶1つ分の大きさになっている。とてもシンプルな構造である。
*プログラム [#m616e83c]
**全体的な説明 [#u4c673a4]
運ぶ缶はE、F、EF間のカーブの3つのみである。他の缶は時間が足りず、着手できなかった。また、Tの缶は積み上げロボットが動き出すときに押しのけられて排除される。
&br;基本的には黒線をトレースして缶を運ぶが、途中でトレースではうまく缶をアームに入れられない箇所や、Tに缶を置くときなどは、トレースをせずに黒線から外れて動くこともある。詳しくはルートの項目で説明する。
**ルート [#me834eb6]
運搬ロボットの役目は缶をTまで運ぶことである。缶をTに運んでから積み上げロボットに合図を送ると、あとは積み上げロボットが缶を回収し、積み上げる。
缶をTに運ぶルートは、A-Eの缶を取る-Tに置く-Fの缶を取る-Tに置く-EF間の缶を取る-Tに置く-しばらく缶から離れる-3段に積み上げられた缶をゴールの中に入れる-缶から離れる、である。細かくわけて別々に詳しく説明する。下図の赤線はトレースして動く箇所、緑はトレースしないで動く箇所である。コースの画像は[[課題3:http://yakushi.shinshu-u.ac.jp/robotics/?2017a%2FMission3]]のものを使っている。
***A-Eの缶を取る-Tに置く[#e8fab088]
#ref(./start-t.JPG,50%,A-E-T);
A-E-P-S-R-Tの目の前 と動く。Rまでは黒線をトレースして、Rからは秒数を指定し回転、直進する。これは、缶をTに置くためには、アーム部分の大きさを考えて機体は交差点の手前で止まらないといけないが、私の作ったプログラムでは直進の途中でトレースをやめることができなかったからである。なので、Tに缶を置くときはいつもトレースではなく普通に直進する。また、Tに缶を置いたら積み上げロボットに合図を出し、積み上げロボットは動き出す。
***T-Fの缶を取る-Tに置く [#h81eaa77]
#ref(./f-t.JPG,50%,T-F-T);
缶を置いた後、一度バックしてRを越えたあたりまで行く。その後機体は大きく時計回りをして円弧SRを光センサーで見つけ出す。そこからトレースでS-Pと動いたら、Pでしばらく待機し、積み上げロボットが最初に運んだ缶をつかみコースから離れるための時間をかせぐ。ある程度待機したら、Fの方向を向き、直進してFの缶を取る。その後、再び時計回りをして円弧QRを見つけ、トレースし、Rへ行く。Rからは一つ目の缶と同じ要領でTに缶を置く。
&br;PからFに直線で向かうのは、P-Q-FとトレースしていくとQからFの方向を向くときにアームが缶にあたり、缶を弾き飛ばしてしまうからである。
***T-EF間の缶を取る-Tに置く [#l46bbe24]
#ref(./ef-t.JPG,50%,T-EF-T);
同じようにバック、時計回りで円弧SRを見つける。そこからS-P-E-EF間で缶を取る-F-Q-P-S-Rとトレースし続ける。ただし、Pで一度止まって積み上げロボットが仕事をする時間を稼ぐ。そして、Rまで来たらまた同じ要領で缶をTまで運ぶ。
&br;EF間の缶は黒線の右側をトレースしていくと自動的にアームに収まる。
&br;また、Qに着いた後にQ-Rと向かわずにQ-P-S-Rと遠回りするのは、F-Qは線の右側をトレースしていて、線の右側をトレースしていると交差点を認識するときに機体が少し右に曲がってしまうので、交差点を左に曲がるプログラムを作るよりも、そのまま右に曲がるほうが簡単だったからである。
***T-一度離れる-ゴールに缶を押し込む [#kf3efc98]
#ref(./end.JPG,50%,end);
3つ目の缶をTに運んだあと、また同じ様にバック、時計回り、円弧PSを見つけ、
**プログラム [#j635eab0]
#define CONN 1
    #define CONN 1
    int a;
    long t;
    int msg;

    sub sound_up()                        //SOUND_UPを鳴らす。
    {    
	    PlaySound(SOUND_UP);
    
    }
    
    sub migi_susumu(int x)                    //黒線の右側をトレースする。xは出発する交差点の曲がり始めや誤認しやすいカーブを超える大体の秒数を入れる。 
    {
        t=CurrentTick();
        while(CurrentTick()-t<x){
            a=0;
            while(a<=3){
                if(SENSOR_1>=55){            //左
                    OnFwd(OUT_A,30);
                    OnRev(OUT_C,30);
                }else if(SENSOR_1>
                    OnFwd(OUT_A,30);
                    Off(OUT_C);
                }else if(SENSOR_1>=45){
                    OnFwd(OUT_C,30);
                    Off(OUT_A);
                }else{                    //右
                    OnFwd(OUT_C,30);
                    OnRev(OUT_A,30);
                    a=a+1;
                }
            } 
        }
    sound_up();
    }

    sound_up();

}



sub hidari_susumu(int y)                    //黒線の左側をトレースする。yは上のxと同じ。

{

    t=CurrentTick();

    while(CurrentTick()-t<y){

        a=0;

        while(a<=3){

            if(SENSOR_1>=55){            //右

                OnFwd(OUT_C,30);

                OnRev(OUT_A,30);

            }else if(SENSOR_1>=50){

                OnFwd(OUT_C,30);

                Off(OUT_A);

            }else if(SENSOR_1>=45){

                OnFwd(OUT_A,30);

                Off(OUT_C);

            }else{                    //左

                OnFwd(OUT_A,30);

                OnRev(OUT_C,30);

                a=a+1;

    sub hidari_susumu(int y)                    //黒線の左側をトレースする。yは上のxと同じ。
    {
        t=CurrentTick();
        while(CurrentTick()-t<y){
            a=0;
            while(a<=3){
                if(SENSOR_1>=55){            //右
                    OnFwd(OUT_C,30);
                    OnRev(OUT_A,30);
                }else if(SENSOR_1>=50){
                    OnFwd(OUT_C,30);
                    Off(OUT_A);
                }else if(SENSOR_1>=45){
                    OnFwd(OUT_A,30);
                    Off(OUT_C);
                }else{                    //左
                    OnFwd(OUT_A,30);
                    OnRev(OUT_C,30);
                    a=a+1;
                }
            }

        }
        sound_up();
    }

    sub chousei()                    //機体は急激に曲がりだすと交差点と認識するため、交差点を直進したいときは機体の角度を調整、行きたい線上に持っていく。
    {
        OnFwd(OUT_A,35);
        OnRev(OUT_C,35);
        Wait(600);
        OnFwd(OUT_AC,30);
        Wait(400);
    }
    
    sub chousei_2()                    //機体は急激に曲がりだすと交差点と認識するため、交差点を直進したいときは機体の角度を調整、行きたい線上に持っていく。
    {
        OnFwd(OUT_C,30);
        OnRev(OUT_A,30);
        Wait(750);
        OnFwd(OUT_AC,30);
        Wait(500);
    }

    sound_up();
    sub s_t()                    //地点S側から地点Rに来た機体を地点Tの前で停止させる。
    {
        OnFwd(OUT_C,20);
        OnFwd(OUT_A,10);
        Wait(600);
        OnFwd(OUT_AC,30);
        Wait(950);
        Off(OUT_AC);
        Wait(400);
        sound_up();
    } 
    
    sub q_t()                    //地点Q側から地点Rに来た機体を地点Tの前で停止させる。
    {
        OnRev(OUT_A,15);
        OnFwd(OUT_C,40);
        Wait(230);
        OnFwd(OUT_AC,30);
        Wait(600);
        sound_up();
    }

}



sub chousei()                    //機体は急激に曲がりだすと交差点と認識するため、交差点を直進したいときは機体の角度を調整、行きたい線上に持っていく。

{
    OnFwd(OUT_A,35);

    OnRev(OUT_C,35);

    Wait(600);

    OnFwd(OUT_AC,30);

    Wait(400);

}



sub chousei_2()                    //機体は急激に曲がりだすと交差点と認識するため、交差点を直進したいときは機体の角度を調整、行きたい線上に持っていく。

{

    OnFwd(OUT_C,30);

    OnRev(OUT_A,30);

    Wait(750);

    OnFwd(OUT_AC,30);

    Wait(500);

}



sub s_t()                    //地点S側から地点Rに来た機体を地点Tの前で停止させる。

{

    OnFwd(OUT_C,20);

    OnFwd(OUT_A,10);

    Wait(600);

    OnFwd(OUT_AC,30);

    Wait(950);

    Off(OUT_AC);

    Wait(400);

    sound_up();

}



sub q_t()                    //地点Q側から地点Rに来た機体を地点Tの前で停止させる。

{

    OnRev(OUT_A,15);

    OnFwd(OUT_C,40);

    Wait(230);

    OnFwd(OUT_AC,30);

    Wait(600);

    sound_up();

}



sub hukki_s()                    //Tに缶を置いた後、後退して旋回、円弧SRを見つけ出し、地点Sまで進む。

{

    OnRev(OUT_AC,40);

    Wait(950);

    OnFwd(OUT_C,35);

    OnRev(OUT_A,10);

    Wait(1000);

    while(SENSOR_1>=50){
   
     OnFwd(OUT_C,30);

        OnRev(OUT_A,10);

    }

    Off(OUT_AC);

    hidari_susumu(1000);

    sound_up();

}



sub hukki_r()                    //地点Fの缶を取った後、旋回して円弧QRを見つけ出し、地点Rまで進む。

{

    OnFwd(OUT_C,30);

    OnRev(OUT_A,10);

    Wait(3000);

    while(SENSOR_1>=50){
   
     OnFwd(OUT_C,30);

        OnRev(OUT_A,10);

    }

    Off(OUT_AC);

    hidari_susumu(1500);
   
 sound_up();

}



task main()

{
   
 SetSensorLight(S1);

    OnFwd(OUT_AC,30);            //Aから出るため少し直進する

    Wait(600);
  migi_susumu(1500);            //地点E、缶を取る

    migi_susumu(1500);            //地点P

    migi_susumu(1500);            //地点S

    chousei();

    migi_susumu(2000);            //地点R

    s_t();                    //地点Tに缶を置く

    RemoteStartProgram(CONN,"taiki.rxe");


    hukki_s();                //地点S

    chousei_2();

    hidari_susumu(2000);            //地点P

    Off(OUT_AC);                //ブレをなくすためにモーターの回転を止める

    Wait(20000);

    OnFwd(OUT_C,30);            //地点Fの方向へ向き、まっすぐ進む

    OnRev(OUT_A,30);
 
   Wait(900);
   
 OnFwd(OUT_AC,30);

    Wait(1900);

    sound_up();                //Fの缶を取る

    hukki_r();                //地点R

    q_t();                    //地点Tに缶を置く


    OnRev(OUT_A,10);
RemoteStartProgram(CONN,"tumu.rxe");


    hukki_s();                //地点S

    chousei_2();

    hidari_susumu(2000);            //地点P

    OnFwd(OUT_AC,30);            //機体を線の左側から右側に変える

    Wait(600);

    Off(OUT_AC);

    Wait(15000);

    migi_susumu(1500);            //地点E

    migi_susumu(28000);            //地点Q

    migi_susumu(1500);            //地点P

    chousei();
    migi_susumu(2000);            //地点S

    chousei();

    migi_susumu(2000);            //地点R

    s_t();                    //地点Tに缶を置く

    OnFwd(OUT_A,30);

    OnFwd(OUT_C,35);
    Wait(500);

    RemoteStartProgram(CONN,"tumu2.rxe");

    OnRev(OUT_AC,30);

    Wait(500);

    hukki_s();                //地点S

    chousei_2();

    hidari_susumu(2000);            //地点
 
    chousei_2();

    hidari_susumu(2000);            //地点Q

    chousei_2();

    Off(OUT_AC);

    Wait(15000);

    hidari_susumu(2000);            //地点R

    hidari_susumu(1500);

    Off(OUT_AC);

    OnRev(OUT_AC,30);

    Wait(1500);




}


*ロボコン結果と総評 [#n4eb9d8d]



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