前回はFABRIK法やCCD法でロボットアームの逆運動学を試してみましたが、今回はヤコビ行列を用いた方法を試してみます。
環境:Python3.8.5、Jupyter Notebook6.1.4
運動学:
運動学においては、各Jointの角度を入力すると、アーム先端のEnd-Effectorの座標が求まります。
3リンクアームの場合、Link1の角度θ1の時のx成分、Link2の角度θ1+θ2の時のx成分、Link3の角度θ1+θ2+θ3の時のx成分を単純に足し合わせればEnd-Effectorのx座標が得られます。y座標についても同様に求めると、End-Effectorの座標(x, y)は以下のように求まります。L1、L2、L3は各Link1、2、3の長さ。
x = L1cos(θ1) + L2cos(θ1+θ2) + L3cos(θ1+θ2+θ3) y = L1sin(θ1) + L2sin(θ1+θ2) + L3sin(θ1+θ2+θ3)
変化量 / ヤコビ行列:
P = f(Θ)
Θ = g(P)
dP/dt = df(Θ)/dt
ΔP = J(Θ)・ΔΘ
J(Θ) = [[dx/dθ1, dx/dθ2, dx/dθ3], [dy/dθ1, dy/dθ2, dy/dθ3]]
dx/dθ1 = - L1sin(θ1) - L2sin(θ1+θ2) - L3sin(θ1+θ2+θ3) dx/dθ2 = 0 - L2sin(θ1+θ2) - L3sin(θ1+θ2+θ3) dx/dθ3 = 0 - 0 - L3sin(θ1+θ2+θ3) dy/dθ1 = L1cos(θ1) + L2cos(θ1+θ2) + L3cos(θ1+θ2+θ3) dy/dθ2 = 0 + L2cos(θ1+θ2) + L3cos(θ1+θ2+θ3) dy/dθ3 = 0 + 0 + L3cos(θ1+θ2+θ3)
J(Θ) = [[- L1sin(θ1) - L2sin(θ1+θ2) - L3sin(θ1+θ2+θ3), - L2sin(θ1+θ2) - L3sin(θ1+θ2+θ3), - L3sin(θ1+θ2+θ3)], [ L1cos(θ1) + L2cos(θ1+θ2) + L3cos(θ1+θ2+θ3), L2cos(θ1+θ2) + L3cos(θ1+θ2+θ3), L3cos(θ1+θ2+θ3)]]
逆運動学 / 疑似逆行列:
ΔΘ = J-1(Θ)・ΔP
J+ = J.T・(J・J.T)-1
J+ = np.linalg.pinv(J)
ΔΘ = J+(Θ)・ΔP
ΔΘ = J+(Θi)・(P - f(Θi))
ΔΘ = J+(Θi)・(P - f(Θi))λ
Θi+1 = Θi + J+(Θi)・(P - f(Θi))λ
- 運動学でEnd-Effectorの座標[x, y]を求める式を用意する
- 運動学の式を偏微分してヤコビ行列Jを求める
- ヤコビ行列Jの疑似逆行列J+を求める
- 目標座標とEnd-Effector座標の差分とJ+を用いて必要な回転量を求める
- スケーラーとしてλ=0.1程度を掛け合わせる
- 以後この操作を繰り返し徐々に目標に近づく
図形的に仕組みを見てみる:
dx/dθ1 = - L1sin(θ1) - L2sin(θ1+θ2) - L3sin(θ1+θ2+θ3) dx/dθ2 = 0 - L2sin(θ1+θ2) - L3sin(θ1+θ2+θ3) dx/dθ3 = 0 - 0 - L3sin(θ1+θ2+θ3) dy/dθ1 = L1cos(θ1) + L2cos(θ1+θ2) + L3cos(θ1+θ2+θ3) dy/dθ2 = 0 + L2cos(θ1+θ2) + L3cos(θ1+θ2+θ3) dy/dθ3 = 0 + 0 + L3cos(θ1+θ2+θ3)
コード:
- 最初にFKの計算式、そしてヤコビ行列を求めたあと疑似逆行列を求めてIKを計算しています。
- numpyにはmatrixクラスもありますが、将来的に廃止となるようなので行列式にはnp.array()を使用しています。
- np.array()の場合、行列同士の掛け算はドット積np.dot(A, B)で計算しますが、A@Bのように@でも計算可能です。
- 最後にインタラクティブにマウス座標を追従するプログラムがあるため、Jupyter Notebookのbackendは%matplotlib notebookを使用しています。
- 同次変換行列を用いる方法
- 特異点における問題点や回避策
- 回転角範囲の制約と設定
- End-Effectorを固定したまま他のジョイントを動かす方法
- クロス積を用いたヤコビアンの計算方法
- 3Dへの拡張