[[2010b]] #contents *課題3の内容とルール [#s4a61046] **課題内容 [#d85c2822] 今回は、コース上を走っているマシンを見つけだしマシンめがけて外からブロックを投げるものと、そのマシンの後ろを5秒間追尾して、ブロックを投げるというものの2つである。 追われる側はマシンの後ろに光センサをつけ、追う側はその光を感知すればよい。 プログラムは追われるためにライントレースするプログラムに加え、光を見つけ出して5秒間光を追尾してブロックを 投げるというものと、光を見つけ出して外から打ち出すものの3つのプログラムを作る必要がある。 **ルール [#n128cb56] 車輪を動かすためのモーターが1つしか使えない。また、車体の後ろに光センサを付けなければいけないので、 光センサ1つでライントレースをしなければならない。 *メンバー [#bf3b5581] ○山本将大 ○水野悠太 *ロボットの紹介 [#ma7b2fba] **モーター1つでどうやって進ませるか? [#fc682978] 今までのように、タイヤに直接モーターをつけようとすると、モーターが2つ必要になる。 ここで、ディファレンシャルギアを使うことによってモーター1つで前進や曲がることができるようになる。 ただし、後退することはできない。また、直進はできない。左右にくねくねとさせることによって前進させる。 ***ディファレンシャルギア [#i1a2ffc3] #ref(./ディファレンシャルギア.JPG,70%) このようにディファレンシャルギアをつなげた。 ディファレンシャルギアはタイヤが必要以上に回転した場合空回りするというもの。 #ref(./ストッパー.JPG,70%) このように左右ともギアにストッパーをかける。 こうすることによって、タイヤが後ろ回転しないようにする。 これでディファレンシャルギアを作用させる。 **ブロックを打ち出す仕組み [#t0611a8e] &ref(./CA3C0295.JPG,50%); &ref(./CA3C0296.JPG,50%); 上の写真はボヤけて見えにくいと思うが、打ち出す前後を比較したものである。 初め、ピッチングマシンのようにタイヤにはさんで打ち出す方法やブロックを持って投げるような方法を考えたが、最終的にモーターにつなげたハンマーのようなものでブロックを打ち出すという方法をとった。 **ブロックを装填する方法 [#ed927be6] &ref(./CA3C0293.JPG,50%); &ref(./CA3C0294.JPG,50%); 上の写真は装填前後を比較したものである。 初め、ブロックはストッパーにより止められているが、モーターを少し始動させてストッパーを外すと ブロックが転がって自動的に装填される。 **完成形 [#xf2e54f1] #ref(./完成型.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() { int i=0; shoot; i=i+1; charge; } sub run() { SetSensor(SENSOR_1, SENSOR_LIGHT); //センサー1を光センサーと認識 SetSensor(SENSOR_3, SENSOR_LIGHT); //センサー3を光センサーと認識 int l=0; //現在の最大光量をlと定義 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=l; //次点光量を現在記録している最大光量と入れ替える } else if((SENSOR_3 >= l) && (SENSOR_3 <= max)) //センサー3がlmax以下l以上の光量を感知したとき { lmax=SENSOR_3; } } } taskmain() { i=0; //変数iをリセット while(i<2) { run(); if(SENSOR_3=lmax) shooting(); wait(100); } Off(OUT_B); } *工夫した点、苦労した点 [#g175219e] ・ディファレンシャルギアがうまく噛み合わなくて、走らせようとしてもギギギっと変な音がしてなかなか走らすことができなかった。噛み合うように外からギアをひっぱって最後はうまく走るようになった。 ・光センサが2つあれば黒線をまたいで、もし黒線を踏んだら修正するという方法がとれたが、光センサは1つしか使えないし、今回はディファレンシャルギアを使用するので直進もできないのでライントレースする方法に悩まされた。 ・光を探し出す際に、相手は光センサの小さい光なので探し出すことが困難であることと、相手もくねくねと進んでいるのでとても難しかった。 *反省 [#f17eb0ce] ***山本 [#b71494bd] 今までモーター2つで車を走らせるということが当たり前になっていたが、ディファレンシャルギアを学んでその概念が覆された。プログラミングも ***水野 [#i0666bc4] *コメントをどうぞ [#m6d9b8fe]