2011b

title.gif

メンバー

  • ぐっP 「ロボコン」って響き、いいよね!
  • だい 全力を出し切って、いいロボットとプログラムを完成させたい。
  • 二宮(天パ) 歌は得意だが、プログラムは苦手。なので組み立て頑張…った(?)

課題内容

競技場
  • 直方体の紙パックを自陣へ運ぶ(図参照)
  • 積み上げて点数を稼ぐことができる
  • RCXは二台使用する
  • 合体で一台でも、別々に独立させてもよい
  • 終了時にロボットは、紙パックに触れていないこと

詳細はこのページにて

ロボット

「キモは積み上げだ」
ならば簡単そうな運搬に数をこなさせ、積み上げとは分離させよう。
と、この班では二台を独立させる方針。
ランタンなる光源のサイズ、位置がはっきりしなかったので、ランタンがどのように影響を及ぼすか分からなかったため序盤は一号機の挙動が不確定だった。
しかし箱庭内には変わりあるまいと、華麗にスタートを切る。出足は順調となった。

ちなみに作戦はこんな感じ
ランタンは結局押しのけて道を確保することになりました。
行動図
途中でぐるぐる回るのは、通信を確実に行うため。回っている間は通信を送りっぱなしである(プログラム参照)。

一号機 運搬

ロボット名「いちごう君」
最初は箱4ツを一気に運ぶ作戦だった。伴って大型になってしまうので障害物との兼ね合いが難しい。
強く、確実な動作を1発目から実現した。しかし幅をとるのが後に問題に。
それにより、2つ持ちへと作戦を変更した。箱を運ぶ動作を3回繰り返すことになるが、そこはプログラムでカバーしたいところ。

全体

全体的に小柄なロボットにできたので、どんな隙間もお手の物。
3種のセンサーを1つずつ搭載し、フィールド内を駆け巡る!
本体 写真左にタッチセンサ 写真中央は回転センサ、左は光センサ

タッチセンサは、黒い棒状のパーツが若干稼働するようになっていて、それが壁に当たるとタッチセンサを押すという仕組みです。
回転センサは、タイヤよりもさらにギヤ比を落として正確性をあげています。

ベース

シンプルなベース。内側に回転センサが取り付けてある。
ポイントは通信部につけた通信補助装置。これにより通信制度が200%UP!(当社比)
1base.JPG

アーム

2個取りにしたことにより、短くなったアーム。
左右のタイヤは幅確保とゴムによるグリップの役割をしている。本当は写真右奥側も大きなタイヤを使用したかったが、黄色パーツにあたってしまって無理でした;
アームの開閉動作にはタイヤを利用。このうち動力を伝えるタイヤを片方(写真では右側)だけにすることで、ギヤを節約。
1arm.png

おまけ(本体旧型)

前回の面影を残した車体。小回りは効くが紙パックを運ぶような力仕事には向いていなかったため変更。
真ん中の写真の赤い光は光センサによるもの。当初は前方に光センサを向けて、ランタンや紙パックを判別することも考えていました。

本体 正面 裏面

おまけ(アーム旧型)

アーム

4つ取りを目指していた時代の超ロングアーム。夢と希望に満ち溢れている。
あらゆる障害にギリギリで対応できるように設計したつもりだが、いくつかの場所ではギリギリアウトであったため、断念。
夢と希望を半分にし、残りの50%に確実性をあてた現在のアームへと姿を変える…

二号機 積上

ロボット名「にごうちゃん」・・・///
運搬された箱を高く積み上げる役割。
本来、ブロックは4つ並んで届く予定だった。
なので、4ついっぺんにつかまない限り横から持ち上げるのは難しく、一度に積み上げる機能も困難と判断。
対策案として2つを上からつかみ、持ち上げる方法を採る事に。そこからが大変時間を食った。
受け取るアームは上下に大きく動く必要があるが、長さのある部品を作るとたわむ、バランスが悪くなるなど様々に問題が出てきた(おまけ参照)
数々の検証の末、上下移動の軸と、それを支える簡易の軸が必要ではないかと着想に至る。
しかしそれもまた新たな問題の種となっていて、思いっきり部品が足らな・・・い・・・。
更にバランス、パーツの問題が氷解した後も発見されるのは通信の問題。RCX、こやつら意外と声が小さいらしく届かない・・・!
では位置を変えれば、バランスがっ!苦労が絶えません。

