[[2010b]] #contents *課題3の内容とルール [#s4a61046] **課題内容 [#d85c2822] 今回は、コース上を走っているマシンを見つけだしマシンめがけて外からブロックを投げるものと、そのマシンの後ろを5秒間追尾して、ブロックを投げるというものの2つである。 追われる側はマシンの後ろに光センサをつけ、追う側はその光を感知すればよい。 プログラムは追われるためにライントレースするプログラムに加え、光を見つけ出して5秒間光を追尾してブロックを 投げるというものと、光を見つけ出して外から打ち出すものの3つのプログラムを作る必要がある。 **ルール [#n128cb56] 車輪を動かすためのモーターが1つしか使えない。また、車体の後ろに光センサを付けなければいけないので、 光センサ1つでライントレースをしなければならない。 *メンバー [#bf3b5581] ○山本将大 ○水野悠太 *ロボットの紹介 [#ma7b2fba] **モーター1つでどうやって進ませるか? [#fc682978] 今までのように、タイヤに直接モーターをつけようとすると、モーターが2つ必要になる。 ここで、ディファレンシャルギアを使うことによってモーター1つで前進や曲がることができるようになる。 ただし、後退することはできない。また、直進はできない。左右にくねくねとさせることによって前進させる。 ***ディファレンシャルギア [#i1a2ffc3] #ref(./ディファレンシャルギア.JPG,70%) このようにディファレンシャルギアをつなげた。 ディファレンシャルギアはタイヤが必要以上に回転した場合空回りするというもの。 #ref(./ストッパー1.JPG,70%) このように左右ともギアにストッパーをかける。 こうすることによって、タイヤが後ろ回転しないようにする。 これでディファレンシャルギアを作用させる。 **ブロックを打ち出す仕組み [#t0611a8e] &ref(./CA3C02951.JPG,50%); &ref(./CA3C02961.JPG,50%); 上の写真はボヤけて見えにくいと思うが、打ち出す前後を比較したものである。 初め、ピッチングマシンのようにタイヤにはさんで打ち出す方法やブロックを持って投げるような方法を考えたが、最終的にモーターにつなげたハンマーのようなものでブロックを打ち出すという方法をとった。 **ブロックを装填する方法 [#ed927be6] &ref(./CA3C02931.JPG,50%); &ref(./CA3C02941.JPG,50%); 上の写真は装填前後を比較したものである。 初め、ブロックはストッパーにより止められているが、モーターを少し始動させてストッパーを外すと ブロックが転がって自動的に装填される。 **完成形 [#xf2e54f1] #ref(./完成型1.JPG,70%) *プログラム [#oc7e3190] **逃げるプログラム(ライントレース) [#s444b97a] #define THRESHOLD 45 //閾値 task main () { SetSensor(SENSOR_1, SENSOR_LIGHT); //光センサを1に定義 while (true){ //whileの中が正しい場合繰り返す。 OnFwd(OUT_B); //モーターを正回転(左に曲がる) until((SENSOR_1 < THRESHOLD)); //センサ1が閾値より小さいとき(黒色を認識するまで) OnRev(OUT_B); //モーターを逆回転(右に曲がる) Wait(20); Off(OUT_B); Wait(20); } } 黒→白→黒→白というように左右にくねくねさせながらライントレースする。 黒を認識するまで左に曲がらせ黒を認識したら0,2秒間右に曲げることを繰り返す。このプログラムでコース上を走らせることはできたが、外枠しか走らすことができなかった。 **山本(外から打ち出す) [#y519f36e] int light_max; //変数を定義 task main () { SetSensor(SENSOR_1, SENSOR_LIGHT); //光センサを1に定義 SetSensor(SENSOR_3, SENSOR_LIGHT); //光センサを3に定義 ClearTimer(0); //タイマをセット light_max = 0; //変数をリセット while(Timer(40)){ //4秒間 whileの中を実行する OnFwd(OUT_B); //左に回りつづける if(SENSOR_1 > light_max){ //もしセンサ1よりlight_maxが大きい場合 light_max = SENSOR_1; //その値をセンサ1とする } } OnFwd(OUT_B); until((SENSOR_1==light_max)); //センサ1がlight_maxとなるまで回りつづける Off(OUT_B); OnFwd(OUT_C); //ブロックを装填する Wait(1); Off(OUT_A+OUT_C); //1秒間静止 Wait(100); OnFwd(OUT_A); //ブロックを打ち出す Wait(50); Off(OUT_A+OUT_C); } //終わり マシンが回っている間に光センサで光を感知し、強い光を感知する度に変数light_maxを更新させる。 1周した後、light_maxの値は一番強い光の値になっている。その後もう一度light_maxの場所まで移動し、 ブロックを強い光めがけて投げつける。 **水野(追いかけながら射ちだす) [#z01d84a8] #define shoot OnFwd(OUT_A); Wait(100); Off(OUT_A); #define charge OnFwd(OUT_C); Wait(1); Off(OUT_C); #define THRESHOLD 45 //閾値 sub shooting() { shoot; i=i+1; charge; } sub run() { SetSensor(SENSOR_1, SENSOR_LIGHT); //センサー1を光センサーと認識 SetSensor(SENSOR_3, SENSOR_LIGHT); //センサー3を光センサーと認識 int lmax=0; //現在の次点光量をlmaxと定義 ClearTimer(0); //タイマー始動 while(FastTimer(0)<100) //機体が光の最大値を10秒間探す { while (true) //whileの中が正しい場合繰り返す。 { OnFwd(OUT_B); //モーターを正回転(左に曲がる) until((SENSOR_1 < THRESHOLD)); //センサ1が閾値より小さいとき(黒色を認識するまで) OnRev(OUT_B); //モーターを逆回転(右に曲がる) Wait(20); Off(OUT_B); Wait(20); if(SENSOR_3 < lmax) //センサー3がlmaxより強い光を感知したとき { lmax=SENSOR_3;; //次点光量を現在記録している最大光量と入れ替える } } } } taskmain() { i=0; //変数iをリセット while(i<2) //二回打つまでwhile内を続ける { run(); if(SENSOR_3=lmax) shooting(); wait(100); } Off(OUT_B); } 10秒の間に最大値(逃げるRCX)を探し、再び見つけたら打ちだす。基本的に上と同じです。 *工夫した点、苦労した点 [#g175219e] ・ディファレンシャルギアがうまく噛み合わなくて、走らせようとしてもギギギっと変な音がしてなかなか走らすことができなかった。噛み合うように外からギアをひっぱって最後はうまく走るようになった。 ・光センサが2つあれば黒線をまたいで、もし黒線を踏んだら修正するという方法がとれたが、光センサは1つしか使えないし、今回はディファレンシャルギアを使用するので直進もできないのでライントレースする方法に悩まされた。 ・光を探し出す際に、相手は光センサの小さい光なので探し出すことが困難であることと、相手もくねくねと進んでいるのでとても難しかった。 *反省 [#f17eb0ce] ***山本 [#b71494bd] 今までモーター2つで車を走らせるということが当たり前になっていたが、ディファレンシャルギアを学んでその概念が覆された。しかし、モーター1つでちゃんと機能させるには苦労した。まず最初はディファレンシャルギアの仕組みを理解する必要があったし、制作段階では噛みあわせ等の理由で走らなかったり、プログラムも走行の仕方が今までと全く違ったので難しかった。 ***水野 [#i0666bc4] これまではプログラム重視だったが、今回はロボもある程度考えないといけなかった。しかしプログラムもややこしく今までの集大成のような課題だった。ディファレンシャルギアを使った走行も最初はギアがしっかり噛み合わなかったり、思うように走行しなくて苦労した。 *コメントをどうぞ [#m6d9b8fe] - 書くべきことは書けています。ただ、プログラムの方に細かいミスがいくつかあると思います。まず、後から改良したり、他の人でも読みやすいように、まとまりごとの改行やindentを使ってください。1人目の15行目では、=は代入なので、等しいという意味では==です。2人目では、定義の位置に気を付けてください。サブルーチン内で定義すると、それが呼び出されるまで定義されませんし、呼び出されるたびに定義することになります。また、run内のwhileの制御が怪しい気がします。 -- [[FI]] &new{2011-02-08 (火) 00:54:11}; - 写真に解説を入れると良いと思います。動作する所に印を付けるだけでも変わります。 -- [[TAKA]] &new{2011-02-08 (火) 13:18:41}; #comment