2015b/Member

課題 ライントレースをさせる

課題条件

2015b-mission2.png

上図 B 地点より各交差点について「右→右→左→左→直進→直進」の順で進行し、A地点に到達させる。

目次

1 ロボット紹介

1-1 光センサ設置位置

車体の小回りを利かせるために、車体の回転半径を小さくさせる。

したがって、車輪と光センサを極力近づけた。

足回り.jpg

1-2 後輪について

小回りを利かすためには地面に対する抵抗を最小限にする必要がある。モータに連動する二つのタイヤが地面に接してしまうのは仕方がないため、それ以外のタイヤによる抵抗(ゴムによる)をなくすことにした。

そこで、そこでゴムタイヤ二つを前輪とし、タイヤのホイールパーツ一つを後輪とする三輪車にした。そうすることで安定性と抵抗の軽減に成功した。下図が後輪である。

後輪.jpg

今回の課題では回転や旋回が数多く使われる。したがってこの改良は非常に役に立った。

2 プログラム紹介

今回の課題はプログラミングが重要な課題となる。それぞれのパートを順々に説明していく。

2-1定数

/*数値代入系*/
#define shiki 48 //黒と白の閾値の基礎
#define TMAX 25 //黒い線をTMAX秒以上通過すると「交差点」or「急なカーブ」と判断する。要は時間。
/*動作制御系*/
#define forward OnFwd(OUT_AC); //直進
#define back OnRev(OUT_AC); //後退
#define left_t OnRev(OUT_A); OnFwd(OUT_C); //左旋回
#define left Off(OUT_A); OnFwd(OUT_C); //左回転
#define right_t OnRev(OUT_C); OnFwd(OUT_A); //右旋回 
#define right Off(OUT_C); OnFwd(OUT_A); //右回転
#define modosu ClearTimer(1);tomaru(100);right_t;Wait(find);back;Wait(50); //後述
#define W_Fwd if(SENSOR_2 >= 48){forward;until(SENSOR_2 < 48);} //交差点を発見した後の動作。
#define W_LEFT if(SENSOR_2 >= 48){left_t;until(SENSOR_2 < 48);} //交差点を発見した後の動作。

2-2 マクロ

#define tomaru(t) Off(OUT_AC);Wait(t); //t秒だけ停止
#define power(s) SetPower(OUT_A+OUT_C,s); //モータのパワーをsにする

2-3 ライントレースと交差点判断

今回「ライントレース」と「交差点判断」の二つのプログラムを一つのsubスクリプト内に書き、main関数の簡略化を行った。したがって、本節ではsubスクリプト内の解説を行う。

/*global変数*/
int n = 0;

交差点に何度進入したかをカウントする。 変数nはmain関数でも使うため、global変数として置く。

