Maxima で解くロボット・ダイナミクス
□ 2リンク・マニピュレータの運動方程式の導出
重心位置
(%i ) depends([q1, q2],[t]);
(%i ) p1: matrix([Lg1*cos(q1)],[Lg1*sin(q1)]);
(%i ) p2: matrix([L1*cos(q1) + Lg2*cos(q1+q2)],[L1*sin(q1)+Lg2*sin(q1+q2)]);
重心速度
(%i ) v1: diff(p1, t);
(%i ) v2: diff(p2, t);
定数の宣言
(%i ) declare(g, constant,
L1, constant, L2, constant,
Lg1, constant, Lg2, constant,
m1, constant, m2, constant,
I1, constant, I2, constant);
運動エネルギー
(%i ) K1: m1*trigsimp(v1.v1/2) + (1/2)*Ig1*diff(q1,t)^2;
(%i ) K2: m2*ratsimp(trigreduce(expand(v2.v2/2)),q1,q2) + (1/2)*Ig2*diff(q1+q2,t)^2;
(%i ) K: ratsimp(K1+K2,diff(q1,t),diff(q2,t));
(%i ) load("lrats");
(%i ) K: ratsimp(fullratsubst([Ig2 = I2 - m2*Lg2^2, Ig1 = I1 - m1*Lg1^2], K),diff(q1,t),diff(q2,t));
位置エネルギー
(%i ) P: m1*g*p1[2][1] + m2*g*p2[2][1];
ラグランジュ関数
(%i ) L: K-P;
ラグランジュ方程式
(%i ) t1: ratsimp(expand(diff(diff(L, diff(q1,t)), t)) - expand(diff(L,q1)), diff(q1,t,2), diff(q2,t,2), g);
(%i ) t2: ratsimp(expand(diff(diff(L, diff(q2,t)), t)) - expand(diff(L,q2)), diff(q1,t,2), diff(q2,t,2), g);
慣性行列
(%i ) M: matrix([coeff(t1, diff(q1,t,2)), coeff(t1, diff(q2,t,2))] , [coeff(t2, diff(q1,t,2)), coeff(t2, diff(q2,t,2))]);
重力項
(%i ) G: matrix([coeff(t1, g)], [coeff(t2, g)])*g;
非線形項
(%i ) h: expand(matrix([t1],[t2]) - M.matrix([diff(q1,t,2)],[diff(q2,t,2)]) - G);
非線形項中の歪対称行列の導出
(%i ) q: matrix([q1],[q2]);
(%i ) s1: diff(M,t)[1] - (transpose(diff(q,t)).diff(M/2,q1))[1];
(%i ) s2: diff(M,t)[2] - (transpose(diff(q,t)).diff(M/2,q2))[1];
(%i ) H: matrix(s1, s2);
(%i ) H1: expand(H-diff(M,t)/2);
(%i ) S: expand(H1-transpose(H1));
証明は省略するが,上記の計算で S が歪対称行列となることが証明できる.
□ 運動方程式に対するリグレッサ行列の導出
(%i ) Reg(eq, pm) :=
block([l:[]], for f in pm do
(eq: fullratsubst([f = aa], expand(eq)),
c: coeff(ratsimp(eq, aa), aa),
eq: eq - c*aa,
l:endcons(c,l)),return(l))$
(%i ) T: [I1, I2, m1*Lg1, m2*Lg2, m2];
(%i ) Y: matrix(Reg(t1, T), Reg(t2, T));
□ リグレッサ行列からの最小動力学パラメータの導出
参考文献:
川崎,村田,神崎,
「数式処理による閉リンクマニピュレータの最小動力学パラメータの解析」,
日本ロボット学会誌,Vol. 13, No. 4, pp.558 〜 564, 1995.
基本関数の導出
(%i ) declare(a, constant, b, constant);
(%i ) tt: expand(trigexpand(a*t1 + b*t2));
(%i ) ff: showratvars(tt);
(%i ) load(flatten);
(%i ) f: flatten(map(lambda([x], if constantp(x) then [] else x), ff));
(%i ) Indets(e, ff) := makelist(hipow(e, ff[j]), j, 1, length(ff))$
(%i ) BF(tt, ff) := block([L:[], r],
for i:1 thru nterms(tt) do (
r: Indets(part(tt, i), ff),
if not member(r, L) then L: cons(r, L)),
L)$
(%i ) Functs(l, f) := product(f[i]**l[i], i, 1, length(l))$
(%i ) bf: map(lambda([l], Functs(l, f)), BF(tt, f));
リグレッサと物理パラメータの更新
(%i ) Fcoef(e, f) := map(lambda([x], if constantp(x) then x else 0),
makelist(ratcoef(expand(trigexpand(e)), f[i]), i, 1, length(f)))$
(%i ) Bcoef(c, f) := block([L:[]],
for i:length(c) step -1 thru 1 do (
L: append(Fcoef(c[i,1], f), L)), L)$
(%i ) drop(l, n) := flatten(makelist(if i = n then [] else l[i],
i, 1, length(l)))$
(%i ) MP(Y,T) := block([B:transpose(matrix(Bcoef(col(Y,1), bf))),
T1:T,Y1:Y,be,Be],
for i:2 while i <= length(row(Y1,1)[1]) do (
bi: transpose(matrix(Bcoef(col(Y1,i), bf))),
B: addcol(B, bi),
be: echelon(B),
if be[i,i] = 0 then block([j,k,dt],
Be: block([L:row(be,1)],
for j:2 thru i-1 do L:addrow(L, row(be,j)), L),
k: invert(submatrix(Be,i)).col(Be,i),
dt: transpose(k)[1]*T1[i],
T1: drop(T1, i),
for j:1 thru length(dt) do T1[j]: T1[j]+dt[j],
Y1: submatrix(Y1,i),
B: submatrix(B,i),
i: i-1
)
),[Y1,T1])$
(%i ) new: MP(Y,T);
(%i ) Y: first(new);
(%i ) T: second(new);
この計算方法は,初期のリグレッサと動力学パラメータの値に依存することに
注意が必要である.たとえば,次の T と Y から最小動力学パラメータを求め
ると,異なる結果が得られる.
(%i ) T1: [m1*Lg1, m2*Lg2, m2, I1, I2];
(%i ) Y1: matrix(Reg(t1, T1), Reg(t2, T1));
(%i ) new: MP(Y1,T1);
(%i ) Y1: first(new);
(%i ) T1: second(new);
《注意》
色々検証を進めた所,上記の計算手順や関数で平面4リンクマニピュレータの
最小動力学パラメータを導出できることが確認できましたが,垂直多関節型の
3リンク以上のマニピュレータでは正しい結果が出てきません.幾つか細かな
点で修正が必要となります.
Maxima
naniwa@rbt.his.u-fukui.ac.jp