2017a/Member

Mission3

最後の課題はMission2で使用したコートの各所に画像のように空き缶、または中身の入った缶を配置し、ゴールまで運ぶ競技である。詳しくはこちらにMission3書いてあるので参照願いたい。 2017a-mission3.png

動作の構想について

この競技でどのようにポイントを稼ぐかチーム内で話し合った結果 ^貘罎牢未亮集から整列

構想1.gif

△發Π貘罎そろえた缶を積む

構想2.gif

という動作をさせることで合致した。この構想であればMission2で苦戦したライントレースを行う必要がなく、シンプルな動作でポイントを稼ぐことが出来ると考えた。 しかしながら、RIS同士の通信の赤外線が思ったよりも弱く、結局2台を別々に動かすのではなく、これらの機構を一台のロボットに合体させることになった。

機構説明

機構はおおまかにに缶を集める機構、缶を積む機構に分かれている。

缶を集める機構

アームの機構.gif

画像はアームの駆動部分である。ウォームギアを使うことで多くの空き缶を集めても、止まらないくらいの動力を得ることができ、同時に左右対称な動きも可能にした。 実際にアームを取り付けて動かした画像は下のようになる

缶整理.gif

缶を積む機構

缶を積む機構は缶をつかむハンドと缶の上下をさせる機構に分かれる。

ハンドの機構について

ハンドの機構1.JPG

ハンドの機構もアームの機構同様に、左右対称に動く。缶を持ち上げている際にもモータは駆動し続けるので、クラッチギアを用いることで無理な動作をしないようにした。またタイヤやチューブを付けることで多少の振動があっても缶が倒れないようにした。

上下の機構

上下の機構1.JPG

先端には回転センサーが取り付けてある。時間制御にするとその都度値を調整しなければならない。その大変さはMission1で経験したため、メンテナンスのしやすさも考えたうえでセンサーを取り付けた。しかし空き缶一缶でも、ロボットには重かったようで1段、2段、3段と積むためには回転センサーの値は少しずつ変えなければならなかった。

上下の機構4.JPG
上下の機構2.gif

機構内部は画像のようになっていて強い動力を得るためにウォームギアを用いている。 2枚目の画像のようにギア付きのシャフトを付けて、左側のラックギアと連動させ、上下するようにしている。実際に動かすと3枚目の画像のようになる。

実際の動作

このハンドと上下の機構で3段まで缶を積むことが出来た。

クリックするとyoutubeの動画ページに飛びます。

プログラムについて

プログラミングについては作業の効率を優先したので担当者は一人である。 本体の詳しい説明はKentyさんの方でされているのでこちらを参考にしてほしい。 ロボットの動作は

.蹈椒奪箸魯粥璽訝賄世醗貭樟上になるように置く。
▲蹈椒奪箸アームを開き、円PQRSの淵にくるまで前進をする。(この動作の判断には光センサーを利用している)この動作で地点EGにある空き缶は巻き込まれて回収される。
ここでロボットがアームを閉じると他の空き缶も回収される。またこの時、車体を左右に揺らして空き缶を一列にそろえる。
じ綢爐靴晋紂180度旋回して、ハンド側の準備をする。
ゥ魯鵐匹防佞い討い觚センサーの値を読み取って、空き缶に近づき、回収して3段に積む。
Ε蹈椒奪箸粒始地点はゴールと一直線上なので、前進して空き缶を置けば、得点になる。

缶回収用プログラム

関数と定義

基本的な動作やロボット間で送受信する際に利用する数字をわかりやすく、使いやすくするために定義されている。それぞれの定義の用途はコメント文の通りである。

#define LINE_BLACK 	35					//黒線反応時の光センサ(ライン判定用)の値
#define CAN_SHORT 	46					//缶に接近したときの 光センサ(缶用)の値
#define TURN_TIME	145					//180°反転までの時間
#define APP_TIME	75					//缶接近までの時間
#define ARM_TIME	200					//アームが真横を向くまでの時間
#define FOWORD 		OnFwd(OUT_AC);				//直進 
#define BACK 		OnRev(OUT_AC);				//後退
#define STOP 		Off(OUT_AC);				//停止
#define TURN_LEFT 	OnFwd(OUT_C); OnRev(OUT_A);		//左旋回
#define TURN_RIGHT 	OnFwd(OUT_A); OnRev(OUT_C);		//右旋回
#define ARM_OPEN	OnFwd(OUT_B);				//アーム開
#define ARM_CLOSE	OnRev(OUT_B);				//アーム閉
#define ARM_STOP	Off(OUT_B);				//アーム停止
#define ROGER 		1					//<受信・送信> 【了解】
#define GO_AHEAD	10					//<送信> 【行動開始】
#define MOTION_END	20					//<受信> 【動作完了】

グローバル変数

一つ目は缶がロボットに十分に接近し、ハンド側に動作の開始の信号を送る際に利用する変数で、二つ目は缶を1段、2段、3段と積み上げる際に別の動作をさせるために使用する。

