レスキューラインでは2015年ルールから「交差点マーカ」が登場しました. コースの交差点に25mm×25mmの緑色の印があり,ロボットはこの印を見て 交差点でどちらに曲がるのか?直進するのか?Uターンするのか?を判断することを要求されます.
「交差点マーカ」を読み取ろうとすると最低左右に1個ずつ計2個のセンサが欲しくなります. TJ3などで使用できるカラーセンサが市販されおりこれで対応可能ですが,複数使うには少し価格が高いということもあり自作してみました.
(2015年に作りましたが一部の部品が生産終了になったため,2019年に改訂しました.)
こんなセンサが欲しい.と考えました.
- なるべく安く.
- マーカを見逃さないようにたくさんのセンサを付けたい.
- ロボットの入力端子をたくさん使うのはイヤ.
- 緑色は当然として,緑色以外のマーカでも使いたい.
- どうせなら,白黒のラインも一緒に見たい.
- プログラムはなるべく簡単に作りたい.
こんなセンサを作ろうか.と考えて作り始めました.
- コスト低減のため,専用のカラーセンサICは使用せず,フルカラーLEDとフォトトランジスタでセンサを構成.
- センサを5組並べて実装.
- ロボットとはI2Cで通信.
- 出力値は色相.
- ついでに明暗から白黒ラインも検出.
- Arduino互換機.
床面に向けた赤,緑,青の3色のLEDを順番に点灯し,その反射光をフォトトランジスタで受光して電圧に変換します. LEDの点灯制御と反射光(電圧)から色相と輝度を求める計算はArduino互換の親基板で処理します. また,親基板(Arduino互換機)はロボット(TJ3など)に色相・輝度のデータを送信します.
実際の回路図,部品表,基板図はこのようにしました.
組み立て方はこちら.
子基板に使用するLEDは,3色並べるとかさ張るので3色が1体になったフルカラーLEDを使用します (挿入実装のOSTA71A1D-Aまたは,表面実装のOSTVAVS4C2Bです). フォトトランジスタは可視光用のNJL7502Lです.
親基板はArduino互換としますが, センサ5個をそのままA/D変換入力端子に接続するためにマイコンはArduino UNOに使用されている挿入実装のATMEGA328P-PUではなく 表面実装のATMEGA328P-AUを使用します.また,部品代節約のためシリアル通信回路は実装していません. 結果としてArduino Pro(5V,16MHz互換)互換となります.
組み立て後
製作した基板をArduino互換機として動作させるためにはマイコン(ATMEGA328P-AU)にヒューズビットとブートローダの書き込みが必要です. AVRマイコンの開発環境Atmel Studio,AVRマイコンの書き込み器ATMEL-ICE-BASICなど,Arduino開発環境のArduino IDEを準備し,下記の手順で実施します.
- ブートローダATmegaBOOT_168_atmega328.hexを書き込む
- ヒューズビットにEXTENDED 0x05,HIGH 0xDA,LOW 0xFFを書き込む
- ロックビットに0x0Fを書き込む
色を数値で表す方法はいくつかありますが,今回はRGBと色相(Hue)を使います. RGBは,赤(Red),緑(Green),青(Blue)3原色それぞれの強さで色を表します.色相は色を順番に円形に並べて角度で色を表します.
今回のセンサではフルカラーLEDの3色を順番に点灯してそれぞれの反射光をフォトトランジスタで電圧に変換してArduinoのA/D変換器で読み込むので, 得られる数値はRGBとなります.(反射光の強さとフォトトランジスタの出力電圧とRGBがリニアに対応するのかという問題はありますが,概ねうまくいきます.)
これをそのままTJ3に送ってもよいのですが,そうすると3色×5センサで15個のデータを送る必要があることと, TJ3のプログラム開発環境C-Styleで計算プログラムを書くのは大変であることから,Arduino側でRGBを色相に変換してから送ることにします. ロボット(TJ3など)はセンサ1つあたり1つの数値を受け取り,その大きさだけで色を判別できるようになります.
色相(色相環)の例.
緑は90°〜180°くらいになります.
RGBから色相(H)を求める式は,
tanH=(√3(G - B)) / (2R - G - B)
なのですが,簡単な代用の式があるのでこれを使います.
R,G,Bの中から,max(最大値)とmin(最小値)を求めて,
max = minのとき,
H = 0
max = Rのとき,
H = (60 * (G - B) / (max - min) + 360) mod 360
max = Gのとき,
H = (60 * (B - R) / (max - min)) + 120
max = Bのとき,
H = (60 * (R - G) / (max - min)) + 240
とします.
実際の回路ではLEDやフォトトランジスタやその他部品などに特性のバラつきがあるため,補正の処理が必要です. 今回は基板上のタクトスイッチ(SW2)を押すと補正値を計算しEEPROMに保存するようにします. リセット時にEEPROMから補正値を読み出し,計算に適用します.
TJ3には,複数のTJ3を接続してI/Oを増設する機能があります.通信はI2Cで1台がマスタ(親機),他のTJ3がスレーブ(子機)となります. I2Cは多くのマイコンやセンサで使用される一般的な通信です. ArduinoでTJ3の子機のマネをして通信すれば,TJ3の親機からはTJ3の子機が繋がっているのと同じように見えます. 今回はこれを利用してTJ3でセンサのデータを読めるようにします.
作成したArduino用のプログラムはこちらです.
Arduino IDEからプログラムを書き込むには,USBシリアル変換アダプタとUSBケーブルを使用します.
TJ3Bでの使い方を紹介します.
カラーラインセンサの親基板と子基板をTJ3Bに取り付け,親基板のCN1またはCN2とTJ3BのCN11またはCN12を4極のケーブルで接続します.
このカラーラインセンサはTJ3Bの子機と同じようにTJ3Bと通信します.
そのため,まずはTJ3BとC-Styleを子機が使える状態に設定します.
パソコンでC-Styleを起動し,ウィンドウの右上にある「Setup」ボタンを押してSetupウィンドウを出します.
Setupウィンドウで「Advanced Mode」にチェックを入れます. 次に出てきた「I2C I/O ID Setup」にもチェックを入れ,その隣のプルダウンメニューは 「I/O[0]:Master」に設定します.
これでC-Styleで子機を使ったプログラムを書く準備ができました.
C-Styleの設定が終わった状態でTJ3Bにプログラムをダウンロードすると, TJ3Bが子機と通信するようになります.
とりあえず,空の無限ループのプログラムをビルド,ダウンロードします.
TJ3Bの電源をONし,センサモニタを起動して,まず「モニタ開始」ボタンを押します. TJ3B(親機)の各センサの値が表示されます.
次に右上のプルダウンメニューで「Master」を「Sub I/O[1]」に変更すると子機であるカラーラインセンサの値が表示されます.
最初は正しい値が表示されないので,センサの補正を行います.
TJ3Bを白い床や紙の上に置いて,センサ親基板のSW2を押します.するとセンサ子基板のLEDが赤,緑,青の順番に点灯します.
次に,センサ親基板のSW1を押します.一旦LEDが消灯しセンサが再起動します.
これで,補正は完了です.
センサの補正が完了すると,白い床の上ではセンサモニタの値は下の図のようになります.
センサモニタでCN1〜CN10の各値の内,前半のCN1〜CN5がセンサ1〜センサ5の色の測定結果です.
色相を0〜359の値で示し,白や黒では色が無いので1023を示します.
後半のCN6〜CN10はセンサ1〜センサ5の明るさの測定結果です.
白で約500を示し,黒に近づくにつれ小さな値を示します.
次に,コース上での例です.
右側2つのセンサ(センサ4と5)が緑マークの上に来るようにTJ3Bを置きました.
センサモニタの値は下の図のようになります.
プログラム中でカラーラインセンサの値を使いたいときも,TJ3Bの子機と同じように使えます.
例えばセンサチェック命令の場合,左の図のようにコネクタ番号を選ぶプルダウンメニューの上をクリックして,
I/O[1]を選ぶことで,カラーラインセンサの値を判定値に使えます.
判定値は1/10の値で入力します.例えば,色相180°を判定したい場合は18%と入力します.
概ねライントレースと緑マークの判定ができる簡単なプログラムの例を示します.
(TJ3Bは電池の電圧でモータの速さが変わるので,適宜プログラムの調整が必要です.)
このカラーラインセンサにはセンサが5組あるので,2個同時黒で直角コーナを検出したり,
左右同時緑でUターンを判断したりするプログラムを作るとより確実な走行ができるようになります.
わりと便利なセンサができたのではないかと思います.
このセンサは緑だけでなく青でも赤でも黄でも好きな色の判定に使用できるので, ロボカップジュニアのレスキューライン競技以外にも汎用的に適用可能です. ただし,赤・緑・青の3色の反射光を順番に測定していることと,I2Cによるシリアル通信を使用していることから, 普通の赤外線フォトリフレクタと比べると低速で,あまり速いライントレースには向きません.