戻る

課題

自作したコース(下図)に沿って一周するロボットを作成せよ。

  • 次のステップでプログラムを作成すること。
    • 交差点をきちんと認識し、正しく判断して通過できるようにする。
    • 確実に一周できるようにする。スタート地点から出発して元にもどるようにする。
    • 空き缶を交差点から10cm以上離した線上に起き、それを一旦どけて再び元の位置にもどすように改良する。
    • 1個の空き缶でうまくいったら、2個の空き缶でやってみる。

(授業で示されたコース図)

zu.jpg

筆者は反時計回りを担当した。

ロボット

  • ドライブベースを小型化した。
  • 光センサーをより駆動部に近づけた。
  • 車輪を2つに減らした。

    →小回りがきくようになった。

  • 支えとして、車輪ではなく底の丸いパーツを使用した。

    →可動部を減らし、故障しうる箇所を減らした。



(ドライブベースの写真)

image_1.jpeg
image_2.jpeg

(ロボットの写真)

image.jpeg

プログラム

コード

/*マクロ・定数*/
#define THRESHOLD 45  //ライントレースの閾値
#define set_H SetPower(OUT_AC,7);  //直進用速度
#define set_L SetPower(OUT_AC,1);  //カーブ用速度
#define turn_l1 set_L;OnFwd(OUT_C);OnRev(OUT_A);  //反時計回り旋回
#define turn_l0 set_L;OnFwd(OUT_C);Off(OUT_A);  //反時計回り移動  
#define turn_r0 set_L;OnFwd(OUT_A);Off(OUT_C);  //時計回り移動
#define turn_r1 set_L;OnFwd(OUT_A);OnRev(OUT_C);  //時計回り旋回
#define go_fwd set_H;OnFwd(OUT_AC);  //前進
#define go_rev set_H;OnRev(OUT_AC);  //後退
#define STEP 1  //ライントレースの各動作時間
#define C1 1000  //最初の交差点に近づくまでの時間
#define LAST_C 3000 //最後の交差点に近づくまでの時間
#define TURN_T 74  //90°回転するための所要時間
#define CAN_T 61  //ドライブ長だけ進むのに必要な時間
#define Clock FastTimer(0)-AFT+BEF  //缶を動かすのに使った時間を除いた時刻
#define NCROSS 5 //交差点を判断するための閾値
#define MOR 100 //交差点を検知したあと、次の交差点を検知し始めるまでの猶予

/*グローバル変数*/
int nline=0; //交差点横断用のカウンタ
int BEF=0; //缶を動かす前の時刻を記録する変数
int AFT=0; //缶を動かした後の時刻を記録する変数
int RCH=0; //反転カウンタ

/*インライン関数*/
void line(){ //通常ライントレース
if(SENSOR_2<THRESHOLD-7){turn_l1;}  //黒い部分を感知したら反時計回り旋回
else if(SENSOR_2<THRESHOLD-5){turn_l0;}  //黒寄りの境界を感知したら反時計回り移動
else if(SENSOR_2<THRESHOLD+3){go_fwd;}  //境界を探知したら直進
else if(SENSOR_2<THRESHOLD+5){turn_r0;}  //白寄りの境界を感知したら時計回り移動
else{turn_r1;}  //白い部分を感知したら時計回り旋回
Wait(STEP);  //決定した動作を一定時間行う
}

void line_r(){ //各動作の方向を反転したライントレース
if(SENSOR_2<THRESHOLD-7){turn_r1;}
else if(SENSOR_2<THRESHOLD-5){turn_r0;}
else if(SENSOR_2<THRESHOLD+3){go_fwd;}
else if(SENSOR_2<THRESHOLD+5){turn_l0;}
else{turn_l1;}
Wait(STEP);
}

void line_c(){ //交差点探索を含むライントレース
if(SENSOR_2<THRESHOLD-7){turn_l1;nline++;} //黒い場所を検知したらカウンタに1加える
else{ //その他の場合はカウンタを0に戻す
	if(SENSOR_2<THRESHOLD-5){turn_l0;}
	else if(SENSOR_2<THRESHOLD+3){go_fwd;}
	else if(SENSOR_2<THRESHOLD+5){turn_r0;}
	else{turn_r1;}
	nline=0;
	}
Wait(STEP);
}

/*サブルーチン*/
sub cross(){ //交差点横断サブルーチン
Off(OUT_AC);PlaySound(2);Wait(10); //交差点を渡り始めることを知らせる 
turn_r1;Wait(TURN_T/2); //方向修正
go_fwd;Wait(40); //交差点を渡る
if(Clock<LAST_C){turn_r1;until(SENSOR_2<THRESHOLD+5);} //ライン上に戻す
else{turn_l1;until(SENSOR_2<THRESHOLD+5);RCH++;} //最後の交差点は逆回転でライン上に戻す
nline=0; //カウンタをリセット
ClearTimer(1); //一定時間は交差点を検知しないようにする。
}

