#content

*課題2 [#bbc41df2]
あらかじめ指定されたコースの線に沿って動くロボットを作る。


#ref(2017b/Member/cyanomelana/Mission2/ロボットコース.JPG,80%,ロボットが通るコース)

***交差点を通る順番(上の写真も参考) [#h3a66d2d]
 1.Aをスタート
 2.Bを直進
 3.Cを右折
 4.Fを直進
 5.Rを左折(一時停止)
 6.Pを直進
 7.X地点の紙コップを取得してコースに戻る
 8.Qを左折
 9.Sを直進(一時停止)
 10.Y地点に紙コップを置いてコースに戻る
 11.Sを直進(一時停止)
 12.Fを左折(一時停止)
 13.Cを右折(一時停止)
 14.D地点へ(ゴール)

*作成したロボット [#v746d730]

作成したロボットはロボットの組み立て方が載っている本のマニュアルを参考に、台車部分を組み立て、台車の上の部分は「センサーの取り付け」「紙コップをとるためのモーターの機構」の組み立てを工夫した。(「ロボットの詳細」で説明する)

#ref(2017b/Member/cyanomelana/Mission2/IMG_6411.JPG,55%,ライントレースするロボット)~
#ref(2017b/Member/cyanomelana/Mission2/IMG_6396.JPG,55%,ライントレースするロボット)~

**ロボットの詳細 [#p642f532]
***センサーの取り付け位置 [#vc70d357]
明るさを読み取るセンサーをロボットに取り付ける工夫として、紙に書かれたラインを正確に読み取れるように地面に対して垂直にセンサーを取り付けた。

#ref(2017b/Member/cyanomelana/Mission2/IMG_6407.1.jpg,100%,ライントレースするロボット)~
#ref(2017b/Member/cyanomelana/Mission2/sensor111.JPG,90%,ライントレースするロボット)~

また、センサーの位置をできるだけ前輪の車軸の近くにすることで急カーブでもスムーズに動作するロボットを作ることができた

#ref(2017b/Member/cyanomelana/Mission2/ロボットセンサー.JPG,55%,ロボットのセンサー)~
#ref(2017b/Member/cyanomelana/Mission2/sennsa.JPG,55%,ロボットのセンサー)~

***紙コップをとる機構 [#e8250dca]
紙コップをとる機構を作るうえでの工夫として、必ず紙コップが取れるように腕の幅を広くした。

#ref(2017b/Member/cyanomelana/Mission2/ude.JPG,45%,紙コップをとる機構)~

*作成したプログラミング [#dc13cb4b]
プログラミングを作るうえでは「線の左を認識」「線の左を認識かつ交差点認識」「線の右かつ交差点認識」「紙コップをとる」「紙コップを放す」の5個のプログラミングに大きく分け、さらに交差点ごとに5個に分けたプログラミングのうち一個を使ってブルーチンを作りロボットが誤作動を起こしたとき、どのプログラミングに問題があるかを見つけやすくした。

**基本的な動作のプログラミング [#de62d4e8]
***ライントレースする仕組み [#t436f16b]
***交差点認識の仕組み [#id50299a]
**主に使用するプログラミング [#g9f1eef7]
*** [#u8892227]
*** [#u0a079ad]
*** [#efea97cb]
*** [#ad5bc5ea]
*** [#wbec5bf1]
**プログラミングの全体 [#a6ec0c7b]
まずdefineで次の内容を定義した。
 #define llt OnFwd(OUT_A,30); OnRev(OUT_C,30);//大きく左に回る
 #define lrt OnRev(OUT_A,30); OnFwd(OUT_C,30);//大きく右に回る
 #define ternleft  OnFwd(OUT_A,50); OnFwd(OUT_C,5);//左に回る
 #define ternright  OnFwd(OUT_A,5); OnFwd(OUT_C,50);//右に回る
 #define go OnFwd(OUT_A,30); OnFwd(OUT_C,30);//直進する
 #define LD OnFwd(OUT_B,30); Wait(400); Off(OUT_B);//コップを取る腕を下す
 #define LU OnRev(OUT_B,30); Wait(400); Off(OUT_B);//コップを取る腕を上げる

全体のプログラミングは「主に使用するプログラミング」で説明したプログラミングに、 次のライントレースのための初期移動を加えたもので構成されている。プログラミングはそれぞれの交差点ごとにサブルーチンを使い,分けて書いた。

***プログラミングの分け方 [#y4065fda]
 1.AB
 2.BC
 3.CFE
 4.ER
 5.RP
 6.catch(紙コップを取る)
 7.PQ
 8.QS
 9.SSA
 10.release(紙コップを放す)
 11.SSB
 12.SF
 13. FC
 14. CD

***AB間のプログラミング [#a1a3f4c0]
AB間のプログラミングは「線の右を認識、交差点を認識」するプログラミングである。~
BC間のプログラムに移動するために右に少し曲がったロボットの軌道を[ternleft]を使い、修正した。

 sub AB()
 {
    SetSensorLight(S1);
    int PB = 0;
    while(PB<180)
 {
    if(SENSOR_1<30)
  {
    lrt;
    PB++;
  }
    else if(SENSOR_1<40)
  {
    ternright;
    PB = 0;
  }
    else if(SENSOR_1<45)
  {
    go;
    PB = 0;
  }
    else if(SENSOR_1<50)
  {
    ternleft;
    PB = 0;
  }
    else
  {
    llt;
    PB = 0;
  }
    Wait(STEP);
 }
    ternleft;//少し左に曲がる
    Wait(200);
    PB = 0;
 }

***BC間のプログラミング [#u21d51ae]
BC間のプログラミングは「線の右を認識、交差点を認識」するプログラミングである。~
CFE間のプログラムに移動するために大きく右に回り、そのあと少し進み、線の左側にセンサーを移動させた。(図参照)

#ref(2017b/Member/cyanomelana/Mission2/C.JPG,40%,C交差点でのプログラミングの動き)~

 sub BC()
 {
    SetSensorLight(S1);
    int PB = 0;
    while(PB<180)
 {
    if(SENSOR_1<30)
  {
    lrt;
    PB++;
  }
    else if(SENSOR_1<40)
  {
    ternright;
    PB = 0;
  }
    else if(SENSOR_1<45)
  {
    go;
    PB = 0;
  }
    else if(SENSOR_1<50)
  {
    ternleft;
    PB = 0;
  }
    else
  {
    llt;
    PB = 0;
  }
    Wait(STEP);
 }
    Off(OUT_AC);
    lrt;          //大きく左に回る
    Wait(600);
    go;           //少し進む
    Wait(200);
    PB = 0;    
 }

***CFE間のプログラミング [#b7e9a477]
CFE間のプログラミングは「線の左を認識」するプログラミングである。~
交差点認識も含めたプログラミングを使うと急カーブの地点でセンサーが黒の上を長く移動するので交差点と認識してしまう、そこで2つの急カーブを通過するのに十分な時間(18秒)を指定し、その時間だけ「線の左を認識」するプログラムを使うことでライントレースしながらスムーズに急カーブを通過することができた。(図参照)

#ref(2017b/Member/cyanomelana/Mission2/CFE.JPG,40%,CFE間でのロボットの動き)~

 sub CFE()
 {
    SetSensorLight(S1);
    long t0 = CurrentTick();
    while(CurrentTick()-t0 <= 18000)//18秒間だけ「線の左を認識」するプログラミングでコースを進む
 {
    if(SENSOR_1<30)
  {
    llt;
  }
    else if(SENSOR_1<40)
  {
    ternleft;
  }
    else if(SENSOR_1<45)
  {
    go;
  }
    else if(SENSOR_1<50)
  {
    ternright;
  }
    else
  {
    lrt;
  }
    Wait(STEP);
 }    
 }

***ER間のプログラミング [#m739d409]
ER間のプログラミングは「線の左を認識、交差点を認識」するプログラムである。~
テスト走行の段階では、RP間のプログラムに移動するためにR地点で交差点を認識し、一時停止した後、大きく左に回るプログラムであったが、旋回後、センサーが線の左側にでるまでに時間を要するため、交差点と誤認識してしまっていた、そこでR地点で一時停止した後、大きく左に回り、そのあと少し進み、センサーが黒を判別するまで右に回るプログラムにすることによって誤認識を防いだ(図参照)

#ref(2017b/Member/cyanomelana/Mission2/ER.JPG,40%,R交差点でのロボットの動き)~

 sub ER()
 {
    SetSensorLight(S1);
    int PB = 0;
    while(PB<180)
 {
    if(SENSOR_1<30)
  {
    llt;
    PB++;
  }
    else if(SENSOR_1<40)
  {
    ternleft;
    PB = 0;
  }
    else if(SENSOR_1<45)
  {
    go;
    PB = 0;
  }
    else if(SENSOR_1<50)
  {
    ternright;
    PB = 0;
  }
    else
  {
    lrt;
    PB = 0;
  }
    Wait(STEP);
 }
    Off(OUT_AC);
    Wait(1000);
    llt;
    Wait(800);
    go;
    Wait(400);
    while(SENSOR_1>45)//センサーが黒に反応するまで右に回る
 {
    ternright;
 }
    PB = 0;    
 }    

***RP間のプログラミング [#t20dad19]
RP間のプログラミングは「線の左を認識、交差点を認識」するプログラミングである。~
紙コップを取るプログラミングに移る前に交差点を先に超えるようにした。~
交差点を超えるために左に少し曲がったロボットの軌道を[ternright]を使い、修正した。

 sub RP()
 {
    SetSensorLight(S1);
    int PB = 0;
    while(PB<180)
 {
    if(SENSOR_1<30)
  {
    llt;
    PB++;
  }
    else if(SENSOR_1<40)
  {
    ternleft;
    PB = 0;
  }
    else if(SENSOR_1<45)
  {
    go;
    PB = 0;
  }
    else if(SENSOR_1<50)
  {
    ternright;
    PB = 0;
  }
    else
  {
    lrt;
    PB = 0;
  }
    Wait(STEP);
 }
    ternright;//少し右に回る
    Wait(300);
    PB = 0;    
 }

***紙コップを取るプログラム [#i7fb0c0a]
紙コップを取るプログラムは単純でその場で回転してアームを下すだけである。~
腕の幅を大きくしたことで紙コップはとても取りやすくなった。

 sub catch()
 {
    lrt;     //その場で約90度右に回転
    Wait(1200);
    Off(OUT_AC);
    LD;
    llt;
    Wait(1200); //その場で約90度左に回転し、元の位置に戻る
    Off(OUT_AC);
 }

***PQのプログラム [#jcaca4f0]
PQ間のプログラムは「線の左を認識、交差点を認識」するプログラムである。
QS間のプログラムに移るために左の車輪を後ろに回転した後、黒の線を十分に超える時間だけ直進し、さらにその後センサーが黒に反応するまで直進させた

#ref(2017b/Member/cyanomelana/Mission2/Q1.JPG,40%,Q交差点でのロボットの動き)~

 sub PQ()
 {
    SetSensorLight(S1);
    int PB = 0;
    while(PB<180)
 {
    if(SENSOR_1<30)
  {
    llt;
    PB++;
  }
    else if(SENSOR_1<40)
  {
    ternleft;
    PB = 0;
  }
    else if(SENSOR_1<45)
  {
    go;
    PB = 0;
  }
    else if(SENSOR_1<50)
  {
    ternright;
    PB = 0;
  }
    else
  {
    lrt;
    PB = 0;
  }
    Wait(STEP);
 }
    PB = 0;
    OnRev(OUT_C,40);//左車輪を後ろに回す
    Wait(600);
    go;      //黒の線を超えるように直進する
    Wait(600);
    while(SENSOR_1>45)//黒を認識するまで直進する
 {
    go;
 }
 }

***QSのプログラミング [#j9ebd9ed]
QS間のプログラミングは「線の左を認識、交差点を認識」するプログラムである。~
SSAのプログラムに移動するために、交差点に入った後、白を認識するまで直進させることで交差点を超えた。

 sub QS()
 {
    SetSensorLight(S1);
    int PB = 0;
    while(PB<180)
 {
    if(SENSOR_1<30)
  {
    llt;
    PB++;
  }
    else if(SENSOR_1<40)
  {
    ternleft;
    PB = 0;
  }
    else if(SENSOR_1<45)
  {
    go;
    PB = 0;
  }
    else if(SENSOR_1<50)
  {
    ternright;
    PB = 0;
  }
    else
  {
    lrt;
    PB = 0;
  }
    Wait(STEP);
 }
    Off(OUT_AC);
    Wait(2000);
    while(SENSOR_1<50)//白を認識するまで直進する
 {
    go;
 }
    
 }

**プログラミングをする段階での課題 [#o4f37ae8]
*感想、反省点 [#lb541596]

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