Aをスタート B Cで一時停止 Dで一時停止、Xの空き缶をキャッチして再びDに戻る Eを直進 Fを左折 Gで一時停止 左折 Hで一時停止 右折 Iで一時停止 右折 Lを直進 Kを直進 Jで一時停止 空き缶をYに置きてJに戻る Bで一時停止 左折 Aで停止
各交差点では、1秒間の一時停止が求められる。
下の画像はロボットの全体写真である.
前輪にはモーター2つ,後輪にはキャスターを取り付けた. 動力は前輪にのみ伝わり,走行する.
前輪の車輪は最初,大きいものを使用していたが,細かいプログラミングの動作により車体が跳ねる事態が多く発生したため,小さいものに付け替えることで重心を低くし、車体の跳ねを抑えた.
今回用いたギア比は,
3本目の棒に車輪がついている。
よって、ギア比は(1/5)*(2/5)*(2/5)=(4/125)となる。 このようにして速度を遅くすることでライントレースの精度を上げることに成功した。
ロボット後部にモーターを取り付け、ゴムにより動力を前部にある四角形のアームへ伝え、上下できる機構をとった.
このモーターをプログラム上でBとした.
#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);
このサブルーチンでは明るさをを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); } }
明るさの判断はサブルーチン(線の右側をライントレース)と同様である.
このサブルーチンでは、値によって作動するが上記のサブルーチンと左右反転したものとなっている.
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); } }
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; } } //定義したライントレースではFを交差点と認識してしまうので,Fを通過し,Gの前までのライントレースの時間を14.5秒と設定した.明るさの値を黒(光度<37),グレー(光度),白(光度<55)の三種類にした.
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; } } //GからH直前までの時間を短縮するために,明るさの値を黒(光度<37),グレー(光度),白(光度<55)の三種類にした.
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); //Hで90°回転する際に一度に回ってしまうと,キャスターと進行方向が直角になってしまい,キャスターが壊れる事態が発生した.これを改善するためにふり幅を大きくし,徐々に車体が進行方向を向くようにプログラミングした.
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; } } //Iまでの道のりは直線であるので,時間を短縮するために,明るさの値を黒(光度<37),グレー(光度),白(光度<55)の三種類にした.Iの直前までの大まかな時間として3.2秒ライントレースを行う.
follow_line1(); Wait(100); //I終了 OnFwd(OUT_A); OnRev(OUT_C); Wait(60); //右周りに約80°回転
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; } } //回転角が大き過ぎた場合にコースへ戻るために2秒間ライントレースを行う.時間を短縮するために,明るさの値を黒(光度<37),グレー(光度),白(光度<55)の三種類にした
follow_line2();
OnFwd(OUT_C); //Lを通過 Wait(50);
follow_line2();
OnFwd(OUT_C); //Kを通過 Wait(50);
follow_line2();
Wait(100); //Jで一時停止
OnFwd(OUT_C); OnRev(OUT_A); Wait(200); OnFwd(OUT_A); OnRev(OUT_C); Wait(40); OnFwd(OUT_C); OnRev(OUT_A); Wait(20); //Jで90°回転する際に一度に回ってしまうと,キャスターと進行方向が直角になってしまい,キャスターが壊れる事態が発生した.これを改善するためにふり幅を大きくし,徐々に車体が進行方向を向くようにプログラミングした
OnFwd(OUT_AC); Wait(100); //円Y内の缶を置く位置まで前進
arm_up;
until(SENSOR_2<37){ OnRev(OUT_AC); } //黒線(光度<37)を判断するまで後退(Jに戻る)
OnRev(OUT_AC); Wait(40); //機体は円Y内で停止するため,黒線を超えるために0.4秒間後退
OnFwd(OUT_C); OnRev(OUT_A); Wait(500); //回転角を大きくとって車体を左回りに約200°回転 until(SENSOR_2<45){ OnFwd(OUT_AC); } //JB間のコースと交差するまで前進.この時,コースの明るさを45と設定した.
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; } } //車体がコースの真ん中に停止することがあったため,コース端に移動するため,3.5秒間ライントレースをするようにした.少ない明るさ判断でコース端へ向かうため,明るさの値を黒(光度<37),グレー(光度),白(光度<55)の三種類にした.
follow_line2();
Wait(100); //Bで一時停止
OnFwd(OUT_AC); Wait(40); //車体は黒線の右側で停止するため,左側へ移動するために0.4秒間前進 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; } } //Bを通過した機体が方向転換をし,BA間の直線を走るまでラインとレースを行う.大まかな時間として8秒間ライントレースするようにした.時間短縮のため,明るさの値を黒(光度<37),グレー(光度),白(光度<55)の三種類にした.
OnFwd(OUT_AC); Wait(400); //Aまで直進するために大まかに4秒間前進
Off(OUT_AC); //終了 }
交差点判断については、黒(光度が37以下)を認識した時点でタイマーが0.02秒ずつ加算され、合計0.25秒を超えた時点で停止するプログラミングを組んだ。
走るプログラムとして、右回り(両側の車輪が互いに反対の方向に動く)、右旋回(片方の車輪が前進)、直進(両方の車輪が前進)、左旋回、左回りを組んだ。また、タイマーが加算されるのは、右回り、左回りの場合のみである。
線の右側をトレースする場合は右に回る場合にのみタイマーが加算される。 線の左側をトレースする場合は左に回る場合にのみタイマーが加算される。
ライントレースの際には、照明の明るさにって光センサーが認識する値が変わるので、調整にかなりの時間がかかった。どうしてもライントレースでは曲がりきることのできない直角のカーブでは、回転角を大きく取り、あえてはみ出て、元の線に戻るなどの工夫をした。反省としては、調整の段階で認識する間隔を狭めることでより正確なライントレースが出来たので、次にはより正確なライントレースをプログラミングを作りたい。