数々の問題を3人で乗り越えて、形になった にごうちゃん。最終的には、通信・バランス・強度全てを踏み越える程立派になりました(ホロリ

全体

完成図.JPG

2all.JPG 2ue.JPG 2sita.JPG 2usiro.JPG

アームで牛乳パックをつかんで、エレベーターのように持ち上げる構造。重心が真ん中ではないため、車体部分を安定させるのが最大の課題だった。
まっすぐに走らせようとしたところ。アームの重さにより、完璧な直進ができない。ずれが重なり、二度目以降の往復作業では光センサが黒線から逸れてしまう。もともと、ブロックの保持を確実なものにするための設計だったので、一方方向にしか走れない2ごうちゃん。黒線をトレース出来てもオンラインに復帰する事は出来ない。

この問題は相当に深刻で、走行用のタイヤを組み替えたり、ベースを幅増ししたり試行錯誤は相当な数になり・・・タイヤ乗せちゃえ☆ と、RCX上に最大サイズのタイヤを全個数配置することで問題解決。なんとこの冗談のような対策が大変効果的。コードのリール的な役割も持たせることで説得力も増した。積み上げに特化は成功、最早本番を待つばかりとなった・・・

ベース

二号base.JPG 2base.JPG

たび重なる減量にて、獲得した驚異の薄さ&堅牢さ。
そして、極めつけは何処に文句をつけようかという完璧を体現する動力部分。
モーターからの動力の伝わり方は写真の通りで、見えにくいが内側にある2枚のギヤがアームに接し、上下させている。
二号柱.JPG二号柱先端.jpg正面図(90°回転)

なお柱の下部には、アーム下降時の目安となるタッチセンサがついています。

アーム

初期からあまり変わらなかった部分。タイヤで動く。まず、かねてから言うバランスの問題。モーターを軸に近付けて安定を求めた。
アーム先端 ブロックに触れる部分はいろいろ試した末「ゴムさえ巻けば、案外なんでも持てる」という天パの結論に基づき余った材料で出来ている。
といってもおざなりではなく、二個分のブロック中心をゆうに挟めるサイズと、自壊しない程度の強度を持ち合わせる。
90度の接合は実はそれほど強くない。しかしブロックを抑えるのにかかる力とは方向が違うので、支障がない。極力軽く、壊れない。
2arm2.JPG

タッチセンサだが、当初は柱についていたのだが反応しない,とれるといったことがあったため、いっそアームのほうにつけてしまおうということになり引っ越してきました。
ぎりぎりの変更だったため、柱上部についている写真もあるけれどこれが最終版です。

おまけ(初期構想)

クレーン予想図.jpg

始めはクレーンゲームをヒントにして、このような構造にしようと思ったが、クレーンの支える棒が不安定になってしまうため、断念。

おまけ(本体旧型)

【二号機ベース初期】
柱を前後の2段構えとし、安定性を図った… つもりが、バランスも悪くパーツを消費しすぎたため変更。
本体 裏面



変遷を重ねた、改良型。
軸を一本にして、余ったパーツをつなぎ合わせて引っ張る。なんとこれはバランス面で大幅な進歩を見せる。
しかし高級パーツの使いどころがもったいなかった&軸からまだパーツを減らせそうだったために分解。方針としては手応えを感じた。

二号機初期.JPG 二号機初期2.JPG
【二号機アーム初期】
箱をつかむには?と考え天パが最初にサクっと作った物。
結局実用には成らなかったが基本的な部分は変わらず。
張力だけを求めて輪ゴムを利用したわけではない、のがポイントか。
最初期アーム.JPG

プログラム

一号機

紙パックを運んでくるプログラムだが、1周目と2周目以降では動作が違うためややこしくなってしまった。
さらに、関数で待ち時間設定したものを回転に使ったり、その逆をしたりしていたのでごちゃごちゃしている。
時間があればもっと見やすくまとめたかったなと思います。

【関数パート】

#define SE_R SENSOR_1              //SENSOR_1をSE_R(右センサの意)と省略
#define SE_C SENSOR_2              //上参照
#define SE_L abs(SENSOR_3)            //SENSOR_3(回転センサ)の値の絶対値をSE_Lと省略
#define WAIT_TIME 50               //待ち時間設定
#define WAIT_TIME_1 75              //待ち時間設定
#define WAIT_TIME_2 7              //待ち時間設定
#define TURN_1 41                //回転数設定
#define TURN_2 45                //回転数設定
#define TURN_3 3                 //回転数設定
#define TH 43                  //光センサの閾値を設定
#define go OnFwd(OUT_AC);            //直進をgoと定義
#define back OnRev(OUT_AC);           //後退をbackと定義
#define turn_right OnFwd(OUT_C);OnRev(OUT_A);  //右折をturn_rightと定義
#define turn_left OnFwd(OUT_A);OnRev(OUT_C);   //左折をturn_leftと定義

int i=1,j,k,line;                //様々な場面で使う変数を定義

void Clear_Sensor()               //センサーと動作のリセット
{
	ClearSensor(SENSOR_3);
	PlaySound(SOUND_FAST_UP);
	Off(OUT_AC);Wait(WAIT_TIME);
}

void arm_open()                 //アームを開く
{
	OnRev(OUT_B);
	Wait(WAIT_TIME);
	Off(OUT_B);
}

【メインパート】

task main()
{
	SetSensor(SENSOR_1,SENSOR_TOUCH);				  //センサー1をタッチセンサと定義
	SetSensor(SENSOR_2,SENSOR_LIGHT);				  //センサー2を光センサと定義
	SetSensor(SENSOR_3,SENSOR_ROTATION);				  //センサー3を回転センサと定義

	Clear_Sensor();						  //センサーと動作をリセット
	back; until(SE_L >= 175);					  //後退
//紙パック確保までのプログラム//
	for(i = 1;i <= 3;i++){					  //{}内を3回繰り返す(紙パックを3回運ぶ)
		Clear_Sensor();
		arm_open();						//アームを開く
		turn_right; until(SE_R == 1);				//タッチセンサが壁にあたるまで右回転
		Clear_Sensor();
		if(i == 1){						//1周目はランタン押してから戻る
			while(SE_L <= 450){				  //ランタンを押し切るまで、{}内を繰り返す
				go;						//前進
				if(SE_R == 1){					//もしタッチセンサが壁に当たっていたら、
					Off(OUT_C);				  //左タイヤを止めて
					until(SE_R == 0);				  //壁から離れる
				}
			}
			Clear_Sensor();
			while(SE_L <= 95){				 	 //紙パックの位置に戻るまで{}内を繰り返す
				back;						//後退
				if(SE_R == 1){					//もしタッチセンサが壁に当たっていたら、
					Off(OUT_A);				  //右タイヤを止めて
					until(SE_R == 0);				  //壁から離れる
				}
			}
		}else{							 //2周目以降は紙パックまで前進
			while(SE_L <= 300){				  //紙パックまで移動するまで{}内を繰り返す
				go;						  //前進
				if(SE_R == 1){					//もしタッチセンサが以下略
					Off(OUT_C);				//左タイヤを止めて
					until(SE_R == 0);				//壁から離れる
				}
			}
		}
		Clear_Sensor();
		turn_left; until(SE_L >= TURN_2);				//左に90℃回転
		Clear_Sensor();
		if(i == 1){						//周回ごとに紙パックまでの距離が違うため、それぞれ進む距離を変数で定義
			line = 115;
		}else if(i == 2){
			line = 160;
		}else{
			line = 205;
		}
		go; until(SE_L >= line);					//前進
		Off(OUT_AC);
		OnFwd(OUT_B);						//アームを閉じる(モーターを止めないで保持力強化)
		Clear_Sensor();
		back; until(SE_L >= 55);					//若干後退
		Clear_Sensor();
		turn_left; until(SE_L >= TURN_3);				//軌道修正のためわずかに左回転
		Clear_Sensor();
		back; until(SE_L >= line);					//壁まで後退して、角度を整える
//紙パックを運ぶプログラム//
		Clear_Sensor();
		go; until(SE_L >= TURN_1);					//前進
		Clear_Sensor();
		turn_left; until(SE_L >= WAIT_TIME);				//左回転
		if(i == 1){						//1周目と2周目以降では紙パックを置く位置が違うため、条件分岐
			line = 170; k = 4;					  //前進中に軌道修正を入れるため、※1のfor文の繰り返し回数kを設定
		}else{
			line = 240; k = 5;					  //ついでに、のちの移動距離※2も設定している
		}
		for(j = 1;j <= k;j++){					//jが1からkになるまで{}内を繰り返し(※1)
			Clear_Sensor();
			go; until(SE_L >= 80);				  //少し前進
			Clear_Sensor();
			turn_left; until(SE_L >= TURN_3);		 	  //わずかに左回転
		}
		go; until(SE_L >= 80);					//最後にもう少し前進
		Clear_Sensor();
		turn_right;						//右折(角度は1周目とそれ以外で異なっている)
		if(i == 1){
			until(SE_L >= TURN_2);				  //1周目は90℃
		}else{
			until(SE_L >= TURN_1);				  //2周目以降は90℃よりやや浅く
		}
		Clear_Sensor();
		go;							//前進(前進も時間が異なる)
		if(i == 1){
			Wait(WAIT_TIME_1);					  //1周目は待ち時間,世餌圓辰晋紂
			until(SE_C <= TH);until(SE_C > TH);			  //スタートエリアの黒線を越えるまで
		}else{
			until(SE_L >= 110);				  //2周目以降はある程度進めたら、
			for(j = 1;j <= 2;j++){				  //位置調整のため{}内を2回繰り返す
				turn_right; Wait(WAIT_TIME_2);			//わずかに右回転
				go; Wait(WAIT_TIME_2);				//わずかに前進
			}
		}
		Off(OUT_AC);
		OnRev(OUT_B);						//アームを開く(紙パックを置く)
		if(i == 1){
			Wait(WAIT_TIME);
		}else{
			Wait(WAIT_TIME_2);					  //2周目以降はすでにある紙パックにぶつからないよう、少しだけ開く
		}
		Off(OUT_B);
		Clear_Sensor();
		go; until(SE_L >= 20);					//きれいに置くため紙パックを少し押す
		Off(OUT_AC);
//紙パックから離れるプログラム//
		OnRev(OUT_C);until(SE_L >= WAIT_TIME_2);			//紙パックを引きずらないようにするために、わずかに左タイヤを後退
		Off(OUT_C);
		back; until(SE_C <= TH);until(SE_C > TH);			//スタートエリアの黒線を越えるまで後退
		until(SE_L >= 70);						//更に少し後退
		if(i != 1){						//1周目以外は、
			until(SE_L >= 20);					  //また更に後退(1周目と角度が違うため、※3で紙パックに当たらない位置まで下げる)
		}
		Clear_Sensor();
		OnFwd(OUT_B); Wait(WAIT_TIME);Off(OUT_B);			//アームを閉じる
		turn_right; until(SE_L >= TURN_2);				//右回転
		Clear_Sensor();
		go;							//積み上げロボットの前まで前進(※2)
		until(SE_L >= line);
		Clear_Sensor();
		turn_right;						//右回転して通信部を合わせる
		if(i == 1){						//1周目と2周目以降で角度が違うため、回転距離が異なる
			until(SE_L >= TURN_2);
		}else{
			until(SE_L >= TURN_1);
		}
		Clear_Sensor();
		turn_right;						//通信中は右回転(※3)
		while(SE_L <= 100){					//1回転半する間、{}内を繰り返す
			SendMessage(11);					  //通信を送り続ける
		}
		Clear_Sensor();
		back; until(SE_C <= TH);until(SE_C > TH);Wait(20);		//黒線を越えるまで後退
	}								//1周終わり
	Off(OUT_AC);						  //すべて終わったら止まる
}

二号機

一号機から通信が送られてきたら、まず1回目は所定の位置にパックが置けるように調整する。
2回目以降は、1号機から通信が送られてきたら、外側に置いたパックを持ち上げ、パックを1回目に置いたパックの上段に置く。

【関数パート】

#define BLACK 43         //光センサの閾値を設定
#define SIGNALON 11               //通信時に送信する数値を設定
#define WAIT_TIME 100             //待ち時間に使う数値を設定
int black =0;                     //黒線を数える時に使用する変数を定義
int step =1;                      //周回数を数える時に使用する変数を定義

【メインパート】

task main()
{SetSensor(SENSOR_1,SENSOR_TOUCH);								//センサー1をタッチセンサと定義
 SetSensor(SENSOR_2,SENSOR_LIGHT);								//センサー2を光センサと定義
 SetSensor(SENSOR_3,SENSOR_TOUCH);								//センサー3をタッチセンサと定義

//待機位置に移動するためのプログラム//
      while(black!=2){									//黒線を2回横切るまで{}内をループ
       if(SENSOR_2 > BLACK){OnRev(OUT_A);until(SENSOR_2 <= BLACK);}				  //白線の上なら黒線まで進める
       if(SENSOR_2 <= BLACK){OnRev(OUT_A);until(SENSOR_2 > BLACK);black++;}			  //黒線の上なら白線まで進めて、blackを+1
        }
      Wait(WAIT_TIME);									//紙パックを置くときにに邪魔にならない位置まで移動
      Off(OUT_A);										//止まる
      black =0;										//blackの値をリセット
//1段目を整えるためのプログラム//
      ClearMessage();									//通信で受信されている数値をリセット
      until ((Message() == SIGNALON)||(SENSOR_3 == 1));					//通信が終わるか、下のタッチセンサが1になる(動作確認用)まで待つ
      PlaySound(SOUND_CLICK);								//通信成功の合図 ピロリロリ〜
      OnRev(OUT_B);									//アームを下げ始める
      OnFwd(OUT_A);until(SENSOR_2 <= BLACK);until(SENSOR_2 > BLACK);until(SENSOR_2 <= BLACK);	//現在の白から、黒→白→黒と判断するまで本体を戻す
      Off(OUT_A);
      until(SENSOR_3 == 1);									//下のタッチセンサまでアームが下がるまで待つ
      Off(OUT_B);
      OnFwd(OUT_C);Wait(50);								//アームを閉じる(紙パックを整える)
      OnRev(OUT_C);Wait(10);								//開く
      Off(OUT_C);
      OnFwd(OUT_B);until(SENSOR_1 == 1);							//上のタッチセンサまでアームを上げる
      Off(OUT_B);
      OnRev(OUT_A);until(SENSOR_2 > BLACK);until(SENSOR_2 <= BLACK);				//現在の黒から、白→黒と判断するまで本体を進める
      Off(OUT_A);
      step++;										//周回数を1つ上げる
//積み上げるためのプログラム//
	while(step<=3)									//2段目と3段目は、同じプログラムをループさせる
	{
       ClearMessage();									//通信で受信されている数値をリセット
       until ((Message() == SIGNALON)||(SENSOR_3 == 1));					//通信が終わるか、下のタッチセンサが1になる(動作確認用)まで待つ
       PlaySound(SOUND_CLICK);								//ピロリロリ〜♪
       while(black!=2)									//黒線を2回横切るまで{}内をループ
         {
        if(SENSOR_2 > BLACK){OnFwd(OUT_A);until(SENSOR_2 <= BLACK);}				  //今度は初期位置の方向に戻す
        if(SENSOR_2 <= BLACK){OnFwd(OUT_A);until(SENSOR_2 > BLACK);black++;}
         }
        until(SENSOR_2 <= BLACK);								//更に黒になるまで本体を進める
        Off(OUT_A);
        black =0;										//blackの値をリセット
       
       OnRev(OUT_B);until(SENSOR_3 == 1);							//アームを下げる
       Off(OUT_B);
       OnFwd(OUT_C);Wait(10);								//アームを閉じる(モーターを止めないで、保持力強化)
       OnFwd(OUT_B);until(SENSOR_1 == 1);							//アームを上げる
       Off(OUT_B); 

       while(black!=2)									//黒線を2回以下略
          {
         if(SENSOR_2 > BLACK){OnRev(OUT_A);until(SENSOR_2 <= BLACK);}				  //待機位置の方向に進める
         if(SENSOR_2 <= BLACK){OnRev(OUT_A);until(SENSOR_2 > BLACK);black++;}
          }
        OnFwd(OUT_A);until(SENSOR_2 <= BLACK);						//更に黒になるまで本体を進める
        Off(OUT_A);
        black =0;

       if(step==2)										//2段目だけ、アームを少し下げる
         {
         OnRev(OUT_B);
         Wait(400);									  //4秒間の時間待ち
         Off(OUT_B);
         }
       OnRev(OUT_C);Wait(10);								//アームを開く(紙パックを離す)
       Off(OUT_C);
       if(step==2)										//2周目の場合は、アームを再び上のタッチセンサまで上げる
        {OnFwd(OUT_B);until(SENSOR_1 == 1);Off(OUT_B);}
       OnRev(OUT_A);until(SENSOR_2 >= BLACK);until(SENSOR_2 < BLACK);				//現在の黒から、白→黒と判断するまで進める
       Off(OUT_A);
       step++;										//周回数を1上げる
       }
      
      OnRev(OUT_A);									//最後にブロックから離れる
      Wait(WAIT_TIME);
      Off(OUT_A);
 }

感想

  • だい
     プログラムはアイデア通りに完成したが、ロボコン本番では1号機が2つ同時に牛乳パックをつかめなかったため、1号機に1つでもつかめるような構造にしたかった。ロボット関連について沢山学ぶことができたので、是非ロボット関連について研究していきたい。
  • ぐっP
     ロボコンまでには多くの時間があったにも関わらず、ロボット本体に時間をかけすぎてしまい、プログラムの微調整などにかける時間が少なくなってしまった。そのまま本番に挑むことになってしまい、思い通りの結果を残せなかったことには悔いが残るし、チームの仲間にも申し訳ないと思った。すみません;だけど、一緒にロボットを作るのはとても楽しかった。ありがとう!
     最後にこの「ロボティクス入門ゼミ」を通して、チームでの作業の協力の大切さや楽しさ、残念ながら一緒にならなかった人とも、発表や対決を通して様々なアイデアに感心したり、競い合う楽しさも実感できました。このような機会を与えてくれた松本先生にはとても感謝しています!と、ゴマをすってみたり…
  • 二宮
     最終課題ということで、これまでの反省点を存分に生かすのが個人的な目標となりました。まず、見込みのない目標に向かわない様にコンセプトを確かなものに。協議を重ね、方法としてはかなり上等なものに成ったと思えます。して、動作も確実にするとはっきりしていればプログラムも書き易かろう、とマシン自体に か な り の時間を割譲。スタートダッシュも早く2週目にはほぼ確定した構想に向けて制作が進みました。ここまでは存分に学習効果を発揮。もうここまでで普通の授業なら単位が貰えそうなものである!(誇張) それでも起こる問題は課題のスケールに伴う、機体の規模によるものばかり…しかし度重なるトラブルにも3人いればなんとやら。一人では即座には解決出来なかっただろう問題も存外早く対処できました。このゼミ、額面以上に教材は道具で 核は別にあるなぁとしみじみ思えました。

コメント

ご意見、ご感想があれば是非コメントをどうぞ↓


このページに来てくれた人 1814 人


添付ファイル: file二号柱先端.jpg 182件 [詳細] filearm_ue.jpg 290件 [詳細] filetactics.gif 299件 [詳細] file1base.JPG 275件 [詳細] file1arm.png 293件 [詳細] filetitle.gif 319件 [詳細] file二号柱先端.JPG 116件 [詳細] file二号柱.JPG 202件 [詳細] file二号base.JPG 188件 [詳細] file2usiro.JPG 292件 [詳細] file2ue.JPG 324件 [詳細] file2sita.JPG 183件 [詳細] file2base.JPG 296件 [詳細] file2arm2.JPG 293件 [詳細] file2all.JPG 280件 [詳細] filecarrier_3.jpg 318件 [詳細] filecarrier_2.jpg 335件 [詳細] filecarrier_1.jpg 284件 [詳細] file完成図.JPG 289件 [詳細] file二号機初期2.JPG 185件 [詳細] file二号機初期.JPG 272件 [詳細] file最初期アーム.JPG 302件 [詳細] fileold6.jpg 292件 [詳細] fileold5.jpg 305件 [詳細] fileold4.jpg 318件 [詳細] fileold3.jpg 217件 [詳細] fileold2.jpg 304件 [詳細] fileold1.jpg 281件 [詳細] fileクレーン予想図.jpg 321件 [詳細] filerobocon2011b.png 375件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2012-02-24 (金) 23:59:41 (2733d)