目次
AからBのコースを選択しました。
スタート地点から1つ目の交差点まではラインの左側をトレースし、1つ目の交差点から2つ目の交差点までラインの右側をトレースし、2つ目の交差点からゴールまではラインの左側をトレースするコースにしました。また、ボールはPQ間の直線の方に置きました。
ロボット本体の後方についているキャスターが頑丈でないので、なるべく前輪に重さがかかるようにしたかったのですが、うまくいきませんでした。
最初、扉を開きボールを中に入れて扉を閉じるような方法を考えましたが、しっかりとした構造を作ることができなかったので、ボールを両側から挟み込むクワガタムシのハサミのようなアームを作りました。このアームで少しボールとの距離が離れていても、ボールを引き寄せて確保することが可能になりました。また、アームの縦幅を少し広くすることで、確保したボールがすり抜けてしまうことを防いでいます。
参考プログラムを読んで、課題1よりもプログラムが複雑になりそうでしたので、ロボットの動きを一つ一つ細かく定義しました。
#define LIGHT 45 //光センサーのしきい値 #define SPEED 20 //カーブや旋回をする時のスピード #define SPEED_STR 25 //直進する時のスピード #define SHOOT_SPEED 80 #define GO(Bs,Cs) OnFwd(OUT_B,Bs);OnFwd(OUT_C,Cs); #define STRAIGHT GO(SPEED_STR, SPEED_STR); #define LEFT_curve GO(SPEED, 0); #define LEFT_turn GO(SPEED, -SPEED); #define RIGHT_curve GO(0, SPEED); #define RIGHT_turn GO(-SPEED, SPEED); #define STEP 1 //一回の動作にかける時間 #define STOP Off(OUT_BC); Wait(2000); #define CROSS1 GO(SPEED,SPEED);Wait(600);STOP; //一つ目の交差点を渡る #define CROSS2 GO(SPEED,SPEED);Wait(1000);STOP; //二つ目の交差点を渡る #define arm_close RotateMotor(OUT_A,20,-80);Off(OUT_A);Wait(1000); #define arm_open RotateMotor(OUT_A,20,55);Off(OUT_A);Wait(1000); #define SHOOT STOP;arm_open;STOP;GO(SHOOT_SPEED,SHOOT_SPEED);Wait(500);STOP; #define REVISE RIGHT_turn;Wait(1000);STOP; //一つ目の交差点を渡る時の位置修正 #define SOUND1 PlaySound(SOUND_UP);Wait(1000); //一つ目の交差点を認識した時に出す音 #define SOUND2 PlaySound(SOUND_DOWN);Wait(1000); //二つ目の交差点を認識した時に出す音
ラインをトレースするためのカーブの速度は、トレースの確実性を上げるために直進するときの速度より遅くしています。
「black」という値を定義することによって、プログラミングを「スタートから1つ目の交差点」「1つ目の交差点から2つ目の交差点」「2つ目の交差点からゴール」の3つの段階に分けました。この値は、光センサーが34より低い値を検知したときに、プラス1されます。つまり、交差点に来たときに、プラス1されます。光センサーが34より小さい値を1回検知するだけで、交差点と判断するプログラムなので、交差点以外で34より小さい値を検知しないようにカーブの外側をトレースするようにしました。
「スタートから1つ目の交差点」までのプログラムです。1つ目の交差点にたどり着いて、光センサーが34より低い値を検知するまで通常のライントレースをして、その後、2秒間停止して「REVISE」のプログラムで向きをコースの内側を向いて、交差点を斜めに通過してラインの左側から右側に移動します。この時に「black++」のプログラムで「black」の値を「1」にします。
task main() { SetSensorLight(S3); int black=0; while (true) { while (black == 0) { if (SENSOR_3 < LIGHT-11) { STOP; arm_close; REVISE; SOUND1; CROSS1; BLACK++; } else { if (SENSOR_3 < LIGHT-7) { LEFT_turn; } else if (SENSOR_3 < LIGHT-3) { LEFT_curve; } else if (SENSOR_3 < LIGHT+3) { STR; } else if (SENSOR_3 < LIGHT+7) { RIGHT_curve; } else { RIGHT_turn; } } Wait(STEP); }
「1つ目の交差点から2つ目の交差点」までのプログラムです。「BLACK == 0」のプログラムと違いラインの右側をトレースするために「RIGHT」「LEFT」を置き換えました。また、交差点の入りが斜めになっているので、「REVISE」のプログラムを使わずにそのまま直進することで、交差点を斜めに渡り、ラインの右側から左側に移動します。この時に「BLACK」の値を「2」にします。
while (black == 1) { if (SENSOR_3 < LIGHT-11) { STOP; SOUND2; CROSS2; BLACK++; } else { if (SENSOR_3 < LIGHT-7) { RIGHT_turn; } else if (SENSOR_3 < LIGHT-3) { RIGHT_curve; } else if (SENSOR_3 < LIGHT+3) { STR; } else if (SENSOR_3 < LIGHT+7) { LEFT_curve; } else { LEFT_turn; } } Wait(STEP); }
「2つ目の交差点からゴール」までのプログラムです。二つ目の交差点を渡った後から時間を計測して、通常のライントレースをし、5秒後に「SHOOT」のプログラムでボールをシュートします。
while(black == 2) { long t1 = CurrentTick(); while (CurrentTick()-t1 <= 5000) { if (SENSOR_3 < LIGHT-7) { LEFT_turn; } else { if (SENSOR_3 < LIGHT-3) { LEFT_curve; } else if (SENSOR_3 < LIGHT+3) { STR; } else if (SENSOR_3 < LIGHT+7) { RIGHT_curve; } else { RIGHT_turn; } Wait(STEP); } } SHOOT; } } }
交差点を検知するプログラムが「連続して黒色を検知した回数」や「黒色を検知した時間」ではなくただ「光センサーの値が34より小さくなった時」という簡単なものしか作れなかったことや、同じ様なプログラムをいくつか作ってしまったことが残念でしたが、そのプログラムをしっかりと動作させるためにライントレースの工夫をすることができたのは、良かったと思います。