Processing math: 0%

2017年8月5日土曜日

現代制御勉強メモと倒立振子の制御例

## 概要

現代制御の勉強メモです.実装するまでの過程をトレースしたかったので,それに必要な知識の確認程度に書いたものです.
内容は状態フィードバック則と同一次元状態オブザーバのまとめと,それを使って適当な制御対象を制御してみてみます.
なお授業で扱った内容を思い出すためのものである上,幾つか扱ってない部分があったり間違ってたり省略してたりするので,ちゃんとした説明は教科書見直してください.学部生なんだ許されてくれ.

## 勉強メモ


### メインコンセプト

次のような状態方程式と呼ばれる形で表された微分方程式がある.ただしxはベクトルで内部状態を表し,uは入力,yは出力である.またA,B,C,Dは定数行列である.

\begin{eqnarray} \dot{x}&=&Ax+Bu\\ y&=&Cx+Du \end{eqnarray}

メインコンセプトは,この微分方程式の内部状態xを,0ベクトルにどうやって近づけるかということである.xが0ベクトルに収束するためには行列「Aの固有値の実部がすべて負」でなければいけない.「Aの固有値の実部がすべて負」の時,xは指数関数的に減衰していくことが知られているため,xは0ベクトルに収束する.

さて,実際にモデルを立てた時に「Aの固有値の実部がすべて負」という条件が満たされていなかったとする.その場合,xは0に収束するどころか発散してしまう場合がある.しかし,このとき入力uをうまく与えてやることで擬似的に「Aの固有値の実部をすべて負」にできる.その最も単純な方式として状態フィードバックを用いた極配置という方法を取る.

この方法では,入力uを次のような形で与える.ただしKは適当な定数行列である.

u=Kx+v

これを上式に代入すると次のようになる.

\begin{eqnarray} \dot{x}&=&(A+BK)x+Bv\\ y&=&Cx+Du \end{eqnarray}

したがって定数行列Aが,擬似的にA+BKとなった.したがってKをうまいこと決めてやれば,定数行列Aの固有値を変えられる.固有値の実部が全て負になるようなKにすれば,xは0ベクトルに収束し目的が達成できる.

さて,現代制御論のメインコンセプトは上に述べたとおりである.しかし上では語弊を承知で具体的な計算などはすべて除いた.そのため実際には安定化させられない条件というのがいくつかある.また,入力uu=Kx+vとすればよいといったが,xがわからなければuを決定できない.そのためxを推定する必要がある.

以下では制御ができるかできないかを表す指標「可制御性」,状態xが推定できるかできないかを表す指標「可観測性」について述べる.

### 状態フィードバック則(文献[1]P35)

先程定数行列Kをうまく決めてやれば,定数行列Aの固有値を擬似的に変えられることをのべた.実際にはKはその要素を適当な変数で置いてやって固有値方程式
\det(\lambda I-(A+BK))=0
が,実部が負となる適当な固有値 \lambda_1,...,\lambda_nを自分で決めてやって,次式のようにその解がその固有値になるようにしてやれば良い.

\det(\lambda I-(A+BK))=\prod_{i=1}^n(\lambda - \lambda_i)

ただし\lambda_1,...,\lambda_nは係数が実数の多項式の解となるような状態(複素平面上においた時に実軸対称)でなければならない.

### 可制御性(文献[1]P35)


さて上記の式を実際に立ててみると連立方程式はKの要素に関する線形連立方程式になることが保証されているらしい.しかし妥当な解が得られないような場合がある.すなわち,思い通りに制御することができない場合がある.思い通りに制御できないことを不可制御性を持つと良い,逆に思い通りに制御できることを可制御であるという.

可制御であるということの必要十分条件は次の条件が満たされている場合である事が示されている(文献[1]P38).
rank M_c=rank [B \,\, AB\,\,\dots\,\,A^{n-1}B]=n

この行列M_cは可制御性行列とよばれるもので,微分方程式の解析解を求めると出てくる

\begin{eqnarray} x(t)&=&e^{At}x(0)+\int_0^t e^{A(t-\tau)}Bu(\tau)d\tau\\ &=&e^{At}x(0)+\int_0^t (\beta_0 (t-\tau)I+\beta_1(t-\tau)A+\dots+\beta_{n-1}(t-\tau)A^{n-1})Bu(\tau)d\tau \\ &=&e^{At}x(0)+[B \,\, AB\,\,\dots\,\,A^{n-1}B][\int\beta_0udt \dots\int\beta_{n-1}udt ]^T\\ &=&e^{At}x(0)+M_c [\int\beta_0udt \dots\int\beta_{n-1}udt ]^T \end{eqnarray}

