目次

はじめに

 今回の課題はライントレースロボットで、図のようなコースを決められた順路を通り、途中においてあるピンポン玉をゴールまで運ぶロボットを作るというものでした。僕はC地点からA地点へ (Q交差点では直進、P三叉路では右折)を通るロボットを作りました。
 今回は前回と違い、本体の作成は簡単でしたが、プログラムに時間がかかりました。

コース

ロボット本体

課題2と同じなので割愛します。

プログラム

#define turnleft OnFwd(OUT_C);OnRev(OUT_A); //左旋回
#define left OnFwd(OUT_C);Off(OUT_A); //左に曲がる
#define right OnFwd(OUT_A);Off(OUT_C); //右に曲がる
#define turnright OnFwd(OUT_A);OnRev(OUT_C); //右旋回

//ライントレース用の関数
void linetrase(int t){
	ClearTimer(0);
	while(FastTimer(0)<t){
		if(SENSOR_3<36){
			turnright;
		}else if(SENSOR_3<39){
			right;
			Wait(2);
		}else{
			if(SENSOR_3<47){
				OnFwd(OUT_AC);
				Wait(3);
			}else if(SENSOR_3<50){
				left;
				Wait(2);
			}else{
				turnleft;
			}
		ClearTimer(0);
		}
	}
}

void linetrase2(int t){
	ClearTimer(0);
	while(FastTimer(0)<t){
		if(SENSOR_3<36){
			turnright;
		}else if(SENSOR_3<39){
			right;
			Wait(2);
		}else{
			if(SENSOR_3<47){
				OnFwd(OUT_AC);
				Wait(3);
			}else if(SENSOR_3<50){
				left;
				Wait(2);
			}else{
				turnleft;
			}
		}
	}
}

task main ()
{
	ClearMessage();
	until(Message() == 1);
	PlaySound(SOUND_CLICK);
	SendMessage(2);

	Wait(300);

	int h=0;
	OnFwd(OUT_B);
	right;
	Wait(10);
	while(h<15){
	h++;
	OnFwd(OUT_AC);
	Wait(h);
	Off(OUT_AC);
	Wait(5);
	}
	Off(OUT_B);

	linetrase2(340);
	PlaySound(SOUND_CLICK);
	linetrase(18);

	PlaySound(SOUND_CLICK);
	left;
	Wait(30);
	Off(OUT_C);

	linetrase2(690);
	PlaySound(SOUND_CLICK);

	int count=0;
	int i=0;
	ClearTimer(1);
	while(count <= 1){
		linetrase(28-i);
		if(FastTimer(1)>50||count==0){
			count++;
			i=6;
			PlaySound(SOUND_CLICK);
		}
		ClearTimer(1);
	}

	PlaySound(SOUND_CLICK);
	left;
	Wait(25);
	Off(OUT_C);

	linetrase2(900);
	PlaySound(SOUND_CLICK);
	linetrase(20);
	PlaySound(SOUND_CLICK);

	Off(OUT_C);
	OnRev(OUT_A);
	Wait(55);
	Off(OUT_A);
	OnRev(OUT_B);
	Wait(50);
	Off(OUT_B);
	OnFwd(OUT_AC);
	Wait(15);
	Off(OUT_AC);

	ClearTimer(0);
	ClearMessage();
	while((Message()!=4)&&(FastTimer(0)<100)){
		SendMessage(3);
	}
	if(Message()==4){
		PlaySound(SOUND_CLICK);
	}else{
		PlaySound(SOUND_LOW_BEEP);
	}

	OnRev(OUT_AC);
	Wait(15);
	Off(OUT_AC);
	OnRev(OUT_ABC);
	Wait(70);
	Off(OUT_B);
	Wait(300);
	Off(OUT_AC);
	ClearTimer(0);
	while(FastTimer(0)<1000){
		SendMessage(3);
	}
	OnFwd(OUT_AC);
	Wait(250);
	Off(OUT_AC);
}

説明

定義

 まずは以下の通り全方向に動くための定義をしました。

