自宅で簡単SimulinkとArduinoを使った温度制御実験

# はじめに
以前の記事にて住宅の暖房システムを題材としたデータドリブンに基づく温度制御のシミュレーションを紹介しました。

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

前回の記事では、実機環境はなく、すべてモデルで完結して、検証自体もシミュレーション止まりでした。

そんな折、ふと以下のブログを見つけ触発を受けたので、今回は実験環境を実際に用意してみて、Simulink＋Arduinoを使って温度制御を試してみたいと思います。

https://www.ubiquitous-ai.com/news/2022/003510.html


# 使用する機材やソフト
今回の実験環境を構築するにあたり、以下の機材を用意することにしました。

・Arduino Mega 2560 ×1
・100均で買ったプラスチック製の容器 ×1
・ブレッドボード ×1
・PTCヒーター(3-10W) ×1
・12V ACアダプター ×1
・温度センサー（LM60BIZ） ×1
・抵抗(100kΩ) ×1
・FET 2SK2231 ×1
・MATLAB R2022a
・Simulink
・Simulink Support Package for Arduino Hardware
・System Identification Toolbox
・Model Predictive Control Toolbox

構築した環境は下図の通りです。
![real.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/99d1f2c9-4b1a-ebe0-07ca-d23bb3acf3cf.jpeg)

回路図で示すと下図のイメージ。

![Screenshot 2023-05-24 164652.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/2871cf53-99f0-5eaf-8735-c386c6ef7718.png)

用意した温度制御の環境では、プラスチックの容器内を室内と見立て、PTCヒーターによって容器内の温度を制御します。（実験時は容器に蓋をします）

制御は、Simulinkのモデルで構成し、モデルをSimulink IOと呼ばれる実行モードで動かして行います。
Simulink IOは、Arduinoを単なるIOボードとして利用し、制御はすべてUSBで接続されたPC側のSimulinkモデルで行わせる機能です。

https://www.youtube.com/watch?v=ksUSdFlAkAI

本モードでは、厳密なリアルタイム性を要求することができませんが、Simulinkのペーシング機能（実行速度を調整する機能）を利用することで疑似的なリアルタイム性をつくることができます。
今回の温度制御は、制御周期を2秒としているので十分に対応できる範囲かと思います。

# 実験データの取得
プラントモデルの構築のために実際に装置側で実験を行って入出力データを取得します。
実験に際しては、下図のようにSimulinkで簡易的にPID制御を組んで、目標温度を色々と動かして閉ループ試験を行います。

![Screenshot 2023-05-24 171212.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/cb956449-b7ce-90e0-4069-bb52641501ab.png)

なお、温度計測の部分は下図のモデルとなっています。
Arduinoのアナログポートで読み取ったLM60BIZからの電圧値を摂氏温度に変換し、さらに移動平均フィルター（MAF）を掛けています。
MAFを設けた理由は、温度センサーであるLM60BIZの検出精度やノイズの影響でかなり不連続な温度値となってしまうので、MAFで平均化することにしたからです。
なお、MAFのタップ数は10としました。

![Screenshot 2023-05-24 171257.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/5d35e7cc-50da-4dab-be3d-209df128d52c.png)

以下が、閉ループ試験で取得した2秒周期の入出力データです。

![画像1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/a07e012d-6f31-d9f2-a688-25377669dfb1.jpeg)

なお、入力値はPWMのduty比を0-255の範囲で表しています。

# システム同定
取得した実験データを利用してシステム同定を行います。
同定する際のモデルタイプとしては連続時間系の状態空間モデルとして、ssest関数によって推定します。

https://jp.mathworks.com/help/ident/ref/ssest.html

試行錯誤の結果、8次の状態空間表現として推定することにしました。（下図参照）

![画像2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/a7e828eb-6b73-0925-1ddf-ebec7c8d1139.jpeg)

