ハンドロンという過去に制作したロボットの動きを強化学習で作りました。その忘備録になります。

ハンドロンとは

ハンドロンは、昔作った卓球ボールを打ち返すロボットです。

この時は、ボールを打つ動作はプログラムで作成しておき、その打つ動作を発動させるタイミングを強化学習で調節させました。

今回の強化学習は、打つ動作は全く組み込まず、動作のすべてを強化学習で作りました。

ゲームオブジェクト

今回のハンドは、前回とほとんど同じで、ArticulationBodyを使った2リンクです(下のTipとbase2というオブジェクトはデバッグ用で関係ないです)。

ただし、今回のハンドは、先端にパッドがなく、ハンド全体でボールを打ち返すという仕様です。

Joint0

根本の設置部分です。Articulation Bodyをaddして、Immovableとしています。

Base

可動部分の実体部分です。

Joint1

根本側の可動部分です。Articulation BodyのRevoluteでJoint0に接続しています。

Link1

Joint1の実体部分です。Mesh Collider とRigidbodyで、玉と衝突できるようにしています。

Joint2

先端側の可動部分です。Articulation BodyのRevoluteでJoint1に接続しています。

Link2

Joint2の実体部分です。Mesh Collider とRegidbodyで、玉と衝突できるようにしています。

plane

下の床面です。

Target

玉です。

WallR

右側の壁です。左側の壁WallLはX座標にマイナスをつけただけなので省略します。

プログラム

Config.yaml

Asserts/ML-Agents/confing/config.yaml

実行コマンド

[name]には任意のシミュレーションID

グラフ描画

パラメータチューニングについて

今回は、ここまでできるまでに、思ったよりも時間がかってしまいました。

思うように動かなかったので、リーチングのタスクに戻して動作を確認をしたら、角度の観測値で、180で割っていないというミスがようやく見つかりました。

エピソード毎にハンドを初期位置に戻すと、その位置に戻るまでも連続的に動き(瞬間的に移動させる方法がわからなかった)、その時のボールをはじいてしまう場合がありました。

Jointの相対座標がうまく取れていなかったりもしました。

反省をまとめると、

環境を変えた場合には、簡単なタスクを成功させながら、バグを直したり、環境のパラメータを調節し、徐々に目的のタスクにしていくことが結局のところ近道になる、ということです。

おまけ。報酬と行動

報酬の決め方も結構重要でした。

初めは、ボールがある一定距離前に行ったら報酬=1でエピソード終了とだけしていました。その結果得られた行動は、下の動画の右側の2列のような動きでした。確かにボールを打ち返すのだけれども、無駄な動きが多いです。

そこで、動きに対するコスト(負の報酬)も導入しました。その結果、無駄のない自然な動作(下の動画の左側の2列)を得ることができました。