†A地点を出発し、下図の赤い矢印にそって動くロボットを作成する。交差点では1秒間停止し、丁字路では直角方向に進入する時のみ一時停止すること。†ライントレースをするためにカラーセンサーを使用する。このカラーセンサーは対象に向かって光を出し、反射した光の量を測って対象の明るさを測定している。黒い部分を測ると反射量が少なくなり値が小さくなる。白い部分を測ると反射量が多くなり値が大きくなる。ライントレースをするにはカラーセンサーの値が常に一定になるように進めばよい。今回は紙とラインの境目をトレースする方法を利用することにした。白い領域に入ったら黒い領域に向かうようにし、黒い領域に入ったら白い領域に向かうようにすることで常に黒と白の中間を辿るようにすることにした。ラインを滑らかにトレースするためにはラインに対して本体が入る角度をできるだけ浅くするために小さく曲がる必要がある。一方で急なカーブを曲がるときには大きく曲がらなければいけない。スムーズな移動をするためには状況によって曲がる量を変える必要がある。このセンサーの値は連続的に変化するので黒と白に加えて黒よりの灰色や灰色、白よりの灰色と分けることができる。基本はライントレースをしているので交差点に入ったことをロボットに認識させる必要がある。ラインの左側をトレースさせる場合交差点に入るとカラーセンサーの値は黒色を示すので左に転回してしまう。ここで普通のカーブと異なる点は黒色の領域にいる時間がカーブの時より長いことである。この違いを利用して交差点を判別することにする。普通はtime関数を使って黒色を示す時間を計測して判別するところだが、ここではあえて黒色を示した”回数”を利用した。このプログラムではwhileを使って0.001秒ごとにカラーセンサーの値を読み取り、ifを使ってその値に合わせた5段階の動き方をするように作っている(0.001秒ごとの周期に設定しているが実際に0.001秒ごとにやってくれているのかはわからない)。ここでロボットがラインに大きく入り込んだとすると、ロボットはラインから出るように動くはずである。この動作は白い部分に出るまで連続で続く。ここで変数(ここではiと置いている)を使って黒に入ったときにiに数を足していきiが一定の値を超えた時にこのトレースが止まるようにすれば交差点を認識できる。黒い領域にいる時間が最も長くなるのは交差点(直角カーブでも止まるが交差点を左折する動きをすれば問題ない)であるから交差点でのみ止まるように値を調節する必要がある。この設定では小刻みにラインに入っても止まるので灰色より明るい場所に入った場合にはiの値を0、すなわちリセットしている。†ボールをつかみ、シュートするという複雑な動きをたった一つのモーターで行わなければけないというのはかなり無理のあることである。我々はこの難題を解決する方法を編み出した。シュートする方法を考えなければならないが、チームの一人がカタパルト式がいいという熱い要望があったのでカタパルト式を採用することになった。次にボールをつかむ必要がある。いってもカタパルトでやる以上水平に対して垂直な円運動の動作しかできない。ボールは地面に置いてあるのでボールを持ち上げるには下から上へ一方通行となる仕組みを作る必要があった。そこで考えたのが下図である。ボールを入れるかごはできるだけ固定せず外側へ開くようにしてアームをボールに押し付けるとアームが押し広げられ、ボールが上へと移動する。上に行ったボールはその自重で落ちることはないのでそのままゴールまでもっていき180°回転してシュートするという算段である。†できるだけシンプルな構造になるように意識した。重要だったのはカラーセンサーの位置でロボットの中心で床との間隔がちょうどよくなるようにすることはもちろん、本体の少し前方につけることでライントレースがより正確に行うことができるようになった。前回よりもコードを多く使ったので絡まらないように配線に気を付けた。†カタパルト式をとっているためアームは少し長めである。#スリープを使うには必要。#進行方向を向いて右側のタイヤを動かすモーター(mL)をoutAに接続。#進行方向を向いて左側のタイヤを動かすモーター(mR)をoutBに接続。#アームを動かすモーター(mM)をoutCに接続。†プログラム作成を円滑にし、かつ第三者に見やすくするためによく使う動作を定義しておく。関数の中でも使っている。各モーターをまとめてリセットする関数。#各モーターに対して指示。stop():ロボットの移動を停止をする関数。カーブを左に曲がるための関数。llspは左曲がり"left"の左車輪"left"のスピード"speed"を意味。#カーブを右に曲がるための関数。turn_left()と同じ関数だが見た感じ分かりやすくするために分けて作った。†4つ目の分岐でiに0.1足しているのは気分である。ここは足さなくても問題はないと思う。upper_limitの部分は交差点やカーブの有無によって変動するので、変えられるようにしておいた。#ラインの左側をトレースする関数。upper_limitには自由に数字を入れられる。#iがupper_limitになるまでトレースを続行。#csの値が20以上なら大きく右折。#csの値が17以上20未満なら小さく右折。#csの値が14以上17未満なら直進。#csの値が11以上14未満なら小さく左折。#csの値がそれ以外、つまり11未満であれば大きく左折。#csの条件判断を0.001秒ごと行う。今回は右折する場面がないので右折は省略。一応aの値をマイナスにすれば右折する。#交差点で左折する関数。#カラーセンサー(以後cs)の値が20になるまで左へ転回することを意味する。stop()交差点に入って少し左に曲がってから止まるので向きを調整する必要があった。進んで右に曲がるとちょうどいい位置で止まってくれた。#交差点で直進する関数。#csの値が15になるまで右に転回。#ボールをつかむ関数。#ボールをシュートする関数。#約80°リフトを上げる。†#の後ろの記述は説明のために書いてあるので、実際に書く必要はない。微調整をしたのでわかりずらい部分は---で囲んである。囲まれた部分を一つの動作としてみてほしい。#ボールにアームの向きを合わせる。#Jの方向に向きを合わせる。