sub decision()
{
/*ライントレース*/
	int find = 100;//交差点かどうか見極めるために用いる。今while文の条件式に当てはめるため「100」とおいている。
	while(find > 80){
		if (SENSOR_2 < shiki -7){ //計測値が閾値より-7以下の時、右旋回
			right_t;
		} else if (SENSOR_2 < shiki -4){ //計測値が閾値より-4から-7の時、右回転
			right;
		} else if (SENSOR_2 < shiki){ //計測値が閾値から-4の時、直進
			forward;
		} else if(SENSOR_2 < shiki +4){ //計測値が閾値から+4の時、左回転
			left;
		} else {           //計測値が閾値より+4以上の時左旋回
			left_t;
		} 
		if(SENSOR_2 > shiki -5){//計測値が閾値より-5以上の時にタイマーをリセット。
			ClearTimer(0);
		}

今回のライントレースは黒い線の右側の境界線部分で行った。計測値が大きいほど白色で、小さいほど黒色を認識したことを意味する。

したがって、閾値を適当な黒の色として、その前後で値が多きければ、境界線の右側に行き過ぎているため、左に向かせる。逆に値が小さければ境界線の左側に行き過ぎているため、右に向かせる。また、トレースの高速化の為に閾値周辺の値、つまり境界線上を走っているときは直進させた。以下にあるGIF画像はイメージ図である。青い四角形が光センサパーツで、赤い円が計測範囲である。

GIFトレース.gif

次にタイマーについての説明を行う。このタイマーは計測値が非常に小さい(真っ黒)の時以外はリセットされるようになっている。タイマーを置く目的は交差点を判断させるためである。

もしタイマーが一定時間進んだ場合、それはロボットの目の前に黒い線が横切ったことを意味する。すなわち、そこには「交差点」若しくは「急な曲がり角」が存在することとなる。今回はその一定時間をTMAXと定義し、TMAX秒以上真っ黒の状態が継続された場合これから説明する「交差点判断」のif文に飛ぶようプログラムをした。

交差点かどうかの判別方法について説明する。

/*交差点判断*/
		if(FastTimer(0) > TMAX){
			tomaru(100); //動きを安定させるため、とりあえず停止する。
			forward;Wait(40); //目の前の黒い線を越す
			ClearTimer(1);//先ほどとは別のタイマーをセットする。これは左旋回をして黒い線にぶつかるまでの時間を計測する
			left_t;//左旋回をする
			until(SENSOR_2 < shiki);//左旋回を留める
			find = FastTimer(1);//最初に定義した変数 find をタイマーの計測時間にする。
			if (find > 80){//findが0.8秒より長いということは目の前の直線が単なる曲がり角を意味するため、ライントレースを再開させる必要がある。その動作を行わせる
				modosu;//find 秒だけ戻り、0.4秒後退して元の場所に戻る。
				right_t;Wait(8);//元のままでは繰り返しになるため、少しだけ右に切り返す。
				tomaru(50);//動作を安定させるための少しばかりの停止
			}
		} 
	} modosu;//findが0.8秒未満、つまり交差点に差し掛かったと判断した場合の動作。元の場所に戻りsubルーチンから抜け出す。
	n++;//今、何回目の交差点かをカウントする。
}

目の前に黒い線が来た場合、それが「交差点」なのか「曲がり角」なのかを判断する必要がある。なぜならば、交差点ならば何回目の交差点でどの方向に進むかが決まっているからだ。

今回その判断材料として「次に現れる黒線までの時間(find)」を使う。

黒線に差し掛かった場合の手順を説明すると

〔椶料阿旅い線を越し、白いところへ出る

∈犬慇回する

旋回している時間(find)を計測する。

い發掘findが短ければ(0.8秒未満)、,捻曚┐森線の先にも黒線がある。すなわち、交差点であるため、交差点の対処をする。

イ發掘findが長ければ(0.8秒以上)、,捻曚┐森線の先には黒線はない。すなわち、曲がり角であるため、,捻曚┐訌阿琉銘屬北瓩蝓閉蠖堯modosuを利用)、トレースを続行させる必要がある。

ということである。

文字ではなかなかわかりにくいと思われる。そこで下図を見ていただきたい。

交差点に進入した場合

GIF交差点.gif

曲がり角に進入した場合

GIF曲線探査.gif

一番最初のコース図を見てもらうとわかるように、今回丁字路は存在しない。したがって、右側の境界線から始めた場合、曲がり角で、指定の時間(0.8秒)以下で黒い線を探知することはない。よって、交差点か否かを認識することができる。

また、曲がり角だとわかった場合、そのまま元の場所に戻ったところで黒線上のため堂々巡りになってしまう。今黒線の右端で行っているため、立ちはだかる曲がり角は「右折」以外あり得ない。そこで、少し右に切り返しをさせることにより、トレースを続行させることが可能となった。

2-4 main関数

前節ではsubルーチン(decison)の説明を行った。本節ではmain関数内の説明を行う。

main関数内では主に交差点だとsubルーチン内で判断された時の処理を行っている。