sub canturn(){ //缶移動サブルーチン
BEF=FastTimer(0);  //実行前の時刻を記録
Off(OUT_AC);PlaySound(5);Wait(10); //缶を動かし始めることを知らせる
go_fwd;Wait(CAN_T);  //缶と一緒にドライブ長だけ進む
turn_l1;Wait(2*TURN_T);  //缶と一緒に180°反時計回り旋回
go_rev;Wait(CAN_T);turn_r1;Wait(2*TURN_T);  //缶を置いてライントレースの位置へ戻る
AFT=FastTimer(0)+CAN_T; //実行後の時刻+αを記録
}

/*メインタスク*/
task main(){
SetSensor(SENSOR_1,SENSOR_TOUCH);
SetSensor(SENSOR_2,SENSOR_LIGHT);
ClearTimer(0); //走行時間タイマー
ClearTimer(1); //交差点検知を停止させるためのタイマー


/*初期動作*/
go_fwd;until(SENSOR_2>=THRESHOLD+4);PlaySound(2);Off(OUT_AC);
//スタート直後の交差点を超えるまで前進

turn_r1;until(SENSOR_2<=THRESHOLD-5);PlaySound(2);Off(OUT_AC);
//黒いところを感知するまで時計回り旋回

/*その後の動作*/ 
while(true){
	
	/*状態:ライントレース開始後一定時間経っていないor交差点横断後一定時間経っていないとき*/
	while(Clock<C1||FastTimer(1)<MOR){
		if(SENSOR_1==0){line();} //ライントレース
		else{canturn();} //缶を検知したら移動させる
	}	

	/*状態:ライントレース開始後一定時間経っており、交差点横断後一定時間経っており、
	さらに反転カウンタに値が入っていないとき*/
	while(Clock>=C1&&RCH==0&&FastTimer(1)>=MOR){
		if(SENSOR_1==0){
			if(nline>=NCROSS){cross();}
			//黒い部分を一定以上連続で検知したら交差点を渡る
			
			else{line_c();} //交差点を探しながらライントレース
			}
		else{canturn();} //缶を検知したら移動させる
	}

	/*状態:反転カウンタに値が入っているとき(=最後の交差点を超えた後)*/
	while(RCH>=1){
		if(SENSOR_1==0){line_r();} //反転ライントレース
		else{canturn();} //缶を検知したら移動させる
	}
}

}

プログラムの詳細

image-22ma.jpg

ポイントA(「初期動作」)

1.まず白い部分を検知するまで前進する。
2.その後黒い部分を検知するまで時計回り旋回を行う。

この部分で通常のライントレースをすると、ロボットの初期位置によっては時計回りコースへ進入してしまうので、
確実に反時計回りコースに侵入するようにこのような方法をとった。

ポイントBまでの間

1. 開始後10秒経過するまでは状態,覇虻遒垢襦
2.10秒経過したら、状態△飽楾圓垢襦
3.黒い部分を5回連続で検知したら、交差点横断サブルーチンを実行する。
4.実行後1秒以内は状態,覇虻遒垢襦
5.1秒経過後は再び状態△飽楾圓垢襦

開始後10秒以内・交差点横断後1秒以内に状態,覇虻遒垢襪里蓮交差点でない部分を誤って交差点と認識してコースから外れてしまうのを防ぐためである。
なお、交差点横断サブルーチンの内容は次項に譲る。

交差点横断サブルーチン

1.停止して、音を発して交差点横断を始めることを知らせる。
2.ロボットがコースに対しておよそ平行になるように、45°だけ時計回り旋回をする。
3.0.4秒直進する。
4.ラインからずれている場合はライン上に乗るまで時計回り旋回する。
5.黒い部分を連続で検知した回数を記録するカウンタをリセットする。
6.実行後1秒は交差点探索を行わないようにするため、タイマーを開始する。

ポイントB

ポイントBの前まで(状態 Ν)は進行方向左側の境界に沿ってライントレースを行っていることをご留意いただきたい。

1.まず交差点横断サブルーチンの1〜3までを行う。
2.このときロボットは進行方向右側にずれるので、4を逆回転(反時計回り)で行う。
3.反転カウンタに+1加える。(状態のトリガー)
4.5・6を行う。
5.状態で動作する。

ここで行っているのは、ライントレースに用いる境界の切り替えである。
境界の切り替えを行わなかった場合、進行方向左側の境界にはゴールの目印となるものはないため、
ゴールを探索する手段を別に講じる必要があった。
しかし境界を切り替えることにより、ゴールするときに特別の工程は不要となる。

プログラムのまとめ

このプログラムは基本的に次の3つの状態を遷移しながら動作する。
状態:進行方向左側の境界に沿ったライントレース
状態:交差点認識を含む進行方向左側の境界に沿ったライントレース
状態:進行方向右側の境界に沿ったライントレース

このほかに、「初期動作」、缶を移動する工程が存在する。

文書1.png

反省点

  • プログラム制作の所要時間を甘く見積もりすぎた結果、プログラムが完成しなかった。
    • 缶を移動するプログラムが出来なかった。
  • 原理不明のまま動作している部分がある。

添付ファイル: file文書1.png 170件 [詳細] fileimage-22ma.jpg 185件 [詳細] fileimage_2.jpeg 187件 [詳細] fileimage_1.jpeg 191件 [詳細] fileimage.jpeg 184件 [詳細] filezu.jpg 205件 [詳細]

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