#define turnleft OnFwd(OUT_C);OnRev(OUT_A); //左旋回
#define left OnFwd(OUT_C);Off(OUT_A); //左に曲がる
#define right OnFwd(OUT_A);Off(OUT_C); //右に曲がる
#define turnright OnFwd(OUT_A);OnRev(OUT_C); //右旋回

 そして、交差点までライントレースするプログラムを関数で書きました。引数を入れたかったのでサブルーチンではなく関数を使っています。引数は一度にどれだけ右に曲がったら交差点と判断するのかを入れられるようにしています。これにより、様々な曲がり角に対応できるようになりました。
 Wait関数を少し入れることでなるべく滑らかに動くようにしています。

void linetrase(int t){
	ClearTimer(0);
	while(FastTimer(0)<t){
		if(SENSOR_3<36){
			turnright;
		}else if(SENSOR_3<39){
			right;
			Wait(2);
		}else{
			if(SENSOR_3<47){
				OnFwd(OUT_AC);
				Wait(3);
			}else if(SENSOR_3<50){
				left;
				Wait(2);
			}else{
				turnleft;
			}
		ClearTimer(0);
		}
	}
}

引数の時間だけ普通のライントレースをする関数も作りました。

void linetrase2(int t){
	ClearTimer(0);
	while(FastTimer(0)<t){
		if(SENSOR_3<36){
			turnright;
		}else if(SENSOR_3<39){
			right;
			Wait(2);
		}else{
			if(SENSOR_3<47){
				OnFwd(OUT_AC);
				Wait(3);
			}else if(SENSOR_3<50){
				left;
				Wait(2);
			}else{
				turnleft;
			}
		}
	}
}

動作

コース

 右の図の様にライントレースしました。

  1. 相手から"1"というメッセージがくるまでまって来たら"2"を返信します。
    	ClearMessage();
    	until(Message() == 1);
    	PlaySound(SOUND_CLICK);
    	SendMessage(2);
  2. 3秒止まってパスをしたロボットが離れるのを待ってから、ゆっくりと加速発進する。
    	Wait(300);
    
    	int h=0;
    	OnFwd(OUT_B);
    	right;
    	Wait(10);
    	while(h<15){
    	h++;
    	OnFwd(OUT_AC);
    	Wait(h);
    	Off(OUT_AC);
    	Wait(5);
    	}
    	Off(OUT_B);
  3. 右に大きく曲がる場所が交差点までに一度あるので、一度目の大きく曲がるところはスルーするようになっています。曲がる時間が長く、二度認識してしまうことがあったので、50秒以内には二度目を認識しないようにしました。
    	int count=0;
    	ClearTimer(1);
    
    	while(count <= 1){
    		linetrase(28);
    		if(FastTimer(1)>500||count==0){
    			count++;
    		}
    		ClearTimer(1);
    	}
  4. 2度目の大きく曲がるところを認識したら、2秒間止まってから線を越えます。そのあとはアームでピンポン玉をはさみます。
    	stop2sec;
    
    	left;
    	OnFwd(OUT_B); //アームを閉じる
    	Wait(20);
    	Off(OUT_C);
    	Wait(100);
    	Off(OUT_B);
  5. ライントレースを再び初めて、角を認識したら2秒間止まる。
    	linetrase(21);
    
    	stop2sec;
  6. ライントレースを再び始め、角を認識したら後ろに下がり、アームを開いてシュートする。
    	linetrase(28);
    	
    	Off(OUT_AC);
    	OnRev(OUT_A); //後ろに下がる
    	Wait(30);
    	Off(OUT_A);
    	OnRev(OUT_B); //アームを開く
    	Wait(50);
    	Off(OUT_B);
    	OnFwd(OUT_AC); //シュートする
    	Wait(60);
    	OnRev(OUT_AC);
    	Wait(60);
    	Off(OUT_AC);

結果・感想

#ref(): File not found: "S__32784393.jpg" at page "2015a/Member/morinokumasan/Mission2/robocon"

 少し歪みはありますが、目的の字を書くことはできました。マス目を意識することによってだいぶ簡単にプログラムをすることができたのがとてもよかったと思いました。
 グループで製作ということで、3人で相談しあいながらなんとか形にできたのは大きな達成感を得ることになりました。
 今回はアーム式だったので45°の斜め線で統一することになりましたが、SetPower関数というものがあるそうなのでそれを今度使ってみたいと思いました。
 おまけで、写真はありませんが、「熊」を書くプログラムも書きました。容量が大きく、defineではコンパイルができなかったので関数を使っています。最後の点3つは繰り返しを使っています。 プログラムはこちら


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2015-08-09 (日) 02:04:20