task main()
{
	power(3); //モータの出力を3にする
	SetSensor(SENSOR_2,SENSOR_LIGHT); //SENSORの設定
	ClearTimer(0); //subルーチン内で使用するタイマーをスタート
	while(true){

それぞれの交差点についての対応の仕方についてを説明する。

また、各交差点について,らΔ猟未携峭罎鮨兇襦H峭罎梁弍箇所は下図参照

map.jpg

 ̄折

		if (n == 0) { //1回目の交差点
			decision(); //subルーチン
			right_t;Wait(35);
			tomaru(50);
			power(0);//ゆっくり前進
			W_Fwd;
			power(3);//モータの出力を元に戻す
                }

,慮鮑硬世任榔折をする。

,任聾鮑硬世鯒Ъ韻靴燭蕁△泙艮Δ棒回する。そしてゆっくりと前に進み黒い線とぶつかったら停止をし、トレースを再開させる。

こうすることで、滑らかにトレースを再開することができる。スピードを落とすのは惰力で進み過ぎてしまうのを防ぐためである。

右折

		 else if(n == 1){ //2回目の交差点
			decision(); //subルーチン
			right_t;Wait(20);
			tomaru(50);
			power(0);//ゆっくり前進
			W_Fwd;
			power(3);//モータの出力を元に戻す
               }

△任聾鮑硬世鯒Ъ韻靴燭蕁△泙梱,鉾罎拆しだけ右に旋回する。そしてゆっくりと前に進み黒い線とぶつかったら停止をし、トレースを再開させる。

△廊,鉾罎戮董交差点の後の直線が短い。したがって、旋回しすぎると黒い線に届かなくなってしまうため、少しだけ旋回させる

左折

		else if(n == 2) { //3回目の交差点
			decision(); //subルーチン
			forward;Wait(47);
			left_t;Wait(60);
			tomaru(50);
			power(0);//ゆっくり左旋回
			W_LEFT;
			right_t;Wait(10);
			power(3);//モータの出力を元に戻す
               }

では交差点を認識したら、まず直進し、大きく左に旋回し正面(直近)の黒い線を越える。そしてゆっくりと左旋回をし黒い線(進行方向)とぶつかったら停止をし、トレースを再開させる。

ゆっくりと左旋回をする理由は´△汎韻犬任△襦

また、最初に旋回する前に直進するのは、そうすることで黒い線を確実に越すことができるからである。

ず言

		 else if (n == 3){ //4回目の交差点
			decision(); //subルーチン
			left_t;Wait(25);
			forward;Wait(40);
			left_t;Wait(60);
			tomaru(50);
			power(0);//ゆっくり左旋回
			W_LEFT;
			right_t;Wait(10);
			power(3);//モータの出力を元に戻す
               }

い任聾鮑硬世鯒Ъ韻靴燭蕁△泙に旋回する。次に前進をし左旋回をする。そしてゆっくりと、また左に旋回し黒い線とぶつかったら停止、トレースを再開させる。

い如↓で行わなかった最初の左旋回を行うのには理由がある。それは、交差点がカーブの後に存在するからだ。交差点がカーブの後に存在すると、車体が斜めになって交差点に進入してくる。今回の場合は大きく右を向いた状態で交差点を認識してしまうのだ。

したがって、い任榔Δ坊垢い深崑里鮑犬惴くように矯正する必要性があるため、最初に左旋回を行う。

,δ梢

		 else{ //5回目以降の交差点
			decision(); //subルーチン
			forward;Wait(35);//無理やり黒線を越える
			tomaru(50);
		}
	}
}

,Δ任聾鮑硬世鯆梢覆気擦襦

したがって交差点を確認したら無理やり数秒間直進させてトレースを再開させれば、問題なく進んでくれるのだ。

3 感想・考察

今回はプログラムがメインの活動であった。「変数」が何かすら理解していない状態でスタートした製作であったが、いろいろ必要なことを学ぶことができたと思う。教えをくれた相方と先生には大変感謝している。初めて完走したときは思わず大きくガッツポーズをしてしまった。

また、可能な限りシンプルな動きで解決させたいと思っていたため、左旋回のみで交差点かどうかを判断する方法を考えた。メリットとしてはプログラムが単純(個人的に)であるということと、動きが「かわいい」ということであった。デメリットとして、稀に直進の動作で黒線内を走ってしまい、適した時間が測れず誤認してしまうことがあった。

今回は出来なかったが、大まかな時間指定で交差点と曲がり角の区別を省略できたら尚よかった。

プログラムがメインではあったが、ハードの設計も個人なりにかなり満足している。小型化と抵抗を少なくし、且つ補強をしっかりとしたために、持ち運ぶ際でも崩壊することはまずなかったため満足している。


添付ファイル: filemap.jpg 112件 [詳細] fileGIF交差点.gif 116件 [詳細] fileGIF曲線探査.gif 98件 [詳細] fileGIFトレース.gif 159件 [詳細] file後輪.jpg 129件 [詳細] file足回り.jpg 110件 [詳細] file2015b-mission2.png 117件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-01-08 (金) 00:04:25