[[2017a/Member]] #contents * 課題内容 [#mb855a0c] 今回の課題は、光センサを使用して図のコース上を指定の経路で走るという内容である。 ~ 詳しい内容は[[2017a/Mission2]]を参照してほしい。 #ref(./課題2 コース.jpg,80%,コースの図) ** 走行コース [#cf89eeb5] 「E地点直進コース」と「E地点右折コース」の内、「E地点右折コース」を走るロボットを作成したため、以下の順番で走行するようになっている。 ~ E→P→Q→R→T→T→H→G→S→P→Q→F→E→A * ロボット本体 [#p0da3634] ロボット本体はできるだけシンプルに、かつコンパクトになるようにした。 #ref(./ロボット全体.jpg,8%,ロボット全体の写真) ロボット本体を組み立てるのに当たって、できるだけ小回りがきくようなロボットにしようと考えた。そこで、タイヤの間隔を極力狭くし、モーター2つとギアの幅だけにすることで旋回半径をできるだけ小さくしている。 ~ また、はじめはセンサーとタイヤとの距離を少し遠く配置していたのだが、必ずHーG地点間のS字カーブやEーF地点間のカーブで旋回しきれずにコースアウトしてしまい、正しくラインをトレースしてくれなかった。そこで、センサとタイヤの距離をできるだけ短くし、より正かくに黒線に沿って走行できるようにもしている。 #ref(./タイヤ・センサ距離.jpg,80%,タイヤとセンサの距離の説明) * プログラム [#d31854c8] ** 定数・マクロ定義・グローバル変数 定義 [#z84376a1] /*---------- 定数・マクロ 定義 -----------*/ #define LINE_BLACK 38 //黒 #define THRESHOLD_LOW 40 //閾値最小(黒より) #define THRESHOLD_HIGH 47 //閾値最大(白より) #define LINE_WHITE 49 //白 #define FOWORD OnFwd(OUT_AC); //直進 #define BACK OnRev(OUT_AC); //後退 #define STOP Off(OUT_AC); //停止 #define TURN_LEFT OnFwd(OUT_C); OnRev(OUT_A); //左旋回 #define TURN_RIGHT OnFwd(OUT_A); OnRev(OUT_C); //右旋回 #define CURVE_LEFT OnFwd(OUT_C); Off(OUT_A); //左折 #define CURVE_RIGHT OnFwd(OUT_A); Off(OUT_C); //右折 #define TIME_MAX_S 26 //直線走行時の黒線判定までの時間 #define TIME_MAX_CO 30 //カーブ(外回り)走行時の黒線判定までの時間 #define TIME_MAX_CI 33 //カーブ(内回り)走行時の黒線判定までの時間 /*----------- グローバル変数 定義 ----------*/ int timer = 0; //タイマー0 格納用変数 int time_max = 0; //交差点判定用 ** サブルーチン [#ye8c85a8] サブルーチンは、黒線をトレースするためのものを"Follow_Line_R()"と"Follow_Line_L()"として左右で設定している。 /*---------- ラインの右側を走行 ----------*/ sub Follow_Line_R() { while(timer < time_max){ if(SENSOR_2 > LINE_WHITE){ TURN_LEFT; ClearTimer(0); } else if(SENSOR_2 > THRESHOLD_HIGH){ CURVE_LEFT; ClearTimer(0); } else if(SENSOR_2 > THRESHOLD_LOW){ FOWORD; ClearTimer(0); } else if(SENSOR_2 > LINE_BLACK){ CURVE_RIGHT; ClearTimer(0); } else{ TURN_RIGHT; } timer = FastTimer(0); } timer = 0; } /*---------- ライン左側を走行 ----------*/ sub Follow_Line_L() { while(timer < time_max){ if(SENSOR_2 > LINE_WHITE){ TURN_RIGHT; ClearTimer(0); } else if(SENSOR_2 > THRESHOLD_HIGH){ CURVE_RIGHT; ClearTimer(0); } else if(SENSOR_2 > THRESHOLD_LOW){ FOWORD; ClearTimer(0); } else if(SENSOR_2 > LINE_BLACK){ CURVE_LEFT; ClearTimer(0); } else{ TURN_LEFT; } timer = FastTimer(0); } timer = 0; } ~ 閾値によって黒と白とその境目を5つに分けているため、それぞれの場所に応じて動作を設定している。光センサの値が"THRESHOLD_LOW"から"THREHOLD_HIGH"の間は、区分分けの中央になるため左右どちらのサブルーチンでも「直進」するようになっている。"THRESHOLD_LOW"より小さい場合と"THRESHOLD_HIGH"より大きい場合は左右で動作が逆になってはいるが、"LINE_BLACK"や"LINE_WHITE"を超えるまでは「タイヤを片方停止してのターン」、超えたら「片方は正転、反対側は逆転しての旋回」を行うようにしている。 #ref(./動作説明図.jpg,30%,動作説明図) ~ また、光センサの値が"LINE_BLACK"より小さい(黒色を検知している)間、タイマーで時間を計測し変数"timer"にその値を渡している。この"timer"を"time_max"(メインタスクで設定)を比較して大きい場合はループから抜けることで交差点を判断している。 ** メインタスク [#w913d29c] * まとめ [#x28c86bc]