最適化を用いたゲインスケジューリング制御器の設計

# はじめに
今回はゲインスケジューリング制御の設計について記事を書いてみたいと思います。
ゲインスケジューリングですが、これはその名の通り制御器のゲインを予め複数用意して計画的に切り替えて制御するアプローチになります。

どのようなときにこのアプローチが必要となってくるのか、それはプラントが非線形な場合です。
プラントの線形、非線形性については過去の記事で解説していますので、よければ参照ください。

https://qiita.com/getBack1969/items/af84984756445018243a

ゲインスケジューリング制御では、予め定めたプラントの動作点やスケジューリングポイントを基に動的にゲインを切り替えていきます。
例えば、制御器の構造がPID制御であった場合、下図のような構成となります。

![GS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/5f8521f3-9700-e0a3-2a49-bc85df0c7b61.png)

PIDの制御構造はそのままに、ゲインだけが外だしとなってテーブル等によって構成されます。

ゲインスケジューリング制御は、プラントの非線形性を補償するための適応的な制御手法であることから適応制御の1種と捉えることもあるようです。

https://www.jstage.jst.go.jp/article/isciesci/42/6/42_KJ00001012241/_article/-char/ja/

# 例題 タンクシステムに対するゲインスケジューリング制御器の設計
それでは、例題を通じてこのゲインスケジューリング制御の設計を行ってみたいと思います。
扱う題材は先ほどの記事でも取り扱ったタンクシステムです。

https://qiita.com/getBack1969/items/af84984756445018243a

![Tank.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/078c5699-29ae-4161-17ff-4eac4718500b.png)

タンクシステムでは、水位を状態量とするモデルにおいて非線形な特性が現れます。
即ち、水位の変化がプラントの特性に影響を与えるということです。

これに対して、今回はPID制御を使ったゲインスケジューリング制御器を構成していきたいと思います。

PIDのゲインスケジューリングを構築するにあたって、MATLABの制御系ツールの一つであるSimulink Control Desginから**PID Gain Scheduler**というブロックが提供されているので、これを使用していきたいと思います。

https://jp.mathworks.com/help/slcontrol/ug/pidgainscheduler.html

今回は水位をスケジューリングの変数と見立て、5、10、20[m]の3点をブレークポイントとしたスケジューリング制御を下図のように構成します。

![controller.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/a89f7c49-9368-e725-7f50-c370c33c57b4.png)

![scheduler.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/778abf7f-8622-295b-ee3a-53e8f37096b0.png)

なお、PIDはコントローラーのタイプをPIとしておきます。（D制御は今回使用しません）

またP・Iゲインの設計に際してはモデルマッチングのアプローチを取り入れることとし、水位に関する閉ループシステムに対する規範モデルを考え、下図のような構成を検討します。

![model.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/2af62f50-0e16-e5ac-b576-0e191de83f28.png)

規範モデルの役割は、閉ループの応答が所望の応答となるような模範の信号を生成することです。
そして、実際の出力と規範出力との偏差を取り、その差が小さくなるように制御ゲインを調整することで所望の応答性を手に入れることが出来ます。
これは下図に示すモデル規範型適応制御（MRAC）と呼ばれる構造に近しいものとなっています。

![MRAC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/d9413715-0f74-e261-f393-6e4e1cfac342.png)

さて、構造ができたところで、いよいよスケジューリングゲインの設計に入っていきます。
設計にはいろいろな方法が考えられますが、今回は最適化手法を活用して合理的に設計をしていきたいと思います。

まずは、ゲインの初期値およびその他のパラメーターを以下のように定義します。

```matlab
% 制御器のサンプリング時間
Ts = 1;
% ブレークポイント
bp = [5 10 20];
% Pゲイン
Kp_array = [1 1 1];
% Iゲイン
Ki_array = [0.1 0.1 0.1];
% Dゲイン
Kd_array = [0 0 0];
% 微分器のフィルター係数
N_array = [100 100 100];
% 規範モデルの時定数
Tref = 2;
```
コントローラーの制御周期は1[s]とし、各スケジューリングゲインはブレークポイントに対して一定と与えています。
また規範モデルの応答性については1次遅れで表し、その時定数を2[s]と設定しました。

まずは、この構成で一度シミュレーションを行ってみます。

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/7adea5b2-32b2-b030-cb49-49aecaf0c2fc.png)

結果を見てみると、左上の出力について、目標となる水位に対して、オーバー／アンダーシュートを伴っており、追従性に関してあまりパフォーマンスが良くないことが分かります。
特に水位が上がるにつれてオーバーシュートの割合が大きくなっています。
その際、Pゲイン、Iゲインは水位に関係なく常に一定です。
よって、単一のゲインでは良好な制御パフォーマンスが得られないということが分かります。

