[[2018a/Member]] #contents *課題 [#f6ad0114] 黒い線に沿って動き、350mlの空き缶(黄色で表示)を移動させるロボットを製作せよ。 **コース [#i9cec202] 私は、第一コースを選択した。 &ref(2018a/Member/Mooo/Mission2/keiro.png,100,経路図); *ロボットの説明 [#rdc3491f] &ref(2018a/Member/Mooo/Mission2/ロボ.jpeg,100,本体); ロボットは、前輪の左右両方に一つずつモーターを取り付け、小回りが利くようにするために後輪部分をタイヤではなく滑りやすい部品にしてある。缶をつかむ方式は、多少位置がずれても確実に缶をつかめるよう、2本の腕をギアを用いて連動させ、クワガタムシのように左右から挟む構造とした。また、光センサーはなるべく地面すれすれになるように設置した。 -ロボットは、前輪の左右両方に一つずつモーターを取り付け、小回りが利くようにするために後輪部分をタイヤではなく滑りやすい部品にしてある。 -缶をつかむ方式は、多少位置がずれても確実に缶をつかめるよう、2本の腕をギアを用いて連動させ、クワガタムシのように左右から挟む構造とした。 -また、光センサーはなるべく地面すれすれになるように設置した。 *プログラムの説明 [#w686cf63] **基本事項の定義 [#a97dd57b] ***色 [#r2bea5dd] #define Bl 37 #define BG 45 #define Gr 50 #define WG 55 #define Wh 60 上から黒、濃い灰色、灰色、薄い灰色、白になっている。 数値の微調整には苦労した。 ***5つの動き [#v8393aa2] 五色の識別をした際にロボットが行動する五パターンの動きも予め定義しておく。 #define RR OnFwd(OUT_C,30);OnRev(OUT_B,30); // 右旋回 #define TR OnFwd(OUT_C,30);Off(OUT_B); // 右折 #define GS OnFwd(OUT_BC,30); // 直進 #define TL Off(OUT_C);OnFwd(OUT_B,30); // 左折 #define RL OnRev(OUT_C,30);OnFwd(OUT_B,30); // 左旋回 ***アームの定義 [#w2621d08] アームの缶を掴む動きと、放す動きも定義しておく。 #define Ca RotateMotor(OUT_A,-30,40); #define Re RotateMotor(OUT_A,30,40); 上が掴むプログラム、下が放すプログラム。 **プログラムの方針 [#o5c83216] 私は基本的なプログラムの方針として、センサーで五段階に色を識別させ白と黒の境界線を辿らせることにした。また、交差点の識別は、連続して黒を検出した回数により判断することにした。 ***色の五段階識別 [#p615b97c] task main(){ if (SENSOR_2<Bl) { //光センサーが黒と判断したならば DO1; } else if (SENSOR_2<BG) { //光センサーが濃い灰色と判断したならば DO2; } else if (SENSOR_2<Gr) { //光センサーが灰色と判断したならば DO3; } else if (SENSOR_2<WG) { //光センサーが薄い灰色と判断したならば DO4; } else { //光センサーが白と判断したならば DO5; } } このプログラムを用いることで、各色ごとに異なる行動をロボットにさせることができる。このプログラムを応用して、白と黒の境界線をたどらせる。 ***交差点の識別 [#ffcb12d1] { int N=0; while(N<100){ if (SENSOR_2<Bl) { N++; //Nに1を足す } else if (SENSOR_2<BG) { N=0; //Nを0のする } else if (SENSOR_2<Gr) { N=0; //Nを0のする } else if (SENSOR_2<WG) { N=0; //Nを0のする } else { N=0; //Nを0のする } }} このプログラムを見てわかるように、今回私は100回連続で光センサーが黒を認識したと きそこを交差点と認識することとした。 **サブルーチンの定義 [#h60ec4cc] 右側の境界線を辿るプログラムと、左側の境界線を辿るプログラムをサブルーチンを使い定義しておく。 ここで先ほど上で紹介した「色の五段階識別」と「交差点の識別」のプログラムを使用する。 ***右側の境界線を辿るプログラム [#x5b90285] sub GOR() { int N=0; while(N<100){ if (SENSOR_2<Bl) { RR; N++; } else if (SENSOR_2<BG) { TR; N=0; } else if (SENSOR_2<Gr) { GS; N=0; } else if (SENSOR_2<WG) { TL; N=0; } else { RL; N=0; } Wait(STEP); } } ***左側の境界線を辿るプログラム [#yb530fdb] sub GOL() { int N=0; while(N<100){ if (SENSOR_2<Bl) { RL; N++; } else if (SENSOR_2<BG) { TL; N=0; } else if (SENSOR_2<Gr) { GS; N=0; } else if (SENSOR_2<WG) { TR; N=0; } else { RR; N=0; } Wait(STEP); } } **具体的な図 [#sa7df5dd] -赤線が左側境界線、青線が右側境界線をたどる場所 -緑色の部分は交差点を認識する場所 &ref(2018a/Member/Mooo/Mission2/keiroo.png,100,経路2); **最終的なプログラム [#q27faa22] #define Ca RotateMotor(OUT_A,-30,40); #define Re RotateMotor(OUT_A,30,40); #define Bl 37 // 黒 #define BG 45 #define Gr 50 #define WG 55 #define Wh 60 #define RR OnFwd(OUT_C,30);OnRev(OUT_B,30); // 右旋回 #define TR OnFwd(OUT_C,30);Off(OUT_B); // 右折 #define GS OnFwd(OUT_BC,30); // 直進 #define TL Off(OUT_C);OnFwd(OUT_B,30); // 左折 #define RL OnRev(OUT_C,30);OnFwd(OUT_B,30); // 左旋回 #define STEP 1 //実行時間 sub GOR() { int N=0; while(N<100){ if (SENSOR_2<Bl) { RR; N++; } else if (SENSOR_2<BG) { TR; N=0; } else if (SENSOR_2<Gr) { GS; N=0; } else if (SENSOR_2<WG) { TL; N=0; } else { RL; N=0; } Wait(STEP); } } sub GOL() { int N=0; while(N<100){ if (SENSOR_2<Bl) { RL; N++; } else if (SENSOR_2<BG) { TL; N=0; } else if (SENSOR_2<Gr) { GS; N=0; } else if (SENSOR_2<WG) { TR; N=0; } else { RR; N=0; } Wait(STEP); } } task main() { SetSensorLight(S2); GOL(); //A〜C Off(OUT_BC); Wait(1000); GOL(); //C〜D GS; Wait(500); GOR(); Off(OUT_BC); Wait(1000); Ca; //Dで缶をとる〜G Wait(1000); TL; Wait(1400); GOL(); GS; Wait(300); GOL(); RL; Wait(700); GOL(); Off(OUT_BC); Wait(1000); GS; //G〜I Wait(300); GOR(); RR; Wait(500); GOR(); GS; Wait(700); GOL(); RR; Wait(700); GOR(); Wait(1000); GOR(); //I〜J GS; Wait(300); GOR(); GS; Wait(1000); GOR(); Wait(1000); RL; //Jで缶を置く Wait(2000); Re; Wait(1000); RR; Wait(2000); GOR(); //J〜A GS; Wait(300); GOR(); GS; Wait(4000); Off(OUT_BC); } *まとめ [#p58174e5] 交差点を認識させるところが一番の難所だった。そこを乗り越えるとすんなりと最後までいくことができた。