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