Maxima で見る現代制御
□ 伝達関数の計算
システム
x'(t) = A x(t) + b u(t)
y(t) = c x(t)
A = [1 , 3; -1, 2], b = [0; 1], c = [2, 1]
の伝達関数を求める.
(%i ) A: matrix([1, 3],[-1, 2]);
(%i ) b: matrix([0],[1]);
(%i ) c: matrix([2, 1]);
(%i ) G: ratsimp(c.invert(s*ident(2)-A).b);
□ 最小実現
伝達関数が
2
s - 1
-----------------
3 2
s + s + 2 s + 1
で与えられる系の最小実現を求める.
(%i ) G: (s^2-1)/(s^3 + s^2 + 2*s + 1);
(%i ) hd: hipow(denom(G), s) - 1;
(%i ) A: addrow(addcol(zeromatrix(hd,1), ident(hd)), makelist(-coeff(denom(G),s,i),i,0,hd));
(%i ) b: addrow(zeromatrix(hd,1), [1]);
(%i ) hn: hipow(num(G), s);
(%i ) c: matrix(makelist(coeff(num(G),s,i),i,0,hd));
□ 可制御性・可観測性
システム
x'(t) = A x(t) + b u(t)
y(t) = c x(t)
A = [-2 , -1; -1, -2], b = [1; 1], c = [1, 0]
の可制御性と,可観測性を調べる.
(%i ) A: matrix([-2, -1],[-1, -2]);
(%i ) b: matrix([1],[1]);
(%i ) c: matrix([1, 0]);
(%i ) Mc: transpose(matrix(transpose(b)[1], transpose(A.b)[1]));
または
(%i ) Mc: addcol(b, A.b);
(%i ) determinant(Mc);
Mc の行列式が 0 なので可制御ではない.
(%i ) Mo: matrix(c[1], (c.A)[1]);
または
(%i ) Mo: addrow(c, c.A);
(%i ) determinant(Mo);
Mo の行列式が 0 でないので可観測である.
□ 対角化
システム
x'(t) = A x(t) + b u(t)
y(t) = c x(t)
A = [-2 , -1; -1, -2], b = [1; 1], c = [1, 0]
を対角化する.
(%i ) A: matrix([-2, -1], [-1, -2]);
(%i ) b: matrix([1],[1]);
(%i ) c: matrix([1, 0]);
(%i ) load(eigen);
(%i ) E: eigenvectors(A);
(%i ) T: transpose(matrix(E[2], E[3]));
(%i ) Abar: invert(T).A.T;
(%i ) bbar: invert(T).b;
(%i ) cbar: c.T;
この結果,システムが可制御ではないが可観測であることがわかる.
□ 可制御正準形
システム
x'(t) = A x(t) + b u(t)
y(t) = c x(t)
A = [-1 , 2; -1, -4], b = [1; 1], c = [1, 0]
を可制御正準形に変換する.
(%i ) A: matrix([-1, 2], [-1, -4]);
(%i ) b: matrix([1],[1]);
(%i ) c: matrix([1, 0]);
(%i ) load(nchrpl);
(%i ) p: NCHARPOLY(A, s);
特性多項式が s^2 + 5 s + 6 となることがわかる.なお,NCHARPOLY は大文字
で認識されるバージョン(5.9.1)と小文字で認識されるバージョン(5.10.0)がある
ようなので,注意が必要である.
NCHARPOLY の代わりに charpoly も使えるが,符号を反転させる必要がある.
(%i ) p: expand(-charpoly(A,s));
(%i ) Mc: addcol(b, A.b);
(%i ) S: matrix([coeff(p, s, 1), 1],[1, 0]);
(%i ) T: Mc.S;
(%i ) Abar: invert(T).A.T;
(%i ) bbar: invert(T).b;
(%i ) cbar: c.T;
□ 安定性判別
システム
x'(t) = A x(t) + b u(t)
y(t) = c x(t)
A = [-1 , 2; -1, -4], b = [1; 1], c = [1, 0]
の安定性を判別する.
(%i ) A: matrix([-1, 2],[-1, -4]);
(%i ) load(nchrpl);
(%i ) p: NCHARPOLY(A, s);
(%i ) solve(p = 0, s);
A の特性方程式の根 r の実部が全て負なので,システムは安定である.
あるいは,行列 A の固有値を次のように求めても良い.
(%i ) load(eigen);
(%i ) eigenvalues(A);
得られた式が複雑すぎて判定が難しい場合には float を用いて実部の数値解を求め
ると良い.
(%i ) v: solve(p = 0, s);
(%i ) float(realpart(v));
□ 状態フィードバック制御の極配置
システム
x'(t) = A x(t) + b u(t)
y(t) = c x(t)
A = [-1 , -2; -1, -4], b = [1; 1], c = [1, 0]
の極を -1+2j, -1-2j に設定する状態フィードバックゲイン f を求める.
(%i ) A: matrix([-1, -2],[-1, -4]);
(%i ) b: matrix([1],[1]);
(%i ) c: matrix([1, 0]);
(%i ) load(nchrpl);
(%i ) p1: NCHARPOLY(A, s);
(%i ) Mc: addcol(b, A.b);
(%i ) S: matrix([coeff(p1,s,1), 1],[1, 0]);
(%i ) T: Mc.S;
(%i ) p2: expand((s - (-1+2*%i))*(s - (-1-2*%i)));
(%i ) f: [coeff(p2,s,0) - coeff(p1,s,0), coeff(p2,s,1) - coeff(p1,s,1)].invert(T);
初期値 x(0) = [1; -1] の場合の応答を確かめる.
(%i ) x: [x1(t), x2(t)];
(%i ) atvalue(x1(t), t=0, 1);
(%i ) atvalue(x2(t), t=0, -1);
(%i ) sol: desolve(map("=", diff(x,t), transpose((A-b.f).x)[1]), x);
(%i ) plot2d([ev(x1(t),sol), ev(x2(t),sol)], [t,0,5], [GNUPLOT_PREAMBLE, "set grid"]);
□ 同一次元オブザーバの構成
システム
x'(t) = A x(t) + b u(t)
y(t) = c x(t)
A = [-1 , -2; -1, -4], b = [1; 1], c = [1, 0]
に対して,-4, -5 に極を持つ同一次元オブザーバ
z'(t) = A z(t) -k[c z(t) - y(t)] + b u(t) = (A - k c)z(t) + k y(t) + b u(t)
のゲイン k を決定する.
(%i ) A: matrix([-1, -2],[-1, -4]);
(%i ) b: matrix([1],[1]);
(%i ) c: matrix([1, 0]);
(%i ) load(nchrpl);
(%i ) p1: NCHARPOLY(A, s);
(%i ) Mo: addrow(c, c.A);
(%i ) S: matrix([coeff(p1,s,1),1],[1,0]);
(%i ) T: transpose(Mo).S;
(%i ) p2: expand((s - (-4))*(s - (-5)));
(%i ) k: transpose([coeff(p2,s,0) - coeff(p1,s,0), coeff(p2,s,1) - coeff(p1,s,1)].invert(T));
オブザーバの推定の様子を確かめる.初期値 x(0) = [0; 0], z(0) = [1; 1]
u(t) = 1 (単位ステップ入力)とする.
(%i ) AA: addrow(addcol(A, zeromatrix(2,2)), addcol(k.c, A-k.c));
(%i ) bb: addrow(b, b);
(%i ) x: [x1(t), x2(t), x3(t), x4(t)];
(%i ) atvalue(x1(t), t=0, 0);
(%i ) atvalue(x2(t), t=0, 0);
(%i ) atvalue(x3(t), t=0, 1);
(%i ) atvalue(x4(t), t=0, 1);
(%i ) sol: desolve(map("=", diff(x,t), transpose(AA.x+bb)[1]), x);
(%i ) plot2d([ev(x1(t),sol), ev(x2(t),sol), ev(x3(t), sol), ev(x4(t), sol)], [t,0,5], [GNUPLOT_PREAMBLE, "set grid"]);
□ 同一次元オブザーバとフィードバック制御の併合システム
システム
x'(t) = A x(t) + b u(t)
y(t) = c x(t)
A = [-1 , -2; -1, -4], b = [1; 1], c = [1, 0]
に対して,-4, -5 に極を持つ同一次元オブザーバ
z'(t) = A z(t) -k[c z(t) - y(t)] + b u(t) = (A - k c)z(t) + k y(t) + b u(t)
の推定値を用いて,極を -1+2j, -1-2j に配置したフィードバック制御を
行う.
(%i ) A: matrix([-1, -2],[-1, -4]);
(%i ) b: matrix([1],[1]);
(%i ) c: matrix([1, 0]);
(%i ) load(nchrpl);
(%i ) p1: NCHARPOLY(A, s);
(%i ) Mo: addrow(c, c.A);
(%i ) S: matrix([coeff(p1,s,1),1],[1,0]);
(%i ) T: transpose(Mo).S;
(%i ) p2: expand((s - (-4))*(s - (-5)));
(%i ) k: transpose(makelist(coeff(p2,s,i)-coeff(p1,s,i),i,0,1).invert(T));
(%i ) Mc: addcol(b, A.b);
(%i ) T: Mc.S;
(%i ) p2: expand((s - (-1+2*%i))*(s - (-1-2*%i)));
(%i ) f: makelist(coeff(p2,s,i)-coeff(p1,s,i),i,0,1).invert(T);
併合システムの応答を確かめる.
初期値 x(0) = [1; -1], z(0) = [0; 0] とする.
(%i ) AA: addrow(addcol(A, -b.f), addcol(k.c, A-b.f-k.c));
(%i ) x: [x1(t), x2(t), x3(t), x4(t)];
(%i ) atvalue(x1(t), t=0, 1);
(%i ) atvalue(x2(t), t=0, -1);
(%i ) atvalue(x3(t), t=0, 0);
(%i ) atvalue(x4(t), t=0, 0);
(%i ) sol: desolve(map("=", diff(x,t), transpose(AA.x)[1]), x);
(%i ) plot2d([ev(x1(t),sol), ev(x2(t),sol), ev(x3(t), sol), ev(x4(t), sol)], [t,0,5], [GNUPLOT_PREAMBLE, "set grid"]);
以前のページでは AA の計算に誤りがあったため、解が求まっていなかった。
Maxima
naniwa@rbt.his.u-fukui.ac.jp