[[2017a/Member]] *目次 [#s3d0feec] #contents *課題 [#qcf82f56] 今回の課題は2cm幅の線に沿って走るロボットの作成だ。 ~[[詳しくはこちら:http://yakushi.shinshu-u.ac.jp/robotics/?2017a%2FMission2]] ~私は点Eで右折するルートを選択した。 ~相方のページは[[こちら:http://yakushi.shinshu-u.ac.jp/robotics/?2017a%2FMember%2Ftomoya%2FMission2]] *機体 [#e40e99e1] **ロボット [#t65272b2] ロボットはセンサーの取り付け位置以外、説明書と同じ構造にした。 ~&ref(aa.png); **工夫した点 [#h2489b2c] ~光センサーの位置を説明書のものよりも本体に近くした。これのおかげでより急カーブを曲がりやすくなった。 ~&ref(light2.png); *プログラム [#ce1730e6] **ライントレイス [#f2a3bc76] 私達の機体の光センサーは白いところでは63、黒いところでは35という値をだした。この範囲を35<=X<39(黒),39<=X<45(暗い灰色),45<=X<53(灰色),53<=X<59(明るい灰色), 59<=X<63(白)の5つに分けた。 ~点Eで右折するコースでは、常に線の右側もしくは、常に左側を走行するプログラムにすると上手に曲がれないところが出てくる。そのため線の右側、左側の両方のライントレースできるように両方のプログラムを作った。 ***右側ライントレイス [#qd1543a1] ~機体が「黒」と判別したとき、その場で右回りに回転とする。 ~機体が「暗い灰色」と判別したとき、右にカーブする。 ~機体が「灰色」と判別したとき、直進する。 ~機体が「明るい灰色」と判別したとき、左にカーブする。 ~機体が「白」と判別したとき、その場で左回りに回転する。 ***左側ライントレイス [#z375e6ea] 右側ライントレイスの回転する方向を逆にしただけである。 ~機体が「黒」と判別したとき、その場で左回りに回転とする。 ~機体が「暗い灰色」と判別したとき、左にカーブする。 ~機体が「灰色」と判別したとき、直進する。 ~機体が「明るい灰色」と判別したとき、右にカーブする。 ~機体が「白」と判別したとき、その場で右回りに回転する。 ***直角と急カーブの見分け方 [#y4f59bed] 点Hから点Gまで移動するとき、20秒間は黒い部分に長時間のっていても止まらないよにした。こうしなければ私のプログラムでは急カーブでも直角でも止まってしまう。しかし、止まらないようにすることによって急カーブを通過しやすくなる、また急カーブでは止まらないが直角では止まるようになる。 **定義 [#g471afce] #define speedH 30 //直進、後退時の速度 #define speedL 20 //曲がるときの速度 #define OnRL(speedr,speedl) OnFwd(OUT_B,speedr);OnFwd(OUT_C,speedl); #define go_forward OnRL(speedH,speedH); //直進 #define go_back OnRL(-speedH,-speedH); //後退 #define spin_left OnRL (speedL,-speedL); //左旋回 #define turn_left OnRL (speedL,0); // 左折 #define turn_right OnRL (0,speedL); //右折 #define spin_right OnRL (-speedL,speedL); //右旋回 #define wait Wait(1000); #define off Off(OUT_BC) **サブルーチン [#cef82b5a] ***線の上を走行時 [#b7ac7ac0] 線の右側を走行する。 sub R() { SetSensorLight(S1); long t0 = CurrentTick(); long tmax = 180; while (CurrentTick()-t0<=tmax) { if (SENSOR_1 >= 59){ spin_left; t0 = CurrentTick(); } else if (SENSOR_1 >= 53) { turn_left; t0 = CurrentTick(); } else if (SENSOR_1 >= 45) { go_forward; t0 = CurrentTick(); } else if (SENSOR_1 >= 39) { turn_right; } else { spin_right; } Wait(1); } off; } 線の左側を走行する。仕組みは右側を走行するときと同じである。 sub L() // { SetSensorLight(S1); long t0 = CurrentTick(); long tmax = 180; while (CurrentTick()-t0<=tmax) { if (SENSOR_1 >= 59){ spin_right; t0 = CurrentTick(); } else if (SENSOR_1 >= 53) { turn_right; t0 = CurrentTick(); } else if (SENSOR_1 >= 45) { go_forward; t0 = CurrentTick(); } else if (SENSOR_1 >= 39) { turn_left; } else { spin_left; } Wait(1); } off; } 点Hから点Gまで移動するときに使う。ヘアピンカーブと直角カーブを間違えないように20秒間は黒い部分に長時間のっていても止まらないようにした。 sub HtoG() { SetSensorLight(S1); long t0 = CurrentTick(); long t1 = 20000; long tmax = 180; while (CurrentTick()-t0 <= t1) { if (SENSOR_1 >= 59){ spin_left; } else if (SENSOR_1 >= 53) { turn_left; } else if (SENSOR_1 >= 45) { go_forward; } else if (SENSOR_1 >= 39) { turn_right; } else { spin_right; } Wait(1); } t0 = CurrentTick(); while (CurrentTick()-t0<=tmax) { if (SENSOR_1 >= 59){ spin_left; t0 = CurrentTick(); } else if (SENSOR_1 >= 53) { turn_left; t0 = CurrentTick(); } else if (SENSOR_1 >= 45) { go_forward; t0 = CurrentTick(); } else if (SENSOR_1 >= 39) { turn_right; } else { spin_right; } Wait(1); } off; } ***各地点での方向転換、 [#s48b88b9] 点E,Q,R,G,P(二回目),Qでの方向転換、直進 sub EQRGPQ() { PlaySound(SOUND_UP); go_forward; Wait(350); off; } 点P(1回目),Sでの左折 sub PS() { PlaySound(SOUND_DOWN); wait; go_back; Wait(600); turn_left; Wait(100); go_forward; Wait(500); } 点Tを通過する sub TT() { PlaySound(SOUND_DOWN); wait; go_forward; Wait(350); off; } 点H,Fの直角コーナーを右折 sub HF() { PlaySound(SOUND_UP); go_back; Wait(500); turn_right; Wait(1700); go_forward; Wait(500); off; } **タスクメイン [#va3f6cff] task main() { R(); EQRGPQ(); L(); PS(); L(); EQRGPQ(); L(); EQRGPQ(); R(); TT(); R(); TT(); R(); HF(); HtoG(); EQRGPQ(); R(); PS(); L(); EQRGPQ(); L(); EQRGPQ(); R(); HF(); R(); } *感想 [#f13ec2b8] 今回の課題はなかなか進行しなかったが、光センサーを本体に近づけることで急にうまくいった。今回、プログラミングに苦戦した。プログラミングの概形ができても細かな調整が必要だった。その中で同じ動きをする場所をみつけて、1つのサブルーチンにまとめることで少しは楽になったと思う。 ~次回はプログラミングの改良だけでなく、ハード面の改良もしながら課題を進めていきたい。