[Unity] ライントレーサーを実装してみた

[Unity] ライントレーサーを実装してみた

Unityでのネタ的な投稿です。

地面の黒ラインに沿って走行するロボット(ライントレーサー)をUnity上で再現してみました。

linetracer-thumb

黒ラインはカメラ画像から認識するようにします。
今回はカメラを照度センサに見立て、画像全体の輝度からロボットをラインに沿って走行するようにフィードバック制御します。

ロボットの実装

自律移動型ロボットの中でも基本的な構造となる独立二輪型を採用しました。

linetracer-1
linetracer-2

左右後部に独立して回転する車輪が2つ、筐体を三点接地で支えるためのキャスタからなる構造です。
前進・後進、旋回、その場旋回などの動きが可能です。

車輪はHingeJointで筐体にジョイント接続します。

linetracer-3

ここで、HingeJointのUserMotorにチェックを入れます。
こうすることで、ジョイントはモータとして機能するようになります。

キャスタはFixedJointで筐体に固定させました。
したがって、走行すると地面と擦れます(笑)
地面との摩擦さえなければ走行には差し支えないので大丈夫でしょう。

照度センサの実装

地面の明暗を計測するための照度センサを実装します。
照度センサはCameraを用いて実装します。

linetracer-4

カメラ画像の照度を取得するためには、画像のピクセルデータを取得する必要があり、TargetTextureにRenderTextureを指定します。
そして、このRenderTextureのピクセルデータから画像全体の輝度を計算するスクリプトを実装し、アタッチします。

IlluminanceSensor.cs

これで照度センサの完成です。

フィードバック制御の実装

ライントレースを行うには、照度センサの値を用いてラインのずれが0となる方向に旋回しながら走行する必要があります。
これは、ラインのずれ計算→旋回量計算→旋回量反映のループ処理を実装することで実現できます。
(今回は説明簡略化のため伝達関数やブロック図云々の話をすっ飛ばします・・・)

ラインのエッジをずれ0の位置とし、右にずれるほど正、左にずれるほど負の値となるようにずれを定義します。

 ラインのずれ = 閾値 – 照度センサ値

そして、ラインのずれを制御偏差(error)としてPID制御を行います。

 制御量 = KP * error + KI * errorの積分値 + KD * errorの微分値
  KP:比例ゲイン
  KI:積分ゲイン
  KD:微分ゲイン

最後に、制御量を左右車輪の目標速度に加減して終了です。

 左車輪の目標速度 = 前進目標速度 – 制御量
 右車輪の目標速度 = 前進目標速度 + 制御量

上記の処理を行うフィードバック制御のスクリプトを実装し、アタッチします。

RobotControler.cs

実際に動かしてみる

走行速度・フィードバック制御のゲインは以下のように設定しました。
(何故かPIが大きい気がしますが、まあいいか・・・)
 speed = 500
 KP = 1500
 KI = 500000
 KD = 500

コースは以下としました。

linetracer-course

以下、実際に走らせた動画です。

黒ラインの左エッジに沿って走行しています。
急カーブでブレてコースアウトしそうになってますが、そこそこの速度でライントレースしてくれるようになりました。

照度センサを増強してみた

照度センサ1個でもライントレースはできますが、環境光に左右されずにライントレースさせるために2個にしたパターンも試してみました。

以下、2個の照度センサでフィードバック制御を行うように改良したスクリプトです。

RobotControler2.cs

2個の照度センサは左右前方に設置します。
両者は距離を少し空けます。

ラインのずれの計算は両者の照度の差分で求まります。
 ラインのずれ = 右の照度センサ – 左の照度センサ

以降のフィードバック制御の処理は照度センサ1個の時と変わりません。

走行速度・ゲインは以下の通り。

 speed = 1000
 KP = 3000
 KI = 500000
 KD = 1000

照度センサ1個の時よりも安定して高速でライントレースしてくれるようになりました。

おわりに

実物のライントレーサーを模倣した原理でライントレースを行っているので、フィードバック制御の学習の題材としての活用が期待できるかもしれません。
ただし、あくまでシミュレータなので参考程度にとどめておくべきかと思います。