これに対し、最適化手法に基づいてゲインをチューニングしていきたいと思います。
そこで使用するのが、制御系ツールの一つである Simulink Design Optimization から提供されている**応答オプティマイザー**という機能です。

https://jp.mathworks.com/help/sldo/ref/responseoptimizer-app.html

本機能については過去の記事でも紹介していますのでよければ参照ください。

https://qiita.com/getBack1969/items/b34fab2aeb34c4959075

さて、それでは応答オプティマイザーを立ち上げて最適なチューニングを実施したいと思います。

まずは、アプリを起動します。
![one.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/2bc8a3d7-8fa5-17cb-6a57-3010e6e85004.png)

アプリが起動したら、画面上の要件の項目から新規をプルダウンします。
すると様々な要件の項目が出現するので、ここから信号プロパティを選択します。
信号プロパティはモデル上の指定した信号線に対する要件を設けるための機能であり、下図のようにモデル上のerrという信号（規範出力と実際の出力の差）に対し、その平方和を最小化するように指定します。

![two.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/90660711-d425-e7ee-5db4-82288eeae22c.png)

続いて、設計変数セット＞新規と進んで、設計変数セットの作成UIからモデル上で使用されている変数を参照し、今回チューニングを掛けたいPゲイン、Ｉゲインの配列変数を指定します。
その際、設計変数には初期値や上下限をUI上から与えることが可能となっているので、探索空間を適当となるように絞りこむことが出来ます。

![three.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/c7fe8c7b-4be3-7fc7-183d-b2818c0cb11c.png)

以上までが完了したら、オプションのアイコンをクリックし、最適化に使用するソルバーを選択します。
こちらはMATLABの最適化ツールであるOptimization ToolboxおよびGlobal Optimization Toolboxから提供される一部のソルバーを利用することが可能になっていますので、問題設定等に合わせて適当なソルバーを選択します。

![four.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/f86b69d8-e0d4-ce9b-f500-40c9a72ddcde.png)

またオプションの並列タブでは、最適化計算の並列化を選択可能です。こちらはParallel Computing Toolboxがあれば利用可能な機能となっています。

![five.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/c4e41b97-8f7d-a7eb-2df7-e1c74cce82be.png)

そして、最後にモデル上の高速リスタートのボタンをクリックしておきます。
この機能は毎回シミュレーション実行時にかかるモデルコンパイルを初回のみ実行し、2回目のシミュレーション以降は省略する機能です。

https://jp.mathworks.com/help/simulink/ug/how-fast-restart-improves-iterative-simulations.html

今回の様にパラメーター探索のシチュエーションにおいては、複数回モデルを実行する必要が出てくるため、本機能を利用すると実行時間の短縮化が図れます。

![six.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/d0139569-eac1-a2b8-2eb5-8c37d380ef18.png)

そして、最後に実行ボタンをクリックすると最適化の計算が開始します。

![seven.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/3fa31f4d-a3b3-4048-440d-728060f80c97.png)

モデルの規模や実行するPCのスペックにも依存しますが、今回は数分程度で計算が終わりました。

![eight.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/cb301b3a-17c5-aea3-e4fd-4ba528294a58.png)

チューニングされたゲインは下図の通りとなりました。

![OptGain.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/8a86ac73-e55c-025a-8ae7-d0c7271fcc44.jpeg)

横軸ブレークポイント（水位の点）に対する各ゲインの値を示していますが、各点でゲインが異なることが分かります。
特に5[m]の点と10[m]の点で値が大きく減少しています。

それでは、この値を使って再度シミュレーションを実行してみます。

![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/7e30b5d2-3b77-3baa-3a99-21bb5901b3c8.png)

いかがでしょう。図を見ると分かる通り、初期値の時と比較して応答性がかなり改善されていることが分かります。
特に出力が規範出力にピッタシくっついており、オーバーシュートがなく良好な応答性を示していることが分かります。
また各ゲインもスケジューリングポイントである水位の変化に応じて適切に切り替わっていることが分かります。

# 最後に
今回は最適化を用いたゲインスケジューリング制御器の設計を行いました。
試行したのはPID制御でしたが、それ以外にも任意の制御器の構造に対して同様な考え方に基づき調整を掛けることが出来ます。
その際、テーブルゲインの作成にはLookup Tableブロックを使用することが可能です。

https://www.youtube.com/watch?v=iS6ePvyo-yY