黒ライントレースをしながらカラーブラックの色を読み取る~レゴマインドストームEV3~
Contents
ライントレース+色の読み取り
以前に教育用レゴマインドストームEV3で前進をしながら4色のカラーブロックの色を読み取るプログラムを作成した。
今回はその時のプログラムの応用で黒ライントレースをしながらカラーブロックの色を読み取るプログラムに改造した。
読み取る条件は以下の通りとする。
- カラーブロックは4色(赤、青、黄、緑)
- カラーブロックの置かれる順番はランダム
- 停止せずにライントレースをしながらカラーブロックを読み取る
- 4色を読み取った後に読み取った順番でカラーを読み上げる
基本的には前回と同じ条件なのだが、ただの前進からライントレースに変更した事により、
- カラーセンサーをライントレース用とカラーブロック用の2つにした
- 黒ライントレースのロジックを追加した
- 1度読み取った色は2度目は読み取らない様にプログラムの修正を行った(誤検知防止)
が前回と異なる。
本体について
本体はトレーニングロボットをベースにしている。
プログラム
全体図
プログラム全体は以下の通り。
処理群1と処理群2に分かれており、
処理群1:トレーニングロボットが4色読み取るまでライントレースを続ける。4色読み取ったら順番に色を読み上げる
処理群2:カラーセンサーにてカラーブロックを読み取った順番に数値配列に格納する。一度読み取った色は2度目は読み取らない
となっており、全体的なプログラムは前回と大きな差は無いのでそれぞれの処理の詳細については前回の記事を参照して欲しい。
今回は変更を加えた部分について説明をしてゆく。
黒ライントレース
処理群1の前半部分、以前はステアリングブロックで前進をしていた部分に黒ライントレースのロジックを追加している。
ライントレースの基本的な考え方はこちらの記事を参照。
基本的な考え方は黒と白の中間地点をカラーセンサーの反射光の強さで読み取って白が多ければ左車輪のパワーを増して右方向へ、黒が多ければ逆の操作を行う。

1 | 変数centerに25をセットする 25は黒と白が半々の状態の時の反射光の強さをセットするのだが、周囲が明るいと小さな値、暗い場合は大きな値になりがちなので事前に値を測定してプログラムにセットする またこの数値が大きい場合(周囲が暗い時)は処理5で割る数値(今回は2)も大きくした方が良い |
2 | 変数Powerに20をセットする 直線走行時のベースとなるパワー値 |
3 | 変数cneterから値を読み込む |
4 | ポート4のカラーセンサーから反射光の強さを読み込む |
5 | 3(中央値)と4(現在の値)と差分を2で割った補正値を算出する 差分をそのまま左右の車輪のパワーに加・減算してしまうと値が大きすぎて蛇行がつよくなるので、適当な数値で割っている 大きな数字で割るほど補正が弱くなり滑らかに走行するが急なカーブでは補正が間に合わなくなりラインから外れてしまう 1の値との関係もあるので周囲が明るさに応じてこの値は調整する |
6 | 変数Power(20がセットされている)を読み込む |
7 | 6(20)から5(補正値)の絶対値の差分を求める |
8 | 7に5の補正値を加算する |
9 | ポートB(左車輪)に8の値をセットする |
10 | 7から5の補正値を減算する |
11 | ポートC(右車輪)に10の値をセットする |
同じ色は読み取らない
カラーブロックは4色あるのだが同じ色はふたつは無いので赤→青→赤という事はありえない。
カラーセンサーが正しく動作をすれば良いのだが誤動作する事も有り得るので念の為、同じ色は2度目は読み取らないようにロジックを改修した。

1 | Red変数に”偽”をセットする |
2 | Blue変数に”偽”をセットする |
3 | Green変数に”偽”をセットする |
4 | Yellow変数に”偽”をセットする |
5 | Blue変数を読み取る |
6 | ロジック判定を行いBlue変数が”真”(1度読み取った事がある)なら上部の7を実行して何もしない ”偽”なら初回のBlueの読み込みなので下部の8の処理を行う |
7 | 既に1度Blueを読み取っているので何もしない |
8 | Blue変数に”真”をセットする 後続の処理については以前の記事を参照 |
プログラム全体
一応、プログラム全体を載せておく。
処理群1・前半
Count変数が4以上になるまでライントレースを続ける。
処理群1・後半
停止してColor数値配列に格納された順番に色を読み上げる。
処理群2・前半
初期値の設定。
処理群2・Blue、Green
カラーセンサーがBlueとGreenを読み取った時の処理。
同じ色は2度目は読み込まず、Color数値配列に読み取った色の数値を格納する。
処理群2・Yellow、Red
カラーセンサーが読み取った色がYellowとRedの時の処理。
処理群2・その他の色
カラーセンサーが読み取った色がBlue、Green、Yellow、Red以外の時は何もしない。
プログラムの実行結果
実際にこのプログラムを実行した時の様子を動画の最後に載せているので確認してみて欲しい。
いつも動画を拝見して参考にさせてもらってます。
昨年、WROという大会に出場したのですが、ライントレースの精度が悪く
ルール上のタスクを全てこなすことができませんでした。
つまり、ライントレースが遅すぎてタイムオーバーしました笑
他校のライントレースを見てると、とても速いかつ、正確でした。
PID制御というものをしているそうです。これまでに上げられた動画を拝見しましたが、
PID制御に触れた動画は一切無かった様なので、ご連絡しました。
申し遅れました、現在高2の普通科に通っている男子高校生です。
色々とお忙しいところでございましょうが、アドバイスを頂けたら光栄です。
岡本さん
コメントありがとうございます。
すいません自分はPID制御はやったことが無いです。
こちらの記事の「今回のロジック」の6~8で左右のPowerの制御を行っていますがここにPID制御を適用するとスムーズにPower調整ができるのだと思います。
こちらのサイトのプログラムは参考になりそうです。
リンク先の記事のプログラムで言うと、
y:直近の反射光の強さ
r:48 中心位置の反射光の強さ
e_pre:前回の誤差
T:制御周期 タイマーブロックで前回のループからの時間を計測
KP,KI,KD:適当な数値を入れて最適な数値を探る
するのでは無いかと思いました(すいません、自分もやったことが無いので曖昧です)