目次
arara(自分)と
※自分は下のコースを逆からまわるプログラミング。 詳しくはプログラミング欄に示す。
図のようなコースを各自で作成した上で、次のような動作をするロボットを作成せよ。 コースの詳細については授業中説明する(下の図において、黒い線の太さは20mmで、線の中央までの距離がcm表示されている)。
1.スタート地点から出発し、黒い線にそって動く。 2.一つ目の十字の交差点と二つめの十字の交差点の間に置かれたピンポン玉をつかむ。 3.さらに黒線に沿って動いてゴール地点を目指す。 4.ゴールに向けてピンポン玉をシュートする。
ただしT字路では、直進、右折、左折を正しく判断させること。また二人一組で同じロボットを使用し、互いにスタート地点とゴール地点を入れ替えること。ロボット本体は共通のものを使うとする。
さらに以下のような動作に挑戦することが望ましい。
•ゴールエリア外からピンポン玉をシュートする。 •曲線部中央の障害物に接触しないようにすること。
詳しくは2014a/Mission1に。
Name:ドルトムント
コンパクトな本体かつ、強度を保っている
車輪を1組にし、小回りUP
車輪の間に光センサー(青パーツ)をはさんだ事でライントレースが正確になった
1.黄色い部分が下がり、ボールをキャッチ
2.黄色い部分が上がると同時に、黒い部分が重みで落下しシュート
右側の【START】を出発し、左側の【GOAL】までを
トレースしながらボールをキャッチしシュートまでを行う
黄色い●はピンポン球を表す
#define SKIT 45 //しきい値 #define HIGHPOWER 7 #define LOWPOWER 1 #define SHOOTPOWER 4 #define set_power_H SetPower(OUT_AC,HIGHPOWER);//速度を速める #define set_power_L SetPower(OUT_AC,LOWPOWER);//速度を落とす #define set_power_S SetPower(OUT_B,SHOOTPOWER);//アームを上げる速度 #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 go_forward set_power_H; OnFwd(OUT_AC); //直進 #define STEP 1 #define nMAX 20 //交差点を判断 #define NOSTEP 200//右旋回しすぎると左に戻るための時間 #define noMAX 20 //右旋回しすぎると左に戻るために判断する最大旋回の値 #define time1 2200 //ボールを取るまで #define time2 500 //ボールを取る #define time3 3900 //ゴール直前まで #define time4 300 //シュート! sub line_trace() //通常運行 { SetSensor(SENSOR_2, SENSOR_LIGHT); int online=0; int nonline=0; while(true){ while (online < nMAX) { if (SENSOR_2 < SKIT-6){ turn_left1; online++; } else if (SENSOR_2 < SKIT-3) { turn_left0; } else if (SENSOR_2 < SKIT+3) { go_forward; } else { if(SENSOR_2 < SKIT+8) { turn_right0; } else { while (nonline < noMAX){ turn_right1; nonline++; } turn_left1; Wait(noMAX*STEP*5); } online=0; nonline=0; } Wait(STEP); } PlaySound(SOUND_UP); turn_right1; Wait(nMAX*STEP*5); go_forward; Wait(100); online=0; } } sub ball_catch() //ボールを取る { Off(OUT_ABC); OnFwd(OUT_B); Wait(30); OnFwd(OUT_AC); Wait(20); OnRev(OUT_B); Wait(30); } sub ball_shoot() //ボールをシュート { Off(OUT_ABC); set_power_S; OnFwd(OUT_B); Wait(30); } task main() { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); OnFwd(OUT_AC); Wait(100); while(FastTimer(0)<=time1){ line_trace(); } ClearTimer(0); Wait(100); while(FastTimer(0)<=time2){ ball_catch(); } ClearTimer(0); while(FastTimer(0)<=time3){ line_trace(); } ClearTimer(0); while(FastTimer(0)<=time4){ ball_shoot(); } ClearTimer(0); }
#define SKIT 45 //しきい値 #define HIGHPOWER 7 #define LOWPOWER 1 #define SHOOTPOWER 4 #define set_power_H SetPower(OUT_AC,HIGHPOWER);//速度を速める #define set_power_L SetPower(OUT_AC,LOWPOWER);//速度を落とす #define set_power_S SetPower(OUT_B,SHOOTPOWER);//アームを上げる速度 #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 go_forward set_power_H; OnFwd(OUT_AC); //直進 #define STEP 1 #define nMAX 20 //交差点を判断 #define NOSTEP 200//右旋回しすぎると左に戻るための時間 #define noMAX 20 //右旋回しすぎると左に戻るために判断する最大旋回の値 #define time1 2200 //ボールを取るまで #define time2 500 //ボールを取る #define time3 3900 //ゴール直前まで #define time4 300 //シュート!
sub line_trace() //通常運行 { SetSensor(SENSOR_2, SENSOR_LIGHT); //ライントレースのための光センサを2番にセット int online=0; //交差点の判断のための数値 int nonline=0; //右旋回のしすぎ感知のための数値 /*しきい値よりも-6以下なら、左旋回&onlineのカウントを1増やす しきい値よりも-3以下なら、左折 しきい値よりも+3以下なら、右折 しきい値よりも+6以下なら、右旋回&nonlineのカウントを1増やす*/ /*onlineの値が20になると交差点と判断し、右に少し戻って前進することで交差点直進 nonlineの値が20になると右旋回しすぎた事を感知し、左旋回をすることで修正*/ while(true){ while (online < nMAX) { if (SENSOR_2 < SKIT-6){ turn_left1; online++; } else if (SENSOR_2 < SKIT-3) { turn_left0; } else if (SENSOR_2 < SKIT+3) { go_forward; } else { if(SENSOR_2 < SKIT+6) { turn_right0; } else { while (nonline < noMAX){ turn_right1; nonline++; } turn_left1; Wait(noMAX*STEP*5); } online=0; nonline=0; } Wait(STEP); } PlaySound(SOUND_UP); turn_right1; Wait(nMAX*STEP*5); go_forward; Wait(100); online=0; } }
しきい値はその境界付近の「黒と白の間の明るさ」を設定している。
このときに交差点があると左側をライントレースしたまま左折してしまうので
それを防ぐためにonlineという変数を使って交差点を判断している。
sub ball_catch() //ボールを取る { Off(OUT_ABC); //全てのモーターを止める OnFwd(OUT_B); //アームを上げる動作を0.3秒間 Wait(30); OnFwd(OUT_AC);//ロボットが前進する動作を0.2秒間 Wait(20); OnRev(OUT_B); //アームを下げる動作を0.3秒間 Wait(30); }
sub ball_shoot() //ボールをシュート { Off(OUT_ABC);//全てのモーターを止める set_power_S; //アームのモーターの速度を4(最高7)に設定 OnFwd(OUT_B);//アームを上げる動作を0.3秒間 Wait(30); //この間にアーム部分の黒い棒の勢いによりボールをシュート }
task main() { SetSensor(SENSOR_2, SENSOR_LIGHT); //ライントレース用の光センサを2番にセット ClearTimer(0); //タイマー0の時間をリセット OnFwd(OUT_AC); //黒線で囲まれたSTARTの正方形エリアから出る Wait(100); while(FastTimer(0)<=time1){ line_trace(); } ClearTimer(0); Wait(100); //スタートしてから22秒経つまでライントレース while(FastTimer(0)<=time2){ ball_catch(); } ClearTimer(0); //時間リセットしてから5秒間はボールをとるための行動をする while(FastTimer(0)<=time3){ line_trace(); } ClearTimer(0); //ボールをとってから39秒間はライントレース while(FastTimer(0)<=time4){ ball_shoot(); } ClearTimer(0); //39秒経ったら3秒間の間にシュートの行動をする }
早すぎるとボールも一緒に持ち上がってしまう。
どこに飛んでいくかわからないような状態になるため、上げる速さの調節に苦労した。
加えて、しきい値も時間や場所が変わると大きく変わってくるため、その都度調整が必要。
大抵そこよりも前にエラー箇所があるため、見つけ出すのに苦労した。
このプログラムにエラーは無いが、実際に動かすとしっかりトレースをしてくれないことが多い。
もう少しライントレースのプログラミングを簡素化できないものか・・・と思う。
4月と比べて、自分の成長が実感できて良かった。