青と赤のボールを運搬して、空き缶の上に載せる。その上にボールを載せておく。†まず、Cでボールをつかみ、C→G→H→Iの順番で、缶を運ぶほうの機械に渡す。次に、I→H→G→Fの道を通り、Fでボールをつかんだ後、F→G→H→Iに行き、ボールを渡す。最後に、I→H→G→D→Eの道を通り、Eでボールをつかんだ後、E→D→G→H→Iに行き、ボールを渡して終了。下のような、ロボットを作りました。缶よりも高い位置にある、ボールをとれるように、アームの高さを、真ん中にある、黒い歯車の大きさを大きくすることで、調節しました。光センサーを用いて、ライントレースするようにし、超音波センサーを用いて、缶までの距離を測り、近くに来ると、アームがと閉じてボールを掴む仕組みです。歯車を回している間や、車体が移動している間に、固定をしないと、アームがぶれるので、固定をしました。左から見ると、こんな感じです。†コントローラーを上部に持っていき、ロボットの土台とコントローラーの間に缶を掴む用のアームを動かすためのモーターを組み込みました.また、コントローラーから超音波センサーを吊り下げるように下向きに取り付け,これによって,缶がアームに入っている状態では超音波センサーの値が小さくなります。缶を掴むためのアームは、上下で缶を支えるようにしてあります。4つあるアームのうち一つを長くすることで、万が一,缶が完全にアーム内に入っていない状態でアームを閉じたとしても引き寄せられるようになります。光センサーを中心にうまく収め、アームと干渉しないようにアームとモーターの位置も調節しました。ang;}この関数は、上で定義した"u-turn"での回る角度を計算するために書きました。}}左トレースして、ボールを取りに行くときに、この関数を使いました。}}右トレースして、交差点を2回渡るときに、使いました。}}右トレースして、ボールを取りに行くときに使いました。}}左トレースして、交差点を2回渡るときに、使いました。}}右トレースして、ボールを真ん中で、缶に乗せるときに、使いました。}}左トレースして、ボールを真ん中で、缶に乗せるときに使いました。}}交差点で、右トレースを、左トレースにするときに、使いました。}}右トレースで、交差点を一回だけ、渡るときに使いました。}}左トレースで、交差点を1回渡るときに、使いました。GetAngle(60);上のように、90度回転する場合と、60度回転する場合の2つを定義しました。follow_stop();Cで左に回転して、空白のところを行き、線GH上に行く、そして、Hで止まる。catch_releaser();Hの場所で、渡り、右トレースして、Iの場所で運んできた缶にボールを乗せる。Wait(7500);向こうの機械が、ボールが乗った缶を持って去るのを、待つ。Wait(100);Iの位置で、左回転し、右トレースをする。(曲がる間に交差点と認識させないために、少しだけ進ませる。catch_ballr();HとGの交差点で、右に曲がるようにする。G→Fでトレースして、ボールを掴むようにする。catch_releaser();Fで右回転し、空白の場所に行ったあと、線GHでライントレースするようにし、Hで渡り、右トレースして、Iでボールを運んできた缶に乗せる。Wait(7500);ボールを乗せた管を運ぶ機械が、去るまで待つ。Wait(100);Iで左回転し、右トレースするようにする。(曲がる間に交差点と認識させないために、少しだけ進ませる。Wait(1000);Hの交差点で止まり、右に曲がる。follow_line1();Gの交差点を一回だけ渡る。Wait(1000);Dの交差点で止まり、右に曲がる。u_turnr1;D→Eでボールをつかんだ後、右に回転して、空白のところを行き、線DG上に行く。follow_line2();Gを渡る。catch_releaser();Hを渡り、H→Iで右トレースして、運んできた缶にボールを乗せて、終了。Off(OUT_BC);}ライントレースは定義した白から黒までの4段階感知を使ってトレースするようにしました。灰色のときは直進で黒灰、白灰では片方のタイヤのみ回転する旋回で、黒、白を感知すると左右のタイヤを逆回転させて大幅に修正するようにしています。黒をq[ms]間感知すると交差点と判断し停止します。変数qは交差点の感知する感度を調整することができるようにするために導入しました。follow_lineは黒線の左トレースで,follow_lineRは黒線の右側をトレースするようになっています。どちらも黒が続いた時間で交差点を判断します。Off(OUT_BC);}上記の関数はfollow_line、follow_lineRの交差点を感知せず指定時間だけひたすらライントレースをするプログラムです。時間指定は変数yになっています。以下、説明部ではintersectionと略して使用します。}}}これらはすべて缶を掴む・離すことに使用する関数です。fetch_ballやopen、closeでアームを動かします。followC、followE、followFでは缶が置いてあるそれぞれの交差点でそれぞれに数値を最適化させたものをまとめています。これらは缶と超音波センサーの距離が15cm以下になったときはclose関数を使用して掴む動作を行い、缶との距離が15cm以上であればライントレースを行うようになっています。}}この関数では超音波センサーによってボールを感知するプログラムです。缶を持っていき、ボールを乗せてもらったときに超音波センサーが計測する値は缶だけのときよりも小さくなります。そのためこの関数では11cm以下になったときにボールがあると捉えるようにしました。完成版には使われていなませんが、制作段階で使ったり使わなかったりしていたため、プログラム内には残してあります。follow_line_for_intersection(1500);最初のCにたどり着くためのプログラムです。最初の10秒間はきついカーブの交差点の誤認識を防止するために交差点を認識しないintersectionを入れています。3行目のfollow_line(200)でHの交差点を認識し、その後のintersectionで交差点を曲がり切り、次のfollow_lineで次のG交差点を探しながらライントレースします。今後も交差点の認識と通過はこの仕組です。それぞれのintersectionで数値が異なるのはその状況に合わせて細かく調整をしているからです。Wait(10000);followCで缶を探しながらライントレースを行います。缶を見つけると缶を掴んだあとにUターンをします。Uターン後は位置が安定しないため、intersectionで整えます。その後にG交差点を感知してRotateMotor以下3行でG交差点を曲がるようにします。intersectionで曲がらないのは、確実に次のライントレースを始められるように位置を調整するためです。最後のH交差点を曲がり、3秒間進んだところで停止し,ボールが運ばれてくるのを待ちます。待っている10秒間でボールを缶に乗せてもらいます。最初の3行はボールを受け取ったあとの動きです。以下の図のように動くことでFにある缶に当たることなく逆向きになります。逆に向いた後は黒い線の右トレースすることで,H交差点を認識できるように知ました.H交差点を感知したあとは左のタイヤだけ回転させることで曲がった先で黒線の左にセンサーが来るようになっています。Cまでは今まで通り交差点を通過していきます。交差点Cを感知したところで後退して缶を離します。この動きをすることで缶を円の中に収めることができます。follow_line_for_intersection(2000);一度下がり、アームが置いた缶に当たらないようにして右回転でUターンをするようにしました。その後、前進することで確実にCから見て交差点Gの先にセンサーが来るようになります。ライントレースを行い、Fに近づいていきます。Wait(9000);Fで缶を掴みIまで持っていきます。これは1つ目の缶を持っていくときとほぼ変わりません。ボールを受け取るまでの時間調整で9秒間待ちます。終了1つ目の缶でボールを受け取ったあとと同じように方向転換をして右側ライントレースをGまで行います。そこから先程と同じように左のタイヤだけ回転させて左トレースに戻り、Fに缶を置きます。follow_line_for_intersectionR(2000);Cで缶を置いたときと同じようにアームが缶に当たらないように下がったあとにG-Dの黒線の右側にセンサーが来るように方向転換をします。Eまで右側トレースで進みます。Wait(15000);Eで缶を掴んだあとはそのままintersectionでDを通過し、Gを感知しても直進することで通過、Iまで行きます。15秒間待ち、最後の缶を戻しに行きます。RotateMotorEx(OUT_BC,SPEED_L,65,0,false,true);ここまででボールを受け取ったあとの方向転換、からGまでのトレースです。E終了Gの交差点感知から直進後は進路が右に向きすぎているため、右タイヤのみ回転させて左に向きを調整する。これが一行目のRotateMotorです。そこからは今まで通りEまで運びます。最後にEだけは確実に円内に缶を収めるためにE交差点を感知して後退したあとに左に向きを調節しています。back(300);}最後に缶から離れて終了です。