2024年11月18日
004-4.アルゴリズム入門-第3回「中間値を求めるロボット」
「アルゴリズム」とは英語で書くと「Algorithm」、プログラムにおける「考え方」を表した言葉です。
この連載では、ロボットのプログラミングの中で、アルゴリズムを活用する方法を紹介していきたいと思います。(文/松原拓也)
◆ グラフを描くロボット

前回に引き続き、「モバイルカラー識別」用ロボットを使って、プログラムを作ってみたいと思います。ロボットの作り方は教育用NXTソフトウェアの「ロボット・エデュケーター」を参照してください。

まずは、光センサの値を読み取って、グラフを描くだけのプログラムを作ってみました。
ロボットの移動する距離は100mm(10cm)です。その移動したぶんだけ光センサを読み取ります。
[Download]グラフを描くプログラム(NXTソフトウェア2.0で作成)

青いワクで囲んだ部分を拡大すると、このようになります。
注目は、中央にある計算ブロックで、角度センサの数値を2.045という値で割っています。
この計算によって、「モータの回転角度(度)」が「ロボットの移動距離(mm)」に変換されます。ちなみに「2.045」というのは、360をタイヤの円周(176mm)で割った値です。

プログラムを実行すると、ロボットが10cm移動してから、停止します。

実行後の液晶画面(LCD)の様子です。
X軸方向がロボットの移動距離で、点1個ぶんが1mmに相当します。 100mm(10cm)移動するのですが、そのうちの99mmまでを記録することができます。
ななめ一直線に傾いたグラフができあがりました。この傾きはほぼ一定になっています。つまり、光センサが検出した床面の明るさに対して、カウント値がきちんと比例しているということになります。
◆ 線を横切らせて測定

たとえば、このようにロボットを置いて、先ほどのプログラムを実行すると、どうなるでしょうか。

実行結果です。写真のように平らなグラフが出来上がりました。ただし、よく見ると、完全に平らではなくて、1~2カウントほど明るさが上下しているように見えます。
これはシートを床に広げたときに、平らになっていない部分があるためです(一つ前の写真の緑色の矢印がそうです)。

続いて、黒いラインを横断させてみましょう。

凹型のグラフが描かれました。
グラフのくぼんでいるところは黒線を読み取って、光センサの値が落ちているところです。
◆ 最低と最高を求める

ここからさらにプログラムを改造して、「最高値」「最低値」を求める機能を追加しました。一気にプログラムが長くなってしまいました。
最高値を求める方法については、前回に紹介した記事が参考になります。一方、最低値を求めるには、最高値を求める方法とほぼ同じですが、符号の向きが逆になることと、初期値が99にする必要があることです。
[Download]グラフを描くプログラムその2(NXTソフトウェア2.0で作成)

最後の青ワクの部分を拡大してみました。
ここで「最高値」「最低値」を液晶画面に表示しています。タブにある「Y」とは、Y座標のことです。ここに入る値が大きいほど画面の上側に表示されます。

それでは、実行してみましょう。写真は実行した様子です。

このような表示になりました。グラフは、文字をかぶせることを考えて、塗りつぶしをやめてみました。

グラフの上側にある数字が「最高値」、下側にある数字が「最低値」です。床面の白と黒で28カウントほど差があるということになります。
なお、このグラフは少しだけ、台形になっています。

光センサの特性については、以前に連載した「データロギング入門」で紹介しています。
◆ 中間値を求める

先のプログラムを改造して、中間値を求めるプログラムを作りました。青いワクで描いた部分が、追加したプログラムです。
中間値は最高値と最低値の中間の値ということです。
[Download]グラフを描くプログラムその3(NXTソフトウェア2.0で作成)

中間を求めるためには、次のような数式を使います。
「(最低値+最高値)÷2=中間値」
、、、つまり、足して2で割るだけです。これをプログラムにすると、写真のようになります。

実行すると、このようなグラフが表示されました。
この場合、「44.5」が中間値です。

グラフはこのように見ます。
中間値は最高値と最低値の中間の値なので、床面の「白色と黒色の中間」ととらえることができます。つまり、白色と黒色を区別するための「しきい値」として中間値が使えるはずです。
◆ 中間値で止まるロボット

さらに先ほどのプログラムをさらに改造して、ロボットが中間値が止まるように作ってみました。
中間で止まるためには、いったんすべてを読み取る必要があります。そこで、10cmほど前進してから、後退して中間値を検出するようにしたいと思います。
[Download]グラフを描くプログラムその4(NXTソフトウェア2.0で作成)

先ほどのプログラムをそのまま使います。青いワクの部分が。追加したプログラムです。

追加部分を拡大してみました。
比較ブロックとループブロックを使って、光センサの値を比較します。この時の比較の条件は、「光センサの値が中間値と同じか、または小さいならループを抜ける」とします。床面の白側から黒側に移動しているからです。

プログラムを実行してみたところ、ロボットは一回往復して、中間値を示したところに停止しました。
ただし良くみると、LEDの赤い光が黒い線に寄った位置で止まっています。本当なら、白と黒の中間でピッタリと止まるはずですが、、、ナゼでしょうか。

その理由を一つ考えてみました。光センサに2つの窓があります。一つは光を出す側(LED)、もう一つは光を受け止める側(フォトトランジスタ)です。この2つの窓の位置によって、光センサの読みとる範囲が変わってきます。今回のような場合だと、二つの窓の中間あたりの明るさを読み取っているということになり、その結果として、LEDの光が黒線に寄った位置でロボットが止まっていると思われます。
◆ 中間値で止まるロボット、その2

光センサの取り付け向きを90度横にしてみました。こうすることで、LEDとフォトトランジスタが一緒に黒線を横切ることができます。

プログラムを実行させてみると、ロボットはこの位置で止まりました。期待どおり、光センサが黒と白が半々の場所に止まってくれました。
【Movie】プログラム1~4の実行結果のムービー(Youtube)
これらのプログラムをライントレースロボットに応用してみてはいかがでしょうか。
当ブログの内容は、弊社製品の活用に関する参考情報として提供しております。
記載されている情報は、正確性や動作を保証するものではありません。皆さまの創意工夫やアイデアの一助となれば幸いです。