不可制御の場合はどうやっても不安定であったりするので,そういう場合は制御対象を何かしら変える必要がある.

### 同一次元状態オブザーバ(文献[1]P121)

状態フィードバック則では,入力uを決定するのにu=Kx+vとしているから,内部状態xがわかっている必要がある.

普通は内部状態xを知ることはできず,ここでは出力yと入力u,および定数行列A,B,Cのみから推定するしか無い.内部状態を推定する方法はいくつかあるらしいが同一次元状態オブザーバというものを紹介する.

まずxと同じ次元を持ち,次のような微分方程式で表される関数z(t)について考える.

\dot{z}=Az+Bu+G(y-Cz)

このzx(t)=z(t)となってくれれば内部状態xがわかったことになる.ここでxzの差e(t)=x(t)-z(t)について考えると,\dot{e}=\dot{x}-\dot{z}であるから,

\begin{eqnarray} \dot{e(t)}&=&A(x-z)-G(Cx-Cz)\\ &=&A(x-z)-GC(x-z)\\ &=&(A-GC)e(t) \end{eqnarray}

となるから,行列A-GCの固有値の実部が全て負であればeは0に収束する,すなわちx=zとなる.したがってA-GCの固有値の実部が全て負となるようにGを状態フィードバック則と同じように決めてやればよい.

### 可観測性(文献[1]P41)

ただ同一次元状態オブザーバを作れない場合がある.すなわち,内部状態をどれだけ頑張っても出力yから知ることができない場合がある.そのようなシステムを不可観測であるといい,逆に内部状態を推定できるシステムを可観測であるという.

システムが可観測であるという必要十分条件は次の可観測性行列M_o
rank M_o = rank\begin{bmatrix}C\\CA\\\vdots\\CA^{n-1}\end{bmatrix}=n

であることである.この可観測性行列は入力が0である場合のyの解析解

\begin{eqnarray} y&=&C e^{At}x(0)\\ &=&C(\beta_0 (t)I+\beta_1(t)A+\dots+\beta_{n-1}(t)A^{n-1})x(0)\\ &=&[\beta_0\dots \beta_{n-1}]M_o x(0) \end{eqnarray}

に出てくる行列である(文献[1]P43).


## 具体例

### 運動方程式の導出

ここでは台車にくっついた倒立振子について考えます.ただし運動方程式の導出は面倒なので参考文献[2]のモデルを用います(というかこの運動方程式の導出がちゃんとできないとだめというか,現代制御ではモデル化ができてしまえば後は勝手に制御則が出てくるので,でもう少し運動方程式の導出を再勉強するべきな気がする).

参考文献[2]より,台車の位置及び振り子の回転角度の運動方程式は次式のようになる.

\begin{bmatrix} M+m&ml\cos(\theta)\\ ml\cos(\theta)&J+ml^2 \end{bmatrix} \begin{bmatrix} \ddot{x}\\\ddot{\theta} \end{bmatrix} + \begin{bmatrix} -ml\dot{\theta}^2\sin\theta\\ -mlg\sin\theta\end{bmatrix} + \begin{bmatrix} B\dot{x}\\C\dot{\theta} \end{bmatrix} =\begin{bmatrix} u\\0 \end{bmatrix}

ここで
T=\begin{bmatrix} M+m&ml\cos(\theta)\\ ml\cos(\theta)&J+ml^2 \end{bmatrix}
とおけば


\begin{eqnarray} \begin{bmatrix} \ddot{x}\\\ddot{\theta} \end{bmatrix} &=&T^{-1}\left(\begin{bmatrix} ml\dot{\theta}^2\sin\theta\\ mlg\sin\theta\end{bmatrix} +\begin{bmatrix} -B&0\\0&-C \end{bmatrix}\begin{bmatrix} \dot{x}\\\dot{\theta} \end{bmatrix} +\begin{bmatrix} u\\0 \end{bmatrix}\right) \end{eqnarray}


となる.数値解析する分にはこの程度の形で書けていればルンゲクッタでシミュレーションできる.

### 線形化

