上の写真が自分たちの作ったロボットです。
課題はライントレースで、ピンポン玉を運び、ゴールに入れるというものだったので、先端にアームをつけ上下させることで玉を運べるようにしました。アームを上げた状態でスタートさせ、球の手前でアームを下げ、球を囲み転がして移動させ、ゴールの手前で再びアームを上げて、最後に球を機体全体で押し出すようにしました。
タッチセンサーは使わずに、光センサーをロボットの中央下部に取り付けることでライントレースしやすいようにしました。
最初は上の写真のようなロボットを作りましたが、あまりにも不安定だったので作り替えました。
#define THRESHOLD 45 //閾値の基準 #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; OnRev(OUT_AC); //前進 #define turn_left1 set_power_L; OnRev(OUT_C);OnFwd(OUT_A); //左に曲がる(速く) #define turn_left0 set_power_L; OnRev(OUT_C);Off(OUT_A); //左に曲がる(ゆっくり) #define turn_right0 set_power_L; OnRev(OUT_A);Off(OUT_C); //右に曲がる(速く) #define turn_right1 set_power_L; OnRev(OUT_A);OnFwd(OUT_C) //右に曲がる(ゆっくり) #define STEP 1 //一回の動作時間 #define nMAX 3 //連続して左に曲がれる最大値 #define short_break Off(OUT_AC); Wait(20); //小休止 #define CROSS_TIME 30 //交差点を渡る時間 #define cross_line OnRev(OUT_AC);Wait(CROSS_TIME);short_break;Wait(200); #define Pmade 700 #define Pkara 900 #define Qmade 1750 #define Qkara 1950 #define Last 2750 #define ageru OnRev(OUT_B);Wait(9);Off(OUT_B); //アームを上げる #define sageru OnFwd(OUT_B);Wait(12);Off(OUT_B); //アームを下げる #define utu OnFwd(OUT_AC);Wait(50);ageru;OnRev(OUT_AC);Wait(50);Off(OUT_AC); //玉を打つ
sub line_traceN() //通常のライントレース { if (SENSOR_2 < THRESHOLD -8) { turn_left1; //37未満ですばやく左折 } else if (SENSOR_2 < THRESHOLD -6) { turn_left0; //37以上39未満でゆっくり左折 } else if (SENSOR_2 < THRESHOLD -3) { go_forward; //39以上42未満で前進 } else if (SENSOR_2 < THRESHOLD -1) { turn_right0; //42以上44未満でゆっくり右折 } else { turn_right1; //それ以外ですばやく右折 } Wait(STEP); }
sub line_traceK() //交差点のライントレース { int nOnline=0; //カウンタを0にする while (nOnline < nMAX) { //黒を連続してnMAX回繰り返さない間 if (SENSOR_2 < THRESHOLD-8) { turn_left1; //37未満ですばやく左折 nOnline++; //カウンタを増やす } else { if (SENSOR_2 < THRESHOLD-6) { turn_left0; //37以上39未満でゆっくり左折 } else if (SENSOR_2 < THRESHOLD-3) { go_forward; //39以上42未満で前進 } else if (SENSOR_2 < THRESHOLD-1) { turn_right0; //42以上44未満でゆっくり右折 } else { turn_right1; //それ以外ですばやく右折 } nOnline=0; //カウンタをリセット } Wait(STEP); } short_break; //小休止 turn_right1; Wait(nMAX*STEP); //機体を線に対してまっすぐにする cross_line; //交差点を渡る nOnline=0; //カウンタを0にする }
task main() { SetSensor(SENSOR_2, SENSOR_LIGHT); //光センサーを2に接続
ClearTimer(0); //タイマーで時間の計測開始
while(FastTimer(0) <= Pmade) { line_traceN(); //スタートからP交差点前 } PlaySound(SOUND_UP); //音を鳴らす while(FastTimer(0) <= Pkara) { line_traceK(); //P交差点 } sageru; PlaySound(SOUND_UP); while(FastTimer(0) <= Qmade) { line_traceN(); //P交差点からQ交差点前 } PlaySound(SOUND_UP); while(FastTimer(0) <= Qkara) { line_traceK(); //Q交差点 } PlaySound(SOUND_UP); while(FastTimer(0) <= Last) { line_traceN(); //Q交差点からゴール } PlaySound(SOUND_UP); utu; //玉を打つ }
自分はA点からB点を担当しました。
モーターAは左側のタイヤ、モーターBはアーム、モーターCは右側のタイヤに接続していて、タイヤはOnRevで前進、OnFwdで後進、アームはOnRevで上がり、OnFwdで下がります。
球の打ち出しはutuで定義し、機体全体の前進により球を打ち出します。
コースを5つ(スタートからP交差点前、P交差点、P交差点からQ交差点前、Q交差点、Q交差点からゴール)に分割し、Pmade,Pkara,Qkara,Qmade,Lastというように定義しました。
ライントレースは二つに分け、line traceNでは通常のライントレース、line traceKでは交差点でのライントレースを定義しました。
閾値は45に設定し、大幅にずれたときにはAとCを共に動かし、そうでないときはどちらか片方が動くようにプログラムし、set powerでスピードも直線用とカーブ用の2種類に分け、スムーズに動くようにしました。
go forwardで前進し、turn left1(right1)ですばやく左(右)に曲がり、turn left0(right0)でゆっくり左(右)に曲がります。
STEPでは一回の動作で作用させる時間、nMAXでは連続して左に曲がれる回数を定義しています。
交差点では2秒間停止するように、short breakを定義しました。
CROSS TIMEでは交差点を渡るのにかかる時間を定義しています。
黒が連続したとき以外は通常のライントレースをします。
センサーの値が37(THRESHOLD-8)を下回ったら、左に曲がりながらカウントを1つ増やします。値が3回以上連続で37を下回ったときにそこを交差点とみなし渡ります。
センサーの値が37以上のときは、カウントをリセットします。
今回作成したプログラムでは、交差点用のプログラムを定義しておき、時間でプログラムを交差点用のものに切り替えるようにしてしまった。この方法でもうまく課題を成功させることはできたが、そこで満足してしまい、他の方法を考えなかった。完全に時間で交差点を認識させたわけではないが、時間をもう少し補助的に使用し、交差点用のプログラムで用いたカウンターをプログラム全体を通してもっと工夫して用い、プログラムの切り替えなしで交差点の判断をすることが出来ればよかった。