#contents
[[2013b/Member/dyuma/Mission2]]

*注意 [#vcc93610]
※コンパイルは通っていますが、実機で動かしたわけではありません。~
うまく動く保証はどこにもありません。~
[[michaegonのプログラム>2013b/Member/michaegon/Mission2]]のほうがよほどいいです。

*プログラム [#tb1ebc02]
**メインマシンのプログラム [#u493d425]

 #define sikiiti 50
 #define BMAX 500
 #define go_left OnFwd(OUT_C,30);OnFwd(OUT_B,-20);
 #define go_right OnFwd(OUT_C,-20);OnFwd(OUT_B,30);
 #define go_straight OnFwd(OUT_BC,15);
 #define turn_right OnFwd(OUT_C,-10);OnFwd(OUT_B,10);
 #define turn_left OnFwd(OUT_C,10);OnFwd(OUT_B,-10);
 #define back_left OnFwd(OUT_C,-30);OnFwd(OUT_B,20);
 #define back_right OnFwd(OUT_C,20);OnFwd(OUT_B,-30);
 #define back_straight OnFwd(OUT_BC,-15);
 #define STOP Off(OUT_BC);Wait(1000);
 #define P 10
 #define MODOSHITIME 300
 #define TEST 11
 #define CONNx 5
 #define CONNy 1
 #define MODOSHITIME 300
 #define KICK 12
 #define FINISH 13
 #define KANOKI 14
 
大量にdefineされていますけど、上半分程は僕がnxcプログラムを書くときにテンプレとして置いているものなので、使わなかったものも多いです。~
いちいち定義を書かずとも、ある程度は指定できるのがいいです。~
 int count[3]={0,0,0};
今回はカウンターは配列形式にしています。~
白ければcount[0]を+1、黒ければcount[1]を+1、交差点と判定されればcount[2]を+1します。
 void TSUSHIN(int x){
	int msg1=0;
	STOP;
	SendRemoteNumber(CONNx,MAILBOX1,x);
	while(msg1==0){
		ReceiveRemoteNumber(MAILBOX1,true,msg1);
		Wait(1);
	}
 }
通信用のプログラムを別に置いています。~
こうすることで、いちいちややこしい送信文、受信文を書かなくてもいいようにしました。
 void START(){
	TSUSHIN(TEST);
	while(SENSOR_1>sikiiti){
		go_straight;
	}
	while(SENSOR_1<sikiiti){
		turn_right;
	}
 }
スタート時の動作です。~
通信テストを行い、ライントレースに行くまでの動作が書かれています。
 int iscan(){
	if(SENSOR_2<15){
                  return 1;
 }else{
                  return 0;
 }
 }
缶があれば1を、なければ0を返す関数です。
 void kick(){
	while(SENSOR_2>10){
		go_straight;
	}
	TSUSHIN(KICK);
 }
もし缶があれば、近づいた上で、キックしろという命令を送ります。


 void LAPfinish(){
	back_straight;
	Wait(500);
	TSUSHIN(KANOKI);
	int msg1=0;
	while(msg1==0){
		ReceiveRemoteNumber(MAILBOX1,true,msg1);
		Wait(1);
	}
	back_straight;
	Wait(2000);
 }
各LAPの終了行動、つまり缶を立てる時の動作が書かれています。
 void line_trace(int t){
	int MEIDO=SENSOR_1-sikiiti;
	if(t==3||t==4){
		OnFwd(OUT_C,P+MEIDO);OnFwd(OUT_B,P-MEIDO);
	}else{
		OnFwd(OUT_C,P-MEIDO);OnFwd(OUT_B,P+MEIDO);
	}
	if(0<MEIDO){
		count[0]=0;
		count[1]++;
	}else{
		count[0]++;
		count[1]=0;
	}
	if(count[0]>50){
		count[0]=0;
		count[1]=0;
		count[2]++;
		if(t==1){
			turn_left;
			Wait(MODOSHITIME);
			go_straight;
			Wait(2000);
		}else if(t==2){
			turn_left;
			Wait(2000);
		}
	}
 }
ライントレースについて書かれています。~
ここでは光センサーの値により、各モーターをどの速度で回すか指定しています。~
課題1のような二段階、さらには6段階などより、格段に多くの段階になっています。~
もしうまくいかなければ、課題1が終わったあとで書いた6段階、それでもうまく行かなければ課題1のときの二段階のライントレースに差し替えることもできます。
 void LAP(int x){
	if(x==1){
		while(SENSOR_1<sikiiti){
			turn_right;
		}
		count[2]=0;
		while(count[2]<7){
			line_trace(1);
			if(iscan()==1){
				kick();
			}
		}
		do{
			Wait(200);
			go_straight;
		}while(SENSOR_1>sikiiti);
		LAPfinish();
		while(SENSOR_1>sikiiti){
			go_left;
		}
	}else if(x==2){
		count[2]=0;
		while(count[2]<3){
			line_trace(0);
			if(iscan()==1){
				kick();
			}
		}
		while(count[2]<7){
			line_trace(1);
			if(iscan()==1){
				kick();
			}
		}
		while(count[2]<9){
			line_trace(0);
			if(iscan()==1){
				kick();
			}
		}
		LAPfinish();
		while(SENSOR_1>sikiiti){
			go_right;
		}
	}
 }	
非常にめんどくさく書かれていますが、通過した交差点の数でいまどこにいるかを把握し、それに対応した行動を行っていくプログラムです。~
もしこのプログラムを調整することがあるならば、最も調整が必要と思われる部分の一つです。
 void LAST_ACTION(){
	go_straight;
	Wait(5000);
	STOP;
	TSUSHIN(FINISH);
 }
最終行動が書かれています。
 task main(){
	SetSensorLight(S1);
	SetSensorLowspeed(S2);
	START();
	LAP(1);
	LAP(2);
	LAST_ACTION();
 }		
メインは簡潔にかかれています。~
たったこれだけです。~

**サブ機のプログラム [#w53019be]

 #define turn_left OnFwd(OUT_C,10);OnFwd(OUT_B,-10);
 #define back_left OnFwd(OUT_C,-30);OnFwd(OUT_B,20);
 #define back_right OnFwd(OUT_C,20);OnFwd(OUT_B,-30);
 #define back_straight OnFwd(OUT_CB,-15);
 #define STOP Off(OUT_BC);Wait(1000);
 #define P 10
 #define MODOSHITIME 300
 #define TEST 11
 #define CONNx 5
 #define CONNy 1
 #define MODOSHITIME 300
 #define KICK 12
 #define FINISH 13
 #define KANOKI 14
defineはメインと変わってません。
 inline void SHIME(){
 
 }
 
 inline void TATE(){
 
 }
 
 inline void HANASU(){
 
 }
この辺はまだ空白です。~
SHIMEで「閉めて」、TATEで「立てて」、HANASUで「離し」ます。~
最終的には消す予定ではありました、というのは同じものをmichaegonが書いていましたので。
 inline void CANOKI(){
	SHIME();
	TATE();
	HANASU();
 }
わかりやすいようにこう書いてはいますが、michaegonのプログラムをそのまま持ってくる、うまく行かなければその場で合ったものを書く予定でした。~
 inline void OTO(){
 	
 }
 
 inline void KERI(){
 
 }
最後の行動が終了した時の音をだすOTO「音」と、缶を叩き込むKERI「蹴り」をここで書く予定でした。~
michaegonのプログラムをそのまま持ってくるなり、その場で書くなりする予定でした。
 task main(){
	while(true){
		int msg1=0;
		while(msg1==0){
			ReceiveRemoteNumber(MAILBOX1,true,msg1);
			Wait(1);
		}
		if(msg1==TEST){
			SendRemoteNumber(CONNy,MAILBOX1,TEST);
		}else if(msg1==KICK){
			KERI();
			SendRemoteNumber(CONNy,MAILBOX1,KICK);
		}else if(msg1==FINISH){
			OTO();
			break;
		}else if(msg1==KANOKI){
			CANOKI();
			SendRemoteNumber(CONNy,MAILBOX1,KANOKI);
		}
	}
 }
メインのプログラムは、通信された時にどう返すかのみ書かれています。~
それ以外は必要ありませんので。

*最後に [#ta279b59]

結果的に使われることのなかったプログラムですが、メインの方はそこそこ上手く書けていると思います。~
サブの方は空白も多く、実際に機体を見ながら、試しながら書く前提で書いたので、こんな感じになっています。~
まだまだ直すべき点は多いと思います。~
今後の課題にしたいです。



トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS