2010a

目次

メンバー

スズキ
ヒデ
Mizu
Ta2

課題

基本ルール

       * スタート時は「スタート地点」の内部以外に接していないこと。
       * スタート時のロボットは1個を越えないこと (スタート後はいくつに分裂してもかまわない)。
       * 開始の合図から5秒以内にRCXのスタートボタンを押す作業を完了すること。
       * 競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。
       * 途中でうまく動かなくなった場合、1回限り再スタートすることができる。
       * 競技時間終了までにもとのスタート地点にもどらなければならない。
       * 競技時間は無制限。ただし審判が、競技続行不能と判断した場合は途中で終了する。

基本得点の計算方法 (ロボット本体の帰還)

       * 最低1個のRCXを含むロボットが右側に移動できれば+5点、障壁を越えて右側に移動した場合はさらに+5点。
       * ピンポン玉に少しでも触れることができれば+5点。ピンポン玉に触れることができなかった場合は以下の得点はなし。
       * 最低1個のRCXを含むロボットが図の右側から左側に帰還できれば+5点、障壁を越えて左側に移動した場合はさらに+5点。
       * 最低1個のRCXを含むロボットがゴールに帰還できれば+10点。
       * 複数回往復した場合は、2回目以降の往復は一回あたり+1点とし、最大で+5点 (合計6往復の場合)とする。
       * スタート時のロボットが全てゴールに帰還できれば+5点。ロボットの一部(半分以下)がゴールからはみ出している場合には2点減点(つまり+3点)。ただし帰還できない部分があればパーツ1個ごとに-1点、最大-5点。

基本得点の計算方法 (ピンポン玉)

       * ピンポン玉1個を持ち帰れば+3点。ピンポン玉を持っているロボットが完全にゴール内にあれば、地面に接触していない限りピンポン玉がゴール外の位置にあってもよい。
       * ゴール外側の黒線の内部にまで移動できているピンポン玉があれば+1点
       * ゴールに運んだボール5個ごとにボーナス点10点

技術点の計算方法

   以下の動作の精度・スピード・確実性などを含めた技術的な工夫や芸術性について他の全てのチーム(9チーム)+TAが20点満点で採点し平均点を求める。得点の目安:
       * 壁を越える動作 (3点)
       * ピンポン玉の収集 (3点)
       * ピンポン玉の運搬 (3点)
       * 帰還の動作(3点)
       * 2台のRCXの連携 (3点)
       * その他 (5点)

ロボットの紹介

相変わらず大型化しました…

工夫した点

何といってもピンポン玉吸い取り&壁の反対側へと送る部分です。 大型化しましたが… キャタピラを使い、吸い取るようにしました。

苦労した点

ピンポン玉吸い取り機構が重すぎて、うまく持ち上がらなかったことです…。 ギアをうまく組み合わせて持ち上げることができるようにするために、多くの知恵を様々な人からいただきました。

プログラム

改善前

#define TIME1 150		//光センサが黒線を渡りきるまでの時間
#define TIME2 50		//坂を上げ下げするための時間
#define ACROSS OnRev(OUT_A+OUT_C);Wait(TIME1);Off(OUT_A+OUT_C);//線を渡る処理
int THRESHOLD	;		//閾値
int x=0;			//交差点の回数
int t1=0;			//スタート地点から2本目の黒線へ行くのにかかる時間
int t2=0;			//2本目の交差点から3本目の交差点までにかかる時間
int t3=0;			//直角に曲がるのにかかる時間

