[[2016a/Member]]
#contents
*課題内容 [#kdf48eac]
合わせて3つあるコースのうち、それぞれ指定されたコースを辿りゴールを目指すロボットを作る。~
---------------------------------------------------------------------------
>&size(20){コース概要}; 線の幅は2cm~
&ref(./課題2 .png,75%,コース);
>>��A地点からB地点へ
>>>A地点 → P直進 → Q直進 → Q直進 → R左折 → B地点
>>��B地点からC地点へ
>>>B地点 → R右折 → Q直進 → Q直進 →P右折 → S右折 → C地点
>>��C地点からA地点へ
>>>C地点 → S左折 → P左折 → Q直進 → Q直進 → R右折 → P左折 → A地点~
---------------------------------------------------------------------------
なお今回私が作るのは、�,鯀�るロボットである。
*機体の解説 [#d242f102]
これが今回作ったロボットである。無駄なものをつけず、コンパクトなものを目指した。~
&ref(./zennkei.jpg,30%,全体);~
#br
センサーはあえて固定せず、メンバーそれぞれが自分のプログラムに合わせて位置を調整できるようにした。また車輪は先生からのアドバイスで、より薄いものへ交換した。~
&ref(./sennsar.jpg,30%,センサー部&車輪);~
後ろは摩擦を減らすため、課題1と同様に半球状のパーツを用いた。~
&ref(./usiro.jpg,30%,後ろ);
*プログラムの解説 [#ob8d85c2]
今回は音楽を鳴らしつつ、線を辿れるようにした。~
以下、プログラムの解説となる。~
~~
後ほど登場するMUSIC_OPERATION()の音符の長さと、音の高さを定義。
#define b8 25 //8分音符
#define b16 b8/2 //16分音符
#define b12 b8*3/2 //12分音符
#define b6 b8*3 //6分音符
#define b4 b8*2 //4分音符
#define b2 b8*4 //2分音符
#define Do 523 //ド
#define re 587 //レ
#define mib 622 //ミのフラット
#define mi 659 //ミ
#define fa 698 //ファ
#define fas 740 //ファのシャープ
#define so 784 //ソ
#define ra 880 //ラ
#define si 988 //シ
#define Doh Do*2 //高いド
#define reh re*2 //高いレ
#define mih mi*2 //高いミ
#define fah fa*2 //高いファ
#define soh so*2 //高いソ
#define rah ra*2 //高いラ
以下がメインのプログラム。
#define Middle 46
task main()
{
SetSensor(SENSOR_2,SENSOR_LIGHT);
STARTING_OPERATION(); //音楽を鳴らしつつ、初めの四角から脱出するプログラム。
repeat(3) //while()でなくrepeat()を使うことで行数を減らしている。
{
TRACE(); //黒線の左側をトレースするプログラム。
OnFwd(OUT_A); //以下3行が交差点を超えて直進するプログラム。片方の車輪だけ回すことでセンサー部を線から先に進ませている。
Wait(50); //出来ればこの3行も関数にしたかったが、エラーにより断念。
Off(OUT_A);
}
repeat(2)
{
TRACE();
}
FINISHING_OPERATION(); //ゴールの四角に入り、今までのBGMを止めて、レベルアップ音を鳴らすプログラム。
}
以下のタスクで鳴らしているのは、スクエアエニックスの「ドラゴンクエスト」シリーズの「序曲」である。言わずと知れた名曲なので、みなさん知っているかと思う。
task MUSIC_OPERATION()
{
while(1)
{
PlayTone(so,b12); Wait(b12+5);
PlayTone(so,b16); Wait(b16+3);
PlayTone(Do,b4); Wait(b4+2);
PlayTone(re,b4); Wait(b4+2);
PlayTone(mi,b4); Wait(b4+2);
PlayTone(fa,b4); Wait(b4+2);
PlayTone(so,b4); Wait(b4+2);
PlayTone(Doh,b2); Wait(b2+2);
PlayTone(si,b12); Wait(b12+2);
PlayTone(ra,b16); Wait(b16+2);
PlayTone(ra,b6); Wait(b6+2);
PlayTone(so,b8); Wait(b8+2);
Wait(b8+2);
PlayTone(fas,b8); Wait(b8+2);
PlayTone(fas,b8); Wait(b8+2);
PlayTone(ra,b8); Wait(b8+2);
PlayTone(so,b8); Wait(b8+2);
Wait(b8+2);
PlayTone(mi,b2); Wait(b2+2);
PlayTone(mi,b12); Wait(b12+2);
PlayTone(mi,b16); Wait(b16+2);
PlayTone(mi,b4); Wait(b4+2);
PlayTone(mi,b4); Wait(b4+2);
PlayTone(fas ,b4); Wait(b4+2);
PlayTone(831,b4); Wait(b4+2); //ここだけは違和感を感じたので調整したため音が周波数で表されている。
PlayTone(ra,b2+b8); Wait(b2+b8+2);
PlayTone(ra,b8); Wait(b8+2);
PlayTone(si,b8); Wait(b8+2);
PlayTone(Doh,b8); Wait(b8+2);
PlayTone(reh,b2+b8); Wait(b2+b8+2);
PlayTone(ra,b8); Wait(b8+2);
PlayTone(ra,b8); Wait(b8+2);
PlayTone(Doh,b8); Wait(b8+2);
PlayTone(Doh,b4); Wait(b4+2);
PlayTone(si,b4); Wait(b4+2);
PlayTone(ra,b4); Wait(b4+2);
PlayTone(so,b4); Wait(b4+2);
PlayTone(mih,b2+b8); Wait(b2+b8+2);
PlayTone(fah,b8); Wait(b8+2);
PlayTone(mih,b8); Wait(b8+2);
PlayTone(reh,b8); Wait(b8+2);
PlayTone(Doh,b2); Wait(b2+2);
PlayTone(ra,b4); Wait(b4+2);
PlayTone(Doh,b4); Wait(b4+2);
PlayTone(reh,b2+b8); Wait(b2+b8+2);
PlayTone(mih,b8); Wait(b8+2);
PlayTone(reh,b8); Wait(b8+2);
PlayTone(Doh,b8); Wait(b8+2);
PlayTone(Doh,b2); Wait(b2+2);
PlayTone(si,b4); Wait(b4+2);
PlayTone(so,b4); Wait(b4+2);
PlayTone(soh,b2+b8); Wait(b2+b8+2);
PlayTone(mih,b8); Wait(b8+2);
PlayTone(fah,b8); Wait(b8+2);
PlayTone(soh,b8); Wait(b8+2);
PlayTone(rah,b2+b8); Wait(b2+b8+2);
PlayTone(ra,b8); Wait(b8+2);
PlayTone(si,b8); Wait(b8+2);
PlayTone(Doh,b8); Wait(b8+2);
PlayTone(fah,b2); Wait(b2+2);
PlayTone(mih,b2); Wait(b2+2);
PlayTone(Doh,b2+b8); Wait(b2+b8+2);
}
}
以下は、「序曲」を鳴らしつつ、初めの四角から脱出するサブルーチン。
sub STARTING_OPERATION()
{
start MUSIC_OPERATION ;
while(SENSOR_2<Middle)
{
OnFwd(OUT_AC);
}
while(SENSOR_2>Middle)
{
OnFwd(OUT_AC);
}
OnFwd(OUT_AC);
Wait(20);
}
以下は、黒線の左側をトレースするサブルーチン。五段階に分けたことで高速化に成功した。FastTimerを用いて、連続した時間において黒を認識し続けると、交差点であると判断させている。
sub TRACE()
{
ClearTimer(0);
while(FastTimer(0)<=30)
{
if(SENSOR_2>Middle+4)//白 右旋回
{
OnFwd(OUT_A);
OnRev(OUT_C);
ClearTimer(0);
}
else if(SENSOR_2>Middle+2)//やや白 右折
{
Off(OUT_C);
OnFwd(OUT_A);
ClearTimer(0);
}
else if(SENSOR_2>Middle)//直進
{
OnFwd(OUT_AC);
ClearTimer(0);
}
else if(SENSOR_2>Middle-2)//やや黒 左折
{
Off(OUT_A);
OnFwd(OUT_C);
}
else //黒 左旋回
{
OnFwd(OUT_C);
OnRev(OUT_A);
}
}
Off(OUT_AC);
Wait(100);
}
以下は、ゴールの四角に入り、「序曲」を止めて、ドラゴンクエストのレベルアップ音を鳴らす
サブルーチン。~
sub FINISHING_OPERATION()
{
OnFwd(OUT_A);
Wait(38);
OnFwd(OUT_AC);
Wait(70);
stop MUSIC_OPERATION ;
Wait(50);
Off(OUT_AC);
PlayTone(fa,10); Wait(12);
PlayTone(fa,10); Wait(12);
PlayTone(fa,10); Wait(12);
PlayTone(fa,28); Wait(30);
PlayTone(mib,28); Wait(30);
PlayTone(so,28); Wait(30);
PlayTone(fa,118); Wait(120);
}
*結果 [#gcd4e9ba]
�,離襦璽箸�50秒(レベルアップ音が終わるまで)で完走することが出来た。
*まとめ [#u0ba75ac]
今回は、メインのタスクを動かしながらBGMを流したり、関数を多く使ったりと、初めてトライしたことが多い課題で、とても大変だったものの確実に実力をつけられた。~
また、BGMを除けばプログラムが100行に収まるように出来たのもよかったと思う。~
次の課題はついに2機の間で通信をしながら行うものだと聞いているので、さらに班のメンバーと協力してクリアしていきたい。