int trans_sign = 0;						//<通信> 送信信号 格納用 
int can_cnt = 0;						//缶 積み上げ本数カウント用

サブルーチン

以下の二つは「値の初期化→受信するまで待機(一つ目のみ)→信号を発信」の動作をサブルーチン化されている。

sub Reception()
{
	ClearMessage();						//<通信> 初期化(最後に受信した値 → 0)
	until(Message() == MOTION_END);				//<通信> 『20【動作完了】』を受信するまで待機
	SendMessage(ROGER);					//<通信> 『1【了解】』を送信
}
sub Transmission()
{
	ClearMessage();						//<通信> 初期化(最後に受信した値 → 0)
	SendMessage(trans_sign);				//<通信> 『"trans_sign"の値』を送信
	until(Message() == ROGER);				//<通信> 『1【了解】』を受信するまで送信し続ける
}

メインタスク

メインタスクについてはコメント文で詳しく説明されているが、kentyさんのページでより詳しく説明されているので参考にして欲しい。

task main()
{
	/*---------- モータパワー・センサ 設定 ----------*/
	SetPower(OUT_AC , 3);
	SetSensor(SENSOR_3 , SENSOR_LIGHT);			//黒線 認識用
	SetSensor(SENSOR_1 , SENSOR_LIGHT);			//缶  認識用
	/*---------- アームを全開 ----------*/
	ARM_CLOSE;						//アーム閉
	Wait(ARM_TIME);						//アームが真横を向くまで閉じる
	ARM_STOP;
	Wait(100);
	/*---------- 缶 回収 ----------*/
	FOWORD;							// アーム側を前方向として
	until(SENSOR_3 < LINE_BLACK);				// 2つ目の黒線まで前進
	until(SENSOR_3 > LINE_BLACK);				//
	until(SENSOR_3 < LINE_BLACK);				//
	STOP;							//停止
	Wait(100);
	ARM_CLOSE;						//アーム閉
	Wait(ARM_TIME + 50);					//アームが平行になるまで閉じる
	ARM_STOP;
	Wait(100);
	BACK;							//  缶を揃えるために
	Wait(50);						//  少し下がる
	STOP;
	ARM_CLOSE;						// アーム閉
	Wait(30);						// 缶を一列にするためにさらに少し閉じる
	ARM_STOP;
	ARM_OPEN;						//  アームを開き、
	Wait(ARM_TIME*2 + 80);					//  スタート時にあった場所まで戻す
	ARM_STOP;
	/*---------- 缶積み上げのための準備 ----------*/
        BACK;							// 後退して、
	until(SENSOR_3 > LINE_BLACK);				// 2つ目の黒線まで前進
	until(SENSOR_3 < LINE_BLACK);				//
	STOP;
       SetPower(OUT_AC , 7);
	TURN_LEFT;						// 右方向へ
	Wait(TURN_TIME);					// 180°旋回
	STOP;
	SetPower(OUT_AC , 3);
	BACK;							// ハンド側を前方向として
	until(SENSOR_1 > CAN_SHORT);				// 缶の手前まで前進
	Wait(20);						// (ここから下は、ハンド方向を前方向とする)
	STOP;
	/*---------- 缶を積み上げ開始 (3回繰り返し、4段にする) ----------*/ 
	while(pile_up_cnt < 3){
		trans_sign = GO_AHEAD;				//<通信> 『10【行動開始】』
		Transmission();					// &#8627;送信
		/* - - - - - - - - - - - - - - - - -*/
		/*   ハンド側が缶の持ち上げを実行   */
		/* - - - - - - - - - - - - - - - - -*/
		Reception();					//<通信> 『20【動作完了】』が送られてくるまで待機
		BACK;						//  缶一つ分だけ(次の缶の手前まで)
		until(SENSOR_1 > CAN_SHORT);			//  前進する
		Wait(20);
		STOP;
		trans_sign = GO_AHEAD;				//<通信> 『10【行動開始】』
		Transmission();					// 
		 /*  ハンドが缶を置き、初期位置に戻る  */
               Reception();					//<通信> 『20【動作完了】』が送られてくるまで待機
               can_cnt++;					//缶の本数 +1
	                      }
}

缶積み上げ用

関数と定義

積み上げ用も缶回収用同様、基本的な動作、メッセージをわかりやすくするため定義されている。

#define HAND_TIME		50			//ハンド開閉 時間
#define ELEVATE_UP		OnFwd(OUT_C);		//<ハンド昇降>上昇
#define ELEVATE_DOWN		OnRev(OUT_C);		//<ハンド昇降>降下
#define ELEVATE_STOP		Off(OUT_C);		//<ハンド昇降>停止
#define HAND_OPEN		OnRev(OUT_B);		//<ハンド開閉>開
#define HAND_CLOSE		OnFwd(OUT_B);		//<ハンド開閉>閉
#define HAND_STOP		Off(OUT_B);		//<ハンド開閉>停止
#define ROGER 			1			//<受信・送信> 【了解】
#define GO_AHEAD		10			//<受信> 【行動開始】
#define MOTION_END		20			//<送信> 【動作完了】

