目次
今回の課題は、課題2で用いたコースを用いてC,D地点にある紙コップを重ね、Q地点の円の内部まで運ぶ事です。
出発はA地点で、C→D→C…の順番で重ねていき、コップを高く重ねるほど高い得点となります。
今回私たちのチームは、マイコン一つのみを用いてすべての動作を行わせようと設計しました。
本体前方にはコップをつかみ、持ち上げるアームの部分、中央付近にはライントレース用の光センサー、後方にマイコンという構成になっています。
アーム部分は、モーターが回転するとアームが閉まり、閉まりきるとアームが上がるようになっています。詳しい説明は、製作者のページのリンクを張っておくのでそちらをご覧ください。
sub setting() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_2,SENSOR_TOUCH); SetSensor(SENSOR_3,SENSOR_LIGHT); SetPower(OUT_AC,4);//タイヤ SetPower(OUT_B,7);//アームの上下 }
センサーなどの設定です。
SENSOR_1の光センサーはライントレース用
SENSOR_2のタッチセンサーはアームの上げ下げ用
SENSOR_3の光センサーは正面に来たコップを認識させる用
でしたが、本体の改良によりSENSOR_2とSENSOR_3は使用しなくなりました。
task keep() { while(1) { OnRev(OUT_B); Wait(1); OnFwd(OUT_B); Wait(1); } }
連続してアームを開閉することでコップを待ちあげた状態で保持しておくサブルーチンです。ただし、ラインとレースと並列動作させるためtaskで定義しています。
sub TRACE() { ClearTimer(0); while(FastTimer(0)<=42){ if(SENSOR_1>Middle+4)//白 左旋回 { OnFwd(OUT_C); OnRev(OUT_A); ClearTimer(0); } else if(SENSOR_1>Middle+2)//やや白 左折 { Off(OUT_C); OnRev(OUT_A); ClearTimer(0); } else if(SENSOR_1>Middle)//直進 { OnRev(OUT_AC); ClearTimer(0); } else if(SENSOR_1>Middle-2)//やや黒 右折 { Off(OUT_A); OnRev(OUT_C); } else //黒 右旋回 { OnFwd(OUT_A); OnRev(OUT_C); } } Off(OUT_AC); PlaySound(SOUND_FAST_UP);//トレース終了、交差点認識 }
課題2で使用したプログラムです。
sub zensin() { OnRev(OUT_A); Wait(106); Off(OUT_A); }
ライントレースで交差点を判断したのち、交差点を直進させるためのサブルーチンです。
sub down() { OnRev(OUT_B); Wait(200); }
持ち上げているコップを下に降ろすためのものです。
sub TURN_180() { OnFwd(OUT_AC); Wait(80); Off(OUT_AC); OnRev(OUT_A); Wait(130); while(SENSOR_1>40) { OnFwd(OUT_C); OnRev(OUT_A); } Off(OUT_AC); }
CもしくはDでコップをつかんだ後、180度回転してCにいるときはDの方向を、DにいるときはCの方向を向くためのサブルーチンです。
実際の動きとしては少し後退したのち、回転し、再び黒線を見つけるまで調整をしています。
sub copjugde() { while(SENSOR_3 < 46) OnRev(OUT_AC); Off(OUT_AC); Wait(100); }
このサブルーチンは改良前の本体で使っていたものです。
最終的には使っていませんが、本体前方部分に光センサーをつけその値の変化により、コップが前にくるまで前進、判定させるものでした。
以下が本番で使ったプログラムです。本番前に予定を変更して紙コップ一つのみを運ぶプログラムに変更したため、少し見にくくなっています。
#define Middle 45 ライントレースの中央値 task main() { setting(); STARTING_OPERATION(); repeat(2) { TRACE(); zensin(); } //交差点からDへ向かう TRACE(); OnRev(OUT_C); Wait(25); TRACE(); //誤差修正 OnRev(OUT_A); Wait(95); Off(OUT_AC); //dに到着 OnFwd(OUT_B);//コップつかむ Wait(250); start keep; TURN_180();//180°回転 TRACE(); zensin(); TRACE(); OnRev(OUT_A); Wait(80); Off(OUT_AC); stop keep; down(); OnFwd(OUT_B); Wait(250); start keep; OnFwd(OUT_A);//Qの方向を向く OnRev(OUT_C); Wait(200); Off(OUT_AC); OnRev(OUT_AC);//進む Wait(100); Off(OUT_AC); //センサー使って進む while(SENSOR_1 > Middle-4) OnRev(OUT_AC); stop keep; //放す Off(OUT_AC); down(); } sub setting() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_2,SENSOR_TOUCH);//モータB止める用 SetSensor(SENSOR_3,SENSOR_LIGHT); SetPower(OUT_AC,4);//タイヤ SetPower(OUT_B,7);//アームの上下 } task keep() { while(1) { OnRev(OUT_B); Wait(1); OnFwd(OUT_B); Wait(1); } } sub TRACE() { ClearTimer(0); while(FastTimer(0)<=42){ if(SENSOR_1>Middle+4)//白 左旋回 { OnFwd(OUT_C); OnRev(OUT_A); ClearTimer(0); } else if(SENSOR_1>Middle+2)//やや白 左折 { Off(OUT_C); OnRev(OUT_A); ClearTimer(0); } else if(SENSOR_1>Middle)//直進 { OnRev(OUT_AC); ClearTimer(0); } else if(SENSOR_1>Middle-2)//やや黒 右折 { Off(OUT_A); OnRev(OUT_C); } else //黒 右旋回 { OnFwd(OUT_A); OnRev(OUT_C); } } Off(OUT_AC); PlaySound(SOUND_FAST_UP);//トレース終了、交差点認識 } sub zensin() { OnRev(OUT_A); Wait(106); Off(OUT_A); } sub down() { OnRev(OUT_B); Wait(200); } sub STARTING_OPERATION() { while(SENSOR_1<Middle) { OnRev(OUT_AC); } while(SENSOR_1>Middle) { OnRev(OUT_AC); } OnRev(OUT_AC); Wait(50); Off(OUT_C); OnRev(OUT_A); Wait(40); while(SENSOR_1<Middle) { OnRev(OUT_AC); } Off(OUT_AC); } sub TURN_180() { OnFwd(OUT_AC); Wait(80); Off(OUT_AC); OnRev(OUT_A); Wait(130); while(SENSOR_1>40) { OnFwd(OUT_C); OnRev(OUT_A); } Off(OUT_AC); } sub copjugde() { while(SENSOR_3 < 46) OnRev(OUT_AC); Off(OUT_AC); Wait(100); }
今回は結果的に一つもゴールに持っていくことが出来なかったので、初めから紙コップを六つ重ねることを前提に進めていくのではなく、まずは一つをそれができたら二つを…と進めていけばよかったと思う。