ロボティクス入門ゼミ  

課題 似顔絵

A4の紙に相棒の似顔絵を書くロボットを作成せよ。
・ひとりにつき一つ以上のプログラムを作成すること。
・ペン以外はキットに含まれる部品を使うこと。
・A4の紙はセロテープ等で固定しないこと
・キットに付属の高価な輪ゴムは切れやすいので切れないように細心の注意を払うこと。
・改良や調整をしやすくするため、ロボット本体だけでなく、プログラムについても可能な部分についてはサブルーチンや関数、マクロなどを使って部品に分けること。

製作過程

h24/5/4〜5/18 2012a/A5/ITY/M1/photo

CIMG1532.JPG

・モータ2個で左右のタイヤを動かし、キャスターとの3点で走行し、モータ1個でペンの上下、光センサ1個を使用。

車体部分

ペンの上下の部分

CIMG1504.JPG
CIMG1544.JPG

・ペンの上下の部分は細いタイヤを回転させ、上下にペンを動かすことが可能かつ、しっかりと保持できる。
また、タイヤとタイヤの間隔を変えることによって、いろいろな大きさ(幅)に対応可能。

工夫したところ


・車軸上にペンを置くことによって、移動距離が少なくてすむようにした。
・また、ガイドを作りペンが垂直に降りて、紙にしっかりとかけるようにした。 旋回の中心にペンを置かないと、下の図のように旋回するだけでペンの位置がずれてしまう

robo1_q.png
robo1_qa.png
CIMG1506.JPG

なので、旋回に中心にペンが来るように設計した。

CIMG1501.JPG

また、ペンを上下させるときにペンがぶれてしまうことがあったので、ガイドを製作した。

CIMG1543.JPG


・先に光センサをつけて、センサが紙から外れたら、回転するようにした。
・タッチセンサを2個使いペンの上下を調整できるようにした。

結果

CIMG1565.JPG

回転する時にタイヤが外側にはみ出してしまい、うまく描写することができなかった。

CIMG1551.JPG

本来ならこの様に書く予定だった。
・光センサセンサの値が紙や場所によって変化してうかくいかなかったので、断念した
・ペンを紙に強く押し付けてしまい左右の設置バランスが崩れたりとプログラムが全然詰めきることができていなかった。

プログラム

/*		2012/5/18 ITY					*/
/*		2012a_robo_kadai1		face-8-7	*/
/*----------------------------------------------------------------------------------
				別名定義
----------------------------------------------------------------------------------*/
#define MOVE_TIME	1500							// 前後に必要な時間
#define TURN_TIME	330     						// 旋回に必要な時間
#define PWM 		100							// PWM(力の大きさ)
#define PAI 		3							// 円周率3.14 300 200
#define D		50							// タイヤの直径
#define ON 		1							// オン
#define OFF		0							// オフ
#define A_UP 	15								// 上げるときの高さ
#define A_DOWN	15								// 下げるときの高さ
#define TRUN_AC	320             					  // 90度の回転角度 
/*----------------------------------------------------------------------------------
				関数宣言
----------------------------------------------------------------------------------*/
void ARM_UP();									// ペンを上げる
void ARM_DOWN();									// ペンを下げる
void MODULATE();									// ぺんの調整
void TURN_R();									// 90度ターン
void LCD();										// LCDにモデルを描写

/*----------------------------------------------------------------------------------
				グローバル変数
----------------------------------------------------------------------------------*/
int s1_touch,s2_touch;								//タッチセンサ