task main(){

 SetSensor(SENSOR_1, SENSOR_LIGHT);		//左側
 SetSensor(SENSOR_3, SENSOR_LIGHT);		//右側
 SetSensor(SENSOR_2, SENSOR_TOUCH);
 THRESHOLD=SENSOR_1-5;				//閾値を取得
 ClearTimer(0);
	while(x<3){
		start follow_line;
		until(SENSOR_1<THRESHOLD&&SENSOR_3<THRESHOLD);//交差点までライントレース
		stop follow_line;
		x+=1;
		if(x==1){							//1回目の交差点なら
			ACROSS();						//交差点を渡る
		}else if(x==2){							//2回目の交差点なら
			t1=FastTimer(0);					//スタート地点からかかる時間を記憶
			TURN_RIGHT(0);						//右折
			ClearTimer(1);
		}else{								//3回目の交差点なら
			t2=FastTimer(1);					//2回目の交差点からかかる時間を記憶
			ClearTimer(2);
			TURN_LEFT(1);						//左折
			t3=FastTimer(2);					//直角に曲がる時間を記憶
		}
	}	
	start follow_line;				//壁にぶつかるまでライントレース
	until(SENSOR_2==1);
	stop follow_line;
	OnFwd(OUT_B);					//坂を上げてもう1台を壁の向こうへ渡す
	Wait(TIME2);
	OnRev(OUT_B);					//坂を下げる
	Wait(TIME2);
	Off(OUT_B);
	TURN_LEFT(1);					//反転
	start follow_line;
	until(SENSOR_1<THRESHOLD&&SENSOR_3<THRESHOLD);	//交差点までライントレース
	stop follow_line;
	TURN_LEFT(1);
	start follow_line;				//曲がるところまでライントレース
	ClearTimer(3);
	until(FastTimer(3)==t2);
	stop follow_line;
	OnFwd(OUT_A);OnRev(OUT_C);			//直角に右折
	Wait(t3);	
	OnFwd(OUT_A+OUT_C);				//スタート地点まで前進
	Wait(t1);
	Off(OUT_A+OUT_C);
}

task follow_line(){
	while (true){
		if(SENSOR_1>THRESHOLD&&SENSOR_3>THRESHOLD){		//両センサ白なら
			OnFwd(OUT_A+OUT_C);Wait(5);			//前進
		}else if(SENSOR_1>THRESHOLD){				//左センサだけ白なら
			OnFwd(OUT_A);OnRev(OUT_C);				//右折
		}else{				   				//右センサだけ白、両センサ黒なら
			OnFwd(OUT_C);OnRev(OUT_A);				//左折
		}
	}
}

void TURN_RIGHT(int r){		//交差点を右に曲がるときの処理
	ACROSS();							//交差点を渡る
	repeat(r){
		OnFwd(OUT_A);OnRev(OUT_C);				//センサが黒線にかかるまで旋回
		until(SENSOR_1<THRESHOLD||SENSOR_3<THRESHOLD);
		OnFwd(OUT_A);OnRev(OUT_C);				//センサが黒線から離れるか黒線をまたぐまで旋回
		until(SENSOR_1>THRESHOLD&&SENSOR_3>THRESHOLD);
	}
}
void TURN_LEFT(int l){		//交差点を左に曲がるときの処理
	ACROSS();								//交差点を渡る
	repeat(l){
		OnFwd(OUT_C);OnRev(OUT_A);				//センサが黒線にかかるまで旋回
		ntil(SENSOR_1<THRESHOLD||SENSOR_3<THRESHOLD);
		OnFwd(OUT_C);OnRev(OUT_A);				//センサが黒線から離れるか黒線をまたぐまで旋回
		until(SENSOR_1>THRESHOLD&&SENSOR_3>THRESHOLD);
	}
}

スタート地点から右回りにライントレースをしながら移動する
時間がなく本番当日まで実際にプログラムを走らせて調整する時間がなかったので、時間指定などの定数を出来るだけ無くし、条件指定や変数を使ってその場で取得する様にした

問題点

  • コードの関係でモーターの前後が合わない
  • 坂を上げてから下げるまでが早すぎて上のロボットが移動する時間がない
  • 閾値の設定に問題があるのかライントレースがうまくいかない
  • TIME1の値が大きすぎて2本目の線を通り過ぎてしまう
  • voidなどのせいでプログラムが重くプログラムを入れるのに時間がかかってしまう
  • 坂をうまく戻すことができず戻るときに回転時に坂が壁にぶつかってしまう

改善後