:::note info
同定モデルはトレンドの高周波成分を適切に捉えることが出来ていませんが、目的とする制御帯域ではなかったのでこれで良しとしています。
:::

```matlab:システム同定のスクリプト
Ts = 2;
d = iddata(y,u,Ts); % y, u が時系列データ
idsys = ssest(d,8); % 8次の状態空間として推定
compare(d,idsys)    % 学習データに対する一致具合を確認
```

ボード線図と安定余裕も表示してみると下図となりました。

![bode.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/ca9d2247-3af2-0d6f-795e-caa4f738620b.jpeg)

また極配置図をプロットしてみると右半面に零点があるので、非最小位相特性があるようです。

![pzmap.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/f707e149-8079-f3d9-bbc8-45773366bb50.jpeg)

しかし、極はすべて左半面にあるので安定なシステムであると分かります。
物理的に考えてみると、系への熱供給が無い限り熱は散逸し、温度は自然と下がるため当然と言えば当然ですかね。

# コントローラーの設計
プラントモデルが得られたので、これを使って制御系を構築していきます。
コントローラーとしては、前回の記事同様にMPC（モデル予測制御）を使っていきます。
設計時のポイントとしては、予測ホライズンを40と少々長めにして、適切にトランジェントを制御するという方針としています。

```matlab:MPCの設計スクリプト
mpcobj = mpc(idsys,Ts); % Ts = 2

% 予測ホライズンの設定
mpcobj.PredictionHorizon = 40;
mpcobj.ControlHorizon = 2;

% 操作量の上下限制約
mpcobj.ManipulatedVariables.Max = 255;
mpcobj.ManipulatedVariables.Min = 0;

% 入出力に対するスケーリング係数
mpcobj.ManipulatedVariables.ScaleFactor = 255;
mpcobj.OutputVariables.ScaleFactor = 30;

% 評価関数の重み
mpcobj.Weights.OutputVariables = 100;
mpcobj.Weights.ManipulatedVariablesRate = 10;
```

制御のモデルを以下の様に用意します。
![Screenshot 2023-05-25 182930.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/6637544c-36c0-0b98-4eed-a5f2d2906b61.png)

# 制御実験
設計したコントローラーを使って温度制御がうまく行くかを確認してみます。
以下が、取得したトレンド図です。

![画像3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525369/a2990dd1-1357-fe2b-8779-e056d46e9869.jpeg)

実験した日は5月の中でも少々暑い日だったため、開始温度が26[degC]と少し高い状況から制御を行っています。
そんな中でもトレンドを見てみると分かるようにしっかり温度の目標値に追従制御できていることが分かります。
特に、実験中わざと温度を下降させる期間を設けています。
今回のシステム構成では温めることはできても、冷やすことはできないため、自然冷却に任せるしかない状況なのですが、冷やしている期間のMPCからの操作量はきちんと0になっています。

先の実験データ取得時にPID制御（実質PI制御）で温度目標値を変えて色々と制御していたのですが、ゲインが調整しきれていないこともあり、積分動作によるオーバーシュートがかなりひどく、なかなか制御が難しい印象だったのですが、MPCはそんなこともなく、目標値に温度が近づく前に適切に操作量をカットして、オーバーシュートを抑制するような動きを見せていて、非常に優秀な制御でした。

# 終わりに
ということで、今回は簡易的な温度制御のための実験環境を用意して、実際にモデルベースでコントローラーを設計して評価してみました。
やっている最中、色々と躓くかなと思っていたのですが、以外にもスムーズにできました。

使っている部品は、電子部品屋さんや近くの100均ショップ、Amazonなどで購入できるものばかりなので興味のある方は自己責任において試してみるといかがでしょうか。

# 参考情報
https://qiita.com/motorcontrolman/items/bd962021be8c5fdcc48b

https://jp.mathworks.com/academia/books/getting-started-in-control-system-design-with-arduino-and-matlab.html