#contents

*課題2[#p5eb685a]
指定の道をあらかじめ模造紙に描き、第1コース・第2コースそれぞれの道順に沿って製作したロボットを動かす。また、その途中に、350mlの空き缶を指定の位置から、指定の位置に運ぶ。

*コース[#l49cfc9f]
第2コース
#ref(2018a-mission2.png)
 1Aをスタート
 2Bを右折
 3Jで一時停止の後、Yの空き缶をキャッチしてJに戻る
 4JからKに向かい、Kを直進
 5Lを直進
 6Iを左折
 7Hで一時停止の後、左折
 8Gで一時停止の後、右折
 9Fで一時停止の後、右折
 10Eを直進
 11Dで一時停止の後、空き缶をXに置いてDに戻り、Cに向かう
 12Cで一時停止の後、直進
 13Bを直進
 14Aで停止
 (一時停止の指定がある場所は、1秒間停止すること)

*ロボットの説明[#fbbc27ea]

**車輪部分[#k29f6177]
課題1と同様、シンプルな3輪構造で、前輪が2輪、後輪が1輪となっている。前輪の2輪が駆動し、後輪の2輪が自由に回転する。

**センサーライト部分 [#zcdc4beb]
2つの車輪ほぼ真ん中前方に、確実に明るさを読み取れるような高さに設置した。
#ref(IMG_1298.JPG)

**アーム[#y0f7317f]
#ref(IMG_1301.JPG)
#ref(アーム.png)
モータBに歯車を直接取り付け、
アームの動作は缶をつかむ動作、缶の方向を変える動作、缶を離す動作の3段階に分かれている。

***缶をつかむ動作 [#u0daf4ae]
モータBを稼働させるだけでは先にアームの方向が変わってしまうので、図のようにある程度固定し、缶をつかむ動作のみが稼働するようにした。
#ref(IMG_1300neo.png)

***缶の方向を変える動作 [#ce6f913e]
缶をつかむ動作を終えると缶をつかむ動きが固定され、缶の方向をかえる力が大きくなる。すると、上の図の部品が外れ、缶の方向が左に変わる。

***缶を離す動作 [#kefdb2d7]
缶の方向が変わると赤で囲まれた部分が回転し、それとともに黄で囲まれた部分が上昇し、回転部分にひっかかる。すると、缶の方向を変える部分が固定され、モータBを回すと、缶を離す。
#ref(IMG_1299ex.png)

*交差点の感知 [#vb1866bb]
今回、私は関数DAI(DAIに深い意味はない)を使って交差点を感知する方法として採用した。関数DAIは4つの範囲で図に示した数値を足されることになっている。
#ref(白黒数値2.png)
 #define LEFT_LINE if(DEEPWHITE){RIGHT DAI -= 3;} else if(WHITE){BIT_RIGHT DAI -= 1;} else if(DEEPBLACK){LEFT DAI += 3;} else if(BLACK){BIT_LEFT DAI += 1;} else {STRAGHT DAI *= 0;}    
 #define RIGHT_LINE if(DEEPWHITE){LEFT DAI -= 3;} else if(WHITE){BIT_LEFT DAI -= 1;} else if(DEEPBACK){RIGHT DAI += 3;} else if(BLACK){BIT_RIGHT DAI += 1;} else {STRAGHT DAI *= 0;}
プログラムのようにその時位置している範囲に従ってそれ相応の数値を足され、指定の方向へ移動する。どの範囲にも属さない時(丁度白と黒の境界にある時)は直進する。

*プログラミングにあたっての準備[#heeafd24]
**色分けするプログラム[#q1542e47]
***白 [#i87cddeb]
#define DEEPWHITE SENSOR_1 > 48
***少し白 [#g54731d9]
#define WHITE SENSOR_1 > 44
***黒 [#t0ece9d1]
#define BLACK SENSOR_1 < 40
***少し黒 [#hdece4ff]
#define DEEPBLACK SENSOR_1 < 36
**指定した方向に一瞬動くプログラム[#k96c0c5c]
***右[#gabb9e62]
#define RIGHT OnFwd(OUT_A,30);OnRev(OUT_C,30);Wait(1);Off(OUT_AC);
***少し右[#f2a3eb93]
#define BIT_RIGHT OnFwd(OUT_A,30);OnRev(OUT_C,10);Wait(1);Off(OUT_AC);
***左[#yf200910]
#define LEFT OnFwd(OUT_C,30);OnRev(OUT_A,30);Wait(1);Off(OUT_AC);
***少し左[#m9a0ad8a]
#define BIT_LEFT OnFwd(OUT_C,30);OnRev(OUT_A,10);Wait(1);Off(OUT_AC);
***直線方向[#d825c59f]
#define STRAGHT OnFwd(OUT_AC,30);Wait(1);Off(OUT_AC);
**左が白、右が黒の境界をたどるプログラム [#t5d828c2]
 右[#gabb9e62]
 #define RIGHT OnFwd(OUT_A,30);OnRev(OUT_C,30);Wait(1);Off(OUT_AC);
 少し右[#f2a3eb93]
 #define BIT_RIGHT OnFwd(OUT_A,30);OnRev(OUT_C,10);Wait(1);Off(OUT_AC);
 左[#yf200910]
 #define LEFT OnFwd(OUT_C,30);OnRev(OUT_A,30);Wait(1);Off(OUT_AC);
 少し左[#m9a0ad8a]
 #define BIT_LEFT OnFwd(OUT_C,30);OnRev(OUT_A,10);Wait(1);Off(OUT_AC);
 直線方向[#d825c59f]
 #define STRAGHT OnFwd(OUT_AC,30);Wait(1);Off(OUT_AC);
各方向に1000分の1秒進み、その時間毎に今存在している範囲を感知することで正確にライントレースできるようにした。

**左が黒、右が白の境界をたどるプログラム [#t115172a]
 #define KANSU DAI < 150
ライントレース中は4つの範囲を行き来するのでほぼ±0に保たれ、交差点にさしかかるとDEEPBLACKの範囲上に比較的長時間存在するので関数DAIが増加し、関数DAIが150を超えると次の動作へうつる。
また、関数DAIを正確に測るためにライントレース前には"DAI *= 0"(関数DAIに0をかけて0にする)をする。

**車輪を止めるプログラム [#odb449aa]
*交差点からの右折等 [#nb589184]
(例)右折
#ref(右折1.png)
#ref(右折2.png)
#ref(右折3.png)
交差点を感知し、停止する。(図A)
85°くらい回転する。(図B)
 while(BLACK){OnFwd(OUT_AC,20);}
地面がBLACKになるまで直進する。(図C)
ライントレースする。

**1秒間止まるプログラム [#d4070551]
*プログラミングにあたっての準備[#heeafd24]
**色分けし、それに伴う方向に動くプログラム [#u32bece1]

 #define DEEPWHITE SENSOR_1 > 48
 少し白 [#g54731d9]
 #define WHITE SENSOR_1 > 44
 少し黒ece9d1]
 #define BLACK SENSOR_1 < 40
 黒 [#hdece4ff]
 #define DEEPBLACK SENSOR_1 < 36
 右[#gabb9e62]
 #define RIGHT OnFwd(OUT_A,30);OnRev(OUT_C,30);Wait(1);Off(OUT_AC);
 少し右[#f2a3eb93]
 #define BIT_RIGHT OnFwd(OUT_A,30);OnRev(OUT_C,10);Wait(1);Off(OUT_AC);
 左[#yf200910]
 #define LEFT OnFwd(OUT_C,30);OnRev(OUT_A,30);Wait(1);Off(OUT_AC);
 少し左[#m9a0ad8a]
 #define BIT_LEFT OnFwd(OUT_C,30);OnRev(OUT_A,10);Wait(1);Off(OUT_AC);
 直線方向[#d825c59f]
 #define STRAGHT OnFwd(OUT_AC,30);Wait(1);Off(OUT_AC);
#ref(白黒判別.png)
※上のプログラムを組み合わせて図のように動作するようにした。

**缶を掴むプログラム [#x1b04c76]
 #define LEFT_LINE if(DEEPWHITE){RIGHT DAI -= 3;} else if(WHITE){BIT_RIGHT DAI -= 1;} else if(DEEPBLACK){LEFT DAI += 3;} else if(BLACK){BIT_LEFT DAI += 1;} else {STRAGHT DAI *= 0;}    
 #define RIGHT_LINE if(DEEPWHITE){LEFT DAI -= 3;} else if(WHITE){BIT_LEFT DAI -= 1;} else if(DEEPBACK){RIGHT DAI += 3;} else if(BLACK){BIT_RIGHT DAI += 1;} else {STRAGHT DAI *= 0;}
 #define KANSU DAI < 150
それぞれ左・右のライントレース時に使うプログラム                               
#br

**缶を離すプログラム [#x88c9fb1]
 #define OFF Off(OUT_AC);
#br
 #define WAIT Wait(1000);
車輪を止めるプログラムと停止するプログラム
#br

**ある関数DAIが150以下であることを示すプログラム [#jc6361cb]
 #define CATCH OnFwd(OUT_AC,20);Wait(300);OFF OnFwd(OUT_B,30);Wait(300);Off(OUT_B);OnRev(OUT_AC,20);Wait(300);OFF
#br
 #define RELEASE OnFwd(OUT_B,30);Wait(1000);Off(OUT_B);Wait(500);OnRev(OUT_B,30);Wait(500);Off(OUT_B);
それぞれアームを閉開するプログラム
#br

**その場で右に旋回するプログラム [#rf6d05fd]
 #define SIMPLE_RIGHT OnFwd(OUT_A,40);OnRev(OUT_C,40);
#br
 #define SIMPLE_LEFT OnFwd(OUT_C,40);OnRev(OUT_A,40);
それぞれ右・左にその場で旋回するプログラム
#br

**その場で左に旋回するプログラム [#qd7894a9]
 #define GO_STRAIGHT OnFwd(OUT_A,40);OnFwd(OUT_C,40);Wait(190);OFF
 #define MOVE_RIGHT SIMPLE_RIGHT Wait(750); OFF
#br
 #define GO_STRAIGHT OnFwd(OUT_A,40);OnFwd(OUT_C,40);Wait(190);OFF
 #define MOVE_LEFT SIMPLE_LEFT Wait(750); OFF
それぞれ交差点で右・左に曲がるプログラム

**交差点で使用するプログラム [#j9565418]

***交差点で右に曲がるプログラム [#c3db0d7e]

**交差点で左に曲がるプログラム [#p5185051]


















#define DEEPWHITE SENSOR_1 > 48
#define WHITE SENSOR_1 > 44
#define BLACK SENSOR_1 < 40
#define DEEPBLACK SENSOR_1 < 36
#define RIGHT OnFwd(OUT_A,30);OnRev(OUT_C,30);Wait(1);Off(OUT_AC);
#define BIT_RIGHT OnFwd(OUT_A,30);OnRev(OUT_C,10);Wait(1);Off(OUT_AC);
#define LEFT OnFwd(OUT_C,30);OnRev(OUT_A,30);Wait(1);Off(OUT_AC);
#define BIT_LEFT OnFwd(OUT_C,30);OnRev(OUT_A,10);Wait(1);Off(OUT_AC);
#define STRAGHT OnFwd(OUT_AC,30);Wait(1);Off(OUT_AC);
#define LEFT_LINE if(DEEPWHITE){RIGHT DAI -= 3;} else if(WHITE){BIT_RIGHT DAI -= 1;} else if(DEEPBLACK){LEFT DAI += 3;} else if(BLACK){BIT_LEFT DAI += 1;} else {STRAGHT DAI *= 0;}    
#define RIGHT_LINE if(DEEPWHITE){LEFT DAI -= 3;} else if(WHITE){BIT_LEFT DAI -= 1;} else if(DEEPBLACK){RIGHT DAI += 3;} else if(BLACK){BIT_RIGHT DAI += 1;} else {STRAGHT DAI *= 0;}                               
#define OFF Off(OUT_AC);
#define WAIT Wait(1000);
#define CATCH OnFwd(OUT_AC,20);Wait(300);OFF OnFwd(OUT_B,30);Wait(300);Off(OUT_B);OnRev(OUT_AC,20);Wait(300);OFF
#define RELEASE OnFwd(OUT_B,30);Wait(1000);Off(OUT_B);Wait(500);OnRev(OUT_B,30);Wait(500);Off(OUT_B);
#define KANSU DAI < 150
#define SIMPLE_RIGHT OnFwd(OUT_A,40);OnRev(OUT_C,40);
#define SIMPLE_LEFT OnFwd(OUT_C,40);OnRev(OUT_A,40);
#define GO_STRAIGHT OnFwd(OUT_A,40);OnFwd(OUT_C,40);Wait(190);OFF
#define MOVE_RIGHT SIMPLE_RIGHT Wait(750); OFF
#define MOVE_LEFT SIMPLE_LEFT Wait(750); OFF

*プログラム本編 [#d73f6990]
task main()
{
 {
    SetSensorLight(S1);

 
    int DAI=0;

 
    while(KANSU){
                    RIGHT_LINE
                  }
    OFF
    DAI *= 0;
    PlaySound(SOUND_DOWN);

    GO_STRAIGHT
    MOVE_RIGHT

    DAI *= 0;           //右ライントレース
    PlaySound(SOUND_DOWN);         //音を鳴らす
 
    GO_STRAIGHT                    //少し直進
    MOVE_RIGHT                     //右に85°曲がる
 
    while(KANSU){
                    RIGHT_LINE
                  }
    OFF
    DAI *= 0;
    PlaySound(SOUND_UP);
    WAIT
    CATCH

    OnFwd(OUT_B,10);

    GO_STRAIGHT
    MOVE_LEFT

    DAI *= 0;                      //右ライントレース
    PlaySound(SOUND_UP);           //音を鳴らす
    WAIT                           //停止
    CATCH                          //掴む
 
    OnFwd(OUT_B,10);               //掴み続ける
 
    GO_STRAIGHT                    //少し直進
    MOVE_LEFT                      //左に85°曲がる
 
    while(BLACK){
                    OnFwd(OUT_AC,20);
                  }
    OFF

    OFF                            //黒になるまで直進
 
    repeat(2){
                 while(KANSU){
                                 LEFT_LINE
                                 }
                 OFF
                 DAI *= 0;

                 DAI *= 0;                      //左ライントレース
 
                 SIMPLE_RIGHT
                 Wait(50);
                 OFF

                 OFF                            //微調整
 
                 while(BLACK){
                                 OnFwd(OUT_AC,30);
                                 }
                 OFF
                 OFF                            //黒になるまで直進
               }

 
    while(KANSU){
                    LEFT_LINE
                  }
    OFF
    PlaySound(SOUND_UP);
    WAIT
    OFF                            //左ライントレース
    PlaySound(SOUND_UP);           //音を鳴らす
    WAIT              //停止
    DAI *= 0;

 
    OnFwd(OUT_AC,30);
    Wait(50);
    OFF

 
    SIMPLE_LEFT
    Wait(450);
    OFF

    OFF                            //微調整
 
    while(KANSU){
                    LEFT_LINE
                  }
    OFF
    DAI *= 0;

    DAI *= 0;                      //左ライントレース
 
    while(BLACK){
                    OnFwd(OUT_A,30);OnFwd(OUT_C,30);
                  }
    OFF

    OFF                            //黒になるまで直進
 
    while(KANSU){
                    RIGHT_LINE
                  }
    OFF
    DAI *= 0;

    DAI *= 0;                      //右ライントレース
 
    while(BLACK){
                    OnFwd(OUT_A,30);OnFwd(OUT_C,30);
                  }
    OFF

    OFF                            //黒になるまで直進
 
    while(KANSU){
                    LEFT_LINE
                  }
    OFF
    DAI *= 0;

    GO_STRAIGHT
    MOVE_LEFT

    DAI *= 0;                      //左ライントレース
 
    GO_STRAIGHT                    //少し直進
    MOVE_LEFT                      //左に85°曲がる
 
    while(KANSU){
                    LEFT_LINE
                  }
    OFF
    WAIT
    DAI *= 0;

    GO_STRAIGHT
    MOVE_RIGHT

    DAI *= 0;                      //左ライントレース
    WAIT                           //停止
 
    GO_STRAIGHT                    //少し直進
    MOVE_RIGHT                     //右に85°曲がる
 
    while(BLACK){
                    OnFwd(OUT_A,30);OnFwd(OUT_C,30);
                  }
    OFF

    OFF                            //黒になるまで直進
 
    while(KANSU){
                    RIGHT_LINE
                  }
    OFF
    WAIT
    DAI *= 0;
    PlaySound(SOUND_UP);

    GO_STRAIGHT
    MOVE_RIGHT

    DAI *= 0;                      //右ライントレース
    WAIT                           //停止
    PlaySound(SOUND_UP);           //音を鳴らす
 
    GO_STRAIGHT                    //少し直進
    MOVE_RIGHT                     //右に85°曲がる
 
    while(KANSU){
                    RIGHT_LINE
                  }
    OFF

    OFF                            //右ライントレース
 
    SIMPLE_RIGHT
    Wait(50);
    OFF

    OFF              //微調整
 
    while(BLACK){
                    OnFwd(OUT_AC,30);
                   }
    OFF

    OFF                            //黒になるまで直進
 
    while(KANSU){
                    RIGHT_LINE
                  }
    OFF

    Off(OUT_B);
    WAIT
    RELEASE

    OFF                            //右ライントレース
 
    Off(OUT_B);                    //掴み続けることをやめる
    WAIT                           //停止
    RELEASE                        //離す
 
    OnFwd(OUT_AC,30);
    Wait(80);
    OFF

 
    SIMPLE_RIGHT
    Wait(500);
    OFF

    OFF              //微調整
 
    while(KANSU){
                    RIGHT_LINE
                  }
    OFF
    DAI *= 0;

    GO_STRAIGHT
    MOVE_RIGHT

    DAI *= 0;                      //右ライントレース
 
    GO_STRAIGHT                    //少し直進
    MOVE_RIGHT                     //右に85°曲がる
 
    while(KANSU){
                    RIGHT_LINE
                  }
    OFF
    WAIT
    DAI *= 0;
    PlaySound(SOUND_UP);

    DAI *= 0;                      //右ライントレース
    WAIT                           //停止
    PlaySound(SOUND_UP);           //音を鳴らす
 
    while(BLACK){
                    OnFwd(OUT_A,30);OnFwd(OUT_C,29);
                  }
    OFF

    OFF                            //黒になるまで直進
 
    while(KANSU){
                    RIGHT_LINE
                  }
    OFF
    DAI *= 0;
    PlaySound(SOUND_FAST_UP);
}
    DAI *= 0;                      //右ライントレース
    PlaySound(SOUND_FAST_UP);      //音を鳴らす
 }

*課題2を終えて [#oe801b50]

**苦労した点 [#p3e849d8]
作成の過程では、センサーライトやアームを所定の位置に設置しつつ、全体のバランスを保つことが難しかった。また、アーム部分を1つのモータで2段階動かすことにこだわり過ぎて、時間と労力を使い過ぎた。プログラミングの過程では、交差点などを正常に通過させる確率を上げることが大変だった。

**工夫した点 [#u95b7b61]
上では苦労したと書いたが、やはり、あらゆる工夫を取り込んで、1つのモータで2段階動かすことができたことがよかった。また、ライントレースに関数を使用することで安定して交差点を認識できるようにした。


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