#define TIME1 50		//光センサが黒線を渡りきるまでの時間
#define TIME2 250		//坂を下ろすまでの時間
#define THRESHOLD 43	//閾値
#define TIME3 92		//直角に曲がるのにかかる時間
int x=0;			//交差点の回数
int t1=0;			//スタート地点から二本目の黒線へ行くのにかかる時間
task main(){

 SetSensor(SENSOR_1, SENSOR_LIGHT);		//左側
 SetSensor(SENSOR_3, SENSOR_LIGHT);		//右側
 SetSensor(SENSOR_2, SENSOR_TOUCH);
 ClearTimer(0);					//タイマーをセット
	while(x<3){
		start follow_line;
		until(SENSOR_1<THRESHOLD&&SENSOR_3<THRESHOLD);//交差点までライントレース
		stop follow_line;
		x+=1;
		if(x==1){							//1回目の交差点なら
			OnRev(OUT_A+OUT_C);					//交差点を渡る
			Wait(TIME1);
			Off(OUT_A+OUT_C);
		}else if(x==2){						//2回目の交差点なら
			t1=FastTimer(0);					//スタート地点からかかる時間を記憶
			OnRev(OUT_A+OUT_C);Wait(20);
			OnRev(OUT_A);OnFwd(OUT_C);
			Wait(TIME3);
			Off(OUT_A+OUT_C);					//右折
		}else{								//3回目の交差点なら
			OnRev(OUT_C);OnFwd(OUT_A);
			Wait(TIME3);
			Off(OUT_A+OUT_C);					//左折
		}
	}	
	OnRev(OUT_A+OUT_C);				//壁にぶつかるまで前進
	until(SENSOR_2==1);
	Off(OUT_A+OUT_C);
	OnRev(OUT_B);					//坂を下げてもう1台を壁の向こうへ渡す
	Wait(TIME2);
	Off(OUT_B);
	Wait(700);
	OnFwd(OUT_B);					//坂を上げる
	Wait(TIME2);
	Off(OUT_B);
	OnFwd(OUT_A+OUT_C);
	Wait(100);	//交差点まで後退
	OnRev(OUT_A);OnFwd(OUT_C);
	Wait(TIME3);
	Off(OUT_A+OUT_C);
	start follow_line;				//壁にぶつかるまでライントレース
	until(SENSOR_2==1);
	stop follow_line;
	OnFwd(OUT_A+OUT_C);
	Wait(20);
	OnRev(OUT_A);OnFwd(OUT_C);			//直角に右折
	Wait(TIME3);
	OnRev(OUT_A+OUT_C);
	Wait(t1);
	Off(OUT_A+OUT_C);
}

task follow_line(){
	while (true){
		if(SENSOR_1>THRESHOLD&&SENSOR_3>THRESHOLD){		//両センサ白なら
			OnRev(OUT_A+OUT_C);					//前進
		}else if(SENSOR_1>THRESHOLD){				//左センサだけ白なら
			OnRev(OUT_A);OnFwd(OUT_C);				//右折
		}else if(SENSOR_1>THRESHOLD){				   				//右センサだけ白、両センサ黒なら
			OnRev(OUT_C);OnFwd(OUT_A);				//左折
		}else{
			OnRev(OUT_A+OUT_C);
		}
	}
}

急いで作ったのでダラダラとすっきりしないプログラムになってしまった、サブルーチンなどを使えばすっきりとしたものになると思う。それなりに動くことができるようになったが、前の方が良かった部分もあるような気がする
曲がるのを時間指定にしたのでラインから外れた時のことを考えるとライントレースを多用できないようになってしまった

変更点

  • モーターAとCの前後を逆転
  • 曲がる動作を時間指定にして、voidだった部分を消した。他にも定数を多くして汎用性は捨て今回のコースに特化させた
  • 坂を上げた後7秒間待つようにした
  • 戻るときの回転前に後退して坂が当たらないようにした

改善前

#define TIME1 150		//アームの上げ下げにかかる時間
#define TIME2 100		//ボール取る時間
#define TIME3 300 		//ボールが転がるまでアームを上げるのにかかる時間
#define TIME4 40		//後退する時間の基準値
int t=TIME4;
task main(){
  SetSensor(SENSOR_1, SENSOR_TOUCH);	//後方タッチセンサ
  SetSensor(SENSOR_2, SENSOR_TOUCH);	//前方タッチセンサ
	until(SENSOR_2==1);				//下ろされるまで待機
	repeat(2){
		repeat(3){
			OnFwd(OUT_C);					//壁に当たるまで前進
			until(SENSOR_2==1);	
			repeat(3){
				OnFwd(OUT_B);				//アームを下ろす
				Wait(TIME1);
				Off(OUT_B);
				OnFwd(OUT_A);					//ボールを取る
				Wait(TIME2);
				Off(OUT_A);
				OnRev(OUT_B);					//アームを上げる
				Wait(TIME1);
				Off(OUT_B);
				OnRev(OUT_C);					//後退して場所移動
				Wait(t);
				Off(OUT_C);
			}
			t+=10;							//後退する時間を増やす
		}
		OnRev(OUT_C);					//壁に当たるまで後退
		until(SENSOR_1==1);
		Off(OUT_C);
		OnRev(OUT_B);					//アームを傾けてボールを壁の向こうへ渡す
		Wait(TIME3);
		OnFwd(OUT_B);					//アームの角度を初期状態に戻す
		Wait(TIME3-TIME1);
		Off(OUT_B);
		t=TIME4;					//後退する時間をリセット
	}
}

