ロボコン

目次

ルール

*迷路を抜け、四段に積まれた空き缶をゴールまで運ぶ。

◇基本ルール

◇基本得点の計算方法

◇技術点の計算方法
  以下の動作の精度・スピード・確実性などを含めた技術的な工夫や芸術性について、
  他の全てのチーム(9チーム+TAor教員)が20点満点で採点し、その平均点を求める。

  得点の目安:

詳しくは2008b/ロボコンを参照。

作戦

1:四つ一度につかみ、縦に積んだまま一遍に持ち運ぶ。

2:とにかく走り回って缶を拾い、一つずつゴールに押し込む。

1の現実性が低そうにみられていたが、作る過程で案外の好感触を得ている。
2はとにかく時間制限のないことを利用して健気に動くロボットの予定。

使用するもの

マシン

hakohako.jpg

▲一個ずつの運搬用ロボ

tsuno.jpg

▲四つ一度の運搬ロボ

 

プログラム

4つ一気に運搬するロボットのプログラム

void go_straight(int t )
{
OnFwd(OUT_A+OUT_C);
Wait(t);
Off(OUT_A+OUT_C);
Wait(16);
}

void go_back(int t )
{
OnRev(OUT_A+OUT_C);
Wait(t);
Off(OUT_A+OUT_C);
Wait(15);
}

void go_right(int t )
{
OnFwd(OUT_A);
OnRev(OUT_C);
Wait(t);
Off(OUT_A+OUT_C);
Wait(15);
}

void go_left(int t )
{
OnFwd(OUT_C);
OnRev(OUT_A);
Wait(t);
Off(OUT_A+OUT_C);
Wait(15);
}

void tozi(int t)              //アームを閉じる関数
{
OnRev(OUT_B);
Wait(t);
Off(OUT_B);
Wait(15);
}

void hiraki(int t)      //アームを開く関数
{
OnFwd(OUT_B);
Wait(t);
Off(OUT_B);
Wait(15);
}

#define THRESHOLD 40     //ライントレース用の閾値
#define RUN_TIME 50      //ライントレース用のタイマーの時間設定

task main()
{
	SetSensor(SENSOR_1,SENSOR_LIGHT);
	SetSensor(SENSOR_2,SENSOR_LIGHT);
	SetSensor(SENSOR_3,SENSOR_LIGHT);
	
	ClearTimer(0);	

	repeat(20)
 	{
	Wait(100);
	PlaySound(SOUND_CLICK);
	}	
	PlaySound(SOUND_UP);			
	repeat(10)
	{
	go_straight(8);
	}				
	go_left(30);
	go_right(2);	
	repeat(10)
	{
	go_straight(8);
	}	
	Wait(50);
	go_right(30);
	go_left(2);
	Wait(50);
	while(Timer(0) <= RUN_TIME)		//5秒間ライントレース
	{	
	 if(SENSOR_1<THRESHOLD)
	  {
	      OnFwd(OUT_C);
	      OnRev(OUT_A);
	      Wait(15);
	  }
	 else
	  {
		OnFwd(OUT_A+OUT_C);
	  }	  
	 if(SENSOR_3<THRESHOLD)
	 {
	   OnFwd(OUT_A);
	   OnRev(OUT_C);  
	   Wait(15);
	 }
	 else
	 {
     OnFwd(OUT_A+OUT_C);
     }	 
 	 if((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD))
	 {
	 	Off(OUT_A+OUT_C);
	 	Wait(200);
 	 	OnFwd(OUT_A+OUT_C);
	 	Wait(80);
 	 }
	 else
	{
		OnFwd(OUT_A+OUT_C);
	}	 
	}	 	 
	   Off(OUT_A+OUT_C);
	   Wait(50);
	   go_left(90);		//左に向いて
	repeat(40)
	{
	go_straight(8);		//まっすぐ進み
	}
	go_left(30);		//さらに左を向き
	go_right(2);		 
	repeat(15)
	{
	hiraki(3);		//アームを開き
	} 	   
	repeat(20)
	{
	go_straight(8);		//さらに進み
	}	   	 	 
	 repeat(40)
 	{
	tozi(3);		//アームを閉じて
	}   	   	   	
	OnRev(OUT_B);
	repeat(20)
	{
	go_straight(10);	//ゴール目指して進む
	}
	Wait(20);
	Off(OUT_B);
	OnRev(OUT_B);		//途中慣性でアームが勝手に開かないように
	go_right(30);		//所々でモータに信号を送る
	go_left(2);
	Wait(20);
	Off(OUT_B);	      	   
	OnRev(OUT_B);
	repeat(60)
	go_straight(8);
	Wait(20);
	Off(OUT_B);
	OnRev(OUT_B);
	go_right(30);
	go_left(2);
	Wait(20);
	Off(OUT_B);	     	
	while(Timer(0) <= RUN_TIME)	//帰りも再びライントレース
	{	
	 if(SENSOR_1<THRESHOLD)
	  {
	      OnFwd(OUT_C);
	      OnRev(OUT_A);
	      Wait(15);
	  }
	 else
	  {
		OnFwd(OUT_A+OUT_C);
	  }	  
	 if(SENSOR_3<THRESHOLD)
	 {
	   OnFwd(OUT_A);
	   OnRev(OUT_C);  
	   Wait(15);
	 }
	 else
	 {OnFwd(OUT_A+OUT_C);} 
	 if((SENSOR_1<THRESHOLD)&&(SENSOR_3<THRESHOLD))
	 {
	 	Off(OUT_A+OUT_C);
	 	Wait(200);
	 	OnFwd(OUT_A+OUT_C);
 	 	Wait(80);
	 }
	 else
	{
		OnFwd(OUT_A+OUT_C);
	}	
	}		 
	   Off(OUT_A+OUT_C);
	   Wait(50);
	OnRev(OUT_B);
	go_left(30);
	go_right(2);
	Wait(20);
	Off(OUT_B);	     	
	repeat(40)
	{
	hiraki(3);		//ゴールの前でアームを開き
	} 	
	go_straight(20);
	Wait(20);		//急停止した衝撃で缶を倒しゴールに入れる	        
	PlaySound(SOUND_DOUBLE_BEEP);		 
	 }

