[[2011a]] *メンバー紹介 [#s79573c3] **くまちゃん [#e0c68ca0] **hiros [#t0a10068] *マシン解説 [#c5dc4b39] *コース紹介 [#o7b65f32] *ハードウェア [#f69f9e3c] *ソフトウェア [#s2af5312] ***コード [#af8f3e5f] **くまちゃん [#g371cfff] #define THRESHOLD 40 #define FIRST_TIME 1700 #define SECOND_TIME 1500 #define THIRD_TIME 1500 #define FOURTH_TIME 1500 #define FIFTH_TIME 1500 #define TURN_TIME 0 task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT); ClearTimer(0); while (Timer(0) <= FIRST_TIME){ if ((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD)){ OnFwd(OUT_A+OUT_C); } else if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD)){ OnFwd(OUT_C); Off(OUT_A);} else if ((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD)){ OnFwd(OUT_A); Off(OUT_C);} else if ((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD)){ OnFwd(OUT_A); Off(OUT_C); PlaySound(SOUND_CLICK) ;} } ClearTimer(1); while (FIRST_TIME < Timer(1) <= SECOND_TIME) { if ((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD)){ Off(OUT_A+OUT_C); OnFwd(OUT_C); Wait(30); OnRev(OUT_A); Wait(30);} else if ((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD)){ OnFwd(OUT_A); Off(OUT_C);} else if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD)){ OnFwd(OUT_C); Off(OUT_A);} else if ((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD)){ OnFwd(OUT_A); Off(OUT_C); PlaySound(SOUND_CLICK) ;} } ClearTimer(2); while ( SECOND_TIME < Timer(2) <= THIRD_TIME ) { if ((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD)){ Off(OUT_A+OUT_C); OnFwd(OUT_C); Wait(50);} else if ((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD)){ OnFwd(OUT_A); Off(OUT_C);} else if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD)){ OnFwd(OUT_C); Off(OUT_A);} else if ((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD)){ OnFwd(OUT_A); Off(OUT_C); PlaySound(SOUND_CLICK) ;} } ClearTimer(3); while ( THIRD_TIME < Timer(3) <= FOURTH_TIME ) { if ((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD)){ Off(OUT_A+OUT_C); OnFwd(OUT_A); Wait(30); OnRev(OUT_C); Wait(30);} else if ((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD)){ OnFwd(OUT_A); Off(OUT_C);} else if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD)){ OnFwd(OUT_C); Off(OUT_A);} else if ((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD)){ OnFwd(OUT_A); Off(OUT_C); PlaySound(SOUND_CLICK) ;} ClearTimer(0); while (FOURTH_TIME <= Timer(0) <= FIFTH_TIME){ if ((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD)){ OnFwd(OUT_C); } else if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD)){ OnFwd(OUT_C); Off(OUT_A);} else if ((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD)){ OnFwd(OUT_A); Off(OUT_C);} else if ((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD)){ OnFwd(OUT_A); Off(OUT_C); PlaySound(SOUND_CLICK) ;} } ClearTimer(3); while ( Timer(3)<FIFTH_TIME ) { if ((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD)){ OnFwd(OUT_A);} else if ((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD)){ OnFwd(OUT_A); Off(OUT_C);} else if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD)){ OnFwd(OUT_C); Off(OUT_A);} else if ((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD)){ OnFwd(OUT_A); Off(OUT_C); PlaySound(SOUND_CLICK) ;} } } **hiros [#gfa35d61] ***作戦(ロータリーなし) [#wbec58d9] 2つの光センサを使って、黒線を挟み、適時修正しながら進めていく。 まずはロータリーについては考えない事にした。 交差点に到達したら、まっすぐ先に進んでいくというプログラムを考えた。 交差点の判定は、「右も左も黒であれば、交差点」と考えた。 あと、できるだけ短く書きたい、そしてどの紙でやっても動くようにしたい&わかりやすくしたい。 **hiros [#c0f85e13] #define isBlack <40 #define isWhite >40 #define R SENSOR_3 #define L SENSOR_1 #define RM OUT_C #define LM OUT_A #define LINE 8 void go(){ OnFwd(RM+LM); } void tr(){ OnFwd(LM); //Off(RM); OnRev(RM); } void tl(){ OnFwd(RM); // Off(LM); OnRev(LM); } void move(){ if (L isWhite && R isWhite) go(); else if (L isWhite && R isBlack) tr(); else if (L isBlack && R isWhite) tl(); else if (L isBlack && R isBlack){ /* PlaySound(SOUND_CLICK); go(); Wait(LINE); } } task main (){ SetSensor (R, SENSOR_LIGHT); SetSensor (L, SENSOR_LIGHT); while (1){ move(); } } ***作戦(ロータリーなし改) [#qc954620] 上のコードでは、直角な交差点ではまっすぐに進むが、私たちの交差点はかなり斜めで、「右も左も黒」、という判定になりにくい。よって、コードを新しく考える必要があった。このコードは寝ぼけていたのでアイディア自体がおかしいかもしれない。 まず、右か左のどちらが最初に黒(道)にあたったかを変数で覚えておいて、そのときに反対側(つまり回転の外側)が何回行われたかを格納しておき、その回数だけ反対側(内側)のモータを動かせば機体を道に対して平行に出来ると考えた。 ***コード [#pf8e7b07] #define isBlack <40 #define isWhite >40 #define R SENSOR_3 #define L SENSOR_1 #define RM OUT_C #define LM OUT_A #define LINE 8 void go(){ OnFwd(RM+LM); } void tr(){ OnFwd(LM); OnRev(RM); } void tl(){ OnFwd(RM); OnRev(LM); } int whichWay = 0; // if 1 then it found the way on its right first. (else if 2 then left first.) int rcount = 0; //L is rcount late. int lcount = 0; //R is lcount late. void move(){ if (L isWhite && R isWhite) go(); else if (L isWhite && R isBlack){ tr(); whichWay = 1; rcount++; lcount = 0; } else if (L isBlack && R isWhite){ tl(); whichWay = 2; lcount++; rcount = 0; } else if (L isBlack && R isBlack){ if (whichWay == 1) PlaySound(SOUND_CLICK); if (whichWay == 2) PlaySound(SOUND_DOUBLE_BEEP); while (1){ go(); if (L isWhite && R isWhite){ if (whichWay == 1) { tl(); Wait (lcount); go(); Wait (LINE); / / if (L isWhite && R isWhite) break; }else if (whichWay == 2){ tr(); Wait (rcount); go(); Wait (LINE); / / if (L isWhite && R isWhite) break; } break; } } go(); Wait (LINE); Off(RM+LM); } } task main (){ SetSensor (R, SENSOR_LIGHT); SetSensor (L, SENSOR_LIGHT); while (1){ move(); } } ***作戦(ロータリーなし改改) [#w644155f] 上のコードは、交差点に入る前、機体が線に対して平行であればうまく行くが、現実的にはそれは難しいので、改良する必要があった。例えば、右が黒で、左は白であるとき、上のコードでは「右に道がある」ということになり、すぐ右に回転をしてしまう。これだと、斜めな交差点にさしかかると「右に回転ー>左に回転」の無限ループに陥って、その場から動かなくなってしまう。 なので、回転する前に判定を入れる事にした。 ***コード [#zdd515b3] *感想 [#y22b0902] **くまちゃん [#jd2fe435] ロータリーと急角度十字路の違いをプログラムするのが大変でした。 プログラムで乗り越えようと思ったのですが、できなかったのでコースを5ブロックに分けてタイマーをセットして乗り切りました。 **hiros [#b3330aaa] #comment