RC回路実験で学ぶモデルベース開発×PID制御 ~最適化によるチューニングも一緒に~

# はじめに
今回は制御工学の教科書でも最初の方で習うことの多い、RC回路（一次遅れ）を用いた制御系設計を行ってみようと思います。
シミュレーションによる設計・評価のほかに、Arduinoを用いた実際の回路による実験も行います。

# 実施環境
制御系の設計・モデルを用いたシミュレーション・Arduinoへの実装は、MATLAB/Simulink（バージョン：R2022a）を利用していきます。
特にArduinoへの実装については、無償のサポートパッケージである[Simulink Support Package for Arduino Hardware](https://jp.mathworks.com/hardware-support/arduino-simulink.html)を利用します。
その他に実験で利用する装置は以下です。

・Arduino Mega2560
・抵抗（1.5kΩ）
・コンデンサ（100μF）
・ブレッドボード

# モデルインザループ（MIL:Model In the Loop）環境の構築
まずはSimulinkを利用してプラントモデルの構築をする必要があります。
RC回路は回路への入力電圧に対して、コンデンサ間の電圧を出力として見た場合、その間のダイナミクス（伝達特性）が一次遅れとして表現されます。

式で導出すると以下の通りです。$^{[1]}$

<img width="500" alt="RC" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/9fd8ba06-874e-0de7-8984-818c8b51972e.png">

まず回路方程式を立てます。
```math
v_{in}(t) = v_{r}(t) + v_{c}(t) \\
v_{r}(t) = Ri(t) \\
v_{c}(t) = \frac{\int i(t)dt}{C} \\
```
上式をラプラス変換$s$して
```math
V_{c}(s) = \frac{I(s)}{Cs} \\
V_{R}(s) = RI(s) \\
V_{in}(s) = (R + \frac{1}{Cs})I(s) \\
```
$V_{c}(s)$を$V_{in}(s)$で割ると
```math
\frac{V_{c}(s)}{V_{in}(s)} = \frac{\frac{I(s)}{Cs}}{(R + \frac{1}{Cs})I(s)} \\
\frac{V_{c}(s)}{V_{in}(s)} = \frac{1}{CRs + 1} \\
```
$CR$を時定数$T$として置きなおせば
```math
\frac{V_{c}(s)}{V_{in}(s)} = \frac{1}{Ts + 1} \\
```
となり、ご存じの**一次遅れ**となります。
これをSimulinkのTransfer Fcnブロックを利用してRC回路のプラントモデルとして構築することができます。
が、今回は伝達関数ではなく、物理コンポーネントとしてRCの電気回路をSimscape™を使って表現しようと思います。
Simscape™は非因果的なモデリング（Modelicaのように方向を意識しないモデリング）をSimulink上で実現できる機能であり、抵抗や回路といった物理コンポーネントが提供されているため、数式を書くことなく、まるで回路図をそのままブロック線図上で表現するようにモデリングができます。

下図はSimscape™から提供されている電気系のライブラリであるResistor及びCapacitorブロックによってRC回路を構成した例です。
![plant.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/014ba2fd-17a4-953d-4b3e-4ef572a329a5.png)
なお、各種SourceブロックやSensorブロック等を利用して、Simulinkとのインタフェースを取ることができます。

補足として、Simscape™は電気以外にも機械や油圧、熱流体、磁気など様々な物理ドメインのモデリングをサポートしています。

以上でプラントモデルが表現できたので、続いて制御系を設計していきます。
制御はPIDで行うこととしたので、下図のように単一のPID制御によってセンシングした出力電圧と目標電圧の差を取って制御することを考えます。

![制御3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/0f93f2b2-218c-e527-dc33-9e1314703855.png)

PIDコントローラーは離散系（制御周期100ms）で組み、出力を0-5[V]で飽和するようにしています。
またPIDの各ゲイン値を以下のように決めることとします。
なお、PID制御の詳細は[過去の記事](https://qiita.com/getBack1969/items/520c68265a410ced630d)で紹介していますので良ければ参考にしてください。

|パラメーター  |値  |
|---|---|
|$K_{P}$  |1  |
|$K_{I}$  |0.5  |
|$K_{D}$  |0  |

# モデルインザループシミュレーション（MILS：Model In the Loop Simulation）
プラントとコントローラーのモデルができたので閉ループ系によるシミュレーションを行ってパフォーマンスを確認します。
シミュレーションでは、シナリオとして目標電圧を3Vに上げてから1.5Vに下げることを考えます。
![MILS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/127f8fdc-eb96-4678-37cd-f06d9473ed6b.png)
上図からPID制御（厳密にはPI制御）によって目標電圧への追従制御が行えていることが確認できますが、応答が少々遅い印象です。

# RC回路による実験
MILSの評価を基に実際の試験でも同一の傾向となるのかを確認してみます。
実験の回路構成は下図の通りです。

<img width="500" alt="RC" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/5f92195a-f20c-50b8-c01b-448c00434d3e.png">

写真も貼っておきます。
<img width="500" alt="RC" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/91420d67-b066-19b8-7c64-bd53dc677089.jpeg">

まずはコード生成用にPID制御のモデルのみを抜き出して、Arduinoのペリフェラルに接続するためのIOドライバーブロックを必要な個所に接続します。
![制御.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/835f47d2-0ea9-39d3-c835-c7003a95a4c3.png)
コンデンサの出力電圧はAnalog IO対応のPin:A0からコントローラーにフィードバックし、PIDコントローラーで計算した回路への入力電圧をPWM対応のPin:D3から出力しています。
ここで、それぞれアナログIO、デジタルIO（PWM）ブロック前後に掛かっているゲインは、各IOプロパティに対応するためのスケーリングになります。

あとはこのモデルのコード生成を行ってArduinoに実装するというフローになりますが、Support Packageの機能を利用することでモデルからの自動コード生成ならびにインプリから実行、ログ信号の取得まではSimulinkからボタン一つで制御することができます。
これはSimulinkの**エクスターナルモード**という実行形態になります。この機能の概要は[過去の記事](https://qiita.com/getBack1969/items/891a6ef46bb35ab5d568)を参照ください
![externalMode.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/027356f6-570d-7b1c-cc31-10545a576bcf.png)


以下は実験結果です。なお、比較のために先ほどのMILSの結果も破線で表示しています。
![exp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/3a256d70-463f-03e2-eb8d-c950790040d5.png)
分かりにくいですが、実験結果とMILSの結果が重なっています。
このように実際の回路実験の結果に対し、モデルを用いたシミュレーションはかなり高い精度で再現できていることが確認できました。
RC回路は線形な特性であるため、モデルでも比較的簡単に再現できている形になります。

# PID制御のチューニング　～最適化～
PID制御のパフォーマンスがいまいちなので、各ゲインのチューニングをしていこうと思います。
PID制御のチューニングでは、手作業による試行錯誤が多いかと思いますが、それ以外にも様々な調整アルゴリズムが存在しています。
**しかし**、チューニングは調整者の制御の知識や経験、感覚の醸成が必要であることに加え、一般に時間を多く費やす過程であるため、課題があります。
よって、チューニングタスクは効率的に自動で実施したいところです。
そこで、今回は最適化手法に基づくチューニングをやっていきたいと思います。

ここで、最適化手法とは評価関数と呼ばれるパフォーマンス（良し悪し）を与える評価指標を、与えられる制約条件下で最小化（または最大化）する変数の組を見つける方法となります。
評価関数をどのように設計するかがミソになります。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/72dba776-0527-6d63-9d37-e50ec853b284.png)

Simulinkのモデルを利用してパラメーターの最適探索を行う機能が**Simulink Design Optimization™**から提供されています。
その機能が**応答オプティマイザー**と呼ばれる機能です。

応答オプティマイザーでは、Simulinkのモデルに対し、任意の構造のコントローラーのゲイン設計やモデルパラメーターの最適化を行うための機能が提供されています。

例えば、

・ステップ応答をある包絡線の中に収めたい
・入力の値を上下限に収めるようにしたい

など、複数の要件と呼ばれる設計条件を指定して、それらを満足するような最適解を最適化手法に基づいて探索します。

最適化問題を解くためのソルバーには、MATLABの最適化製品であるOptimization Toolbox™及びGlobal Optimization Toolboxから提供されている一部ソルバーから選択を行って、実際にSimulinkモデルのシミュレーションを回しながら反復を行っていきます。
（※利用にはこれらの最適化製品が必要です）
![sdo.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/6384ad8a-0d10-81a2-895e-fa54faf8b29c.png)
上図は実際の計算結果になります。（GUIのスナップショット）

要件として、

**・PIDの出力値を0-5Vに収めること**
**・出力電圧のステップ応答を所定の包絡線の中に収めること**
**・制御偏差の平方和を最小にすること**

を与え、計算を行いました。
結果として得られたPIDのゲイン値は以下の通りです。

|パラメーター  |値  |
|---|---|
|$K_{P}$  |13.2251  |
|$K_{I}$  |373.9204  |
|$K_{D}$  |0.0328  |

I制御のゲインがかなりハイゲインです。
これは人間の手作業のチューニングではなかなか見つけられない解の候補かもしれません。
なお、最適化で求める際に設計変数の値の上下限を定めることが可能ですので、探索空間を萎めて計算することもできます。

# MILS（最適化後）
最適化で求めた値を使用して、もう一度MILSを行って評価してみます。
![mils.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/ead97c11-a15f-c4cd-24f5-7ded38685700.png)
初期値の結果と比較して、かなり応答性や目標値への追従性が改善していることが確認できます。
チューニングの結果は良好です。

# RC回路による実験（最適化後）
最後に実機を用いた確認を行います。
![exp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/f8a33316-3fd2-6415-ba1b-6a3aabcac7a7.png)
上図からMILSの結果と同じく、高い制御パフォーマンスを発揮できていることが確認できます。
ただノイズの影響が入力電圧に乗っかってきています。
これは、**おそらくD制御を加えた影響**です。
D制御は周波数特性上でハイパス特性を持っているため、センシングした際に乗っかってくる高周波のノイズを増幅してしまっているものと考えられます。
ノイズが問題となる場合には、D制御ではなく、フィードフォワードや2自由度制御系を組んで目標値への応答性の部分の工夫を行うことが必要になります。
（もちろんPID以外の制御を検討することも視野に入ります）

# 最後に
今回は制御の基本中の基本であるRC回路（一次遅れ）の制御実験をシミュレーションと実際の回路を組み合わせて行ってみました。
モデルで事前に設計、評価することで、実機による調整の労力がかなり低減できることが分かります。
今回は単純なモデルでしたが、これが車両やロボット、飛行機などもっと複雑な対象でも原理的にやることは同じです。
いかに良いモデルが作れるかが制御系設計におけるモデルベース開発の良し悪しを決めることになります。

ちなみに、今回使用したSimulink Design Optimization™では応答オプティマイザーのほかに、モデルと実機応答の合わせ込みを行う**パラメーター推定器**、パラメーターのばらつきを考慮したモンテカルロ法に基づく感度解析を行う**感度アナライザー**が提供されており、このツールがあれば、基本的な制御系設計を一通り完結できるのでイチ制御屋として結構オススメな機能であったりします。

# 参考文献
[1]嶋田 有三：わかる制御工学入門―電気・機械・航空宇宙システムを学ぶために, 産業図書