黒いラインを追従して進む移動ロボットのシミュレーション(ライントレーサー)をChainerRL(DQN)を用いて実装しました。
学習結果を可視化したものが以下になります。
こんな感じで、エージェント(緑色の玉)が黒い線を追従しているのがわかると思います。
カクカクと動いている青い線はエージェントの進もうとしている方法(速度)を表しています。
コードはこちらにてアップしてあります。
https://github.com/slowsingle/LineTrace
描画はすべてcv2モジュールを使っています。画像処理じゃなくて画像描画のためにcv2をメインで使うのは久しぶりというか、あまり見ないような気がします。
本当はPyQtとかwxPythonを使うのが正攻法かもしれません。(ま、今回はcv2だけで事足りる程度のタスクだっただけです)
エージェントの設計
def update(self, act_num):
# act num に応じて方向転換する
act_list = (np.pi / 3.0, np.pi/ 4.0, np.pi/ 6.0, 0.0, -np.pi / 6.0, -np.pi/ 4.0, -np.pi / 3.0)
# :
# <略>
行動は左方向へ進むのが3段階、右方向へ進むのが3段階、直進と合計7つ用意しました。
したがって、DQNにおけるニューラルネットワークの出力ユニットは7個になります。
環境の読み込み
# フィールド画像の読み込み
# フィールド画像には白の中に黒線があるものを想定する
self.field = cv2.imread("field/field.png")
# :
# <略>
環境はpng画像として用意し、それを読み込みました。
githubにもフィールド画像をアップしています。このように、画像さえ作ってしまえば色々な領域でエージェントを走らせることができます。
状態の取得
lineTrace.pyのAgentクラスのget_state()メソッドに実装してあります。
エージェントが取得できる状態はエージェントの前方においたセンサアレイから取得される、各センサの値(0 or 1)のリストになります。
ライントレーサーについては以下のサイトなどを参考にしてください。
http://www.cct.ac.jp/mech/yume2/yume2.htm
上記のサイトですと、センサが2つあって、どのセンサが黒い線上にいるかを検知して、次の行動を決定しています。
私のプログラムではセンサは9つ用意してあります。
センサの数はlineTrace.pyのLineTraceクラスの__init__()メソッドのobs_space変数にて設定できます。
学習とテスト方法
学習はdqn.pyに実装されています。
中身は、以下のサイトに書いてあるコードをコピー&ペーストし、ちょいちょいと書き換えただけです。
https://github.com/pfnet/chainerrl/blob/master/examples/quickstart/quickstart.ipynb
テストはdqn-test.pyでできます。
githubには学習済みのモデルも上げていますので、すぐに実行できると思います。