頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


強化学習(DQN)で3枚板のロボットを歩かせる(3)

強化学習(DQN)で3枚板のロボットを歩かせる(2)
↑この続き。
まずいなと思うところがあったのでいくつか修正した。

ランダムな部分の影響を下げるため脚を短くしてみた。
板がある程度の角度で回転してもいけるように隙間を設けた(見栄えは悪いけど)。
どっちに向かって移動しようとしているのかわかるように中央の板に絵を描いた(視線の方に動こうとしてる)。



↑動作チェック。ちゃんと中央の板が持ち上がるし、反対側も引っかからない。
トルクが大きすぎると激しく飛び跳ねてしまったり、小さいと動かないわけで。

しばらくこれで学習させてみた結果、、、



あかん。
左右の脚が連動するわけでもなく、、、ただもがいてるだけ。
脚を短くしても意味がなかったか。
脚が自重で動きにくくなってたりするのもよろしくないかも。

アクションを与えた時の結果がどうしても偶然による要素が大きくなってしまい、同じ入力でも結果が異なってしまったりする。このあたりをなんとかしないとダメだなあ。



SceneKitの物理エンジンでオブジェクト間の隙間を設定する

サイズや状況にもよるんだけど、例えば立方体を床に落っことした時に立方体は床に接地してるはずなのに微妙な隙間が見える、、、なんて場合がある。

SCNBoxの場合の隙間

↑SCNBoxオブジェクトならデフォでも問題ないのかもしれないが、

Blenderで作成したオブジェクトの隙間

↑Blenderで作成したオブジェクト(daeファイルでインポート)だとデフォでこんな感じで表示される。なんでやー?!ってくらい隙間あいてる。
ちなみにどちらもサイズ1の立方体。
{
    box.physicsBody = [SCNPhysicsBody bodyWithType:SCNPhysicsBodyTypeDynamic shape:nil];
}
↑SCNBoxオブジェクトならこれでもいいんだけど、daeファイル経由のオブジェクトの場合はこのnilになってるSCNPhysicsShapeオブジェクトのオプションで指定する。こんな感じ↓
{
    NSDictionary *option = @{SCNPhysicsShapeTypeKey:SCNPhysicsShapeTypeBoundingBox  ,    SCNPhysicsShapeOptionCollisionMargin:@0.0};
    SCNPhysicsShape *physicsShape = [SCNPhysicsShape shapeWithGeometry:box.geometry options:option];
    box.physicsBody = [SCNPhysicsBody bodyWithType:SCNPhysicsBodyTypeDynamic shape:physicsShape];
}
オプション設定時の隙間

↑隙間がなくなった。

オプション設定時の隙間(失敗)

↑SCNPhysicsShapeTypeKeyはデフォでSCNPhysicsShapeTypeConvexHullだったと思うのだが、これだとSCNPhysicsShapeOptionCollisionMarginをゼロにしても隙間はまだ目立つ。

ともかく隙間が気になったらこのあたりをいじってみる。


強化学習(DQN)で3枚板のロボットを歩かせる(2)

強化学習(DQN)で3枚板のロボットを歩かせる
↑この続き。
766ステップ後は↓こんな感じになってる。



赤い線を右(x軸をプラス方向)に行くように学習しているんだが、入力は板の角度だけであり、自分の姿勢は考慮外なので、実行時にロボットはどっち方向へ向かってるかは知らぬ存ぜぬ、である。

誤差がなければy軸(画面の上方がプラス)周りに回転するはずもなく、z軸(青い線、画面手前方向がプラス)方向の移動もないはずなんだが、、、そういうわけにもいかないようで(それを希望なら2次元の物理エンジンを使えってことだな)。

一定方向へ進んでいるようにも見えるがよくわからない。
困ったことにNNの係数が変わっていなくても試行のたびに動きが異なるのである。いろいろと誤差を含むところあるしなあとは思うのだが、NNによるアクションよりも偶然の物理エンジンの処理結果の方が影響が大きいようで、これをなんとかしないといけないな。








shader modifiersでバグ回避

SceneKitでシェーダを適用すると不具合発生?
↑APPLEにバグレポ出したってのはここで書いてるんだけど、そしたら担当の人から
「ほな shader modifiers やったらどうや?」
って返事が来た。

え?shader modifiersって何?
と思っていろいろ調べて、あー、そういうのもあるのねと。

SCNShadable - SceneKit | Apple Developer Documentation
↑公式リファレンスに参考になるコードがある。
{
    SCNMaterial *material = node.geometry.firstMaterial;
    material.shaderModifiers = @{
                                 SCNShaderModifierEntryPointGeometry :
                                     @"_geometry.position.x = _geometry.position.x+2;" ,
SCNShaderModifierEntryPointFragment :
                                     @"uniform sampler2D mainTexture;"
                                     "_output.color = texture2D(mainTexture, _surface.diffuseTexcoord);"
};

    SCNMaterialProperty *imageProperty = [SCNMaterialProperty materialPropertyWithContents:@"paper5.jpg"];

    [SCNTransaction begin];
    [material setValue:imageProperty forKey:@"mainTexture"];
    [SCNTransaction commit];

}
↑自分なりにいじりつつ書いたコード。簡単な例だけど、オブジェクトはx軸方向に移動し、テクスチャを変更する、という今までならvertex shaderとfragment shaderでやってきたことと同等の処理をshader modifiersを使ってできるようになった。まだ十分じゃないのでいろいろと試していかないとまだダメだけど。

なお、shaderに相当する記述をこんなところに書くのは見通しが悪い!気色悪いわ!と俺は思ったんだが、このshaderModifiersに渡すdictionaryのshaderに相当する部分は文字列(NSString)でいいので
NSString *vertexShader =[self loadVertexShader];
みたいにして別ファイルに記述したのを読み込んでshaderModifiersに与えても動いた。
{
    material.shaderModifiers = @{
        SCNShaderModifierEntryPointGeometry : vertexShader,
        SCNShaderModifierEntryPointFragment : fragmentShader 
    };
}
これですっきりやわ。

で、この形式でシェーダーを与えたら、、、

意図通り表示されたオブジェクト

↑意図通りに表示された!!!
そうなの、、、?こっちならいけるのは何でだろう?と深く考えるのはよそう、だってSceneKitだもの(みつを)。

ちなみにバグレポで「これやったらいけたで!」って返事しようとしたら
No response received. Now closing this bug.
って書いててCLOSEDになってて返事できない状態。1ヶ月ほど返事しなかったらそうなるのかな。案外迅速なのね、、、


強化学習(DQN)で3枚板のロボットを歩かせる

3枚板ロボット
強化学習(DQN)が面白いので倒立振子の次にこんなのをやっている。↑
板を3枚ならべSceneKitのSCNPhysicsHingeJointで接続、両端の2枚にトルクをかけられるようにしてる。
従来通りTensorFlowで学習、SceneKitの物理エンジンを使ってる。

NNは全結合層をいくつか重ねたもので従来と同等レベル(今の所)。
入力は3枚の板の角度を過去4時刻分で12個。
出力は左右の板にプラスかマイナスのトルクをかける、ということで2x2の4個。

移動するほどいいよ、という報酬を与えて学習させてみたところ、、、



赤い線を右に行くように学習してるはずなのですが、、、
ぜんぜんダメです、ピクピクしてるだけですね!
はい、これから頑張ります。








Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.

FC2Ad