モーターA→ボール吸い取り部分、モーターB→アーム、モーターC→本体車輪
移動とボールの吸い取りを合計48回繰り返す
枠にぶつかるたびに後退時間を増やしてボールをとる場所を変えている

問題点

  • アームとタッチセンサの幅が狭く、奥までアームがいかないので、後退するとアームが枠から出てしまうので後退する意味がない
  • 左右の重さのバランスや、初期の方向のせいで何回もやるとボールが取れる位置からずれてしまうので、48回は時間の無駄
  • ボールを左側に送る時ボール吸い取り部分のキャタピラを回してボールの移動をスムーズにする
  • ボールを左側に送るときアームを戻すのが早すぎてうまくできない
  • 後ろのスイッチがうまく押せないので起動をほかの方法にする必要がある
  • アームの重さのせいでアームを上げるときに必要な時間が下げるときより多く必要
  • ボールの吸い取りがうまくいかない
  • アームが重くアームをボールが転がり落ちない45度くらいに保つのが難しい

改善後

#define TIME1 190		//アームの下げるのにかかる時間
#define TIME2 100		//ボール取る時間
#define TIME3 230		//ボールが転がる角度までアームを上げるための時間

task main(){
  SetSensor(SENSOR_1, SENSOR_TOUCH);	//後方タッチセンサ
  SetSensor(SENSOR_2, SENSOR_TOUCH);	//前方タッチセンサ
  SetSensor(SENSOR_3, SENSOR_TOUCH); //前方タッチセンサ2
	ClearTimer(0);
	until(FastTimer(0)==2200);				//下ろされるまで待機	
	repeat(6){
		OnFwd(OUT_C);					//壁に当たるまで前進
		until(SENSOR_2==1||SENSOR_3==1);
		Off(OUT_C);
		OnFwd(OUT_A+OUT_B);				//アームを下ろす
		Wait(TIME1);
		Off(OUT_B);
		OnFwd(OUT_C);				//前後して引っかかっているボールを外す
		Wait(30);
		OnRev(OUT_C);
		Wait(30);
		Wait(TIME2);					//ボールをとる
		Off(OUT_C);
		Off(OUT_A);
		OnRev(OUT_C);					//壁に当たるまで後退
		until(SENSOR_1==1);
		Off(OUT_C);
		OnRev(OUT_B);					//アームを傾けてボールを壁の向こうへ渡す
		OnFwd(OUT_A);
		Wait(TIME3);
		Off(OUT_B+OUT_A);
		Wait(300);					//ボールが転がり落ちるのを待つ
	}
}

ボールを取っては運び、取っては運びの単純な動きをする

変更点

  • タッチセンサを増やしたので対応
  • ボールを吸い取るときの後退処理を全削除
  • 吸い取るとき小さく前後してボールの引っかかりが減らせるようにした
  • アームを下ろし始めた時からボール吸い取り部分を作動させて吸い取りやすくした
  • ボールが左側へ転がり落ちるまでの時間をいれた
  • 左側へ送る際にボール吸い取り部分のキャタピラを動かしてスムーズに送れるようにした
  • 1回1回左側へ送ることでアームを完全に下すか、完全に上げるかだけでいいようにした
  • プログラムの起動をタッチセンサからタイマーに変更
  • アームの上げる時間と下げる時間を別々にした

感想・反省

Ta2

主にロボット組み立てを担当しました。相変わらずいろいろと大きくなりまして、ギアの組み合わせなど、苦労しました。最終的に作り上げても球を吸い取るバレル部分がうまく当たらないなど、不具合も多かったですが、みんなで頑張って、満足できるものを作れたと思います。

スズキ

結果的にボールを運べなかったので悔しかったけど、最後の課題をメンバーみんなで協力して製作できたのでよかったです。

mizu

今回はプログラムを担当したが何度も誤作動をさせてしまい、えらく迷惑をかけてしまった。
最終的にボールを運ぶことはできなかったが、役割分担という形ではあるけど今までの課題の中で一番メンバー全員で協力してできたと思うので満足できた。

コメント

コメントをどうぞ

  • 写真がないならしょうがないので、その説明を充実させてください -- FI? 2010-08-16 (月) 20:05:33


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-08-16 (月) 20:05:34 (3292d)