次のいずれかのコースで黒い線に沿って動き、途中でボールをゴール付近に立てた350mlの空き缶(黄色で表示)に当てるロボットを製作せよ。自分は第1コースを選択したため、以下の赤線で示した道順を辿り、Q地点の空き缶にボールを当てる。課題で指定されている地点(矢印の終点)で1秒間停止する。†モーターAで前方のアーム、モーターB・Cでそれぞれ右前輪・左前輪を稼働させる。固定前輪2輪と駆動後輪1輪の計3輪でライン上を移動する。車体前方下部に光センサを取り付け、明暗を測定する。前方を向くように超音波センサを取り付け、障害物までの距離を測定する。ボールをアームで固定し、投射時にはアームを上げることで転がす。最初の構想では、超音波センサ・ボール投射部分ともにロボット左方につける予定だったが、重心が偏り旋回が上手くいかなかったので、ロボット前方に取り付け安定するようにした。時間で一回転旋回させるのは安定しなかったため、角度で行った。今回は「光センサが線外に出た時線上に戻る」「光センサが線上にある時線外に出る」「光センサが線の境目にある時は直進する」という3つの動作を光センサの値によって制御することで、ロボットがライントレースを行えるようにした。線をトレースするのではなく、線の境目をトレースしていくことになる。{光センサが中間(値が40から50の間)→直進}のように動作を制御する。いう動作を行い、右の境目をトレースしている場合はその逆の動作を行う。交差点や急なカーブにおいては片方の前輪を動かすだけでは曲がり切れないため、曲がりたい方向の前輪を逆回転させることで、ロボットが急激に曲がるようにしている(旋回)。そのため旋回は一定時間以上光センサが線上か線外にあるときに行われるようにした。加えて交差点と急なカーブでは、交差点の方がより長く光センサが線上にある。交差点判断として、旋回を行っても一定時間以上線外に光センサが出なければ、そこは交差点であると認識するようにしている。今回はボールを当てる空き缶がロボットに一番近い障害物であるため、一度ロボットを旋回により一回転させ、その後一番近い障害物の方を向くような動作を行わせる。ロボットを一回転させる方法として、まずロボットの前輪間の距離を直径とするような円を考えた。その円周を前輪がどれだけ回転したかで、ロボットが何度旋回するかがわかるので、その値が360度になるまで前輪を回転させることでロボットを一回転させた。前輪を回転させることにより、一番近い物体の方を向くようにした。定義、使用することで各動作の持続時間を測定し、条件分岐を行っている。t00にはロボットがライントレースを開始した時刻が代入される。これは1つのライントレースプログラムを終えるまで更新されることはない。次に、t0はロボットが直進を行うたびにその現在時刻が代入され、t1は直進、右折、左折のいずれかの動作を行うたび、すなわち今その時の時刻が代入され続ける。以上のように時間関数を定義し更新することで、各動作を持続している時間を算出し、条件分岐に使用することができる。急なカーブを曲がるために旋回を行う条件分岐として{t1-t0>150}を考える。この時150とは0.15秒を表す。ロボットが直進しているときはt0は常に更新され、t1も常に更新される。t1-t0=0であるから旋回は行われない。次にロボットが右または左に曲がる場合を考えると、t1は変わらず更新され続けるが、t0は直進を最後に行ったとき、つまり右左折を行い始めた時刻から更新されない。ゆえにロボットが右左折を継続して行っている限りt1-t0の値は増加する。上記にも書いてあるが、急なカーブや交差点では右左折を行う時間が、直線のライントレースを行う時間より長くかかる。そのため0.15秒以上右左折を行っていれば旋回を行うという条件がたてられる。このように{t1-t0}はロボットが右左折(旋回を含む)を継続して行っている時間を示す。そのほかにも今回は{t00-t1}という式も使用しており、これは{今その時の時刻[t1]-ライントレース開始時刻[t00]}を表すため、ライントレースを開始してから何秒間経過したかを示す。左の境目をトレースする動作をl_line_trace、右の境目をトレースする動作をr_line_traceとしている。動作説明の通り{t1-t0}は右左折持続時間を示すので、その値が0.15より大きく0.25未満であれば急カーブとみなし、0.25より大きければ交差点であると判断している。ライントレース開始から指定した秒数間[min]の間は交差点判断を行わないように{t1-t00<min}という条件を組み込んでいる。d_min]を長めに取っておくことで、必ず更新されるようにしている。Off(OUT_BC);旋回開始を基準として、360度旋回するまでのタイヤの回転角度[MotorTachoCount(OUT_C)]から障害物を探知した時のタイヤの回転角度[angle]を引くことで、より旋回角度が小さくなるような前輪の回転角度[ang_min]で旋回するようにしている。//ボールを投げる向きをもとに戻すときには旋回時とタイヤの回転を逆にしているのでangleを使用している。true);//向きを戻す。前回の課題1に比べて順調に進み、発表にも間に合い成功できたので良かった。行わない}という条件の時間指定に難儀して、調整に手間取った。ロボットを一回転旋回させるプログラムは相棒に頼り切りになってしまったが、全体を通しては良く協力できたように思う。見返してみるとプログラム内のt00の更新は、void関数内に組み込んでも問題ないように感じる。次回の課題はロボコンで、今回の課題の発展的なことを行うようなので、今回の成功を活かして頑張っていきたい。