- 追加された行はこの色です。
- 削除された行はこの色です。
目次
#contents
*1、概要 [#k5f70c83]
今回、私が担当したのはコースBである。下の写真はロボットの全体像である。
#ref(2016b/Member/ats/Mission2/view.jpg,50%,全体像)
*2、ロボットについて [#v222303c]
**⑴台車と光センサー [#o25c6efa]
今回の課題のコースは、急なカーブがあったりたくさんの交差点があったりと、一つの光センサーで乗り越えるには厳しいコースだった。そのため、精密なプログラムを組む必要があった。しかしながら、いくらプログラムが良くても電池の減り具合などの要因で正しくプログラムを実行できないという可能性があった。よって、ロボットはタイヤを前方の2つのみとし、後方は下が丸い部品で滑りをよくし、小回りが利くようにした。また、光センサーはタイヤの近くに設置し、急激なセンサー値の変化によるエラーを防いだ。
&ref(2016b/Member/ats/Mission2/daisha.jpg,100%,台車(前方のみにタイヤを設置してある)); &ref(2016b/Member/ats/Mission2/tire_sensor.jpg,50%,タイヤとセンサーの位置関係);
**ボールを保持する機構 [#hb549acb]
今回私のペアは、リング状の部品を作成し、そこにボールを閉じ込めることにした。
#ref(2016b/Member/ats/Mission2/ring.jpg,70%,機構の全体像)
リング状の部品は台車の乗せたモーターを動力として上下に動く。ボールはピンポン玉であるためリング状の部品は低い位置に、地面と平行になるのが望ましいと考えている。しかしながら、台車の構造の都合でモーターは低い位置に設置するのは困難であった。そこで上の写真でもわかるように、モーターが動力を伝える軸から下方にさらに軸を伸ばした。こうすることで、リング状の部品が低い位置で地面に平行になるようにし、正常に上下できるようにした。
#ref(2016b/Member/ats/Mission2/suka-to.jpg,50%,スカート)
また、上の写真を見てもわかるように台車に直接設置してある平な部品(スカート)がある。仮にこの部品が無いと、光センサーが出っ張った構造となってしまう。そうなると、最後にボールをシュートするときにボールが横に逃げてしまう。そこでそれを防ぐためにこの部品を設置した。幅はリング状の部品との間に隙間がなくなるようにし、両側にブロックを取り付けることでさらに正確性を向上させた。
**制御措置(電池ボックス) [#sd618e84]
台車は、正確な動作を実現するために少ない部品で構成している。そのため、制御装置も台車を補強する役割がある。今まで載せてきた写真を見てもわかるように、前方ぎりぎりに設置してある。これを一つでも後方に移すと後方にかかる重さが大きくなり、後方の滑りが悪くなってしまう。そうなれば、正しくプログラムを実行することができなくなってしまう。
*2、プログラムについて [#if0e6e82]
プログラムはB→P、P→Q、Q→ボールキャッチ、ボールキャッチ→C、C→シュートの5つのサブルーチンにわけて書いた。そのうち、「P→Q」と「ボールキャッチ→C」は同じサブルーチンで動作する。
**B→P [#d1180365]
*3、プログラム(について [#if0e6e82]
プログラムはB→P、P→Q、Q→ボールキャッチ、ボールキャッチ→C、C→シュートの5つのプロセスにわけて書いた。そのうち、「P→Q」と「ボールキャッチ→C」は同じサブルーチンで動作する。
//とても明るい(白)
#define KYOKAI_1 50 //境界
//明るい(白黒境界よりやや白側)
#define KYOKAI_2 46 //境界
//普通(白黒境界)
#define KYOKAI_3 42 //境界
//暗い(白黒境界よりやや黒側)
#define KYOKAI_4 38 //境界
//とても暗い(黒)
#define TURN_L OnRev(OUT_A);OnFwd(OUT_C); //左回転
#define L OnFwd(OUT_C);Off(OUT_A); //左折
#define R OnFwd(OUT_A);Off(OUT_C); //右折
#define TURN_R OnRev(OUT_C);OnFwd(OUT_A); //右回転
#define CROSS_TIME 32 //交差点と判断する基準となる回転時間
#define CHECK_TIME 25 //十字路かT字路かを判断するために直進するときの直進時間
#define WAIT Off(OUT_ABC);Wait(20); //動作安定のために一時停止するプログラム
#define BER_UP PlayTone(500,30);OnFwd(OUT_B);Wait(30);Off(OUT_B); //ボールをつかむプログラム(音付き)
#define BER_DOWN PlayTone(500,30);OnRev(OUT_B);Wait(30);Off(OUT_B); //ボールを離すプログラム(音付き)
#define START_SOUND Wait(100);PlaySound(SOUND_UP);Wait(150); //一番最初に鳴らす音
#define CROSS_SOUND PlaySound(SOUND_DOUBLE_BEEP);Wait(150); //交差点と判断した時に鳴らす音
#define CROSS_FORWARD_SOUND PlayTone(440,100);Wait(150); //十字路と判断した時の音
#define CROSS_T_SOUND PlaySound(SOUND_LOW_BEEP);Wait(150); //T字路と判断した時の音
#define GOAL_SOUND Wait(100);repeat(3){PlayTone(600,50);Wait(100);}PlayTone(900,100);Wait(200); //最後のシュートする前に鳴らす音
#define END_SOUND Wait(100);PlaySound(SOUND_DOWN);Wait(150); //最後に鳴らす音
以下では4つのサブルーチンを紹介する。サブルーチン内で使われているマクロは上に記されている。
**B→P用 [#d1180365]
sub P1()
{
ClearTimer(1); //タイマー1をリセット
while(FastTimer(1) < CROSS_TIME) //ラインの左側を走行するプログラム(交差点と判断するまで左回転をすると次のプログラムに進む)
{
if(SENSOR_2 > KYOKAI_1)
{
TURN_R;
ClearTimer(1);
}
else if(SENSOR_2 > KYOKAI_2)
{
R;
ClearTimer(1);
}
else if(SENSOR_2 > KYOKAI_3)
{
OnFwd(OUT_AC);
ClearTimer(1);
}
else if(SENSOR_2 > KYOKAI_4)
{
L;
ClearTimer(1);
}
else
{
TURN_L;
}
}
Off(OUT_AC);
CROSS_SOUND; //停止して交差点と判断した音を鳴らす
TURN_R;
Wait(70);
OnFwd(OUT_AC);
Wait(30);
Off(OUT_AC); //次のサブルーチンの始点に移動
}
このプログラムは、途中Rを直進するという難所がある。しかし、RはT字路なのでラインの左側を走行することで難所を攻略できた。
**Q→ボールをキャッチ用 [#yc9b6143]
sub P2()
{
TURN_L;
Wait(20);
WAIT; //次の走行の時に、間違えて交差点と判断しないように光センサーを白のエリアに移す
ClearTimer(0); //タイマー0をリセット
while(FastTimer(0) < 300) //3秒間、線の左側を走行
{
if(SENSOR_2 > KYOKAI_1)
{
TURN_R;
}
else if(SENSOR_2 > KYOKAI_2)
{
R;
}
else if(SENSOR_2 > KYOKAI_3)
{
OnFwd(OUT_AC);
}
else if(SENSOR_2 > KYOKAI_4)
{
L;
}
else
{
TURN_L;
}
}
BER_DOWN; //ボールをキャッチする
WAIT;
}
このプログラムはサブルーチン「P3」の次に実行されるため、このサブルーチンが始まる時はかなりラインの内側に光センサーがある可能性がある。すると、いきなり交差点と判断してしまうというエラーが起こる可能性が高まる。その対策として、上記のように最初に左回転を実行することにした。また、ボールはライン上にある。そのため、ロボットの構造上、どうしてもラインの右側を走行するとリング状の部品がボールに当たり、ボールをキャッチできない。そこでラインの左側を走行させることにした。
**P→Q、ボールをキャッチ→C用 [#i71ff35a]
sub P3()
{
ClearTimer(1);
while(FastTimer(1) < CROSS_TIME) //ラインの左側を走行するプログラム(交差点と判断するまで左回転をすると次のプログラムに進む)
{
if(SENSOR_2 > KYOKAI_1)
{
TURN_R;
ClearTimer(1);
}
else if(SENSOR_2 > KYOKAI_2)
{
R;
ClearTimer(1);
}
else if(SENSOR_2 > KYOKAI_3)
{
OnFwd(OUT_AC);
ClearTimer(1);
}
else if(SENSOR_2 > KYOKAI_4)
{
L;
ClearTimer(1);
}
else
{
TURN_L;
}
}
Off(OUT_AC);
CROSS_SOUND; //交差点と判断し、停止して音を鳴らす
TURN_R;
Wait(CROSS_TIME);
WAIT; //交差点に進入した時の位置に戻る
OnFwd(OUT_AC);
Wait(CHECK_TIME);
Off(OUT_AC); //十字路かT字路かを判断
if(SENSOR_2 < KYOKAI_1) //十字路だった場合は音を鳴らし、タイマー1をリセットして次に進む
{
CROSS_FORWARD_SOUND;
ClearTimer(1); //
}
else //T字路だった場合は音を鳴らした後、0.5秒間右回転し、タイマー1をリセットして次に進む
{
CROSS_T_SOUND;
TURN_R;
Wait(50);
WAIT;
ClearTimer(1);
}
}
このプログラムは、十字路なら直進、T字路なら右に曲がるという動作をする。これにより、複雑な「ボールキャッチ→C」のプロセスを単純にwhileで繰り返せるようにした。また、このプロセスの間には半径4cmの急カーブがある。そのため、ラインの右側を走行すると光センサーが黒い部分を通り続け、交差点と判断する可能性が高かった。そこでラインの左側を走行することにした。これは、白い部分は交差点の判断材料にならないからだ。
**C→シュート→終了 [#wc1a33fb]
sub END()
{
TURN_L;
Wait(50);
Off(OUT_AC);
WAIT; //サブルーチン「P3」終了後、ロボットをゴールの方向に戻すプログラム
OnRev(OUT_AC);
Wait(100);
WAIT; //ボールに勢いをつけるために下がる
GOAL_SOUND; //シュートまでのカウントダウン
OnFwd(OUT_AC);
BER_UP;
Wait(180);
Off(OUT_AC); //シュート
}