やってる人が全く見当たらなかったのでやってみました。
完成形
何がどうやって微分が出てくるのか
IKは、基本的に以下のパラメータから関節の角度を計算します。
- 現在の関節の角度
- ターゲットの位置
この計算は、以下の関数の合成関数です
+
*
-
/
sin
cos
sqrt
acos
そうです。全部微分できる関数です。つまり、機械学習のように勾配を求めてパラメータを更新してやればIKになるのではないか、というのが一番はじめの考え方です。
クォータニオンの微分
クォータニオンは、交換法則が成り立たないので、普通には微分できません。が、そもそもクォータニオンはただの4次元ベクトルで、積に定義があるだけなので、要素ごとに追跡して微分すればできます。
え、手計算するんですか、するわけ無いでしょう。微分するプログラムを書くためのプログラムを書きました。というかまんま微分用のコードを出力してくれるものを作りました。
題してBibuner。とはいってもただのグラフからただの勾配グラフと関数定義を作るだけなので、大した事はありません。
実装を乗せると説明が非常に冗長になると思うので、TensorflowまたはPytorchとかの機械学習ライブラリと同じようなものだと思ってください。
最適化関数とWeightDecay
最適化関数は脳死でMomentumを選びました。特に意味はないです。
WeightDecay(L2正則化)をするために、パラメータの値を0に近づけるためのオフセットが必要なところ以外はふつうの正則化です。
関節の曲がる角度
今回は、もともと曲がっている角度
から180-もともと曲がっている角度
の間、1軸のみで回転できるものとしました。 別に2軸にしても3軸にしても本質的に全く同じなのでお好みで良いと思います。
その他損失関数に加算する値
今回は特にほかに加算していません。目的のIKにそった関数を定義して加算すれば、より良い結果が得られると思います。