#contents *課題3の内容とルール [#tfe55046] 相手のロボットに向かってブロックを投げるロボットを製作せよ。ただし、ロボットは課題2で用いたコースを走る。 +ライントレースをしながら相手のロボットを見つけ、5秒間追跡した後ブロックを投げること。 +コース外の所から相手のロボットを探し出し、そちらに向けブロックを投げること *ロボットの概要 [#xf9efff3] 後輪駆動。 後ろのタイヤ2つと前につけた棒の3点で支えている。 #ref(./CA3C0286.JPG,100%,完成作品) ***投げる装置の仕組み [#td17a9fb] -赤矢印のように、モーターを回転させて打ち出す仕組み。緑の枠のレゴで縦に固定した。(モーターの向きが下向きの為) #ref(./CA3C0287.JPG,50%,投球装置) -ブロックを縦に置いた時、隙間ができるだけ狭くなるように工夫した。そうすることでブロックが真っ直ぐ飛び、飛距離がのびた。 #ref(./CA3C0304.JPG,50%,投球装置その2) -ブロックを2つ以上装置に積むときに、1回ブロックを打って2個目のブロックが装填されるときにレゴの突起に引っ掛からないようにした。 #ref(./CA3C0305.JPG,50%,投球装置その3) ***モーター1つで方向転換できる仕組み [#ca63015a] ディファレンシャル・ギアとラチェットを用いて考えられる方法 +左右のタイヤの回転方向は同じ + ラチェット1つ →直進可、方向転換一方向のみ可 +左右のタイヤの回転方向は逆 + ラチェット2つ →直進不可、方向転換左右とも可 (2)を採用。 しかしラチェットを取り付ける際、構造上の理由で右側のラチェットが長くなった。 #ref(./CA3C0288.JPG,100%,) **製作過程 [#of227fff] -初めはキャスターを使っていた。しかしキャスターがうまく動かず、摩擦を大きくする原因になってしまった。 キャスターの改良もしたが、試しに棒一本を使ってみたところ上手くいったので、採用することにした。 -タイヤが空回りしてしまうという問題があった。後輪の摩擦を大きくすることで解決をはかった。 実際には、1,RCXを後ろ寄りにつける 2,前の棒を長めにする という方法をとった。 その結果、車体が上向きになり、ブロックが装置から落ちないという利点が付いた。 *プログラム [#z47e3adb] ***光センサ1つでライントレースする仕組み [#z6388ae2] #define THRESHOLD 40 //しきい値 task main(){ SetSensor(SENSOR_1, SENSOR_LIGHT); //センサー1定義(ライントレース用) while(1){ if(SENSOR_1<THRESHOLD){ //最初にライン上(黒)の場合 OnFwd(OUT_C);Wait(15); //左に逸らす if(SENSOR_1>THRESHOLD){ //ライン外(白)の場合 OnRev(OUT_C);Wait(15); //右に逸らす } } } Off(OUT_C); } 最初ライン上(黒)に置く。これによってwhile内の1つ目のifに入る。 すると左に逸れ、センサはライン外(白)に。 ライン外(白)になると、2つ目のifにはいり右に逸れる。 ディファレンシャル・ギアと2つのラチェットを使ったことで直進が出来ない。しかしセンサ1つなので、白と黒を交互に感知して進む方法をとり、ジグザグに進むことにした。 **松澤(追跡あり) [#k84a262e] #define THRESHOLD 40 //しきい値 #define RUN_TIME 500 //相手を探す時間 int s=0; //打つ回数の変数 void shoot(){ //弾を打つ関数 OnFwd(OUT_A); //一度引く Wait(5); OnRev(OUT_A); //打つ Wait(5); OnFwd(OUT_A); //引く Wait(5); Off(OUT_A); s++; // sをインクリメント } task main(){ SetSensor(SENSOR_1, SENSOR_LIGHT); //センサー1定義(ライントレース用) SetSensor(SENSOR_3, SENSOR_LIGHT); //センサー3定義(相手の探索用) int l=0; //入力された光の値用の変数 int l_max=0; //光の最大値用の変数 while(s != 2){ //弾を2回打つまで繰り返す(2回打たなければ終わらない) ClearTimer(0); //Timer(0)をリセット while(Timer(0)<=RUN_TIME){ //相手を探すループ if(SENSOR_1<THRESHOLD){ //最初にライン上(黒)の場合 OnFwd(OUT_C);Wait(15); //左に逸らす repeat(2){PlaySound(SOUND_CLICK) ;} if(SENSOR_1>THRESHOLD){ //ライン外(白)の場合 OnRev(OUT_C);Wait(15); //右に逸らす } } if(SENSOR_3>60){ //蛍光灯か相手の光かを判断する(ある程度光が当たっていたら) l=SENSOR_3; // lに観測値を代入 if(l>l_max){ //入力値が観測最大値よりも大きかったら l_max=l; // l_maxに観測値lを代入(l_maxを更新) } } } if(SENSOR_3>=(l_max-5)){ //SENSOR_3がl_max(相手の光)を感知したら[誤差±5] repeat(16){ //5秒間追跡する OnFwd(OUT_C);Wait(15); OnRev(OUT_C);Wait(15); } shoot(); //弾を打つ } PlaySound(SOUND_UP); } Off(OUT_C); } 『5秒間相手を探し続け、いなければまたそれを繰り返す』というプログラムにしました。一番大きな欠点は、ライントレースをするプログラムが、ただ黒を見つけ出すというもので、ライン外に出てしまったときに止まってしまうということです。 **伊藤 [#re7d4db2] task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT); while (1) { if (SENSOR_3<40) //ライントレース {OnRev(OUT_C); Wait(25); if (SENSOR_3>40) {OnFwd(OUT_C); Wait(25); } } if (SENSOR_3>45) //光センサ45以上の時 {OnFwd(OUT_A); //弾を打つ Wait(20); Off(OUT_A); OnRev(OUT_A); Wait(20); Off(OUT_A); } } } ライントレースは上記、光センサ1つでライントレースする仕組みによる。このライントレースは交差点を直進することはなく、左折してしまう。結果的にコースの外回りを走る。 弾を打つのは光センサの値が45を上回ったとき。 45というのは、相手の光を感知したときの値。普段は大きくても43までにしかならないため *反省 [#lb11e93d] **松澤 [#s2d03151] 今回の課題は、光の最大値を求めるというものでしたが、うまくできたと思います。しかし、一番悩んだことがディファレンシャル・ギアを使ってロボを製作することでした。最初はディファレンシャル・ギアを直接タイヤに付け、真っすぐ進ませるようにしようとしましたが、機体が重く摩擦が大きくなり直進が出来ませんでした。それにギアを反転させて方向転換をしようとしましたが、それも重さのせいで出来ませんでした。結局直接つけるのはやめて、ジグザグに進ませるようにしました。こちらの方がよく動きました。ロボ製作のおかげでロボの組み立てがうまくなったと思います。 ロボ製作は弾を飛ばす装置にこだわりました。ギアの反動でレゴが外れてしまう事が何度も起きました。これを解決するために頑丈にしましたが、重くなってしまい外れて落ちてしまう事がありました。レゴが多すぎず、且つ頑丈にするように工夫しました。プログラミングはシンプルにできたと思います。今回の課題でプログラミングの理解がより深まりました。 **伊藤 [#h649d1e2] 追尾しなくてよいということだったので、前に動くものがあった(光センサの値の変化)場合に投げることにしようと考えた。しかし、光センサは、前方に物があることを十分感知できなかった。方向によっても値の変化が大きかったので、センサの周りを囲って周りの影響を小さくすることもしてみた。しかしあまり効果がなかった。 したがって相手のセンサからの光を感知するしかないと考えた。 蛍光灯の明りがあるため、通常の状態とセンサの光が当たった時の差が小さいと思う。暗いところでやれば、もっと正確に光を見つけられるのではないかと思った。 *コメント欄 [#de1d6748]