1つずつ運搬するロボットのプログラム

//基本動作
void go_straight(int t){ 
	OnFwd(OUT_A+ OUT_C);
	Wait(t);
}

void go_straight2(int t,int w){ 
	go_straight(t);
	Off(OUT_A+ OUT_C);
	Wait(w);
}

void go_back(int t){ 
	OnRev(OUT_A+ OUT_C);
	Wait(t);
}

void go_back2(int t,int w){ 
	go_back(t);
	Off(OUT_A+ OUT_C);
	Wait(w);
}

void turn_right(int t){
	OnFwd(OUT_A);
	OnRev(OUT_C);
	Wait(t);
}

void turn_right2(int t,int w){
	turn_right(t);
	Off(OUT_A+ OUT_C);
	Wait(w);
}

void turn_left(int t){
	OnRev(OUT_A);
	OnFwd(OUT_C);
	Wait(t);
}

void turn_left2(int t,int w){
	turn_left(t);
	Off(OUT_A+ OUT_C);
	Wait(w);
}
//グローバル変数
int loopcount;//ループ数カウント用
int stopcount;//停止時間カウント用
int rot_old;//前回の回転値記憶用
int b_flag=0;//ループ脱出用フラグ
int step;//各行動指定値用
//停止時間計測処理
//60ループごとに記憶していたそれ以前の回転値と現在の回転値を比較
//値が変化していなければ回転が止まっている=停止している
//値が変化していた場合は前回の回転値を更新
void stopcountor(){
	if(loopcount%60==0){
		if(SENSOR_1==rot_old){
			stopcount++;
		}else{
			stopcount=0;
		}
		rot_old=SENSOR_1;
	}
		
	if(loopcount>65535){
		loopcount=-1;
	}
	loopcount++;
}


//各行動時に一定時間停止していた場合の復帰処理
void stopcheck_L(){
	stopcountor();
	
	if(stopcount>6){
		while(1){
			turn_right2(5,20);
			rot_old++;
			if(rot_old>=2){
				break;
			}
		}
		go_straight2(10,5);
		//go_back2(10,30);
		stopcount=0;
		ClearSensor(SENSOR_1);
	}
}

void stopcheck_R(){
	stopcountor();
	
	if(stopcount>6){
		while(1){
			turn_left2(5,20);
			rot_old--;
			if(rot_old<=-2){
				break;
			}
		}
		go_straight2(10,5);
		//go_back2(10,30);
		stopcount=0;
		
		ClearSensor(SENSOR_1);
	}
}

void stopcheck_S(){
	stopcountor();
	
	if(stopcount>5){
		b_flag=1;
		stopcount=0;
		ClearSensor(SENSOR_1);
	}
}
//各行動用サブルーチン
sub step1_s1(){
	while(!SENSOR_3){
		go_straight2(20,10);
		//go_straight(0);
		stopcheck_S();
		if(SENSOR_2||b_flag){
			break;
		}
	}
	Wait(20);
	go_back(step);
	b_flag=0;
	Off(OUT_A+OUT_C);
	Wait(20);
}

