2005/C4/課題1左

「左」を書くロボット

  • ロボットの写真

051104_1935~001.jpg

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


添付ファイル: file051104_1936~001.jpg 175件 [詳細] file051104_1935~001.jpg 168件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2006-02-09 (木) 16:31:38