空き缶をコース上に戻して再びコースに戻って進む(ando)
奇数回目に空き缶に遭遇したら、その場で反転して進み、偶数回目に遭遇したら、空き缶を押しのけて進む(sin)
共通
・速さと正確さを追求すること
・コースを1周したら自動的に止まること
・交差点では一時停止すること
初代。足はマニュアルにあるローヴァーボットそのまま。小回りもきいて、速度もですぎない、ライントレースにはベストの選択だと思った。
足はよかったがこのままでは、投げ輪をすかした時に、うまく運べず、缶が倒れてしまった。
二代目。写真のまろやかミルクのカフェラッテは買った後に、350ml缶でないことに気付いた。
上記の缶が倒れてしまう問題を改善するために、下にさながらコーカサスオオカブトのような角(バンパー)をつけた。
この角によって、缶をある程度中央に誘導するように、また運搬時にも安定するようになった。ついでにタッチセンサーの反応もよくなった。
でも上アームの輪が小さくて、うまくキャッチできない事や缶を倒す事が多かった。
そこでアームの輪を広くした。
なかなかうまくいったが、振り下ろした威力で、アームがふっとぶことが多々あった。
いろいろ組んでみたけれど、結局アームをつなぐパーツを一つにすることで強度を上げた。簡単であるのは、最善です。
最強のマシーン誕生の瞬間である。
と思ったら、アームを振り下ろした衝撃で缶が倒れるので、少しタッチセンサーの位置を前にずらして缶に当たらないように調整した。
・アームがよく崩壊するのパーツ数を少なくすることで強度をあげた。
・キャッチする際、アームが缶に当たらないようにバンパーの位置調整した。
・左右の光センサーの感覚をある程度広げてうまくライントレースするようにした。
・全体的に頑丈にした。
・アームを振り下ろす勢いが強すぎた。ギアを噛ませて調節できればよかったかもしれない。
簡単なコース、かと思いきや右のカーブの連続が予想以上の難所でコースアウトが続出した。
ライントレース開始
缶に当たる
缶をつかむ(このときロボを左右に振って完全にアームに収める)
ライントレースをしながら少し缶を押す(この時は交差点で一時停止しない)
ラインまで旋回し元の場所に缶を押す(交差点で別の線にセンサーが反応しないように最低120度は回る)
(旋回時にバンパーに引っかからないように)缶を少し押して少し下がってまた旋回してライントレース再開
三回目に缶に当たったら停止
//ライントレース(空き缶をコース上に戻して再びコースに戻って進む) #define T 40 //光センサーの域値 int C;//缶にふれた数をカウントする変数 int W;//ずっと白いかどうか判定する変数 sub trace_fwd()//トレース { if((SENSOR_1<T)&&(SENSOR_3<T)){W=0;OnFwd(OUT_A+OUT_C);} //両センサーが黒にあるとき前進 else if((SENSOR_1>T)&&(SENSOR_3>T))//両センサーが白にあるとき前進 { OnFwd(OUT_A+OUT_C); if(W==0){ClearTimer(2);}W=1; if(Timer(2)>=20){;//ずっと白だと後退する while((SENSOR_1>T)&&(SENSOR_3>T)){OnRev(OUT_A+OUT_C);} W=0;Wait(20);} } else if(SENSOR_1<T){W=0;OnFwd(OUT_C);OnRev(OUT_A);} //右センサーが黒にあるとき右へ else if(SENSOR_3<T){W=0;OnFwd(OUT_A);OnRev(OUT_C);} //左センサーが黒にあるとき左へ } void catch_can() { Off(OUT_A+OUT_C); OnFwd(OUT_B);Wait(50);Off(OUT_B);//缶をキャッチ OnFwd(OUT_A);OnRev(OUT_C);Wait(15);//左右に車体をふって完全にアームに収める OnFwd(OUT_C);OnRev(OUT_A);Wait(30); OnFwd(OUT_A);OnRev(OUT_C);Wait(15); ClearTimer(2);ClearTimer(0);while(Timer(0)<=15){trace_fwd();}Off(OUT_A+OUT_C);//前に少しライントレース OnFwd(OUT_A);OnRev(OUT_C);Wait(133);ClearTimer(0);//120度旋回 while((SENSOR_3>T)&&(Timer(0)<=17)){OnFwd(OUT_A);OnRev(OUT_C);}Wait(30);Off(OUT_A+OUT_C);//ラインがくるor270度回るまで旋回続ける OnRev(OUT_B);Wait(50);Off(OUT_B);//缶を離す OnFwd(OUT_A+OUT_C);Wait(30);Off(OUT_A+OUT_C);OnRev(OUT_A+OUT_C);Wait(30);Off(OUT_A+OUT_C);//少しおして戻る OnFwd(OUT_C);OnRev(OUT_A);Wait(133);ClearTimer(0);//120度旋回 while((SENSOR_1>T)&&(Timer(0)<=37)){OnFwd(OUT_C);OnRev(OUT_A);}Wait(30);Off(OUT_A+OUT_C);//ラインがくるor450度回るまで旋回続ける Off(OUT_A+OUT_C);ClearTimer(2); } task main() { SetSensor(SENSOR_1, SENSOR_LIGHT); SetSensor(SENSOR_3, SENSOR_LIGHT); SetSensor(SENSOR_2, SENSOR_TOUCH); C=0; W=0; ClearTimer(2);//ずっと白部分にいるかどうかのタイマー ClearTimer(1);//メインのタイマーリセット while(Timer(1)<=1200)//2分で止まる { start trace_line; until (SENSOR_2==1);//缶に触れたら少し押してライントレース止める C+=1; if(C>=3){break;}//3回目に缶に触れた時(だいたい一周した時)止まる。 Wait(100); stop trace_line; catch_can();//缶をどかす } stop trace_line; Off(OUT_A+OUT_C); } task trace_line() { while(true) { if((SENSOR_1<T)&&(SENSOR_3<T)){Off(OUT_A+OUT_C);Wait(100);OnFwd(OUT_A+OUT_C);Wait(20);} //両センサーが黒にあるとき(交差点)一時停止 trace_fwd(); } }
・缶をつかんだらすぐに後ろをむいて置くのでは、元の場所から缶がずれてしまうので、少し運んでから旋回して置く必要があった。
しかし、缶の前方がカーブだったりすると、ただまっすぐ運ぶのでは、缶を置いた後、ラインを見失ってしまう。
そのために缶をつかんだあともライントレースしながら前進し、旋回時も線までするようにした(このとき交差点の別の線に反応しないようにとりあえず最低120度は回るようにした)。
こうすることで、缶前方のコースが曲がりくねっていても、置いたあとにライントレースを続けられるようになった。汎用性(?)が増したがプログラムも増した・・・。
・ライントレースに失敗した時の為に、ずっと白い部分にいると後退し、線に復帰するようにした。
・缶をキャッチした後のライントレース時には交差点で一時停止しないように、ライントレースサブルーチンを作った。ライントレースタスクではサブルーチンをwhileしつつif文によって交差点では一時停止する。
カーブがきついとライントレースに失敗する。
sub line() //ラインをトレースさせる { OnFwd(OUT_A+OUT_C);//基本的には前身。 if (SENSOR_1 < 40){ SetPower(OUT_A,1); OnFwd(OUT_C); OnRev(OUT_A); Wait(20); if ((SENSOR_1<40)&&(SENSOR_3<40))//両方黒(交差点)なら停止して前身。 {Off(OUT_A+OUT_C);Wait(100);} Toggle(OUT_A);} if (SENSOR_3 < 40){ SetPower(OUT_C,1); OnRev(OUT_C); OnFwd(OUT_A); Wait(20); if ((SENSOR_1<40)&&(SENSOR_3<40))//両方黒(交差点)なら停止して前身。 {Off(OUT_A+OUT_C);Wait(100);} else{Toggle(OUT_C);}} if ((SENSOR_1 < 40)&&(SENSOR_3 < 40)) {OnFwd(OUT_A+OUT_C);} else{OnFwd(OUT_A+OUT_C);}} task main(){ SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_2,SENSOR_TOUCH); SetSensor(SENSOR_3,SENSOR_LIGHT); while(SENSOR_2 == 0)//奇数回目(というより一回目)触れるまで。 {line();} OnRev(OUT_A+OUT_C);//以降反転させる。 Wait(100); OnFwd(OUT_A); OnRev(OUT_C); until(SENSOR_3 < 40); Off(OUT_A+OUT_C); Wait(50); OnFwd(OUT_A); OnRev(OUT_C); until(SENSOR_1 < 40); Off(OUT_A+OUT_C); while(SENSOR_2 == 0)//偶数回目に触れるまで。 {line();} OnRev(OUT_A+OUT_C);//以降、アームを下ろして押しのける。 Wait(100); Toggle(OUT_A); until(SENSOR_1 < 40); OnFwd(OUT_A+OUT_C); Wait(80); Off(OUT_A+OUT_C); OnFwd(OUT_B); Wait(20); Off(OUT_B); OnFwd(OUT_C); until(SENSOR_1 < 40); OnRev(OUT_B); Wait(20); Off(OUT_B); while(SENSOR_2 == 0)//3回目でおよそ一周なので停止。 {line();} Off(OUT_A+OUT_C);}
ライントレースをするときに出力調整を変えて調整したりスピンした直後に一瞬だけ前身したりして調節した。 奇数偶数の判定は3回目の接触でおよそ一周なのでwhileとサブルーチンの連続で乗り切った。
上記のようにライントレースさせるた結果として交差点で思い通りの挙動をする確立が下がってしまった。また奇数偶数の判定はまだ改善の余地があると思う。
缶をどかす、交差点で一時停止などが入ってくると急に複雑になり、とくに缶をどかした後にライントレースに復帰するのが大変でした。また、強度をあげる事が大切だと思いました。
本番で失敗しまくってしまったけど、失敗を修正するプログラムが役に立ってよかったかも。(ando)
なかなか思い通りのライントレースができず苦労した。最終的には少し妥協して、今の形で落ち着いた。
苦労した点は、いかにアームの強度を強固なものにするか、それと奇数回目、偶数回目の判定をどうするかで考えた。まだ改善の余地があると思う。後、交差点でしょっちゅう踊る。
またホームページの作成を相方に頼ってしまったことは反省したい。
(sin)