グローバル変数

上2つは缶回収用と同様で、下2つは缶を1段、2段、3段と積んでいく際に異なった動作をさせるために利用する。

int can_cnt = 0;					//積み上げた缶の本数
int trans_sign = 0;					//送信用 信号 格納変数
int hand_flag = 0;					//<ハンド>開閉 判断用
int elevate_flag = 0;					//<ハンド>昇降 判断用

サブルーチン

ハンドを上下させるプログラムである。変数の値でif文が分岐されていて、異なった動作をすることが出来る。

sub Hand_Elevate()
{
	if(elevate_flag == 0){				//ハンド上昇
		ELEVATE_UP;
		until(SENSOR_1 > 385);
		ELEVATE_STOP;
		elevate_flag = 1;			//ハンド上昇終了 次:降下を実行
	}
	else if(elevate_flag == 1){			//ハンド降下(缶をのせる)
		ELEVATE_DOWN;
		until(SENSOR_1 < 360);
		ELEVATE_STOP;
		elevate_flag = 2;			//ハンド降下終了 次:下降を実行
	}
	else if(elevate_flag == 2){			//ハンド初期位置(一番下)へ移動
		ELEVATE_DOWN;
		until(SENSOR_1 < 3);
		ELEVATE_STOP;
		elevate_flag = 0;			//ハンド下降終了 次:上昇を実行
	}
}

一連の動作は「掴む→押さえる→離す」のように行われていく。「hand_flag」の変数の値で行われる動作が変化する。

sub Hand_OC()
{
	if(hand_flag == 0){
		SetPower(OUT_C , 3);
		HAND_CLOSE;
		Wait(100);
		SetPower(OUT_C , 6);		
		hand_flag = 1;				//ハンド閉 次:ハンドを開く
	}
	else{
		HAND_OPEN;
		Wait(HAND_TIME);
		HAND_STOP;
		hand_flag = 0;				//ハンド開 次:ハンドを閉じる
	}
}

以下二つはアーム側と同じ機能である。

sub Reception()
{
	ClearMessage();					//<通信> 初期化(最後に受信した値 → 0)
	until(Message() == GO_AHEAD);			//<通信> 『10【行動開始】』を受信するまで待機
	SendMessage(ROGER);				//<通信> 『1【了解】』を送信
}
sub Transmission()
{
	ClearMessage();					//<通信> 初期化 (最後に受信した値 → 0)
	SendMessage(trans_sign);			//<通信> 『"trans_sign"の値』を送信
	until(Message() == ROGER);			//<通信> 『1【了解】』を受信するまで送信し続ける
}

メインタスク

メインタスクの説明はコメント文で説明されているが、kentyさんのページでより詳しく説明されているので参考にしてほしい。

task main()
{
	/*---------- モータパワー・センサ 設定 ----------*/
	SetSensor(SENSOR_1 , SENSOR_ROTATION);		//回転センサ設定
	ClearSensor(SENSOR_1);				//回転センサ初期化
	/*---------- 缶 積み上げ(3回繰り返し、4段にする)----------*/
	while(can_cnt < 3){
		Reception();				//<通信> 『10【行動開始】』を受信するまで待機
		Hand_OC();				//缶をつかむ
		Hand_Elevate();				//ハンド上昇
		trans_sign = MOTION_END;		//<通信> 『20【動作完了】』
		Transmission();				//送信
		/* - - - - - - - - - - - - - - - - - - -*/
		/*	駆動側が缶の手前まで移動	*/
		/* - - - - - - - - - - - - - - - - - - -*/
		Reception();				//<通信> 『10【行動開始】』を受信するまで待機
		Hand_Elevate();				//ハンド下降
		Hand_OC();				//缶を放す
		Hand_Elevate();				//一番下までハンドを下ろす
		trans_sign = MOTION_END;		//<信号>『20【動作完了】』
		Transmission();				// &#8627;送信
		can_cnt++;				//缶の本数 +1
	}
	Reception();
}

反省

今回のMission3は個々の機構の動作は思い通りに動いたが、いざそれらを一つのロボットにすると、それらをくっつけるブロックが不足したり、コードの長さが足りなかったりした。練習で重い機構を何度も何度も上下するので、電圧によって動作が変化してしまうこともやはりあった。世の中の資源は無限にあるわけでなく、それらを最適な方法で利用していく大切さを今回は学ぶことが出来た。


添付ファイル: file缶3段.png 39件 [詳細] file上下の機構4.JPG 86件 [詳細] file上下の機構2.gif 105件 [詳細] file上下の機構3.JPG 39件 [詳細] file上下の機構1.JPG 81件 [詳細] fileハンドの機構1.JPG 91件 [詳細] file缶整理.gif 85件 [詳細] fileアームの機構.gif 99件 [詳細] file構想2.gif 100件 [詳細] file構想1.gif 74件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-08-13 (日) 21:28:55