お米 is ライス

C#やらUnityやらを勉強していて、これはメモっといたほうがええやろ、ということを書くつもりです

ml-agentsでRayを飛ばして観測データを得る方法(RayPerceptionSensorComponent3D)

以下のページの「Raycast Observations」の項に簡単な説明が書いてあったのでメモ。
RayPerceptionSensorはバージョン0.12.0からのもので、このドキュメントはバージョン0.15.0時点でのもの。
ベータ版のものだというのと、誤解している箇所があるかもしれないので注意。
github.com

RayPerceptionSensorComponentとは

ml-agentsにおいて、ゲーム空間上の観測データを得る方法の一つとして用意されているもの。
使用方法は簡単で、RayPerceptionSensorComponent3D(2Dの場合はRayPerceptionSensorComponent2D)をAgentオブジェクトにアタッチするだけ。
このコンポーネントはゲーム空間上にいくつかのRay(設定によってはSphere)を飛ばし、検出されたものを観測データとしてAgentに送る。

RayPerceptionSensorComponentの設定

Detectable Tags

観測対象とするオブジェクトのタグをここで列挙する。

Rays Per Direction

飛ばすRayの数を定義する。
正面にはデフォルトで1本Rayが飛ばされるようになっていて、その左右にここで定義された本数ずつRayが飛ばされる。
したがって実際に飛ばされるRayの本数は (1 + Ray Per Direction * 2) 本になる。
例えばここに3がセットされてあれば、飛ばされるRayの数は7本となる。

Max Ray Degrees

一番外側のRayと中心のRayとの角度を表す。
90度が指定されていればちょうど左右にRayが照射されることになる。

[Rayの飛び方サンプル]

Rays Per Direction : 3
Max Ray Degrees : 90
正面を0度として-90度から30度ごとに90度まで7本Rayが飛んでいる。
f:id:spi_8823:20200320192057p:plain

Sphere Cast Radius

Rayの代わりにSphereで観測データを得る場合のSphereの半径。
0がセットされている場合はRayを使用する。
多分だけど、Rayの方向にポンとボールを投げてボールに当たったものを観測するというイメージっぽい。
Rayを使ったほうが(特に複雑なシーンでは)効果的らしい。

Ray Length

Rayを飛ばす距離

Observation Stacks

スタックに保持しておく過去の観測データの数。
例えば3を指定すれば過去3回分の観測データがAgentへのインプットとして用いられるっぽい。
Behaviour ParametersのStacked Vectorsとは独立していると書いてある。

Start Vertical Offset (3Dのみ)

Rayの照射元の位置のY方向オフセットを定義。

End Vertical Offset (3Dのみ)

Rayの照射先の位置のY方向オフセットを定義

[Length・Offsetで決定されるRayの飛び方]

f:id:spi_8823:20200320195804p:plain

[Agentへのインプットとして送られるRayデータの数]

(Observation Stacks) * (1 + 2 * Rays Per Direction) * (Detectable Tags + 2) 個
それぞれのRayに対して(タグの個数+α)個のfloat値があって、検出されたタグに応じた位置のfloatにその物体までの距離が入れられてるはず(未確認)
タグの個数にプラスアルファしているのは何も当たらなかった場合などにも対応するため(未確認)

Tips

  1. 相対的な位置を気にする必要があるようなケースでRayPerceptionSensorを使うと効果的
  2. 学習の安定性やパフォーマンスのを気にするなら、タグの個数や飛ばすRayの本数は必要最小限にしたほうがよい

その他

RayPerceptionSensorを複数個アタッチすればその分だけ観測データとして使える。
Agentスクリプトと一緒にアタッチされるBehaviour ParametersUse Children SensorsがONになっていれば子オブジェクトのRayPerceptionSensorも使用することができる。
子オブジェクトのTransformをうまい具合に変更してやればAgentオブジェクトから離れた位置からRayを飛ばしたり、Rayを飛ばす方向を変えることも可能。


以上。