スタート地点から出発し、スタート地点外のすぐ近くに置かれたピンポン玉をつかむ。 ピンポン玉をつかんだら速やかにスタート地点の境界の黒線に戻り、そこから黒線に沿って動いてゴール地点を目指す。ただしT字路では、直進、右折、左折を正しく判断させること。また、曲線部中央の障害物に接触しないようにすること。 ゴール地点に到達したら、ゴールエリア外からピンポン玉をゴールにシュートする。ただし、どうしてもエリア外からのシュートが難しい場合は、エリア内からシュートした後、エリアから出てもよい。
一人目とは逆方向からスタート。コースが微妙に違う。
コース
名前「SPTadao」
名前の由来はバイクのマフラー「SP忠男」からとったもの。マフラーのようにあまり目立たないように活躍してほしいという願いを込めてる。ちなみに、SPTadaoを日本語表記するとスペシャル理夫である。忠男ではない。Tadaoはやればできる子だと俺たちは信じてる。がんばれTadao!!負けるなTadao!!
全体図
前輪及びピンポン玉をつかむ機構
キャスターを装備し小回りがきくように改良。光センサをタイヤに近づけ旋回半径を小さくした。これで、急なカーブや直角を曲がることができるようになった。しかし、光センサをタイヤに近すぎると前進しなくなるので適当な距離が必要。ピンポン玉を挟んでゴールに押し込むだけのシンプルなつくり。余分なものはできるだけ少なくしたつもり。最初は小型化を目指していたが、曲がるたびこけるという事態になり少しでかくなりながらも改良しつつ現在に至る。
プログラム名「ただお」
一応走ることができたがまだ完全ではないので、ひらがなで表記している。
図のように走るプログラムを作った。最初は、左側をトレースして最初の交差点を曲がった後右側をトレースするようにして緩やかなカーブを曲がった後、初めの交差点を通り過ぎゴールにピンポン玉を押し込む。
まず定義
#define THRESHOLD 48 #define HIPOWER 7 /*力の設定*/ #define LOWPOWER 2 /*力の設定*/ #define set_power_H SetPower(OUT_AC,HIPOWER); /*強い力*/ #define set_power_L SetPower(OUT_AC,LOWPOWER); /*弱い力*/ #define go_forward set_power_H; OnFwd(OUT_AC); /*強い力で直進*/ #define turn_left1 set_power_L; OnFwd(OUT_C); OnRev(OUT_A); /*左旋回*/ #define turn_left0 set_power_L; OnFwd(OUT_C); Off(OUT_A); /*左折*/ #define turn_right0 set_power_L; OnFwd(OUT_A); Off(OUT_C); /*右旋回*/ #define turn_right1 set_power_L; OnFwd(OUT_A); OnRev(OUT_C); /*右折*/ #define STEP 1 /*0.01秒ごとに判定*/ int n=0; /*黒の連続回数を数えるカウンタ*/
最初の左側をトレースするプログラム
task main() { go_forward; Wait(80); Off(OUT_AC); OnFwd(OUT_B); Wait(100); Off(OUT_B); n==0; /*ボールを回収する動作*/ SetSensor(SENSOR_2,SENSOR_LIGHT); /*光センサを設置*/ ClearTimer(0); /*時間をリセット*/ while(FastTimer(0)<700){ /*最初の交差点を渡るまでの時間*/ if(SENSOR_2<THRESHOLD-6) { turn_left1; /*真っ黒な時*/ } else if (SENSOR_2<THRESHOLD-2) { turn_left0; /*黒いとき*/ } else if (SENSOR_2<THRESHOLD+2) { go_forward; /*中間色の時*/ } else if (SENSOR_2<THRESHOLD+7) { turn_right0; /*少し白いとき*/ } else { turn_right1; /*それ以外、つまり真っ白の時*/ } }
次の右側をトレースするプログラム。7秒以上経つと右側にトレースし始める。右回りのカーブで入れ替えるとたまに逆走する時があったので、大体左回りのカーブで入れ替えるように時間を調節した
while(700<=FastTimer(0)&&FastTimer(0)<=2000){ /*緩やかなカーブを曲がり終えるまで*/ if(SENSOR_2<THRESHOLD-6) { turn_right1; } else if (SENSOR_2<THRESHOLD-2) { turn_right0; } else if (SENSOR_2<THRESHOLD+2) { go_forward; } else if (SENSOR_2<THRESHOLD+7) { turn_left0; } else { turn_left1; /*左側トレースの左右を入れ替えた*/ } Wait(STEP); }
カーブを曲がってから最初の交差点をカウンタを使って交差点と判断し無視するプログラム。こちらも右回りのカーブで反応することがあったのでカーブを過ぎたところでプログラムが動くように時間を設定
while(FastTimer(0)>2000){ /*ここから次の交差点を無視する*/ if(SENSOR_2<THRESHOLD-9) { turn_right1; n++; /*黒くなったのでカウント*/ } else if (n>=3) { /*交差点(右に曲がる命令が三回連続で来たとき)に来たときの動作*/ PlaySound(SOUND_UP); /*いつ反応したかわかりやすいように音がなる*/ go_forward; Wait(150); Off(OUT_AC); /*交差点を越える動作*/ ClearTimer(1); /*二つ目のタイマーをリセット*/ while(700>FastTimer(1)){ /*ゴールの手前まで走る*/ if(SENSOR_2<THRESHOLD-9) { turn_right1; } else if (SENSOR_2<THRESHOLD-5) { turn_right0; } else if (SENSOR_2<THRESHOLD+2) { go_forward; } else if (SENSOR_2<THRESHOLD+7) { turn_left0; } else { turn_left1; } Wait(STEP); } while(700<FastTimer(1)){ /*シュートする*/ go_forward; Wait(100); Off(OUT_AC); OnRev(OUT_B); Wait(100); Off(OUT_B); OnFwd(OUT_AC); Wait(50); OnRev(OUT_AC); Wait(50); Off(OUT_AC); Wait(1000); /*ゴールに押し込む動作*/ } } else if (SENSOR_2<THRESHOLD-5) { turn_right0; n++; /*黒かったのでカウント*/ } else if (SENSOR_2<THRESHOLD+2) { go_forward; n==0; /*連続じゃなかったのでカウンタをリセット*/ } else if (SENSOR_2<THRESHOLD+7) { turn_left0; n==0; /*連続じゃなかったのでカウンタをリセット*/ } else { turn_left1; n==0; /*連続じゃなかったのでカウンタをリセット*/ } Wait(STEP); } } /*task mainのかっこ*/
左折や直進するとカウンタをリセットする。これで連続で右の判定が来た時、交差点と反応するようになる。二つ目のタイマーを使ったのは、一つ目のタイマーだと動作が最初からやり直してしまいループするので二つ目のタイマーを使った。