以下のようなコースを作成し、ミッションを遂行するためにロボットを作成する
A地点を出発し、次のいずれかの経路を黒い線にそって動くロボットを作成する。 私の選んだコースは以下のコースである。 A地点から出発 → B → C(直進) → D(一時停止の後、直進) → E → F → G(一時停止の後、右折) → H → I → J(右折) → K(左折) → L(ピンポン玉をつかむ) → K(直進) → M(一時停止) → シュート→ A地点に入る(ゴール)
今回製作したロボットは以上のものである。モーターは、車輪の駆動に2つ(旋回などの小回りの利く機体を目指したため)、ピンポン玉をつかむ機構の駆動で1つ、合計で3つ使用した。
このロボットの一番の特徴といってもいいのが、最小化された機体である。
これは写真のようにモーターを縦に組み合わせ、車輪も一回り小さいものを使用することで達成された。これによって横幅、縦幅ともに車輪を含んでもロボットがRISコンピューター以内の大きさに収まっている。この機体の小型化によって小回りの利く動きが可能となっている。この製作にあたっては、授業内で紹介された先生のモデル及び11班のメンバーの方々の協力があったものなので、この場を借りて謝辞を申し上げたい。
写真のように、今回使用した機体はそれぞれ車輪へとモーターから直接動力が伝わっている。機体の小型化によってモーターは縦に二つ配列したために、右側車輪は前方モーターからの出力、左側車輪は後方モーターからの出力によって動いている。この出力の差異の調整はプログラムからではなく、コンピュータにつなげるコードの向きの調整を行うことで解決した。
車輪の特徴として二輪であることを説明したい。本来は四輪の機体製作を目指していたが、機体の小型化を優先するにあたって、四輪の製作に行き詰ったために、二輪でも動くことを確認できたので今回は二輪車となった。
課題は機体の傾きと重心の取り方であった。二輪であるために機体がタイヤの前後に傾きふらつくことがしばしばあった、そのため解決策としてロボットの前方下部にブロックを追加することで、機体の傾きの軽減を行った。また次に紹介する球をつかむ機構を取り入れた際に、アーム部分が動くことで重心がずれ挙動が不安定になることも多々あった。この解決策として前方向(コンピュータと車輪の間部分)にブロックを追加することで重心の安定化を図った。
実際にミッションを達成できたロボットは上記で紹介したものになるが、ミッションの遂行にあたってうまく行かなったプロトタイプのロボットがあるので説明したい。
このロボットはモーターを横に2つ連結したものであった。見てわかるように機体の横幅がRISのコンピュータをはみ出したものである。このプロトタイプロボットでは、ラインのトレースと交差点の認識に関しては問題もなく、四輪走行であるために非常に安定したトレースが行われた。しかし実際コースを作成して、動かしてみると、機体の横幅が大きいためにカーブ(特にU字部分など)でうまく曲がることができず、ラインのトレースはうまくいくものの機体が追い付かないという問題が発生した。そのため急遽機体の直径を小さくして小回りの利く機体を製作することとなった。
RISのキット付属のワームを2重にして球をつかむ機構を製作した。アームを直接モーターにつなぎ、上下に動かすことで球をつかみ移動することにした。直接モーターからの出力のために、動作の制御に苦労した。
今回の機体は光センサーを利用したトレースロボットであったが、私たちが使用したトレースを紹介したい。 私たちは閾値を35として、35以下の時を黒、35以上の時を白と2つに認識することで、白、黒をトレースしているときにそれぞれについて右または左に移動するという、最も単純なトレース形式を採用した。なお数値のブレをなくすためにも光センサの位置は地上から2.5cmを常に保つようにロボットの改良を随時行った。
今回の反省は一重にトレースを閾値一つで行ってしまったことである。このトレースで行うことでプログラムの単純化を図ったが、結果的にはそれ以上に問題点を多く生じさせてしまった。具体的には、以下の2つが挙げられる。
・白黒交互にトレースを行うため、進行がスムーズではなくとても効率悪く進んでしまったこと ・交差点の認識の際に(特にK点やG点において)認識せずにトレースを進行してしまうことが何回かあったこと
例えば、白、白に近い灰色、黒に近い灰色、黒と4つの範囲を設定するだけでも以下のような効果が期待されたと考えられる。
・直進するプログラムを行うことでトレースをスムーズ行う。 ・白と黒の境界を設けることで交差点とカーブの認識をわかりやすくする。 (交差点に入るといきなり暗くなるが、カーブに入ると少し暗くなる..など)
プログラムを書く当初はトレースに関してはあまり重要でないと思い込んでいたが、サブルーチンを完成させて最後のコースを走る段階になって初めて、トレースの重要なことに気づいた。今後光センサーを使用する機会があれば、今回の反省をしっかりと生かしていきたいと思った。
今回のプログラムにおいて、A出力は左輪のモーター、B出力は右輪のモーター、C出力はアームのモーターに使用した。なお、SetPowerについては今回は調整を行っておらず、デフォルトの7ですべてのモーター出力を行っている。
今回のプログラムで使用される定義したプログラムを紹介したい。
#define Boundary 35
ライントレースの際に利用した閾値である。
#define Go_Straight OnFwd(OUT_AB);
直進する際のプログラムである。
#define Left_K Off(OUT_A);OnFwd(OUT_B); #define Right_K OnFwd(OUT_A);Off(OUT_B);
左回転及び右回転するときのプログラムである。ライントレースのプログラムに多用されている。
#define armUp OnRev(OUT_C);Wait(30); #define armDown OnFwd(OUT_C);Wait(30);
球をつかむアームの上げ下げに関するプログラムである。
#define turn OnFwd(OUT_A);OnFwd(OUT_C);Wait(170);
180°旋回する際に使用したプログラムである。今回のミッションではL地点で球を掴んだ後に向きを変えるために利用した。
#define freez Off(OUT_AB);Wait(100);
車輪動作の電源のオフと、それに伴い静止時間を設けたプログラムである。ロボットの挙動を安定させるために随時使用した。
{ ClearTimer(0); FastTimer(0); //ClearTimerとともにタイマーのセットを行う。 SetSensor(SENSOR_1, SENSOR_LIGHT); //センサーをオンにする while(FastTimer(0)<30) //タイマーの作動時間は0.3秒に設定した。 { if (SENSOR_1< Boundary) { Right_K } //もし閾値より低いライン(黒)をトレースしている場合右側へ移動しようとする。 この時タイマーが作動しているため規定時間以上黒をトレースするとプログラムは終了する。 else { Left_K; ClearTimer(0) } } //もし閾値より高いライン(白)をトレースしている場合左へと移動する。 なおcleartimerによってタイマーはリセットされているためにこの際にはタイマーによる カウントは行われていない。 Off(OUT_AB);Wait(100); } //タイマーが作動してプログラムが実行された場合停止する。
このサブルーチンは交差点停止のためのプログラムで黒い直線をトレースする場合に右側をトレースする際に使用する。反対側をトレースするサブルーチンとの区別を行うために、名前はfollow_line(1)としてある。
{ ClearTimer(0); FastTimer(0); SetSensor(SENSOR_1, SENSOR_LIGHT); //上記同様 while(FastTimer(0)<30){ //タイマーは同じく0.3秒で設定 if (SENSOR_1< Boundary) { Left_K } //先ほどとは異なり黒をトレースする際に左に曲がる。 else { Right_K; ClearTimer(0); //白をトレースする際には右にまがる。タイマーは作動しない。 }} Off(OUT_AB);Wait(100); //機体停止 }
このサブルーチンはfollow_line1とは反対側のラインをトレースする際に使用した。 同様に交差点を認識するようになっていて、0.3秒黒をトレースし続けたときに停止するようになっている。
{ Go_Straight;Wait(35); //直進 } このサブルーチンは交差点を認識し、停止した後に主に交差点を右左折せず直進する際に使用した。 交差点のラインを超えることでまたサブルーチンに復帰して、トレースを続けることができる。
{ Go_Straight;Wait(100);Off(OUT_AB); //直進 freez; //停止 armDown; //アームを下し球をつかむ freez; //停止 turn; //180°転回 freez; //停止 }
このサブルーチンはミッションにおいてK地点で交差点を認識してから、L地点で球をつかみ、方向転換をするまでのものである。初めはプログラムが複雑にならないようにサブルーチンとして保存した。
task main () { armUp; //アームを上げる
follow_line2(); //トレースを開始する。 この時トレースはラインの左端で行っておりD地点で交差点の認識を行い停止する。
Right_K;Wait(50);freez;across_road(); //D地点で停止した後機体を右回転して 図形DEFGHの内側にロボットを入れる。
follow_line1(); //先ほどとは異なり、トレースラインを右端へと変更して トレースを再開する。
follow_line1();follow_line1();follow_line1(); //E地点、F地点において交差点と認識してしまい、 三回停止をしてしまったので微調整としてサブルーチンを繰り返した。 このプログラムによってG地点で機体は停止する。
Right_K;Wait(100); //G地点で停止した後、円GHIJの外側を回るため調整として、 機体を右に回転させる。 follow_line1(); //回転後、円の外側のトレースを開始する。なおH地点で停止する Left_K;Wait(70);across_road(); //H地点で停止した後、交差点を直進する要領で、 直線DHを横切る。
follow_line1(); //H地点を通過した後再びトレースを再開する。 Left_K;Wait(40);across_road(); //Hを通過した際と同様に直線GIを横切る。
follow_line1(); //再びトレースを再開する。このトレースはK地点で終了する。 Left_K;Wait(80);freez; //K地点で停止した後、次のサブルーチンに向けて機体を回転させる。 KL_turn(); //上記で紹介したサブルーチンである。Lで反転するところまでを行う。
follow_line2(); //R=4(半径4)の半円部分まで移動するプログラムである。 カーブが急であったために、トレースを二回に分けて行うことにした。 across_road();follow_line1(); //小さい半円においてラインを横切ることで 反対側のライン端のトレースを行うプログラムである。 follow_line1(); //一度のトレースでは半円の途中で機体が停止したため、 もう一度ライントレースを行った。
Left_K;Wait(20);freez; //シュートに向けての角度の調整である。 armUp; //玉を掴んでいたアームをあげる。
Wait(20);Go_Straight;Wait(100); //機体を押し出すことでシュートを行う。
Off(OUT_ABC); //プログラムを終了する。 }
上記のように今回のプログラムではとにかくfollow_line(交差点認識プログラム)をごり押しして、なんとかミッションを達成したという形であった。(follow_lineを数回連続した箇所などもあるそのため、応用性や実用性に欠けるように感じた。
今回のミッションの一番の反省点は、理想のロボットを組み立てようとそこに時間をかけすぎたためにプログラムにうまく時間を割くことができなかった点である。特にトレースのプログラムに関しては、前述したように閾値を4つ設けなかったために、後々不都合が多く生じてしまったので、ミッション3では、サブルーチン等の準備段階のプログラムを入念に作りたいと思った。