[[2006a/C2/課題3左]] #hr CENTER:&size(25){光源を見失った時には曲を演奏しながらぐるっと旋回して光源を探すプログラム}; #hr RIGHT:カウンタ&counter; RIGHT:[[ロボティクス入門ゼミ]] RIGHT:[[2006a/C2/課題3左にもどる>2006a/C2/課題3左#g1294642]] --目次 #contents *プログラム全体 [#r5799124] #define Standard_of_light 55 //懐中電灯の光の強さの定義 #define turn_time 200 //一回転にかかる時間 task play_Ride_of_the_Vallyries() { #define vfa3 349*vk //Vallyriesのファ(低) #define vra 440*vk //Vallyriesのラ (低) #define vsi 494*vk //Vallyriesのシ #define vDo 523*vk //Vallyriesのド #define vre 587*vk //Vallyriesのレ #define vmi 659*vk //Vallyriesのミ #define vfa 698*vk //Vallyriesのファ(中) #define vfa2 740*vk //Vallyriesのファ(高) #define vra2 880*vk //Vallyriesのラ (高) #define vn 3 //曲の速さを調節するための数値 #define vt 5 //曲の速さを調節するための数値 #define vk 1 //音の高さを調節するための数値 while(true){ PlayTone(vsi,6*vn);Wait(6*vn+vt); PlayTone(vfa3,2*vn);Wait(2*vn+vt); Wait(vn); //休符 PlayTone(vsi,3*vn);Wait(3*vn+vt); Wait(vn); //休符 PlayTone(vre,12*vn);Wait(12*vn+vt); PlayTone(vsi,12*vn);Wait(12*vn+vt); PlayTone(vre,6*vn);Wait(6*vn+vt); PlayTone(vsi,2*vn);Wait(2*vn+vt); Wait(vn); //休符 PlayTone(vre,3*vn);Wait(3*vn+vt); Wait(vn); //休符 PlayTone(vfa2,12*vn);Wait(12*vn+vt); PlayTone(vre,12*vn);Wait(12*vn+vt); PlayTone(vfa2,6*vn);Wait(6*vn+vt); PlayTone(vre,2*vn);Wait(2*vn+vt); Wait(vn); //休符 PlayTone(vfa2,3*vn);Wait(3*vn+vt); Wait(vn); //休符 PlayTone(vra2,12*vn);Wait(12*vn+vt); PlayTone(vra,12*vn);Wait(12*vn+vt); PlayTone(vre,12*vn);Wait(12*vn+vt); PlayTone(vra,4*vn);Wait(4*vn+vt); Wait(vn*2); //休符 PlayTone(vre,6*vn);Wait(6*vn+vt); Wait(vn*2); //休符 PlayTone(vfa2,24*vn);Wait(24*vn+vt); } } sub follow_light() //光を追う事を命ずるサブルーティン { #define Borderline_S 4 //小さい境界線 #define Borderline_L 20 //大きな境界線 詳しい説明は下記 while((SENSOR_1>Standard_of_light)|| (SENSOR_1>Standard_of_light)) //光センサー1・光センサー3のどちらかに光が当たっている場合 { int d; //dという変数を定義する d=SENSOR_1-SENSOR_3;//dは光センサー1と光センサー3のとる値の差である if((-Borderline_S <= d) && (d <= Borderline_S)) {OnFwd(OUT_A+OUT_C);} //go if((Borderline_S <d) && (d< Borderline_L)) {OnFwd(OUT_C);Float(OUT_A);} //sllowly_turn_right if(( Borderline_L <=d) && (d<= 100)) {OnFwd(OUT_C);OnRev(OUT_A);} //rapidly_turn_rigth if((-Borderline_L <=d) && (d<-Borderline_S)) {OnFwd(OUT_A);Float(OUT_C);} //sllowly_turn_left if((-100 <=d) && (d< -Borderline_L)) {OnFwd(OUT_A);OnRev(OUT_C);} //rapidly_turn_left } } sub look_for_light() //光源を見つけるサブルーティン { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT); int light_max=0; //変数light_maxを定義、0を代入 int time=0; //同じく変数itmeを定義、0を代入 ClearTimer(0); //タイマー(0)をリセット time=FastTimer(0); //timeにFastTimerの値を代入する light_max=SENSOR_1; //light_timeにSENSOR_1の値を代入する start play_Ride_of_the_Vallyries ; //ワルキューレの騎行を演奏開始する while(FastTimer(0)<=turn_time){ //マシンが一回する間、実行し続ける OnFwd(OUT_C);OnRev(OUT_A); //右に回りましょう if(SENSOR_1>light_max) //もし光センサー1の値が光の最大値よりおおきいならば { time=FastTimer(0); //そのときのタイマー(0)の値がtimeとなる light_max=SENSOR_1;} //そのときのセンサー1の値が光の最大値となる } Off(OUT_A+OUT_C); Wait(50); //0,5秒間停止 OnFwd(OUT_A);OnRev(OUT_C); Wait(turn_time-time);左に回転 Off(OUT_A+OUT_C); Wait(50); //0.5秒間停止 } task main() { SetSensor(SENSOR_1,SENSOR_LIGHT);//センサー1が光センサーであることを定義 SetSensor(SENSOR_3,SENSOR_LIGHT);//センサー3が光センサーであることを定義 look_for_light(); //いよいよメインタスクです while(true){ // if((SENSOR_3>Standard_of_light)||(SENSOR_1>Standard_of_light)) {//どちらかのセンサーに光が当たっている場合、 follow_light(); //光を追うサブルーティンを実行 }if((SENSOR_1<Standard_of_light) && (SENSOR_3<Standard_of_light)){//どちらのセンサーにも光が当たっていない場合 look_for_light();//光源を見つけるサブルーティンを実行 stop play_Ride_of_the_Vallyries;}//演奏を中止 } } *プログラムの各部分の事細かな解説 [#w8e83ac0] **演奏部分 [#cab90bb7] -task task play_Ride_of_the_Vallyries() --vn・vk・vtnなどといった数値を変化させることにより簡単に曲の速さ・音の高さを変えることができる。 --vn・vk・vtn・vfa・vdo・vra…などの頭についているvはVallyriesの頭文字です。 [[君が代>2006a/C2/課題3左#kadai3kyokusyoukai]]で用いるドレミと混同することを避けるための処置です。 --int vt(vn); vt(vn)=SENSOR_1/5;などを用いれば、光の強さに応じて曲の速さを変化させることが出来る -- **光を追っかける部分 [#xa89bdd9] -sub follow_light() --旋回速度を2種類用意することで、滑らかにかつどこまでも光を追い続けることが出来る --一見すると、とってもとってもややこしく見えますので、分かりやすくするために、表を作りまとめてみます。 ---dは光センサー1と光センサーのとる値の差 ---dが正の数となるならば、マシンは右に動く ---dが負の数となくならば、マシンは左に動く --Borderline_Sが4でBorderline_Lが20の場合 |>|BGCOLOR(olive):CENTER:&color(white){条件式とその意味};|BGCOLOR(olive):CENTER:&color(white){マシンの行動};| |if( (-Borderline_S <= d) && (d <= Borderline_S) )|差が4以内ならば|左右のタイヤを順回転ささて前進する| |if( (Borderline_S <d) && (d< Borderline_L) )|差が4より高く20未満であるならば|左タイヤを順回転、右タイヤを停止させ右に旋回する| |if( ( Borderline_L <=d) && (d<= 100) ) ))|差が20以上であるならば|左タイヤを順回転、右タイヤを逆回転させ右に急旋回する| |if( (-Borderline_L <=d) && (d<-Borderline_S) ) |差が4より高く20未満であるならば|右タイヤを順回転、左タイヤを停止させ左に旋回する| |if( (-100 <=d) && (d< -Borderline_L) ) |差が20以上であるならば|右タイヤを順回転、左タイヤを逆回転させ左に急旋回する| --int d; d=SENSOR_1-SENSOR_3;をwhile(……)のなかに入れないとうまくマシンが働かない **光源を見つける部分 [#ec95f9ec] -sub look_for_light() --int light_max=0;の部分の=0を抜かしていることになかなか気づくことが出来ず、相当苦労した。=0なしには光を見つけることは出来ない *以上3つをつなげる過程で生じた問題 [#u9872330] -意外と3つのプログラムを上手につなげるのは難しい。 -当初、演奏部分もサブルーティンを用いてつなげようとしたため、演奏が終わるまで次の命令を聞かないといった問題が発生した -task main()のなかのwhile(true)とsub follow_light()の中のwhile(true)の条件を合わせないと、マシンは思うように働いてくれない。 *感想 [#nb7b03b6] -非常に難しい課題でした。 -上記の=0の問題などほんの些細なことで、プログラム全体が狂ってしまいます。とても難しかったです。 -おまけに今週は忙しく作業時間もうまく確保することが出来ませんでした。自宅でも作業が出来るように、myPCにbricx command centerをインストールしました。 -期限の前日は午前3時まで、作業をしてました。 ***プログラム・レポートの書き方に関するコメント [#l068f03b] ---------- #comment -------- RIGHT:[[ロボティクス入門ゼミ]] RIGHT:[[2006a/C2/課題3左にもどる>2006a/C2/課題3左#g1294642]]