[[2018a/Member]] *課題2(ライントレース) [#t6718c46] **課題条件 [#kbf0aba9] &ref(IMG_3462.PNG); Aをスタート B Cで一時停止 Dで一時停止、Xの空き缶をキャッチして再びDに戻る Eを直進 Fを左折 Gで一時停止 左折 Hで一時停止 右折 Iで一時停止 右折 Lを直進 Kを直進 Jで一時停止 空き缶をYに置きてJに戻る Bで一時停止 左折 Aで停止 各交差点では、1秒間の一時停止が求められる。 *ロボット紹介 [#g7a2b87e] **全体の構造について [#deb49ede] 下の画像はロボットの全体写真である. &ref(IMG_3469.jpg); &ref(IMG_3466.jpg); 前輪にはモーター2つ,後輪にはキャスターを取り付けた. 動力は前輪にのみ伝わり,走行する. **車体について [#w307979d] 前輪の車輪は最初,大きいものを使用していたが,細かいプログラミングの動作により車体が跳ねる事態が多く発生したため,小さいものに付け替えることで重心を低くし、車体の跳ねを抑えた. &ref(IMG_3467.jpg); &ref(IMG_3472.jpg); 今回用いたギア比は,~ +モーター(1)に歯数8の歯車をつけ、2本目の棒(2)の歯数40の歯車に噛ませる。(ギア比8:40なので速度1/5)~ +2本目の棒には歯数40の歯車と歯数16の歯車がついている。(ギア比は16:40なので速度2/5)~ +歯数16の歯車と、3本目の棒(3)の歯数40の歯車に噛ませる。(ギア比は16:40なので速度2/5)~ 3本目の棒に車輪がついている。 よって、ギア比は(1/5)*(2/5)*(2/5)=(4/125)となる。 このようにして速度を遅くすることでライントレースの精度を上げることに成功した。 **缶をつかむ機構 [#a711f040] &ref(IMG_3470.jpg); ロボット後部にモーターを取り付け、ゴムにより動力を前部にある四角形のアームへ伝え、上下できる機構をとった.~ このモーターをプログラム上でBとした. *プログラム紹介 [#v036d419] **プログラムについて [#sd5389e8] ***define [#z0ec57f2] #define turn_right Off(OUT_AC);OnFwd(OUT_A);OnRev(OUT_C);Wait(2);Off(OUT_AC); #define turn_left Off(OUT_AC);OnFwd(OUT_C);OnRev(OUT_A);Wait(2);Off(OUT_AC); #define run_right Off(OUT_AC);OnFwd(OUT_A);Wait(2);Off(OUT_AC); #define run_left Off(OUT_AC);OnFwd(OUT_C);Wait(2);Off(OUT_AC); #define arm_down Off(OUT_AC);OnRev(OUT_B);Wait(300);Off(OUT_B); #define arm_up Off(OUT_AC);OnFwd(OUT_B);Wait(300);Off(OUT_B); ***サブルーチン(線の右側をライントレース) [#l544076b] このサブルーチンでは明るさをを5種類の値で判断している.~ 明るさは、黒(光度<37),暗いグレー(光度<42),グレー(光度<47),明るいグレー(光度<50),白(光度<55)で分類されている.各値によって作動するプログラムが変わる.~ 明るさの判断は0.02秒間隔で行われており,黒と判断された場合にのみタイマーが加算され,加算された時間が0.20秒を超えたときにサブルーチンから抜け出すようになっている. sub follow_line1(){ClearTimer(0); while(FastTimer(0)<20) { if(SENSOR_2<37){ run_left; }else if(SENSOR_2<42){ turn_left; ClearTimer(0); }else if(SENSOR_2<47){ OnFwd(OUT_AC); ClearTimer(0); }else if(SENSOR_2<50){ turn_right; ClearTimer(0); }else if(SENSOR_2<55){ run_right; ClearTimer(0); } } ***サブルーチン(線の左側をライントレース) [#of843453] 明るさの判断はサブルーチン(線の右側をライントレース)と同様である.~ このサブルーチンでは、値によって作動するが上記のサブルーチンと左右反転したものとなっている. sub follow_line2(){ClearTimer(0); while(FastTimer(0)<20) { if(SENSOR_2<37){ run_right; }else if(SENSOR_2<42){ turn_right; ClearTimer(0); }else if(SENSOR_2<47){ OnFwd(OUT_AC); ClearTimer(0); }else if(SENSOR_2<50){ turn_left; ClearTimer(0); }else if(SENSOR_2<55){ run_left; ClearTimer(0); } } ***メインプログラム [#qe0749d0] task main(){ SetSensor(SENSOR_2,SENSOR_LIGHT); OnFwd(OUT_AC); Wait(100); //スタートからAの黒線を超えるまで1秒間走行 ClearTimer(1); while(FastTimer(1)<300) if(SENSOR_2<37){ turn_left; }else if(SENSOR_2<47){ OnFwd(OUT_AC); }else if(SENSOR_2<55){ turn_right; } } //BC間のカーブまでの走行時間を短縮するために,明るさの値を黒(光度<37),グレー(光度),白(光度<55)の三種類にした.タイマーの値「300」はカーブに差し掛かる前までの大まかな時間である. follow_line1(); Wait(100); //Cで交差点判断をし,1秒間停止 OnFwd(OUT_AC); Wait(70); //Cを通過 follow_line1(); //D前の直角カーブまでライントレース.直角カーブでは誤って交差点判断をしてしまうので,サブルーチンを抜けだした後は90°回転が必要となる. OnFwd(OUT_C); OnRev(OUT_A); Wait(140); //90°回転 follow_line1(); Wait(100); //Dで交差点判断の後に一時停止 Off(OUT_AC); //D終了 OnFwd(OUT_AC); Wait(100); //缶まで前進 arm_down; //缶をつかむ until(SENSOR_2<37){ OnRev(OUT_AC); } //黒線(光度<37)を判断するまで後退(Dに戻る) OnRev(OUT_AC); Wait(40); //機体は円X内で停止するため,黒線を超えるために0.4秒間後退 ClearTimer(1); while(FastTimer(1)<300){ if(SENSOR_2<37){ turn_left; }else if(SENSOR_2<47){ OnFwd(OUT_AC); }else if(SENSOR_2<55){ turn_right; } } //Dに戻った時,戻る場所にばらつきがあるためコースに確実に戻るために大まかな時間として3秒間ライントレースを行う.時間を短縮するために,明るさの値を黒(光度<37),グレー(光度),白(光度<55)の三種類にした. follow_line1(); //Eまでライントレース OnFwd(OUT_A); Wait(50); //Eで交差点判断した後に,Eを通過.この時Eは円上にあるため,外側の車輪(モーターA)だけを前進させた. ClearTimer(1); while(FastTimer(1)<1450){ if(SENSOR_2<37){ turn_left; }else if(SENSOR_2<47){ OnFwd(OUT_AC); }else if(SENSOR_2<55){ turn_right; } } //定義したライントレースでは follow_line1(); Wait(100); //G終了 ClearTimer(1); while(FastTimer(1)<3400){ if(SENSOR_2<37){ turn_left; }else if(SENSOR_2<47){ OnFwd(OUT_AC); }else if(SENSOR_2<55){ turn_right; } } follow_line1(); Wait(100); //Hで一時停止 OnFwd(OUT_A); OnRev(OUT_C); Wait(190); OnFwd(OUT_C); OnRev(OUT_A); Wait(40); OnFwd(OUT_A); OnRev(OUT_C); Wait(23); OnFwd(OUT_C); OnRev(OUT_A); Wait(3); OnFwd(OUT_AC); Wait(60); ClearTimer(1); while(FastTimer(1)<320){ if(SENSOR_2<37){ turn_right; }else if(SENSOR_2<47){ OnFwd(OUT_AC); }else if(SENSOR_2<55){ turn_left; } } follow_line1(); Wait(100); //I終了 OnFwd(OUT_A); OnRev(OUT_C); Wait(60); ClearTimer(1); while(FastTimer(1)<200){ if(SENSOR_2<37){ turn_right; }else if(SENSOR_2<47){ OnFwd(OUT_AC); }else if(SENSOR_2<55){ turn_left; } } follow_line2(); OnFwd(OUT_C); //Lを通過 Wait(50); follow_line2(); OnFwd(OUT_C); //Kを通過 Wait(50); follow_line2(); Wait(100); OnFwd(OUT_C); OnRev(OUT_A); Wait(200); OnFwd(OUT_A); OnRev(OUT_C); Wait(40); OnFwd(OUT_C); OnRev(OUT_A); Wait(20); OnFwd(OUT_AC); Wait(100); arm_up; until(SENSOR_2<37){ OnRev(OUT_AC); } OnRev(OUT_AC); Wait(40); //缶置き終了 OnFwd(OUT_C); OnRev(OUT_A); Wait(500); until(SENSOR_2<45){ OnFwd(OUT_AC); } ClearTimer(1); while(FastTimer(1)<350){ if(SENSOR_2<37){ turn_right; }else if(SENSOR_2<47){ OnFwd(OUT_AC); }else if(SENSOR_2<55){ turn_left; } } follow_line2(); Wait(100); OnFwd(OUT_AC); Wait(40); ClearTimer(1); while(FastTimer(1)<800){ if(SENSOR_2<37){ turn_right; }else if(SENSOR_2<47){ OnFwd(OUT_AC); }else if(SENSOR_2<55){ turn_left; } } OnFwd(OUT_AC); Wait(400); Off(OUT_AC); } **交差点判断について [#ie66efc6] 交差点判断については、黒(光度が37以下)を認識した時点でタイマーが0.02秒ずつ加算され、合計0.25秒を超えた時点で停止するプログラミングを組んだ。 走るプログラムとして、右回り(両側の車輪が互いに反対の方向に動く)、右旋回(片方の車輪が前進)、直進(両方の車輪が前進)、左旋回、左回りを組んだ。また、タイマーが加算されるのは、右回り、左回りの場合のみである。 線の右側をトレースする場合は右に回る場合にのみタイマーが加算される。 線の左側をトレースする場合は左に回る場合にのみタイマーが加算される。 *感想・考察 [#u12c3c89] ライントレースの際には、照明の明るさにって光センサーが認識する値が変わるので、調整にかなりの時間がかかった。どうしてもライントレースでは曲がりきることのできない直角のカーブでは、回転角を大きく取り、あえてはみ出て、元の線に戻るなどの工夫をした。反省としては、調整の段階で認識する間隔を狭めることでより正確なライントレースが出来たので、次にはより正確なライントレースをプログラミングを作りたい。