/*----------------------------------------------------------------------------------
				メインルーチン
----------------------------------------------------------------------------------*/
task main()
{
   SetSensorLight(IN_4);									//アナログセンサの宣言
   SetSensorTouch(IN_3);									//タッチセンサの宣言
   SetSensorTouch(IN_1);									//タッチセンサの宣言
   int i,j,p,n,num,s_ligh;								//変数宣言
   i=0,p=0,num=1,s_ligh=0;								//変数の初期化
	s1_touch = Sensor(IN_3);							//タッチセンサの値を取得
	s2_touch = Sensor(IN_1);							//タッチセンサの値を取得
	if((s1_touch == ON) || (s2_touch == ON)){					//スイッチ1か2が押されているとき
		MODULATE();									//ペンの上下調整
	}
	else{											//スイッチ1と2が押されていないとき
	Wait(100);
	while(true){
		s_ligh = Sensor(IN_4);							//アナログセンサの値を代入
		NumOut(10,60,s_ligh,0);							//LCDにセンサの値を表示
		ResetScreen();								//LCDの表示の初期化
		NumOut(10,60,num,0);							//LCDにセンサの値を表示
		switch(num){	
			case 1:								//輪郭を書く
				for(i=0;i<4;i++){
					ARM_DOWN();						//ペンを下げる		
					RotateMotor(OUT_AC,40,180);			//左右ACのモータを正転
					ARM_UP();						//ペンを上げる
					TURN_R();
				}
			break;
			case 2:
					RotateMotor(OUT_AC,40,40);			//左右ACのモータを正転
					TURN_R();						//90度回転
			break;
			case 3:
					RotateMotor(OUT_AC,40,40);			//左右ACのモータを正転
					ARM_DOWN();						//ペンを下げる	
					RotateMotor(OUT_AC,40,40);			//左右ACのモータを正転
			break;
			case 4:
					ARM_UP();						//ペンを上げる		
					RotateMotor(OUT_AC,40,40);			//左右ACのモータを正転	
			break;
			case 5:
					ARM_DOWN();						//ペンを下げる		
					RotateMotor(OUT_AC,40,40);			//左右ACのモータを正転
			break;
			case 6:
					ARM_UP();						//ペンを上げる	
					TURN_R();						//90度回転
					TURN_R();						//90度回転
					RotateMotor(OUT_C,40,40);				//左右ACのモータを正転	
					TURN_R();						//90度回転
					RotateMotor(OUT_AC,40,40);			//左右ACのモータを正転
					ARM_DOWN();						//ペンを下げる	
					RotateMotor(OUT_AC,40,40);			//左右ACのモータを正転	
			break;
			case 7:
					ARM_UP();						//ペンを上げる
					RotateMotor(OUT_A,40,40);				//左右ACのモータを正転
					TURN_R();						//90度回転
					ARM_DOWN();						//ペンを下げる	
					RotateMotor(OUT_AC,40,40);			//左右ACのモータを正転	
			break;
			default:
		}
//		PlayTone(4000,20);								//音を鳴らす
		num++;										//次の処理に移る
	}
	}
}
/*----------------------------------------------------------------------------------
				サブルーチン
----------------------------------------------------------------------------------*/
void ARM_UP()										//ペンを上げる
{
	RotateMotor(OUT_B,50,-A_UP);
//	PlaySound(1);									//ビープ音
}
void ARM_DOWN()										//ペンを下げる
{
	RotateMotor(OUT_B,50,A_DOWN);							//モータBを回転
	Off(OUT_B);										//ペンの固定
//	PlaySound(2);									//ビープ音
}
void TURN_R()										//90度ターン
{
	int tako_a=0,tako_c=0;								//変数宣言
	ResetScreen();									//LCDの初期化
	OnFwdSyncEx(OUT_AC,40,-100,RESET_NONE);					//左右ACのモータを回す
	while((tako_a < TRUN_AC) && (tako_c < TRUN_AC)){				//90度回転していないとき
		tako_a = abs(MotorTachoCount(OUT_A));					//タコメータからモータAの値を取得
		tako_c = abs(MotorTachoCount(OUT_C));					//タコメータからモータBの値を取得
		NumOut(10,48,tako_a,0);							//LCDにタコメータ(A)の値を表示
		NumOut(10,40,tako_c,0);							//LCDにタコメータ(A)の値を表示
	}
	Off(OUT_AC);										//モータの停止
}
void MODULATE()										//ペンの調整用
{
    int t_count;	
    s1_touch=0,s2_touch=0,t_count=0;							//変数宣言
	while(true){										//変数の初期化
	s1_touch = Sensor(IN_3);								//タッチセンサの値を取得
	s2_touch = Sensor(IN_1);								//タッチセンサの値を取得
	NumOut(10,60,s1_touch,0);								//LCDにセンサの値を表示
	NumOut(10,40,s2_touch,0);								//LCDにセンサの値を表示
		if((s1_touch == OFF) && (s2_touch == OFF)){				//スイッチ1と2が押されていないとき
			t_count = 0;								//カウンタの初期化
			Off(OUT_B);								//モータの停止
		}
		else if((s1_touch == ON) || (s2_touch == ON)){			//スイッチ1か2が押されているとき
			if(t_count < 100){							//0.1秒間押されているか判定
				t_count++;							//カウンタをまわす
			}
			else{
				if((s1_touch == ON) && (s2_touch == ON)){		//スイッチ1と2が押されているとき
					RotateMotor(OUT_B, 50,-14);			//ペンを上げる
					Off(OUT_B);						//ペンの固定
					while(true){						//調整の終了
						LCD();						//
						ResetScreen();				//LCDの表示の初期化
					}
				}
				else if(s1_touch == ON){				//スイッチ1が押されているとき
					OnFwd(OUT_B,20);					//ペンを上げる
				}
				else if(s2_touch == ON){				//スイッチ2が押されているとき
					OnRev(OUT_B,20);					//ペンを下げる
				}
				else Wait(100);						//それ以外の時、待つ
			}
		}
	}
}
void LCD()										//LCDにイメージを描写
{	
	TextOut(10,60,"kadai1 face",0);							//文字の表示
	Wait(1000);
	ResetScreen();									//画面の初期化
	LineOut(30,50,70,50,0);
	Wait(200);
	LineOut(70,50,70,10,0);
	Wait(200);
	LineOut(70,10,30,10,0);
	Wait(200);
	LineOut(30,10,30,50,0);
	Wait(200);
	LineOut(30,31,34,35,0);
	Wait(200);
	CircleOut(40,35,6,0);
	Wait(200);
	LineOut(46,35,54,35,0);
	Wait(200);
	CircleOut(60,35,6,0);
	Wait(200);
	LineOut(66,35,70,35,0);
	Wait(200);
	LineOut(50,30,50,24,0);
	Wait(200);
	LineOut(50,24,55,24,0);
	Wait(200);
	LineOut(45,15,55,15,0);
	Wait(2000);
}

工夫したところ


・電池によって、走行距離や、スピードが変わってしまうことがあったので、タコメータの値を取得して、モータを制御した。
・音を鳴らすようにして、今どこまでプログラムが動いているか分かるようにした。
・LCDに値を表示させ、プログラムの変数の値を確認しやすくした。
・動かす前に、ペンの調整モードを作った。

反省・感想


・ペンを車軸上に置いた事はよかったが、裏のキャスターに重心が掛かりすぎてしまったために紙を巻き込んでしまった。また車体の重心が高いために走行時にぶらついて、旋回時に片側だけに負荷が加わってしまった。紙が動いてしまうということをもう少し考えて、ロボットの設計とプログラムをしたい。


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2012-05-29 (火) 05:05:10