2006a/C2/課題3左
光源を見失っていないときにはある曲を演奏し、見失った時には別の曲を演奏しながら光源を探すプログラム
カウンタ787
プログラム内容†
#define timer 200
//music nomber
#define Do 523
#define Re 587
#define Mi 659
#define Fa 698
#define So 784
#define Ra 880
#define Si 988
#define Do2 1047
#define Do2f 1109
#define Re2 1175
#define Mi2 1319
#define Fa2 1397
#define So2 1568
#define Ra2 1760
int touch;
task music(){ //音楽部分
while(1){
if((SENSOR_1 < touch) && (SENSOR_3 < touch)){ //センサーがともに閾値を下回った時
PlayTone(Ra,5); Wait(10);
PlayTone(So,5); Wait(10);
PlayTone(Do,15); Wait(20);
PlayTone(Do2,5); Wait(20);
PlayTone(Do2,5); Wait(20);
PlayTone(Ra,5); Wait(10);
PlayTone(So,5); Wait(10);
PlayTone(Do,15); Wait(15);
PlayTone(Do2,5); Wait(20);
PlayTone(Do2,5); Wait(20);
PlayTone(Ra,5); Wait(10);
PlayTone(So,5); Wait(10);
PlayTone(Do,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(So,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Ra,15); Wait(20);
PlayTone(Si,5); Wait(20);
PlayTone(Si,5); Wait(20);
PlayTone(Ra,5); Wait(10);
PlayTone(So,5); Wait(10);
PlayTone(Re,15); Wait(20);
PlayTone(Si,5); Wait(20);
PlayTone(Si,5); Wait(20);
PlayTone(Ra,5); Wait(10);
PlayTone(So,5); Wait(10);
PlayTone(Re,15); Wait(20);
PlayTone(Si,5); Wait(20);
PlayTone(Si,5); Wait(20);
PlayTone(Ra,5); Wait(10);
PlayTone(So,5); Wait(10);
PlayTone(Re,15); Wait(20);
PlayTone(Si,15); Wait(20);
PlayTone(Ra,15); Wait(20);
PlayTone(Si,15); Wait(20);
PlayTone(Do2,5); Wait(20);
PlayTone(Do2,5); Wait(20);
PlayTone(Do2,5); Wait(20);
}else if((SENSOR_1 >= touch) || (SENSOR_3 >= touch)){ //センサーのどちらか一方が閾値を超えた時
PlayTone(So,15); Wait(20);
PlayTone(Ra,15); Wait(20);
PlayTone(Si,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Ra,15); Wait(20);
PlayTone(So,15); Wait(20);
PlayTone(Ra,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Ra,15); Wait(20);
PlayTone(So,15); Wait(20);
PlayTone(Ra,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Ra,15); Wait(20);
PlayTone(So,15); Wait(20);
PlayTone(Ra,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Ra,15); Wait(20);
PlayTone(So,15); Wait(20);
PlayTone(Ra,25); Wait(40);
PlayTone(Re2,15); Wait(20);
PlayTone(Re2,15); Wait(20);
PlayTone(Re2,15); Wait(20);
PlayTone(Re2,15); Wait(20);
PlayTone(Re2,15); Wait(20);
PlayTone(Do2f,15); Wait(20);
PlayTone(Do2f,15); Wait(20);
PlayTone(Do2,75); Wait(100);
PlayTone(Mi2,25); Wait(30);
PlayTone(Re2,15); Wait(20);
PlayTone(Fa2,75); Wait(90);
PlayTone(Mi2,15); Wait(20);
PlayTone(Do2,15); Wait(20);
PlayTone(Mi2,15); Wait(20);
PlayTone(Ra,75); Wait(90);
PlayTone(Re2,15); Wait(20);
PlayTone(Si,15); Wait(20);
PlayTone(Ra,15); Wait(20);
PlayTone(So,75); Wait(90);
PlayTone(Re2,15); Wait(20);
PlayTone(Re2,15); Wait(20);
PlayTone(Mi2,15); Wait(20);
PlayTone(So2,75); Wait(90);
PlayTone(Mi2,15); Wait(20);
PlayTone(Ra2,15); Wait(20);
PlayTone(So2,15); Wait(20);
PlayTone(Re2,75); Wait(90);
}
}
}
task main(){
SetSensor(SENSOR_1,SENSOR_LIGHT);
SetSensor(SENSOR_3,SENSOR_LIGHT);
touch = (SENSOR_1 + SENSOR_3) * 3 / 5;
while(1){
if((SENSOR_1 < touch) && (SENSOR_3 < touch)){
if(SENSOR_1 > SENSOR_3){
trun_r();
}else if(SENSOR_1 < SENSOR_3){
trun_l();
}
}else if((SENSOR_1 >= touch) || (SENSOR_3 >= touch)){
straight();
}
}
}
void trun_r(void){
start music;
OnFwd(OUT_C);
OnRev(OUT_A);
until((SENSOR_1 >= touch) || (SENSOR_3 >= touch));
}
void trun_l(void){
start music;
OnFwd(OUT_A);
OnRev(OUT_C);
until((SENSOR_1 >= touch) || (SENSOR_3 >= touch));
}
void straight(void){
start music;
OnFwd(OUT_A+OUT_C);
until((SENSOR_1 < touch) && (SENSOR_3 < touch));
}
プログラム紹介†
- このプログラムは光源を追いかけるときは音楽を流し、光源を見失った時には別の音楽を演奏しながらぐるっと旋回して光源を探すプログラムです。マシンの状態はセンサー二つの時を想定して作りました。曲目光源を追いかけるときは「 ピアノ協奏曲第1番変ロ短調第1楽章」のアレンジバージョンで光源を探しているときは「ねこふんじゃった」です。
- 細かい作りは、光源を見失った時には曲を演奏しながらぐるっと旋回して光源を探すプログラムと全く同じです。
- 最初にプログラムを作成していたときは、各曲は一つ一つのタスクをつくってそこに入れていたのですが、多少ややこしいと感じたため、一つのタスク内にif文で条件式をつくって、条件に合った曲を流すようにしました。また先生の指摘通り、if文の中が長くなってしまっているので、サブルーチンをつくって分割した方がいいかもしれません。
- このプログラムは旋回時だけでなく通常走行時でも音楽を流すプログラムなので、旋回するサブルーチン内だけでなく通常走行をするサブルーチン内でも再生するように設定しています。これは、どの状態から始まるか分からないためにこうなっています。そう考えると、main内のどこかにもうけてサブルーチン内から消せば見やすくなるのかもしれません。ですが、とりあえず今はこの形でうまくいっているので現状維持をしておこうかと思います。また旋回用サブルーチン内ではどちらか一方のセンサーがライトに反応するまで、通常走行用サブルーチン内では両方のセンサーがライトの認識をしなくなった時まで、サブルーチンから抜けないようuntil文で足止めしています。
コメント・感想・アドバイス†
- ifブロックが長くなる時には、中身を別途サブルーチンとして定義することで見やすいプログラムになります。 -- 松本(教員)
- ご指摘ありがとうございます。確かにif文内が長くなっていて、私自身も多少見づらいと感じます。まだ時間があるのでmusicの位置も含めて改善していこうと思います。 -- H・L・ニコ