sub step1_s2(){
	ClearSensor(SENSOR_1);
	while(1){
		go_straight2(10,5);
		if(SENSOR_1>step){
			Off(OUT_A+OUT_C);
			break;
		}
	}
	Off(OUT_A+OUT_C);
	Wait(20);
}

sub step1_R(){
	ClearSensor(SENSOR_1);
	while(1){
		turn_right2(5,20);
		if(SENSOR_1>step){
			break;
		}
		stopcheck_R();
	}
	Off(OUT_A+OUT_C);
}

sub step1_R90(){
	turn_right2(21,step);
	Off(OUT_A+OUT_C);
}

sub step1_L(){
	stopcount=0;
	ClearSensor(SENSOR_1);
	while(1){
		turn_left2(5,20);
		if(SENSOR_1<step){
			break;
		}
		stopcheck_L();
	}
	Off(OUT_A+OUT_C);
}

sub step1_L90(){
	turn_left2(22,-step);
	Off(OUT_A+OUT_C);
}
//ほぼ指定移動
task main(){
	SetSensor(SENSOR_1,SENSOR_ROTATION);//車輪回転チェック
	SetSensor(SENSOR_2,SENSOR_TOUCH);//ゴール地点判断
	SetSensor(SENSOR_3,SENSOR_TOUCH);//壁判断

	ClearSensor(SENSOR_1);

//スタート地点からループ開始地点へ
	step=5;
	step1_s1();
	step=5;
	step1_R();
	step=33;
	step1_s2();
	step=-9;
	step1_L();
//ループ開始
	while(1){
	//往路
		step=5;
		step1_s1();
		step=7;
		step1_R();
		step=15;
		step1_s1();
		step=-6;
		step1_L();+
		step=5;
		step1_s1();
		go_back(5);
		step=-5;
		step1_L();
		step=5;
		step1_s1();
	//帰路
		step=-7;
		step1_L();
		step=5;
		step1_s1();
		step=-5;
		step1_L();
		step=5;
		step1_s1();
		step=6;
		step1_R();
		step=5;
		step1_s1();
		step=6;
		step1_R();
		step=5;
		step1_s1();
		step=-7;
		step1_L();
		step=5;
		step1_s1();
		step=-6;
		step1_L();
		step=33;
		step1_s2();
		step=6;
		step1_R();
		step=10;
		step1_s1();
	//転回
		step=-7;
		step1_L();
		step1_L();
	}

	Off(OUT_A+OUT_C);	
}

制作過程

マシン

三つの光センサーで動作する4つまとめて運ぶマシン

 ▼『4つ一度につかみにいく』ための腕

tuno.jpg
 

 ▼『4つ〜』進化版。安定性に欠けるが角が二本に。

kuwagata.jpg
 

 ▼『4つ〜』安定性向上版。仰々しいが安定性は格段に上昇。

nihonude.jpg
 

 ▼『健気に一つずつ缶を押し込む』ためのマシン本体暫定版。
  基本はこんな感じで、缶を囲い込むように作りいくつかのセンサを使う。

kenage.jpg
 

 ▼『一つずつ〜』骨格完成版。

kakou.jpg
 

 ▼『一つずつ〜』腕中スペース。ここに缶を収納。

hako.jpg
 

 ▼『一つずつ〜』センサ搭載版
  回転センサーと2つのタッチセンサーで動作するようになっており、壁にぶつかったときと、ゴールの枠にぶつかったときに反応する。

sensor.jpg
 

動作

 

↓缶をつかんで保持する動作。

 

本番

 
robokon.jpg

↑本番(二回目)の様子。

 

・本番では缶までたどりつけなかったが、ロボットは、回転センサを利用していったん後退するプログラムのおかげで健気に頑張ってくれたと思う。
・結果は8位だった。

反省・感想

まとめて運ぶために長いアームのついたロボットを作ったが、耐久度に問題があり、結局使うことができなかったのが残念だった。耐久度を上げようと努力したが、今度は重心が偏ってしまったりして、何か問題が残る形になってしまった。 回転センサーを使うと、初期位置によって誤差が生まれるので、失敗が多かった。

 

コメントをどうぞ



添付ファイル: filedouga1 4can.flc 471件 [詳細] filetsuno.jpg 403件 [詳細] filehakohako.jpg 369件 [詳細] filerobokon.jpg 381件 [詳細] filerobocon5 181件 [詳細] filerobocon1 178件 [詳細] filesensor.jpg 321件 [詳細] filehako2.jpg 199件 [詳細] filenihonude.jpg 358件 [詳細] filekakou.jpg 362件 [詳細] filehako.jpg 361件 [詳細] filetuno.jpg 378件 [詳細] filekenage.jpg 391件 [詳細] filekuwagata.jpg 349件 [詳細]

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-02-16 (月) 06:23:22