#contents **ロボットについて [#u97250fc] ロボットの全容である。 #ref(./robot1,80%,ロボット画像1) #ref(./robot2,80%,ロボット画像2) #ref(./robot1.jpeg,80%,ロボット画像1) #ref(./robot2.jpeg,80%,ロボット画像2) 車軸の部分 #ref(./robot3,80%,ロボット画像3) #ref(./robot3.jpeg,80%,ロボット画像3) シュートを出したりパスを受けたりする部分 #ref(./robot4,80%,ロボット画像4) #ref(./robot4.jpeg,80%,ロボット画像4) #ref(./robot5,80%,ロボット画像5) 車軸の部分は課題1で作成したロボットを参考にして作成した。課題1の時は、車体の上部にパーツをつけすぎて、走行が安定しないことがあったが、そうならないように重心を低めに設定した。 ボールをキャッチする部分は、上からかぶせる形にした。こうすれば、走行中にボールをこぼすことはない。さらに、かぶせる範囲を広めにして、キャッチの可能性が上げた。このかぶせる部分を上に持ち上げる動作をすると同時に、奥に取り付けてあるパーツがボールに当たり、パスやシュートが出せる仕組みになっている。 **コースの攻略 [#ge6b19b8]] [#x0cc3d33] #ref(./robot6,80%,コース) #ref(./robot6.jpeg,80%,コース) -競技時間は審判が続行不能と判断するまで、あるいはリタイアするまで。 -書き足した直線部からスタートする。 -図の上部からスタートしたロボットAがピンポン玉を取りにいく -直線部までピンポン玉を持ってくる (1) -直線部に入ってからロボットBへパスを送る (2) -ロボットBは直線部でパスを受け取る -ロボットBは直線部でパスを送る (3) -ロボットAは直線部でパスを受けとる -ロボットAは直線部でパスを送る (4) -ロボットBは直線部でパスを受け取る -ロボットBがゴールの空き缶の近くまでピンポン玉を運んで空き缶に当てる (5) (ただし黒い線で囲まれた空き缶の領域には入ってはいけない) -ロボットBはシュートをした後もう一つのピンポン玉を取りにいく -以後は、これまでのAとBの役割を反対にして、パスを繰り返し、最終的にはロボットAがもう一つのゴールにシュートする。 -開始の合図から5秒以内にスタートボタンを押す作業を完了すること。 -競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。 -途中でうまく動かなくなった場合、1回限り再スタートすることができる(再スタートの際に別プログラムで起動してよい)。 **ボールをシュートする側のプログラム [#wdaacae0] #define BLACK_high 36 //一番黒いしきい値 #define BLACK_low 38 //少し黒いしきい値 #define WHITE_low 42 //少し白いしきい値 #define WHITE_high 44 //一番白いしきい値 #define turn_left_senkai OnRev(OUT_A); OnFwd(OUT_C); //左旋回する #define turn_left_kaiten Off(OUT_A); OnFwd(OUT_C); //左カーブする #define turn_right_kaiten OnFwd(OUT_A); Off(OUT_C); //右カーブする #define turn_right_senkai OnFwd(OUT_A); OnRev(OUT_C); //右旋回する #define go_fwd OnFwd(OUT_AC); //前進する #define short_break Off(OUT_AC); Wait(100); //小休止する #define SHOTBALL OnFwd(OUT_B); Wait(500); //ボールを撃つ #define CATCHBALL OnRev(OUT_B); Wait(500); //ボールを受け取る #define time2 10 //シュートしない側が交差点から一回目に前進する時間 #define time3 10 //シュートしない側が交差点から二回目に前進する時間 #define nMAX 300 //交差点と判断する基準 #define STEP 1 //ライントレース時の待ち時間 task main(){ SetSensor(SENSOR_2,SENSOR_LIGHT); int nOnline=0; int nCross=0; int counter=0; while (nCross < 2) { //交差点までのライントレース while (nOnline < nMAX) { if(SENSOR_1 < BLACK_high) { turn_right_senkai; nOnline++; } else { if (SENSOR_1 < BLACK_low) { turn_right_kaiten; } else if (SENSOR_1 < WHITE_low) { go_fwd; } else if (SENSOR_1 < WHITE_high) { turn_left_kaiten; } else { turn_left_senkai; } nOnline==0; } Wait(STEP); } PlaySound(SOUND_UP); //交差点を感知してwhileから抜ける short_break; nCross++; nOnline=0; } turn_left_senkai; Wait(70); until(FastTimer(1) > 4500); CATCHBALL; turn_left_senkai; Wait(70); while (FastTimer(0) <= time2){ if(SENSOR_1 < BLACK_high) { turn_right_senkai; } else if (SENSOR_1 < BLACK_low) { back_turn_right_kaiten; } else if (SENSOR_1 < WHITE_low) { go_fwd; } else if (SENSOR_1 < WHITE_high) { back_turn_left_kaiten; } else { turn_left_senkai; } Wait(STEP); } nCross=0; turn_right_senkai; wait(70); until(FastTimer(1) > 6000); SHOTBALL; turn_left_senkai; Wait(70); while (nCross < 1){ while (nOnline < nMAX){ if(SENSOR_1 < BLACK_high){ turn_right_senkai; nOnline++; } else { if (SENSOR_1 < BLACK_low){ turn_right_kaiten; } else if (SENSOR_1 < WHITE_low){ go_fwd } else if (SENSOR_1 < WHITE_high){ turn_left_kaiten; } else { turn_left_senkai; } nOnline==0; } Wait(STEP); } PlaySound(SOUND_UP); short_break; nCross++; nOnline=0; } while (FastTimer(0) <= time2){ if(SENSOR_1 < BLACK_high) { turn_right_senkai; } else if (SENSOR_1 < BLACK_low) { back_turn_right_kaiten; } else if (SENSOR_1 < WHITE_low) { go_fwd; } else if (SENSOR_1 < WHITE_high) { back_turn_left_kaiten; } else { turn_left_senkai; } Wait(STEP); } turn_right_senkai; Wait(70); until(FastTimer(1) > 7500); CATCHBALL; turn_left_senkai; Wait(70); while(counter < 1){ while(nOnline < nMAX){ if (SENSOR_1 < 38){ turn_right_senkai; nOnline++; } else { if (SENSOR_1 < 39){ turn_right_kaiten; } else if (SENSOR_1 < 42){ go_fwd; } else if (SENSOR_1 < 44){ turn_left_kaiten; } else { turn_left_senkai; } } nOnline=0; } Wait(STEP); } short_break; turn_left_senkai; Wait(150); go_rev; Wait(100); SHOTBALL; } **ボールをシュートしない側のプログラム [#n1c1013b] #define BLACK_high 36 //一番黒いしきい値 #define BLACK_low 38 //少し黒いしきい値 #define WHITE_low 42 //少し白いしきい値 #define WHITE_high 44 //一番白いしきい値 #define turn_left_senkai OnRev(OUT_A); OnFwd(OUT_C); //左旋回する #define turn_left_kaiten Off(OUT_A); OnFwd(OUT_C); //左カーブする #define turn_right_kaiten OnFwd(OUT_A); Off(OUT_C); //右カーブする #define turn_right_senkai OnFwd(OUT_A); OnRev(OUT_C); //右旋回する #define go_fwd OnFwd(OUT_AC); //前進する #define short_break Off(OUT_AC); Wait(100); //小休止する #define SHOTBALL OnFwd(OUT_B); Wait(500); //ボールを撃つ #define CATCHBALL OnRev(OUT_B); Wait(500); //ボールを受け取る #define TURNSTEP 10 //横のセンサーを使う時の繰り返しの待ち時間 #define time2 10 //シュートしない側が交差点から一回目に前進する時間 #define time3 10 //シュートしない側が交差点から二回目に前進する時間 #define nMAX 300 //交差点と判断する基準 #define STEP 1 //ライントレース時の待ち時間 task main(){ SetSensor(SENSOR_2,SENSOR_LIGHT); int nOnline=0; int nCross=0; ClearTimer(0); while(nCross <= 1){ while(nOnline < nMAX){ if(SENSOR_1 < BLACK_high){ turn_left_senkai ; nOnline++ ; } else if(SENSOR_2 < BLACK_low){ turn_left_kaiten; } else if(SENSOR_2 < WHITE_low){ go_fwd; } else if(SENSOR_2 < WHITE_high){ turn_right_kaiten; } else { turn_right_senkai; } } nOnline == 0; nCross ++; short_break; cross_line; } nCross=0; go_fwd; Wait(500); OnRev(OUT_A); OnFwd(OUT_C); Wait(100); //ボールの方向を向く CATCHBALL; OnFwd(OUT_AC); Wait(200); //ボールを取る until(SENSOR_1 < BLACK_low){ turn_left_kaiten; } //コースに戻る while(nCross <= 1){ if(SENSOR_1 < BLACK_high){ turn_left_senkai; nOnline ++; } else if(SENSOR_2 < BLACK_low){ turn_left_kaiten; } else if(SENSOR_2 < WHITE_low){ go_fwd; } else if(SENSOR_2 < WHITE_high){ turn_right_kaiten; } else { turn_right_senkai; } } nCross=0; turn_left_senkai; Wait(70); until(FastTimer(1) > 4500); SHOTBALL; turn_right_senkai; Wait(70); while(nCross <= 1){ if(SENSOR_1 < BLACK_high){ turn_left_senkai; nOnline ++; } else if(SENSOR_2 < BLACK_low){ turn_left_kaiten; } else if(SENSOR_2 < WHITE_low){ go_fwd; } else if(SENSOR_2 < WHITE_high){ turn_right_kaiten; } else { turn_right_senkai; } } nCross=0; while (FastTimer(0) <= time2){ if(SENSOR_1 < BLACK_high) { turn_right_senkai; } else if (SENSOR_1 < BLACK_low) { back_turn_right_kaiten; } else if (SENSOR_1 < WHITE_low) { go_fwd; } else if (SENSOR_1 < WHITE_high) { back_turn_left_kaiten; } else { turn_left_senkai; } Wait(STEP); } turn_left_senkai; Wait(70); until(FastTimer(1) > 6000); CATCHBALL; turn_right_senkai; Wait(70); while (nCross < 1){ while (nOnline < nMAX){ if(SENSOR_1 < BLACK_high){ turn_right_senkai; nOnline++; } else { if (SENSOR_1 < BLACK_low){ turn_right_kaiten; } else if (SENSOR_1 < WHITE_low){ go_fwd } else if (SENSOR_1 < WHITE_high){ turn_left_kaiten; } else { turn_left_senkai; } nOnline==0; } Wait(STEP); } PlaySound(SOUND_UP); short_break; nCross++; nOnline=0; } turn_left_senkai; Wait(70); until(FastTimer(1) > 7500); SHOTBALL; } *ボールをシュートする側のプログラムの説明 [#z9b168ea] まずはライントレースを行う際ののしきい値と、ライントレース行う際にによく使う一連の動きを定義する。 さらにこの課題で重要な動きであるボールの発射と受け取りの動作を定義する。 最後に時間関係の定数を定義する。 **定義 [#u4213539] #define BLACK_high 36 //一番黒いしきい値 #define BLACK_low 38 //少し黒いしきい値 #define WHITE_low 42 //少し白いしきい値 #define WHITE_high 44 //一番白いしきい値 #define turn_left_senkai OnRev(OUT_A); OnFwd(OUT_C); //左旋回する #define turn_left_kaiten Off(OUT_A); OnFwd(OUT_C); //左カーブする #define turn_right_kaiten OnFwd(OUT_A); Off(OUT_C); //右カーブする #define turn_right_senkai OnFwd(OUT_A); OnRev(OUT_C); //右旋回する #define go_fwd OnFwd(OUT_AC); //前進する #define short_break Off(OUT_AC); Wait(100); //小休止する #define SHOTBALL OnFwd(OUT_B); Wait(500); //ボールを撃つ #define CATCHBALL OnRev(OUT_B); Wait(500); //ボールを受け取る #define time2 10 //シュートしない側が交差点から一回目に前進する時間 #define time3 10 //シュートしない側が交差点から二回目に前進する時間 #define nMAX 300 //交差点と判断する基準 #define STEP 1 //ライントレース時の待ち時間 **スタートから第一のパス [#o8d2f911] まずはスタート位置から二回交差点をこえるまでライントレースを行う。 二回目の交差点をこえたら左に旋回してパスをもらう準備をする。 スタートしてからの時間がある点をこえたときにパスをする。 そのままボールを持ちながら進む方向へと向きを変える。 task main(){ SetSensor(SENSOR_2,SENSOR_LIGHT); int nOnline=0; int nCross=0; int counter=0; while (nCross < 2) { //交差点までのライントレース while (nOnline < nMAX) { if(SENSOR_1 < BLACK_high) { turn_right_senkai; nOnline++; } else { if (SENSOR_1 < BLACK_low) { turn_right_kaiten; } else if (SENSOR_1 < WHITE_low) { go_fwd; } else if (SENSOR_1 < WHITE_high) { turn_left_kaiten; } else { turn_left_senkai; } nOnline==0; } Wait(STEP); } PlaySound(SOUND_UP); //交差点を感知してwhileから抜ける short_break; nCross++; nOnline=0; } turn_left_senkai; Wait(70); until(FastTimer(1) > 4500); CATCHBALL; turn_left_senkai; Wait(70); **第一パスから第二パス [#r0675926] 第一パスを終えたらそのままライントレースを行い交差点まで行く。 交差点をこえた時から時間をはかり二つの交差点の中心までライントレースする。 中心についたら右に旋回してパスを待つ。 再びスタートしてからの時間がある点をこえたときにパスをする。 パスを打ち終わったら元の向きに戻る。 while (nCross < 1){ while (nOnline < nMAX){ if(SENSOR_1 < BLACK_high){ turn_right_senkai; nOnline++; } else { if (SENSOR_1 < BLACK_low){ turn_right_kaiten; } else if (SENSOR_1 < WHITE_low){ go_fwd } else if (SENSOR_1 < WHITE_high){ turn_left_kaiten; } else { turn_left_senkai; } nOnline==0; } Wait(STEP); } PlaySound(SOUND_UP); short_break; nCross++; nOnline=0; } while (FastTimer(0) <= time2){ if(SENSOR_1 < BLACK_high) { turn_right_senkai; } else if (SENSOR_1 < BLACK_low) { back_turn_right_kaiten; } else if (SENSOR_1 < WHITE_low) { go_fwd; } else if (SENSOR_1 < WHITE_high) { back_turn_left_kaiten; } else { turn_left_senkai; } Wait(STEP); } nCross=0; turn_right_senkai; wait(70); until(FastTimer(1) > 6000); SHOTBALL; turn_left_senkai; Wait(70); **第二パスから第三パス [#nb4f9938] ここは第一から第二とほぼ同じ動きをする。 違うところは交差点から時間で進むときの距離が短いことである。 while (nCross < 1){ while (nOnline < nMAX){ if(SENSOR_1 < BLACK_high){ turn_right_senkai; nOnline++; } else { if (SENSOR_1 < BLACK_low){ turn_right_kaiten; } else if (SENSOR_1 < WHITE_low){ go_fwd } else if (SENSOR_1 < WHITE_high){ turn_left_kaiten; } else { turn_left_senkai; } nOnline==0; } Wait(STEP); } PlaySound(SOUND_UP); short_break; nCross++; nOnline=0; } while (FastTimer(0) <= time2){ if(SENSOR_1 < BLACK_high) { turn_right_senkai; } else if (SENSOR_1 < BLACK_low) { back_turn_right_kaiten; } else if (SENSOR_1 < WHITE_low) { go_fwd; } else if (SENSOR_1 < WHITE_high) { back_turn_left_kaiten; } else { turn_left_senkai; } Wait(STEP); } turn_right_senkai; Wait(70); until(FastTimer(1) > 7500); CATCHBALL; turn_left_senkai; Wait(70); **第三パスからシュート [#mb89f9b9] まずはゴール近くの交差点までひたすらライントレースを行う。 この交差点を基準にすることで時間指定するよりも誤差が減少し、シュート成功確率も上がる。 あとは左に旋回し、後ろに少し下がってからシュートを打つ。 後ろに下がるのは規定に「輪の中に入った状態でシュートをしてはいけない」とあるからである。 while(counter < 1){ while(nOnline < nMAX){ if (SENSOR_1 < 38){ turn_right_senkai; nOnline++; } else { if (SENSOR_1 < 39){ turn_right_kaiten; } else if (SENSOR_1 < 42){ go_fwd; } else if (SENSOR_1 < 44){ turn_left_kaiten; } else { turn_left_senkai; } } nOnline=0; } Wait(STEP); } short_break; turn_left_senkai; Wait(150); go_rev; Wait(100); SHOTBALL; } *ボールをシュートしない側のプログラムの説明 [#g2b15528] **定義 [#t4720d49] #define BLACK_high 36 //一番黒いしきい値 #define BLACK_low 38 //少し黒いしきい値 #define WHITE_low 42 //少し白いしきい値 #define WHITE_high 44 //一番白いしきい値 #define turn_left_senkai OnRev(OUT_A); OnFwd(OUT_C); //左旋回する #define turn_left_kaiten Off(OUT_A); OnFwd(OUT_C); //左カーブする #define turn_right_kaiten OnFwd(OUT_A); Off(OUT_C); //右カーブする #define turn_right_senkai OnFwd(OUT_A); OnRev(OUT_C); //右旋回する #define go_fwd OnFwd(OUT_AC); //前進する #define short_break Off(OUT_AC); Wait(100); //小休止する #define SHOTBALL OnFwd(OUT_B); Wait(500); //ボールを撃つ #define CATCHBALL OnRev(OUT_B); Wait(500); //ボールを受け取る #define TURNSTEP 10 //横のセンサーを使う時の繰り返しの待ち時間 #define time2 10 //シュートしない側が交差点から一回目に前進する時間 #define time3 10 //シュートしない側が交差点から二回目に前進する時間 #define nMAX 300 //交差点と判断する基準 #define STEP 1 //ライントレース時の待ち時間 ここはシュートする側とほぼ同じである。 進む時間に微妙な違いがある。 **スタートからボールを取るまで [#k0fd3754] まずは交差点までライントレースを行う。 交差点をこえたら一定時間直進をし、そのまま右に旋回しボールに向く。 ボールに向いたらそのまま直進しボールを取る。 task main(){ SetSensor(SENSOR_2,SENSOR_LIGHT); int nOnline=0; int nCross=0; ClearTimer(0); while(nCross <= 1){ while(nOnline < nMAX){ if(SENSOR_1 < BLACK_high){ turn_left_senkai ; nOnline++ ; } else if(SENSOR_2 < BLACK_low){ turn_left_kaiten; } else if(SENSOR_2 < WHITE_low){ go_fwd; } else if(SENSOR_2 < WHITE_high){ turn_right_kaiten; } else { turn_right_senkai; } } nOnline == 0; nCross ++; short_break; cross_line; } nCross=0; go_fwd; Wait(500); OnRev(OUT_A); OnFwd(OUT_C); Wait(100); //ボールに向く CATCHBALL; OnFwd(OUT_AC); Wait(200); //ボールを取る **ボールを取ってから第一パスまで [#m0208f76] ボールを取ったらラインを感知するまで左に進み、ラインに乗ったらライントレースを開始する。 交差点までライントレースを行い、交差点を感知したらコース内側を向いてパスの準備をする。 スタートしてからの時間がある点をこえたところでパスをして、そのまま元の向きに戻る。 until(SENSOR_1 < BLACK_low){ turn_left_kaiten; } //コースに戻る while(nCross <= 1){ if(SENSOR_1 < BLACK_high){ turn_left_senkai; nOnline ++; } else if(SENSOR_2 < BLACK_low){ turn_left_kaiten; } else if(SENSOR_2 < WHITE_low){ go_fwd; } else if(SENSOR_2 < WHITE_high){ turn_right_kaiten; } else { turn_right_senkai; } } nCross=0; turn_left_senkai; Wait(70); until(FastTimer(1) > 4500); SHOTBALL; turn_right_senkai; Wait(70); **第一パスから第二パス [#kaf58729] 第一パスを終えたら再び時間指定付きライントレースを行う。 ここの距離は短いので誤差は少なくて済む。 ある点まですすんだらコース内側を向き、パスの準備をする。 スタートしてからの時間がある点をこえたところでパスをして、そのまま元の向きに戻る。 while (FastTimer(0) <= time2){ if(SENSOR_1 < BLACK_high) { turn_right_senkai; } else if (SENSOR_1 < BLACK_low) { back_turn_right_kaiten; } else if (SENSOR_1 < WHITE_low) { go_fwd; } else if (SENSOR_1 < WHITE_high) { back_turn_left_kaiten; } else { turn_left_senkai; } Wait(STEP); } turn_left_senkai; Wait(70); until(FastTimer(1) > 6000); CATCHBALL; turn_right_senkai; Wait(70); **第二パスから第三パス [#j5f406f0] 第二パスを終えたら次の交差点までライントレースを行う。 交差点をこえたら少し進んでから左に旋回してコース内側を向く。 スタートしてからの時間がある点をこえたところでパスをする。 while (nCross < 1){ while (nOnline < nMAX){ if(SENSOR_1 < BLACK_high){ turn_right_senkai; nOnline++; } else { if (SENSOR_1 < BLACK_low){ turn_right_kaiten; } else if (SENSOR_1 < WHITE_low){ go_fwd } else if (SENSOR_1 < WHITE_high){ turn_left_kaiten; } else { turn_left_senkai; } nOnline==0; } Wait(STEP); } PlaySound(SOUND_UP); short_break; nCross++; nOnline=0; } turn_left_senkai; Wait(70); until(FastTimer(1) > 7500); SHOTBALL; } **感想 [#u1ed9970] この課題を初めて出された時、四人が協力して取り組む必要があると思った。課題1の時は、お互いにうまく連携ができずに終わってしまったという面もあったので、今回は、四人集まる機会を前回よりも増やした。それでも、テスト期間に重なるなどでなかなか集まるということができなかったため、プログラムを四分割して作るという方法をとった。結果、四人のプログラムをうまく合わせることができずに終わってしまった。何かを行うにあたって、しっかりとたてられた計画の上で行う必要があるという場合がこれから多くあると思う。この失敗をそのような場面で生かすことができたらよいと思った。他のメンバーにはとてもお世話になり、迷惑もかけた。自分の役割を確立・理解し、実行する力を身に着けることが大切だと思った。