目次 #contents *Mission2 [#w66b9398] **Mission2の内容 [#pe0192c2] 参照→[[2014a/Mission2]] **ロボットの紹介 [#q44cde01] ロボットはタイヤを動かすためのモーターを二つ、アームを動かすためのモーターが一つ。 ライントレース・紙コップを判断するための光センサーを二つ使用した。 コンピュータ本体は一つでも動かすことが出来るが通信点を取るために二つ使用。 アームのみ通信で動かすようにプログラムを作成した。 アームはつかみ終わると同時に持ち上がる動作へと変わります。 &ref(Mission2 (2).JPG); &ref(Mission2 (1).JPG);&ref(Mission2 (3).JPG); &ref(Mission2 (8).JPG);&ref(Mission2 (9).JPG); **プログラミングの作成 [#e21192d0] ***定数 [#tbe0f4ec] 定数についての説明はMission1参照 #define s1 50 //高速 #define s2 30 //低速 #define OnRL(x,y) OnFwd(OUT_A,x); OnFwd(OUT_C,y); //xに左車輪のスピード,yに右車輪のスピード #define go OnFwdSync(OUT_AC,s2,0); //直進 #define left1 OnRL(-s2,s2); //左旋回 #define left0 OnRL(0,s2); //左折 #define right0 OnRL(s2,0); //右折 #define right1 OnRL(s2,-s2); //右旋回 #define step 1 #define nMAX 300 //nMAXを超えた時交差点と判断する #define short_break Off(OUT_AC); Wait(500); //小休憩 #define cross_line go;Wait(200);short_break; //交差点を渡る #define open 4 //slave機ですることを数字で決めます #define motiageru 1 //上に同じ #define tukamu 2 //上に同じ #define hanasu 3 //上に同じ #define time1 2000 //始めの旋回、ちょうど90°旋回できる時間、要設定 #define part2 15000 //Aを掴んでから1に置くまでの時間、要設定 #define part3 10000 //Aを掴んでから2に置くまでの時間、要設定 #define part4 15000 //Aを掴んでから3に置くまでの時間、要設定 #define song PlaySound(SOUND_CLICK);//音を鳴らす ***黒線をライントレースする [#o2af34f9] これはMission1と内容的に変わりません while(CurrentTick()-t1 <= part2){ //t1がpart2より大きくなるまでライントレースを続ける while (line < nMAX) { // lineがnMAX以上になるまで続ける if (SENSOR_2 < 40) { right1; //40未満だったら右旋回 line = line + 10; //交差点を抜けやすくするためにlineの数値増加を早める } else { if (SENSOR_2 < 45) { right0; //上の条件でなかったら45未満で右折 } else if (SENSOR_2 < 55) { go; //上の条件でなかったら55未満で直進 } else if (SENSOR_2 < 60) { left0; //上の条件でなかったら60未満で左折 } else { left1; //上の条件でなかったら左旋回 } line=0; } Wait(step); } short_break; //小休憩 right1; //右旋回 Wait(200); //0.2秒続ける cross_line; // 交差点を渡る line=0; } ***紙コップをつかむ・持ち上げる・放す [#o21a0424] アームは通信を使ってもう一つのコンピュータから命令を出すようにした。 SendRemoteNumber(サブ機の番号,0,作動させるコマンド); ReceiveRemoteNumber(本機の番号,true,SendRemoteNumberから送られた作動させるコマンドをmoterOnという関数の中に入れます); SendRemoteNumber(1,0,open);//サブ機にアームを開くように送ります SendRemoteNumber(1,0,tukamu);//サブ機にアームを閉じるように送ります SendRemoteNumber(1,0,motiageru);//サブ機に紙コップを持ち上げるように送ります task main() { int moterOn; //moterOnという関数を設置します while(true){ ReceiveRemoteNumber(0,true,moterOn); //本機からサブ機で動かすコマンドを受け取ります /*アームを開けるプログラム*/ if(moterOn == 4){ OnFwd(OUT_B,50); Wait(300); Off(OUT_B); Wait(500); } /*コップを持ち上げるプログラム*/ if(moterOn == 1){ OnRev(OUT_B,30); Wait(1000); Off(OUT_B); int moterOn =0; } /*コップをつかむプログラム*/ else if(moterOn == 2){ OnRev(OUT_B,30); Wait(1000); Off(OUT_B); int moterOn =0; } /*コップを放すプログラム*/ else if(moterOn == 3){ OnFwd(OUT_B,30); Wait(1000); Off(OUT_B); int moterOn = 0; } } } ***紙コップを判断する [#s0c23f1b] 色の判断は白黒の濃度なので光センサーで測ってその数値によってどのルートを通るかを決めます。 Mission2のページにあるA地点を起点として次の紙コップもプログラムされたルートを通っていきます。 int n1 = 0;//n1という関数を設置 int rooot = 0;//roootという関数を設置 /*こっから紙コップの判別に入る*/ while(rooot = 0){ //roootが0の時に作動します if(SENSOR_3 < 42){ rooot = 3;}//センサーが42未満の場合ルート3へ else if(SENSOR_3 < 50){ rooot = 2;}//センサーが50未満の場合ルート2へ else{ rooot = 1;}//それ以外の場合ルート1へ } ルート別のプログラムについては長いので完成したプログラムの本機の下方部を参照してください。 **完成したプログラム [#ha26163d] ***本機 [#y967f064] #define s1 50 #define s2 30 #define OnRL(x,y) OnFwd(OUT_A,x); OnFwd(OUT_C,y); #define go OnFwdSync(OUT_AC,s2,0); #define left1 OnRL(-s2,s2); #define left0 OnRL(0,s2); #define right0 OnRL(s2,0); #define right1 OnRL(s2,-s2); #define step 1 #define nMAX 300 #define short_break Off(OUT_AC); Wait(500); #define cross_line go;Wait(200);short_break; #define open 4 #define motiageru 1 #define tukamu 2 #define hanasu 3 #define time1 2000 #define part2 15000 #define part3 10000 #define part4 15000 #define song PlaySound(SOUND_CLICK); task main() { SetSensorLight(S2); //ライントレースのためのセンサーを設置します SetSensorLight(S3); // go;//直進 Wait(4500);//4.5秒間続ける song;//確認のために音を鳴らします left1;//左に旋回 Wait(time1);//90度回転するまで続ける song; go;//直進 Wait(800);//0.8秒間続ける song; SendRemoteNumber(1,0,open);//サブ機にアームを開くように送ります song; go;//直進 Wait(3000);//3秒間続ける SendRemoteNumber(1,0,tukamu);//サブ機にアームを閉じるように送ります song; int n1 = 0;//n1という関数を設置 int rooot = 0;//roootという関数を設置 /*こっから紙コップの判別に入る*/ while(rooot = 0){ //roootが0の時に作動します if(SENSOR_3 < 42){ rooot = 3;}//センサーが42未満の場合ルート3へ else if(SENSOR_3 < 50){ rooot = 2;}//センサーが50未満の場合ルート2へ else{ rooot = 1;}//それ以外の場合ルート1へ } song; SendRemoteNumber(1,0,motiageru); //子機に送信しアームを稼働し持ち上げる song; go;//直進 Wait(1000);//1秒間続ける left0;//左折 Wait(1000); until(SENSOR_2 <45);//ライントレースするセンサーが45未満になるまで続ける long line = 0;//long lineという関数を設置 long t1 = CurrentTick();//t1という関数を設置 while(rooot = 1){ //roootが1の間ライントレースを続ける while(CurrentTick()-t1 <= part2){ //t1がpart2より大きくなるまでライントレースを続ける while (line < nMAX) { // lineがnMAX以上になるまで続ける if (SENSOR_2 < 40) { right1; //40未満の時右旋回 line = line + 10; //交差点を抜けやすくする } else { if (SENSOR_2 < 45) { right0; //45未満の時右折 } else if (SENSOR_2 < 55) { go; //55未満の時直進 } else if (SENSOR_2 < 60) { left0; //60以下の時左折 } else { left1; //それ以外の時左旋回 } line=0; } Wait(step); } short_break; //小休憩 right1; //右旋回 Wait(200); //0.2秒続ける cross_line; //交差点通過 line=0; } SendRemoteNumber(1,0,hanasu); //サブ機に紙コップを放すプログラムを送る rooot = 0; /*A地点まで戻るためのプログラム*/ OnRev(OUT_AC,50); Wait(500); left1; Wait(time1*2); go; Wait(4000); } /*ルート1のプログラム*/ while(rooot = 2){ while(CurrentTick()-t1 <= part3){ if(SENSOR_2 < 40){ left1;} //40未満の時左旋回 else if(SENSOR_2 < 45){ left0;} //45未満の時左折 else if(SENSOR_2 < 55){ go;} //55未満の時直進 else{ right0;} //それ以外の時は右折 //右旋回はなし、2に向かうには交差点判断も必要ない Wait(step); } SendRemoteNumber(1,0,hanasu); //サブ機に紙コップを放すプログラムを送る rooot = 0; OnRev(OUT_AC,50); //A地点付近まで戻る Wait(500); left1; Wait(time1); go; until(SENSOR_2 < 45); } /*ルート2のプログラム*/ while(rooot = 3){ while(CurrentTick()-t1 <= part4){ if(SENSOR_2 < 40){ right1;} //40未満で右旋回 else if(SENSOR_2 < 45){ right0;} //45未満で右折 else if(SENSOR_2 < 55){ go;} //55未満で直進 else if(SENSOR_2 < 60){ left0;} //60未満で左旋回 else{ left1;} //それ以外左旋回 } SendRemoteNumber(1,0,hanasu); //サブ機に紙コップを放すコマンドを送る rooot = 0; /*A地点まで戻るプログラム*/ OnRev(OUT_AC,50); Wait(500); right1; Wait(time1 + 300); go; Wait(3000); go; until(SENSOR_2 < 45); } //ここから2つ目をつかみにかかる //2枚目のスタート地点に向かう、円軌道に乗ってる途中、右に曲がってスタート地点に行く前に //B地点にショートカットする } ***サブ機 [#a06538bc] task main() { int moterOn; //moterOnという関数を設置します while(true){ ReceiveRemoteNumber(0,true,moterOn); //本機からサブ機で動かすコマンドを受け取ります /*アームを開けるプログラム*/ if(moterOn == 4){ OnFwd(OUT_B,50); Wait(300); Off(OUT_B); Wait(500); } /*コップを持ち上げるプログラム*/ if(moterOn == 1){ OnRev(OUT_B,30); Wait(1000); Off(OUT_B); int moterOn =0; } /*コップをつかむプログラム*/ else if(moterOn == 2){ OnRev(OUT_B,30); Wait(1000); Off(OUT_B); int moterOn =0; } /*コップを放すプログラム*/ else if(moterOn == 3){ OnFwd(OUT_B,30); Wait(1000); Off(OUT_B); int moterOn = 0; } } } **反省と感想 [#l32c7687] 一つ目の紙コップを確実につかむことが出来なければ他の動作に行くことが出来なく、電池の消耗などでモーターの出力が下がり作動距離に誤差が出て正確に作動することが出来なかった。ライントレースも確実に作動できるわけではなかったので光センサーの設置場所、車体の重心をなるべく真ん中にすれば振動によるセンサーの数値の誤差が減ったかもしれない。 結果的にMission2は完全なプログラムを完成することが出来なかったが、この授業でプログラムの基礎を少しだけ学ぶことが出来た。また機械の制度はあまり信用してはならないと思った。