式を、今度は数値シミュレーションとして読む
この回では、制御を含む連立常微分方程式を、時間応答としてどう追うかを整理します。
第1回で物質収支の式を作って、第2回で制御器をつないだのよね。でも、まだ少し気持ちのどこかで「式は式」という感じも残っているのよ。時間とともに本当に動くものとして、まだ見切れていない気がして。
そこを埋めるのがシミュレーションたい。式をそのまま時間発展に通してやると、P・I・D がどこで効いとるかが、波形として見えてくるばい。
なるほどね。この回はコードを読むというより、「式をどうやって時間応答へ持ち込むか」を見る回なんだ。
このシリーズでは、第1回で2槽タンクの物質収支モデルを作り、第2回でそこへ P / PI / PID 制御を組み込みました。この回では、その結果として得られた連立常微分方程式を改めて整理し、それをどう数値シミュレーションへ持ち込むかを説明します。
ここで大事なのは、実際のPythonコードそのものではありません。むしろ重要なのは、式 → 状態変数 → 時間微分の計算 → 数値積分 → 応答の解釈 という流れが見えることです。
途中には、実際に得られたシミュレーション結果の図を差し込めるようにしてあります。この記事では、その図をどう読めばよいかまで含めて整理します。
まず、実際に時間発展させる連立常微分方程式を確認する
この回では、最終的に得られた式をそのままシミュレーション対象として扱います。
今回の2槽タンクでは、上槽液位を $h_1(t)$、下槽液位を $h_2(t)$ とします。上槽から下槽への流れを $q_{12}$、下槽から外部への流れを $q_{out}$、上槽への流入を $q_{in}$ とします。
ここではシミュレーションのために、流量を次のような簡単な関係で置きます。
$$q_{12}=\frac{h_1-h_2}{R_{12}},\qquad q_{out}=\frac{h_2}{R_2}$$
また、上槽への流入は基準流入 $q_0$ と制御入力 $u(t)$ を使って
$$q_{in}=q_0+u(t)$$
とします。すると、プラントの物質収支は
$$\frac{dh_1}{dt}=\frac{q_0+u-q_{12}}{A_1}$$
$$\frac{dh_2}{dt}=\frac{q_{12}-q_{out}}{A_2}$$
です。さらに、下槽液位 $h_2(t)$ を制御対象とし、目標値を $h_{set}$ とすると、偏差は
$$e(t)=h_{set}-h_2(t)$$
で定義されます。
PI / PID では、これに積分状態 $z(t)$ が加わります。
ここで一回ちゃんと式を見直しておくと安心するのよね。シミュレーションって言われると先に道具の話に飛びそうになるけど、結局はこの式を時間に沿って追っていく、ということなんだよね。
そうたい。シミュレーションは別の理屈を持ち込むんやなか。この連立常微分方程式を、時刻を少しずつ進めながら追いかけるだけたい。
P制御では、操作量は
$$u(t)=K_p e(t)=K_p\bigl(h_{set}-h_2(t)\bigr)$$
なので、シミュレーション対象は
$$\frac{dh_1}{dt}=\frac{q_0+K_p(h_{set}-h_2)-q_{12}}{A_1}$$
$$\frac{dh_2}{dt}=\frac{q_{12}-q_{out}}{A_2}$$
という2本の連立常微分方程式です。
PI制御では、積分状態
$$\frac{dz}{dt}=e(t)=h_{set}-h_2(t)$$
を導入し、操作量を
$$u(t)=K_p(h_{set}-h_2)+K_i z(t)$$
と書くので、シミュレーション対象は
$$\frac{dh_1}{dt}=\frac{q_0+K_p(h_{set}-h_2)+K_i z-q_{12}}{A_1}$$
$$\frac{dh_2}{dt}=\frac{q_{12}-q_{out}}{A_2}$$
$$\frac{dz}{dt}=h_{set}-h_2$$
という3本の連立常微分方程式になります。
PID制御では、さらに微分項を加えて
$$u(t)=K_p e(t)+K_i z(t)+K_d\frac{de}{dt}$$
とします。ここで目標値 $h_{set}$ を一定とすれば、
$$\frac{de}{dt}=-\frac{dh_2}{dt}$$
ですから、PID制御では
$$u(t)=K_p(h_{set}-h_2)+K_i z+K_d\frac{de}{dt}$$
を使って時間発展を追うことになります。
つまり、この回で本当に実装するのは、Pなら2状態、PI / PID なら3状態の連立常微分方程式です。
コードより先に、シミュレーションのアルゴリズムを言葉で整理する
何を、どの順番で計算していくのかが見えれば、実装はかなり自然に読めます。
数値シミュレーションの流れは、実はそれほど複雑ではありません。必要なのは、「ある時刻での状態が分かっているとき、その状態から時間微分を計算できる」ということです。常微分方程式の数値積分は、この手続きを時刻ごとに繰り返していきます。
基本アルゴリズム
- 最初に、初期状態を与える。P制御なら $h_1(0), h_2(0)$、PI / PID ならこれに加えて $z(0)$ を与える。
- 現在の状態から偏差 $e(t)=h_{set}-h_2(t)$ を計算する。
- 制御則にしたがって操作量 $u(t)$ を決める。Pなら比例項だけ、PIなら比例項と積分項、PIDならさらに微分項まで含める。
- 現在の液位から流量 $q_{12}, q_{out}$ を計算する。
- 物質収支により、各状態の時間微分 $\frac{dh_1}{dt}, \frac{dh_2}{dt}$、必要なら $\frac{dz}{dt}$ を計算する。
- その時間微分を使って、少し先の時刻の状態を数値的に更新する。
- これを計算時間の終わりまで繰り返し、液位と操作量の時系列を得る。
Pythonではこの「状態から時間微分を返す関数」を用意し、それを数値積分器へ渡します。けれど、実際にやっていることの中身は上の7段階です。
こうやって順番で書かれると、かなり落ち着いて見えるのよね。最初は「シミュレーション」って聞くと、何か大きな仕掛けがあるように見えるけど、結局は今の状態から次の変化量を計算していくのが中心なんだ。
そうたい。コードの見た目に引っぱられると難しく見えるけど、中身は「状態を読む → 入力を決める → 微分を出す → 進める」の繰り返しばい。
状態変数が増えると、アルゴリズムのどこが変わるのか
P制御では、状態変数は $h_1, h_2$ の2つだけです。したがって、各時刻で追うべき量も2つです。
PI制御になると、偏差の積分を表す $z$ が状態として追加されます。すると、各時刻で「液位だけでなく、積分状態も同時に更新する」という作業が必要になります。
PID制御でも、少なくとも P と I の部分は PI制御と同じです。その上で、D項を計算するために偏差の変化率を見ることになります。つまり、アルゴリズムとしては「何を状態として持つか」と「入力をどう決めるか」が、制御則ごとに少しずつ変わるわけです。
「どの変数が状態で、どの量がその場で計算される補助量なのか」
を混同しないことです。
ここにシミュレーション結果を貼り、その波形を読む
この記事では、結果の図を途中に差し込んで、その意味を解釈する構成にします。
この位置に、P / PI / PID のシミュレーション結果を貼り込みます。おすすめは、少なくとも次の3種類の図です。
- 上槽液位 $h_1(t)$ の時間応答
- 下槽液位 $h_2(t)$ の時間応答(目標値 $h_{set}$ も重ねる)
- 操作量 $u(t)$ の時間応答
もし1枚にまとめるなら、「上槽液位」「下槽液位」「操作量」を縦に並べると読みやすいです。特に下槽液位 $h_2(t)$ は制御対象なので、目標値の線と並べて見ることが重要です。
グラフが出てくると、つい「どれが一番きれいか」みたいな見方をしそうになるのよね。でも、本当はまず何を見ればいいのかな。
最初に見るのは下槽液位 $h_2(t)$ たい。制御対象やけんね。目標値へどう近づくか、ずれが残るか、行き過ぎるか、揺れるか。まずそこを見るばい。そのあとで、操作量 $u(t)$ がどう動いたかを重ねて読むと、なぜその応答になったかが見えやすか。
結果の図を読むときは、まず 制御対象である下槽液位 $h_2(t)$ を見ます。ここで目標値への近づき方、ずれの残り方、行き過ぎ、揺れの有無などを確認します。
次に、操作量 $u(t)$ を見ます。入力がどれだけ強く動いているか、急に大きく変化していないかを見ると、波形の背景が分かりやすくなります。
最後に、上槽液位 $h_1(t)$ を見ます。下槽を制御しているときでも、上槽がその影響をどう受けているかは系全体の理解に重要です。
P制御のシミュレーションでは、まず「その場の偏差だけ」を見ていることが現れる
P制御の役割は、結果の波形でも比較的素直に読み取れます。
P制御では、操作量はその瞬間の偏差だけで決まります。したがって、アルゴリズムとしてはかなり単純です。各時刻で $h_2(t)$ を読み、目標値との差から $u(t)$ を計算し、その $u(t)$ をプラントへ戻すだけです。
このとき、過去の偏差は持ち越しません。つまり、P制御は「いまズレているぶんだけ押し返す」制御です。
だからP制御の結果を見るときは、「いまのズレに対して素直に反応しているか」を見る感じなのよね。
そうたい。そのかわり、目標値へぴたりとは合わず、少しずれが残る様子も見えやすかばい。そこがP制御の特徴として波形に出やすいところたい。
結果の図では、P制御の下槽液位 $h_2(t)$ が目標値へ近づいていく一方で、わずかなずれが残る形が見えやすいはずです。ここでは、P制御が「その場で反応する」ことと、「履歴を持たない」ことの両方が波形として現れます。
PI制御のシミュレーションでは、積分状態が時間をかけて効いてくる
ここで初めて、第2回で導入した積分状態 $z$ が波形の意味を持ちはじめます。
PI制御では、P制御の比例項に加えて、偏差の履歴をためる積分状態 $z(t)$ を同時に時間発展させます。したがってアルゴリズム上は、液位 $h_1, h_2$ だけでなく、$z$ も毎時刻更新することになります。
この一点が、P制御との最も大きな違いです。P制御では「いまの偏差」しか見ませんでしたが、PI制御では「これまでどれだけずれてきたか」も入力の計算に反映されます。
ここが少し好きなのよね。第2回では $z$ が増えるって聞いて、最初は「文字が増えた」くらいに見えていたけど、シミュレーションの話になると、ちゃんと過去を抱えて進んでいる感じが出てくるんだ。
そうたい。PI制御では、偏差はその場で消えて終わりやなか。積分状態に少しずつ残っていくけん、時間がたつほど効き方に差が出てくるばい。
結果の図では、PI制御はP制御よりも目標値へ寄せる力が強く見えるはずです。ここで読み取りたいのは、I制御は偏差の履歴を通じて、あとからじわっと効いてくるということです。
もしP制御では残っていたずれが、PI制御でより小さくなっているなら、それは積分状態 $z$ が効いているからです。つまり、積分項は「その場の反応」ではなく、「時間をまたいで補正を持ち込む項」として読むと理解しやすくなります。
PID制御のシミュレーションでは、変化の速さを見る位置が加わる
D項は、偏差そのものとは少し違う場所で効くので、波形の読み方も少し変わります。
PID制御では、比例項と積分項に加えて、偏差の時間変化率を使います。したがってアルゴリズム上は、各時刻で単に偏差の大きさを見るだけではなく、その偏差がどちら向きに、どれくらいの速さで変わっているかも評価することになります。
このため、PID制御は P や PI とは少し違った場所で効きます。Pは偏差そのものに、Iは偏差の履歴に反応していましたが、Dは「変化の勢い」に反応する項です。
D項は、式だけ見ていると少し抽象的だったのよね。でもシミュレーションの話で考えると、「各時刻で偏差の変わり方も読む」と言われた方が、だいぶ具体的に感じるのよ。
そうたい。D項は「どれだけずれとるか」だけではなく、「今そのずれがどう動いとるか」を見とるばい。やけん、波形の立ち上がり方や揺れ方を見ると、存在感が分かりやすか。
結果の図では、PID制御はP / PIと比べて、立ち上がりや揺れ方に違いが出るはずです。ここで重要なのは、「D項があると応答がどう変わるか」を、偏差の時間変化を見る項として読むことです。
つまり、D制御は目標値との距離そのものを埋めるというより、応答の動き方へ先回りして作用する項として理解すると、結果の図とつながりやすくなります。
P / PI / PID を見比べると、「式の違い」が「応答の違い」として見えてくる
ここで初めて、第2回までの数式が波形としてひとつにつながります。
ここまでの結果を見比べると、P / PI / PID の違いは、単に式の見た目の違いではなく、時間応答の違いとして読めるようになります。
- P制御:その場の偏差だけで操作量を決める。
- PI制御:偏差の履歴を持ち込むので、時間をかけて補正が蓄積される。
- PID制御:偏差の変化の速さも見ながら入力を決める。
シミュレーションの価値は、ここにあります。第2回までは「Pは比例」「Iは積分」「Dは微分」と言葉で整理していましたが、この回ではそれが時間応答として見えるようになります。
なるほどね。第1回では物質収支で骨格を作って、第2回では制御器を式の上に載せて、この回でようやく「その違いが時間応答としてどう出るか」を見ているんだ。
そうたい。式は骨格、シミュレーションはその骨格がどう動くかを見せる場たい。同じモデルを別の角度から見とるだけやけん、ここでようやく話がひとつにつながるばい。
まとめ
この回で見たかったのは、コードそのものではなく、式が時間応答へ変わる流れです。
この回では、2槽タンクのプラント方程式と、そこへ組み込んだ P / PI / PID 制御を改めて連立常微分方程式として示し、それをどう数値シミュレーションへ持ち込むかを整理しました。
大事なのは、実装の細部よりも、どの変数が状態で、どの量がその場で計算される補助量で、どういう順番で時間発展を追うのか が見えていることです。
ここまで通すと、第1回の物質収支、第2回の制御を含む微分方程式、そして今回のシミュレーション結果が、ひとつの連続した話として読めるようになります。