各チームで作成したコースに沿って動くロボットを作成せよ。ただし、
-速さと正確さを追求すること -交差点で優先側を走っていない場合には、一時停止すること -前方にあるもう一台のロボットに接触した場合には停止して相手のロボットが行き過ぎる、あるいは距離が離れるのを待つこと -コースを2周したら自動的に止まること
先生の提示したお手本をもとに、独創的な形を求めてみました。
黒線の太さが一様でないのは仕様です。描き始めたときに太くしすぎたんです。
交差点をよく見ると直線じゃなかったりと、脱線が発生しやすいコースだったかなと思います。
常にカーブし続けるレイアウトだった為に速さには期待できない…
最初ダブルバンパーを付けようと考えたが、適当な長さのコードが4つしかないことが判明し、仕方なく長いコードを使おうとしたがやはり長過ぎた。 また光センサは当初モータを利用して左右に動くようにしようと思ったが、センサ1つよりも2つでラインを挟むタイプのほうが正確であることがわかった。
→最終的にバンパーはシングルに決定。光センサは写真のようになるべく本体に近い位置に付けることで、ブレを少なくし安定させることができた。
なんと一発でわりとすんなりライントレースしてしまいました。
// しきい値を決めておく。 #define BORDER 40 // ループから抜け出すためのフラグ用変数 int flag = 0; task main () { // センサーは 1番と3番が光 2番がタッチ SetSensor ( SENSOR_1, SENSOR_LIGHT ); SetSensor ( SENSOR_2, SENSOR_TOUCH ); SetSensor ( SENSOR_3, SENSOR_LIGHT ); Wait ( 100 ); //ボタンを押してから1秒だけ待ってほしい while ( flag < 5 ){ //5回交差点を通るまでループ(2周) if ( SENSOR_2 == 1 ){ //タッチセンサが発動したら、 OnRev(OUT_A+OUT_C); Wait(50); //ちょっと緊急回避して、 Off(OUT_A+OUT_C); Wait(300); //3秒待機して、 OnFwd(OUT_A+OUT_C); Wait(50); //もとの場所にもどる } else{ //タッチされてない場合、 if ( SENSOR_1 > BORDER ){ //右センサは白で、 if ( SENSOR_3> BORDER ){ //左センサも白なら、(L1 R1) OnFwd(OUT_A+OUT_C); //直進する } else { //左センサは黒なら、(L0 R1) OnFwd(OUT_A); Off(OUT_C); //左のほうに曲がる } } else { //右センサは黒で、 if ( SENSOR_3> BORDER ){ //左センサは白なら、(L1 R0) Off(OUT_A); OnFwd(OUT_C); //右のほうに曲がる } else { //左センサも黒なら、(L0 R0) Off(OUT_A+OUT_C); //交差点と思われるのでストップして、 Wait(150); //1.5秒間待機して、 OnFwd(OUT_A+OUT_C); //直進しはじめて、 Wait(150); //1.5秒間直進して、 flag++; //交差点カウンタに1足す } } } } Off(OUT_A+OUT_C); //終劇。おつかれさまでした。 }
Wait ( 100 ); //ボタンを押してから1秒だけ待ってほしい
ボタンを押した瞬間に動き出す場合、ボタンを押した手をさっと避けなければなりません。 焦った挙げ句パーツを吹っ飛ばしたりしたらいけないので、心に余裕を持たせる意味でボタンを押してから0.1秒後に発進するようにしました。細かい点です。
while ( flag < 5 ){ //5回交差点を通るまでループ(2周)
コース1周ごとに交差点は2つあります。2周するので 2*2=4 ですが、スタート地点が交差点直前なのでその1回を足して 5 です。
if ( SENSOR_2 == 1 ){ //タッチセンサ発動 OnRev(OUT_A+OUT_C); Wait(50); //ちょっと緊急回避 Off(OUT_A+OUT_C); Wait(300); //3秒待機する OnFwd(OUT_A+OUT_C); Wait(50); //もとの場所にもどる }
相手ロボにぶつかった際、ただその場で停止するだけではかえって邪魔です。ジェントルロボは一歩退いて道を譲ります。
if ( SENSOR_1 > BORDER ){ //右センサは白 if ( SENSOR_3> BORDER ){ //左センサも白(L1 R1) OnFwd(OUT_A+OUT_C); //直進する }
左右のセンサーが共に明るいなら、その2つのセンサーの間にラインがあると思われます。なので直進です。
else { //左センサは黒(L0 R1) OnFwd(OUT_A); Off(OUT_C); //左のほうに曲がる }
右は明るく、左は暗い場合、道はこうなっていると考えられます。
左側のモータを止めることで左に曲がります。
else { //右センサは黒 if ( SENSOR_3> BORDER ){ //左センサは白(L1 R0) Off(OUT_A); OnFwd(OUT_C); //右のほうに曲がる }
右は暗く、左は明るい場合は、先ほどと左右反転した状況です。
else { //左センサも黒(L0 R0) Off(OUT_A+OUT_C); //ストップする Wait(150); //1.5秒間待機する OnFwd(OUT_A+OUT_C); //直進する Wait(150); //1.5秒間直進する flag++; //交差点カウンタに1足す }
左右とも暗いなら、
このように、交差点のストップマークに当たったと判断できます。
「交差点で優先側を走っていない場合には、一時停止すること」の条件より、一時停止します。
その後、交差点を渡りきるまで紙面上の線を無視して進みます。
また、通った交差点の数を数えるカウンタ用変数に1加えます。
このループを延々と繰り返すことで黒線上を動く動作を実現しました。
実際にライントレースをしている様子(YouTube)
主に時間が掛かったのはコースレイアウトの決定とロボットの設計でした。
例そのままのコースでは面白みがないし、かといって煩雑なコースになると2つのロボットが頻繁にぶつかるようになってうまく動かない可能性が高くなります。