[[2019a/Member]] 目次 #contents *課題について [#m8a38d19] 詳しくはこちらを参照[[2019a/Mission2]] -ロボットを動かすルートは次の通り。 A→B→C→D→E→F→G→J→K→L→M *ロボットについて [#k040e525] -今回の課題は線に沿って動く動作と球を掴んでゴールするという動作の2つが必要となるので、形を考えるのに少し苦労した。後でも述べるが、センサーの位置がタイヤの後ろになってしまっているのが今回の失敗の1番の原因だと思われる。 -ロボットの下部 #ref(./ろぼっと1.jpg) -画像左側がロボットの前部分になるが、見てわかるようにタイヤの後ろにセンサーがきてしまっている。 -ロボットの全体 #ref(./ろぼっと2.jpg) -アームを取り付けるだけの簡易的なものにしたため、アーム用のプログラムを書く手間が省けた。しかし球が取れるかはモーターの動き具合に左右されてしまうので、そこも改善すべき点の1つである。しかし、アームの先端に小さな返しを取り付けることによって球を出にくくした。センサーはなるべく紙面と垂直になるように取り付けた。 *プログラムについて [#t965a40d] -今回のプログラムは、センサーを使って、黒線をトレースするもの,交差点を直進するもの,ヘアピンカーブを曲がるものの3つを作った。またセンサーが示す色の値を5段階で表すことによって、より細かい動きが可能になった。 **定義について [#p017fad2] -今回のプログラムの定義は次のようにした。左右に曲がる曲がり方をそれぞれ3種類ずつに区切ることで、よりカーブをやりやすくした。 #define BLACK 28 //黒色の値 #define WHITE 54 //白色の値 #define SPEED_H 30 //速い方のスピード #define SPEED_L 20 //遅い方のスピード #define go_forward OnFwd(OUT_BC,SPEED_H); //前進 #define turn_left1 OnFwd(OUT_B,SPEED_L);Off(OUT_C); //ゆっくり左折 #define turn_left2 OnFwd(OUT_B,SPEED_H);Off(OUT_C); //速く左折 #define turn_left3 OnFwd(OUT_B,SPEED_L);OnRev(OUT_C,10); //急カーブ(左) #define turn_right1 Off(OUT_B);OnFwd(OUT_C,SPEED_L); //ゆっくり右折 #define turn_right2 Off(OUT_B);OnFwd(OUT_C,SPEED_H); //速く右折 #define turn_right3 OnRev(OUT_B,10);OnFwd(OUT_C,SPEED_L); //急カーブ(右) #define STEP 1 **線をトレースするプログラム [#c0e3b0c4] -僕は今回、左トレースで考えた。そうすることによってほとんどの線を左トレースだけで動くことができると思ったからだ。CurrentTickを使うことで黒色の時間を計り、その値がt_maxを超えるとwhileループから抜け出すようになっている。また、untilを用いることでしっかりループの時間を設定した。 -僕は今回、左トレースで考えた。そうすることによってほとんどの線を左トレースだけで動くことができると思ったからだ。CurrentTickを使うことで黒色の時間を計り、その値がt_maxを超えるとwhileループから抜け出すようになっている。ここでのt_maxは黒でいる時間の上限であり、そこに数値を代入してしきい値の役割を果たしている。また、untilを用いることでしっかりループの時間を設定した。 void follow_line() { long t0=0,t_BLACK=0,t_max=110; t0=CurrentTick(); while(t_BLACK<t_max){ if(SENSOR_3>BLACK){ //黒灰のとき turn_left2; } else if(SENSOR_3>BLACK+5){ //灰のとき go_forward; } else if(SENSOR_3>WHITE-5){ //白灰のとき turn_right2; } else if(SENSOR_3>WHITE){ //白のとき turn_right1; } else{ //黒のとき turn_left1; t0=CurrentTick(); until((SENSOR_3<BLACK+5)&&(SENSOR_3>BLACK)); t_BLACK=CurrentTick()-t0; } Wait(STEP); } } **ヘアピンカーブを曲がるプログラム [#l1117b1d] -このプログラムは線をトレースするプログラムとほとんど同じであるが、急カーブを曲がる際にトレースするだけのプログラムだとセンサーの位置やロボットの形状、思わぬ方向に向いてしまうため、曲がる用にもう1つプログラムを用意した。 void follow_line() { long t0=0,t_BLACK=0,t_max=110; t0=CurrentTick(); while(t_BLACK<t_max){ if(SENSOR_3>BLACK){ //黒灰のとき turn_left2; } else if(SENSOR_3>BLACK+5){ //灰のとき go_forward; } else if(SENSOR_3>WHITE-5){ //白灰のとき turn_right2; } else if(SENSOR_3>WHITE){ //白のとき turn_right3; } else{ //黒のとき turn_left3; t0=CurrentTick(); until((SENSOR_3<BLACK+5)&&(SENSOR_3>BLACK)); t_BLACK=CurrentTick()-t0; } Wait(STEP); } } **交差点を突き進むプログラム [#re5b1113] -上記のプログラムで交差点に差し掛かるとロボットは、斜め左を向いているはずである。そこで一旦黒線から抜け出して右回転して元の線に戻れるようなプログラムを作った。ここでもuntilを使うことでちゃんとした向きになるまで回転したり動いたりできるようにしてある。 void cross_line() { go_forward; until(SENSOR_3>WHITE-5); turn_right2; until(SENSOR_3>BLACK); } **全体のプログラム [#h2a64b16] 上記のプログラムを組み合わせてこのように組んだ。 task main() { SetSensorLight(S3); follow_line(); //AからDまで cross_line(); //D地点の交差点 follow_line(); //ゴールまで突っ込む Off(OUT_`BC); } -僕は今回ぎりぎりまでプログラムを少なくしてみようと思った。僕の考えではこれらのプログラムを組み合わせればゴールできると考えていたからだ。今回のルートだとそれは可能だと思う。球をとる動作に関しては球を置く位置をアームが動く可動範囲に置いておくことで自動的に入るという仕組みにしてある。意外と入ってくれたので良かったと思う。 *結果 [#c99b7835] -直線的な部分はしっかり進んだが、急カーブになると正しい道から逸れてしまった。 -モーター(電池)の都合で上手く曲がってくれなかった。 *考察 [#b15cb5df] -「ロボットについて」でも述べたように、タイヤの後ろにセンサーを付けてしまったせいでより多くの時間回転してしまったため思わぬ方向にロボットが向いてしまったと考えられる。また、こまめに電池の管理を怠っていたために今回のように電池がたりなくなってしまったと思われる。 *感想と反省 [#k60903df] **感想 [#xd27195d] -今回課題2をやってみて、とりあえず難しいなと心から感じた。ペアの人といくら悩んでもわからないエラーが出てきたり、先生がホワイトボードに書かれたプログラムを試してもうまくいかないなどたくさんの問題が出てきた。と同時に、やっていて楽しくも感じた。直しても直しても出てくる課題に立ち向かうことが特に楽しかった。課題3は4人でやるのでみんなで協力してやっていきたい。 **反省 [#hd6ac875] -課題2では、わからないことが課題1に比べてたくさん出てきた。それにもかかわらず1番頼りになる先生に聞くこともなく自分たちだけで悩んだことが最も反省すべき点だと思う。もっと早く聞いていたらロボットの構造的な問題に気づいていたかもしれない。また、プログラムの簡略化を図りそれのせいで誤作動が多くなり、改良する回数が増えたのもよくないと思う。適度に簡単にすることが大事なんだなと思った。