次に,現代制御を適用するために\dot{\theta},\thetaが微小であるという近似をすると
T=\begin{bmatrix} M+m&ml\\ ml&J+ml^2 \end{bmatrix}
であり,微分方程式は次のようになる.

\begin{eqnarray} \begin{bmatrix} \ddot{x}\\\ddot{\theta} \end{bmatrix} &=&T^{-1}\left(\begin{bmatrix} 0&0\\ 0&mlg\end{bmatrix}\begin{bmatrix} {x}\\{\theta} \end{bmatrix} +\begin{bmatrix} -B&0\\0&-C \end{bmatrix}\begin{bmatrix} \dot{x}\\\dot{\theta} \end{bmatrix} +\begin{bmatrix} 1\\0 \end{bmatrix}u\right)\\ &=&\frac{1}{\det T}\left( \left[\begin{matrix}0 & - g l^{2} m^{2}\\0 & g l m \left(M + m\right)\end{matrix}\right]\begin{bmatrix} {x}\\{\theta} \end{bmatrix}\\+\left[\begin{matrix}- B \left(J + l^{2} m\right) & C l m\\B l m & - C \left(M + m\right)\end{matrix}\right]\begin{bmatrix} \dot{x}\\\dot{\theta} \end{bmatrix} +\left[\begin{matrix}J + l^{2} m\\- l m\end{matrix}\right]u \right) \end{eqnarray}
ここで状態量を(変数名かぶってますが)x=\begin{bmatrix}x&\dot{x}&\theta&\dot{\theta}\end{bmatrix}^Tとすると
\frac{d}{dt}x=\frac{1}{\det T} \begin{bmatrix} 0&\det T&0&0\\ 0&-B(J+ml^2)&-m^2l^2g&Cml\\ 0&0&0&\det T\\ 0&Blm&mgl(M+m)&-C(M+m) \end{bmatrix}x+ \frac{1}{\det T} \begin{bmatrix} 0\\J+ml^2\\0\\-ml \end{bmatrix}u
となるから,
\begin{eqnarray} A&=&\frac{1}{\det T} \begin{bmatrix} 0&\det T&0&0\\ 0&-B(J+ml^2)&-m^2l^2g&Cml\\ 0&0&0&\det T\\ 0&Blm&mgl(M+m)&-C(M+m) \end{bmatrix}\\ B&=& \frac{1}{\det T} \begin{bmatrix} 0\\J+ml^2\\0\\-ml \end{bmatrix}\\ C&=& \begin{bmatrix} 1&0&0&0\\ 0&0&1&0\\ \end{bmatrix}\\ \end{eqnarray}
とおけば線形化した場合の状態方程式が書ける.

### オブザーバ,フィードバックゲインの決定

オブザーバ,フィードバックゲインは手計算で求めるとめんどくさそうなのでライブラリを使います.python-controlやmatlabにはplace関数というものがあって,それを用いるとフィードバックゲインなどを求めることができます.

なお,place関数はA+BKKを決めてくれる関数です.したがって状態オブザーバのゲインGを決める方法については,A-GCの転置をとったA^T-C^TG^TG^Tを求めることをすれば良いです.

コードはこんな感じです.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

### シミュレーション

シミュレーションはProcessingで行いました.自分用の行列ライブラリ,ODEライブラリを作っておきたかったので読みにくいかもしれないです.

コードはここに上げてあります.
上が制御対象(RK4でシミュレーションした非線形微分方程式),下がオブザーバの出力を可視化したものです.初期値は0にしてあり,キーボードの矢印キーで外乱(入力)を与えてやれば動きます.
制御していない場合は発散し,制御している場合にはちゃんと倒立していることがわかります.オブザーバの出力もだいたい上のと同じ感じになってます.

## 感想

大変だったけどいい経験になりました.あと先輩に聞くと結構授業では端折っているところがあったりするらしいので,もっと勉強しないとなと思いました.

## 参考文献

[1] 吉川恒夫,井村順一,現代制御論,(2014),コロナ社
[2] http://www.robot.mach.mie-u.ac.jp/~nkato/class/sc/Invpend_eq3.pdf
[3] Python で任意極配置のフィードバックゲインを求める | org-技術, http://org-technology.com/posts/pole-placement.html
[4] python-controlを利用する際に直面したエラー - szmlb.net, http://szmlb.hatenablog.com/entry/2015/09/08/203643