[[2005/C4/課題1左]]
*「左」を書くロボット [#ue7b7ece]
-ロボットの写真

~ #ref(051104_1935~001.jpg)
~ &ref(051104_1935~001.jpg);

~ #ref(051104_1936~001.jpg)
~ &ref(051104_1936~001.jpg);

-説明

~ 機械の構成:紙に接するタイヤ2個、地面に接するタイヤ1個、ペンを持つアーム、アームを上下させるモーター

~役割:紙に接するタイヤは、それを回転させることによって紙を前後に動かす役割がある。それにあたって、地面に接するタイヤは本体を地面に対して固定するのに必要である。

~ペンを持つアームは、紙が動く向きに対し垂直の方向に動くようになっている。アームの動きに伴い、アームに固定されたペンの位置が動くようになっている。
このように、紙を動かすこととペンの位置を動かすことで、ペンの位置を(限られた範囲内で)自由に変えることができる。

~プログラムの特徴:ペンの位置を任意の方向に動かすためにvoid run()関数を使用する。二つのカウンタを用いて、アームの動きと紙の動きの移動量を調整する。アームと紙の動きに携わるモーターを、ある方向に回転させている状態と止まっている状態を、それぞれある頻度で繰り返すことで、結果的にペンの位置を任意の方向に動かせるようになっている。

~メインルーチン:void run()とsub penon()、sub penoff()を使って、ペンの位置とペンの上下をコントロールし、漢字を描画する。

~プログラムの使われていない関数・サブルーチンについて:void line()関数は、引数に二つの座標を与えるものである。この座標は関数内でペンの位置として解釈され、最初の座標から二番目の座標までの直線を紙に描く働きを持つ。

~毎回、直線を書くたびに原点に戻るなど、冗長な操作を繰り返すため、また、漢字の一角を書くたびに呼び出されるため、コンパイルし送信しようとしてもメモリに入りきらなくなる。そのためこの関数は使用をしないこととした。

~sub errorcorrection()は、void line()から呼び出されるサブルーチンである。void line()で直線を書いた後にペンは原点に戻るが、そのときに少し位置がずれるので、それを修正する。

~これらの使われていない関数・サブルーチンは使われていないので本来はソースコードから削除するべきなのだろうが、折角書いたのに消すのはもったいないように感じたので敢えて残した。残しておいても動作に悪影響はない。

-製作
~ 機械作成:ひろし & あすか
~ プログラム作成:ひろし

-ロボットのソースコード。
~いくつか使われていない関数・サブルーチンが残ったままで
メンテナンスされていない。

 #define ARM OUT_A
 #define TIRE OUT_B
 #define PEN OUT_C
 
 #define SIZE 3
 //  SIZE ... tweak rendering size
 
 int penstat=0; // penstat ... remember pen status
 
 // task main ... write the letter "左"
 task main(){
 	Wait(200);
 	
 	// ready for 1st line
 	penoff();
 	run(-1,1,5,1,3*SIZE);
 	
 	// write the 1st line
 	penon();
 	run(0,-1,0,1,4*SIZE);
 	
 	// ready for 2nd line
 	penoff();
 	run(1,1,7,1,2*SIZE);
 	
 	// write the 2nd line
 	penon();
 	run(-1,1,1,6,3*SIZE);
 	
 	// ready for 3rd line
 	penoff();
 	run(1,-1,2,7,2*SIZE);
 	
 	// write the 3rd line
 	penon();
 	run(0,-1,0,1,3*SIZE);
 	
 	// ready for 4th line
 	penoff();
 	run(0,1,0,3,3*SIZE);
 	
 	// write the 4th line
 	penon();
 	run(-1,0,2,0,2*SIZE);
 	
 	// ready for 5th line
 	penoff();
 	run(0,1,0,3,2*SIZE);
 	
 	// write the 5th line
 	penon();
 	run(0,-1,0,1,3*SIZE);
 	
 	// go gack to first position
 	penoff();
 	run(1,-1,3,8,5*SIZE);
 	
 	//////////////////////////
 	//// call void line() ////
 	//////////////////////////
 	//line(3,30,30,30);
 	//line(3,10,13,40);
 	//line(10,22,27,22);
 	//line(17,22,17,9);
 	//line(10,9,30,9);
 	
 	penoff();
 }
 
 // sub penon ... enable the pen
 sub penon(){
 	if(penstat!=1){
 		//Write
 		SetPower(PEN,3);
 		OnFwd(PEN);
 		Wait(20);
 		Float(PEN);
 		penstat=1;
 		Wait(50);
 	}
 }
 
 // sub penoff ... disable the pen
 sub penoff(){
 	if(penstat!=0){
 		//Dont Write
 		SetPower(PEN,4);
 		OnRev(PEN);
 		Wait(10);
 		Float(PEN);
 		penstat=0;
 		Wait(50);
 	}
 } 
 
 // void run ... move arm and tire
 //
 // int mvarm ... mvarm<0 -- OnFwd(ARM)
 //               mvarm==0 -- do nothing(ARM)
 //               mvarm>0 -- OnRev(ARM)
 //
 // int mvtire ... mvtire<0 -- OnFwd(TIRE)
 //                mvtire==0 -- do nothing(TIRE)
 //                mvtire>0 -- OnRev(TIRE)
 //
 // int armspeed ... tweak arm speed
 //                  1 -- move the arm without wait
 //                  over 1 -- move the arm much slower
 //
 // int tirespeed ... tweak arm tire
 //                  1 -- move the tire without wait
 //                  over 1 -- move the tire much slower
 //
 // int t ... set duration of movement
 void run(int mvarm,int mvtire,int armspeed,int tirespeed,int  t){
 	SetPower(ARM+TIRE,3);
 	int c1=0,c2=0;
 	int i;
 	//c1=0;
 	//c2=0;
 	
 	Off(ARM+TIRE);
 	for(i=0;i<t;i++){
 		if(mvarm!=0){
 			if(c1==0){
 				if(mvarm<0){
 					OnFwd(ARM);
 				}else{
 					OnRev(ARM);
 				}
 			}else if(c1==1){
 				Float(ARM);
 				
 			}
 			c1=(c1+1)%armspeed;
 		}
 		if(mvtire!=0){
 			if(c2==0){
 				if(mvtire<0){
 					OnFwd(TIRE);
 				}else{
 					OnRev(TIRE);
 				}
 			}else if(c2==1){
 				Float(TIRE);
 				
 			}
 			c2=(c2+1)%tirespeed;
 			
 		}
 		
 		//Wait(1);
 		
 	}
 	Off(ARM+TIRE);
 	Wait(100);
 }
 
 ///////////////////////////////////////
 ////  following lines are obsolete ////
 ///////////////////////////////////////
 #define C_MOTER_ARM 1
 #define C_MOTER_TIRE 3
 
 void line(int x1,int y1,int x2,int y2){
 	penoff();
 	move(x1,y1);
 	penon();
 	move(x2-x1,y2-y1);
 	penoff();
 	move(-x2+x1,-y2+y1);
 	move(-x1,-y1);
 	//move(-x2,-y2);
 	
 	errorcorrection();
 	
 }
 
 sub errorcorrection(){
 	SetPower(ARM+TIRE,1);
 	
 	OnFwd(ARM);
 	Wait(5);
 	Off(ARM);
 	
 	OnRev(TIRE);
 	Wait(1);
 	Off(TIRE);
 	
 	Wait(50);
 }
 
 void move(int x,int y){
 	//swap x and y
 	//swap y's plus and minus
 	int xm,ym;
 	int xm2=1,ym2=1;
 	int ms;
 	
 	if(x==0){
 		xm=0;
 	}else{
 		xm=1;
 	}
 	if(y==0){
 		ym=0;
 	}else{
 		ym=1;
 	}
 	if(x<0){
 		xm*=-1;
 	}
 	if(y<0){
 		ym*=-1;
 	}
 	
 	if(xm==0 && ym==0){
 		return;
 		
 	}else if(x*xm>y*ym){
 		//yokonaga
 		ms=x*xm;
 		ym2=x*xm;
 		if(ym!=0){
 			xm2=y*ym;
 		}
 		
 	}else{
 		//tatenaga
 		ms=y*ym;
 		xm2=y*ym;
 		if(xm!=0){
 			ym2=x*xm;
 		}
 	}
 	run(-ym,xm,C_MOTER_ARM*ym2,C_MOTER_TIRE*xm2,ms/SIZE);
 	
 }

-関数の引数や変数の役割などは、コメント文で説明しておきましょう。 -- [[松本(教員)]] &new{2005-12-01 (木) 09:46:06};
-おしい!!説明分は大変丁寧でよいのですが、肝心のプログラムが分かりにくいです。コメントを加えるだけでなく、(消すのが惜しいのならば)別途に必要な部分のみを抜き出したプログラムを載せると良いのでは? -- [[かとりーぬ(TA)]] &new{2005-12-02 (金) 19:05:47};

#comment

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS