2024年11月12日
004-2.ライントレース入門-第3回「ステアリングを使ってトレースする」
「ライントレースロボット」とは、床面にある線(ライン)を追いかける(トレースする)ロボットのことです。こうしたロボットには「入力」と「出力」という制御の基本が詰まっている(なおかつ奥が深い)ので、ロボット競技の世界では定番の要素となっています。 このコーナーでは、「教育用レゴ マインドストームNXT(以下、NXT)」を使ってライントレースロボットを作り、制御することの面白さをお伝えしたいと思います。 (文/松原拓也)
◆ ステアリングを持ったロボット

前回までは、ライントレースロボットを作るさいに光センサを1個だけ使い、ラインを検出していました。
今回は、部品の数を増やして2個の光センサを使い、早くて確実に走るロボットを作ってみたいと思います。

こちらが新しく製作したライントレースロボットです。
光センサを2個使用していますが、その他に、新しい試みとして、ロボットに「ステアリング」の機構を取り入れてみました。ステアリングというのは、タイヤの向きを変える仕掛けのことです。
ステアリングは本物の自動車でおなじみの機構ですが、ライントレースのロボット競技(マイコンカーラリーやロボットランサーなど)でも当たり前のように使われています。
しかし、レゴマインドストームを使ったロボット競技では、ステアリングの機構はほとんど見られません。その理由については、あとで紹介します。

使用している部品の関係を図にしてみました。
右用の光センサをポート1、左用の光センサをポート2に接続します。
モータはステアリング用と前進用で2個使っています。ステアリング用をポートA、前進用をポートBに接続します。

ロボットを裏返した様子です。後輪で駆動する三輪型のロボットです。
前輪にタイヤを1個。後輪にタイヤを2個使っています。タイヤは基本セットに付属する直径56mmのものです。

インテリジェントブロックを外してみた様子です。骨組みはほとんどありません。
部品の数を極力減らしています。

裏返して、前輪部分の光センサとタイヤを外してみた様子です。中央の大きな歯車がターンテーブルです。モータを動かすと、黒い部分が回転して、タイヤの角度が変わります。
◆ テストプログラム

まずは手始めに、床面のラインを検出するテストプログラムを作ってみました。
プログラムが長いので、AとBにの2つに分けて解説します。
[Download]光センサのテストプログラム
(NXTソフトウェア1.0で作成)

Aの部分です。
左右の光センサの値を変数「r_white」「l_white」に格納します。これよって、白い床面を学習します。

Bの部分です。
左右の光センサの黒レベルを別々に求めます。そしてその両者の値を引き算してLCD(液晶ディスプレイ)に表示し続けます。

では、実際にプログラムを動かしてみましょう。
センサをラインの中心に置いてから、プログラムを実行します。

プログラムの実行直後、床面の白レベルを変数に格納します。こうすることで、光センサの誤差を吸収します(センサの誤差については前回の記事を読み直してみてください)。

プログラムの実行後、手でセンサを動かしてみてください。

ステアリングの位置とセンサの関係を図にしてみました。
一番上の図が、センサがラインの中心にある状態、その下が右にずれている状態、一番下が左にずれている状態です。
プログラムでは、ラインの位置を次の数式で求めています。
「(右センサの黒レベル)-(左センサの黒レベル)」
つまり、
・センサが中心より右側にある場合、左のセンサが黒を検出する→位置のマイナス値が増える。
・センサが中心より左側にある場合、左のセンサが黒を検出する→位置のプラス値が増える。
となるわけです。

実際に確認してみました。
センサが右へ動くと値が減り(マイナス値)、センサが左へ動くと値が増えました(プラス値)。中央ぴったりだと0になります。実験成功です。
◆ ステアリングを動かす

今度はステアリング用モータを動かしてみたいと思います。
モータの回転とステアリングの関係は、この写真のとおりです。モータを正転させると左折、逆転させると右折します。

先に作ったテストプログラムにステアリング用モータの制御を組み込んで、ライントレースロボットのプログラムを作ってみました。
プログラムが長くなってしまいましたので、 A、B、Cの3つに分けて解説します。
[Download]ライントレースロボットのプログラム
(NXTソフトウェア1.0で作成)

一番最初の部分、Aです。
左右のセンサを変数に代入して、白レベルを学習します。
そして、ポートBの前進用のモータを回転させます。これがロボットの移動スピードになります。 モータのパワーは「50」にしてみました。あとで紹介する改良によって、最終的に「75」までパワーを上げることができました。

中間の部分、Bです。
学習した白レベルを元にセンサの黒レベルを求め、ラインの位置を変数valに格納します。

最後の部分、Cです。
スイッチブロックを使って、変数valの値がプラスかマイナスかで処理を分岐します。
・変数valがプラスの場合(センサがラインの中心より右にある場合)→→モータを逆転(ステアリングを左に)。
・変数valがマイナスの場合(センサがラインの中心より左にある場合)→→モータを正転(ステアリングを右に)。
という制御を繰り返すことで、センサをラインの中心に保ちます。
ステアリング用モータのパワーは、変数valを3倍(または-3倍)した値を与えています。もし、ステアリングがムダに動き過ぎる場合には、この値を減らしてください。

プログラムの動作中の様子です。
見事にロボットがライン上をトレースしています。ただし、あまり早い変化にはステアリングの動きが追いつきません。光センサの測定範囲が狭いので、ラインを見失いやすいのです。
マイコンカーラリーやロボットランサーで使われているロボットは6~7個の光センサを並べることでセンサの読み取り幅を広げているのですが、レゴマインドストームだとそれを実現することが難しいです。そのため、レゴマインドストームを使ったロボット競技にはステアリングの機構があまり登場しません。

ちょっと気になる問題が新たに見つかりました。
カーブを曲がる(コーナリング)時に、ロボットがグラグラとゆれてしまいます。
ロボットが安定していないようです。
◆ 四輪車型ロボット

先のグラグラする問題の対策として、 ロボットの形状を「三輪車型」から「四輪車型」にしてみました。
これで安定性が増すはずです。

ロボットの裏側です。
改造したのは、前輪の部分だけです。前輪のタイヤを1つ増やしました。
ついでにですが、光センサの取り付けるシャフトを長く伸ばしました。これはスピード上げた時にステアリングを追いつきやすくさせるためです。

先ほどと同じプログラムを実行させてみました。 走っている時のグラグラする動きは見事になくなりましたが ……しかし、ここで新しい問題が出てきました。 コーナリング時に、何かタイヤを引きずるような動きをするようになってしまいました。

この現象を図にしてみました。
図に描いた赤色の線が内側のタイヤの移動量、青色の線が外側のタイヤの移動量です。 この赤と青の線はカーブを曲がるさい、長さに差が生じます。この差を「内輪差」といいます。
内側と外側のタイヤは1本のシャフトでつながっていますので、移動量が合いません。そこで、タイヤを引きずってしまっていたわけです。
なお、図に書かれている「W」とは、タイヤの前輪から後輪までの長さ(ホイールベース)です。そして、水色で描いた扇(おうぎ)型がステアリングの切った「角度A」です。この2つの条件だけがあれば、三角関数という数学の方法を使って、カーブの半径Rを割り出すことができます。三角関数については、おそらく高校あたりで習うと思います。
さらにこの図を見れば「W」が長くなると、ロボットの小回りがきかなくなることも分かります。数学はロボット作りにいろいろと活用できるのです。
◆ ディファレンシャルギヤを使う

内輪差の問題を解消するために、ロボットを改良してみました。
パッと見ただけでは分かりにくいですが、後輪を改良しています。

裏返した様子です。前輪部分はそのままです。

後輪部分をちょっとアップにしてみました。中央に見える部品が「ディファレンシャルギヤ」(差動装置)です。ディファレンシャルギヤは「ベベルギヤ」というカサ状の歯車を3枚と、それを囲む外側の歯車でできています。

ディファレンシャルギヤの仕組みを紹介します。
まず、モータを使って、ディファレンシャルギヤの外側の歯車を回転させます。これよって、内側のギヤが回転して、左右のタイヤが回転します。
この時、タイヤの回転は右と左に分散されます。たとえば、右のタイヤが少なく回ると、左のタイヤが多く回り、その逆に右のタイヤが多く回ると、左のタイヤが少なく回ります。これよって、カーブを曲がるさいには、左右のタイヤの回転量を自動的に割り当てることができるわけです。

ディファレンシャルギヤを組み込んだことによって、内輪差の問題は解決したのですが、さらに新しい問題が出てしまいました。
ギヤを増やしたため、ホイールベース(前輪から後輪までの長さ)が伸びてしまい、小回りがきかなくなってしまったのです。
その他、もっと重心を低くしなくてはいけないなど、まだまだ改良点が多いのですが、次回までの宿題にしたいと思います。
当ブログの内容は、弊社製品の活用に関する参考情報として提供しております。
記載されている情報は、正確性や動作を保証するものではありません。皆さまの創意工夫やアイデアの一助となれば幸いです。