フィードバック制御とは?制御工学の基本概念をわかりやすく解説

制御工学は、対象となるシステム(プラント)の振る舞いを目標通りに制御するための学問です。宇宙機の姿勢制御、ロボットアームの位置決め、自動車のクルーズコントロール、産業用プラントの温度管理など、エンジニアリングのあらゆる場面で制御工学の知識が必要になります。

本記事では、制御工学の最も基本的な考え方であるフィードバック制御を中心に、開ループと閉ループの違い、ブロック線図の読み方、PID制御の概要までを解説します。最後に、Pythonを用いて1次遅れ系のステップ応答をシミュレーションし、フィードバック制御の効果を確認してみましょう。

本記事の内容

  • 制御工学とは何か
  • 開ループ制御と閉ループ制御の違い
  • フィードバック制御の基本構成要素
  • ブロック線図の読み方
  • 伝達関数の直感的な意味
  • 温度制御(エアコン)の具体例
  • PID制御の概要
  • Pythonで1次遅れ系のステップ応答をシミュレーション

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

制御工学とは

制御工学(Control Engineering)は、対象システムの出力を望ましい目標値に追従させるための理論と手法を扱う学問分野です。

イメージとしては、車を運転しているときに「道路の中央を走り続けたい」という目標があり、ハンドルを微調整してズレを修正する行為が「制御」に相当します。このような「目標値と実際の状態のズレを検出し、修正する」という考え方を工学的に体系化したものが制御工学です。

制御工学の知識が活用される代表的な分野を挙げます。

分野 制御の応用例
航空宇宙 人工衛星の姿勢制御、ロケットの誘導制御
ロボティクス 産業用ロボットアームの位置・力制御
自動車 クルーズコントロール、ABS、自動運転
プラント制御 化学プラントの温度・圧力・流量制御
電力系統 発電機の周波数制御、電圧制御

制御工学は大きく 古典制御現代制御 に分けられます。古典制御は伝達関数をベースにした周波数領域の解析手法であり、現代制御は状態空間モデルをベースにした時間領域の解析手法です。本記事では、古典制御の基礎となるフィードバック制御の考え方に焦点を当てます。

開ループ制御と閉ループ制御

制御の方式は、大きく開ループ制御(Open-loop control)閉ループ制御(Closed-loop control) に分けられます。

開ループ制御

開ループ制御は、出力の結果を確認せずに、あらかじめ決められた入力をプラントに加える方式です。

身近な例としては、トースターが挙げられます。タイマーを3分にセットしたら、パンの焼き加減に関係なく3分間加熱を続けます。パンが焦げていても、まだ焼けていなくても、タイマーが切れるまで動作は変わりません。

開ループ制御の特徴は次の通りです。

  • 構造がシンプルで安価
  • 外乱やモデルの誤差に対して弱い
  • 出力のフィードバックがないため、目標値からのズレを修正できない

閉ループ制御(フィードバック制御)

閉ループ制御は、出力をセンサで測定し、目標値との差(偏差)に基づいて入力を修正する方式です。これがフィードバック制御と呼ばれるものです。

先ほどのトースターの例で言えば、庫内のセンサでパンの表面温度を測定し、「まだ焼けていなければ加熱を続ける」「焦げそうなら加熱を弱める」という制御に切り替えるイメージです。

閉ループ制御の特徴は次の通りです。

  • 外乱やモデルの不確かさに強い(ロバスト)
  • 出力のズレを自動的に修正できる
  • 構造がやや複雑になり、センサが必要
  • 設計を誤ると系が不安定になる場合がある

実用的な制御系のほとんどは、閉ループ制御(フィードバック制御)を採用しています。

フィードバック制御の基本構成

フィードバック制御系は、以下の5つの基本要素で構成されます。

1. 目標値(Reference / Set point)$r(t)$

システムの出力をどの値にしたいかを指定する入力信号です。例えばエアコンの設定温度 25 ℃ がこれに当たります。

2. 偏差(Error)$e(t)$

目標値と実際の出力(測定値)の差です。

$$ e(t) = r(t) – y(t) $$

偏差が正であれば出力が目標に届いていないことを意味し、負であれば出力が目標を超えていることを意味します。

3. 制御器(Controller)$C(s)$

偏差 $e(t)$ を受け取り、プラントへの操作量 $u(t)$ を計算する要素です。PID制御器が最も広く使われている制御器です。

4. プラント(Plant)$G(s)$

制御の対象となるシステムそのものです。モーター、炉、タンク、航空機など、制御したい物理的な対象が該当します。操作量 $u(t)$ を入力として受け取り、出力 $y(t)$ を生成します。

5. センサ(Sensor / Feedback element)$H(s)$

プラントの出力を測定し、フィードバック信号として偏差の計算に渡す要素です。温度計、エンコーダ、ジャイロスコープなどがこれに該当します。理想的なセンサは $H(s) = 1$(出力をそのまま返す)ですが、実際にはセンサにも遅れや誤差があります。

ブロック線図の読み方

制御系の構造を視覚的に表現するために、ブロック線図(Block diagram) が使われます。ブロック線図は、信号の流れと各要素の関係を図示したもので、制御工学における共通言語です。

ブロック線図の基本的な構成要素は以下の3つです。

ブロック(Block)

入力信号を受け取り、ある変換規則(伝達関数)に従って出力信号を生成する要素です。長方形で描かれ、内部に伝達関数を記入します。

加え合わせ点(Summing junction)

複数の信号を加算または減算する点です。丸い記号で描かれます。フィードバック制御では、目標値 $r(t)$ からフィードバック信号を減算して偏差 $e(t)$ を得る部分がこれに相当します。符号として $+$ や $-$ を記入します。

引き出し点(Branch point)

1つの信号を分岐させて、複数の経路に送る点です。信号が分岐しても、信号の値は変わりません。

フィードバック制御系のブロック線図を文字で表すと、次のような信号の流れになります。

r(t) --→ [+] --→ e(t) --→ [ C(s) ] --→ u(t) --→ [ G(s) ] --→ y(t) --→
          [-]↑                                                        |
             |                                                        |
             ←------------ [ H(s) ] ←---------------------------------

信号の流れを追うと、

  1. 目標値 $r(t)$ が入力される
  2. 加え合わせ点で、目標値からフィードバック信号を引いて偏差 $e(t) = r(t) – H(s) \cdot y(t)$ を得る
  3. 制御器 $C(s)$ が偏差から操作量 $u(t) = C(s) \cdot e(t)$ を生成する
  4. プラント $G(s)$ が操作量を受けて出力 $y(t) = G(s) \cdot u(t)$ を生成する
  5. センサ $H(s)$ が出力を測定し、フィードバック信号として加え合わせ点に戻す

この「ループ」が閉じていることが、閉ループ制御の名前の由来です。

伝達関数の直感的な意味

ブロック線図に登場する $C(s)$ や $G(s)$ は 伝達関数(Transfer function) と呼ばれます。伝達関数は、入力信号をどのように変換して出力信号にするかのルールを $s$ の関数として記述したものです。

ここで $s$ はラプラス変換の複素変数であり、時間領域の微分方程式を代数方程式に変換するために導入されます。

例えば、ある系の入出力関係が次の微分方程式で記述されるとします。

$$ \tau \frac{dy(t)}{dt} + y(t) = K u(t) $$

ここで $\tau$ は時定数、$K$ はゲインです。初期値をゼロとしてラプラス変換を適用すると、

$$ \tau s Y(s) + Y(s) = K U(s) $$

$$ (\tau s + 1) Y(s) = K U(s) $$

したがって、伝達関数は次のようになります。

$$ G(s) = \frac{Y(s)}{U(s)} = \frac{K}{\tau s + 1} $$

これは1次遅れ系と呼ばれる最も基本的な伝達関数であり、入力に対して出力が指数関数的に遅れて追従することを表しています。

伝達関数を使えば、微分方程式を直接解かなくても、入出力関係を代数的に扱えるようになります。これが制御工学で伝達関数が広く使われる大きな理由です。

閉ループ伝達関数

フィードバック制御系の全体的な入出力関係(閉ループ伝達関数)は、ブロック線図の関係から導出できます。

センサが理想的($H(s) = 1$)な場合を考えます。

$$ e(t) = r(t) – y(t) $$

ラプラス領域では、

$$ E(s) = R(s) – Y(s) $$

操作量は、

$$ U(s) = C(s) E(s) $$

出力は、

$$ Y(s) = G(s) U(s) = G(s) C(s) E(s) = G(s) C(s) [R(s) – Y(s)] $$

$Y(s)$ について整理すると、

$$ Y(s) + G(s) C(s) Y(s) = G(s) C(s) R(s) $$

$$ Y(s) [1 + G(s) C(s)] = G(s) C(s) R(s) $$

$$ \frac{Y(s)}{R(s)} = \frac{G(s) C(s)}{1 + G(s) C(s)} $$

この式が閉ループ伝達関数です。分子が開ループ伝達関数 $G(s)C(s)$、分母が $1 +$ 開ループ伝達関数の形になっていることが特徴です。

具体例: エアコンの温度制御

フィードバック制御の具体例として、エアコンの温度制御を考えてみましょう。

構成要素 エアコンの例
目標値 $r(t)$ リモコンで設定した温度(例: 25 ℃)
出力 $y(t)$ 室内の現在温度
偏差 $e(t)$ 設定温度と現在温度の差
制御器 $C(s)$ エアコンのマイコン制御回路
操作量 $u(t)$ コンプレッサーの回転数、風量
プラント $G(s)$ 部屋(熱容量を持つ空間)
センサ $H(s)$ 室内温度センサ
外乱 窓からの日射、人の出入り

動作の流れを追ってみます。

  1. 設定温度 25 ℃ に対して、室温が 30 ℃ の場合、偏差は $e = 25 – 30 = -5$ ℃(暑すぎる)
  2. 制御器が偏差に基づいてコンプレッサーを高速で回転させる(冷房全力運転)
  3. 室温が徐々に下がり、偏差が小さくなっていく
  4. 室温が 25 ℃ に近づくと、偏差が小さくなり、コンプレッサーの回転数も下がる
  5. 室温が 25 ℃ を維持するように、微調整が続く

もし誰かがドアを開けて暖かい空気が入ってきた(外乱)場合、センサが温度上昇を検出し、再びコンプレッサーの出力を上げて対応します。このように、フィードバック制御は外乱に対しても自動的に修正が効くことが大きな利点です。

PID制御の概要

実際のフィードバック制御で最も広く使われている制御器がPID制御器です。PID制御器は、偏差 $e(t)$ に対して 比例(Proportional)積分(Integral)微分(Derivative) の3つの操作を組み合わせて操作量 $u(t)$ を決定します。

$$ u(t) = K_p e(t) + K_i \int_0^t e(\tau)\,d\tau + K_d \frac{de(t)}{dt} $$

これをラプラス領域で書くと、

$$ C(s) = K_p + \frac{K_i}{s} + K_d s $$

各項の役割を説明します。

P制御(比例制御)

$$ u_P(t) = K_p e(t) $$

偏差に比例した操作量を出力します。偏差が大きいほど大きな修正を加えます。$K_p$ を大きくすると応答が速くなりますが、大きくしすぎると振動的になります。P制御だけでは、定常偏差(目標値と定常状態の出力の差)が残ることがあります。

I制御(積分制御)

$$ u_I(t) = K_i \int_0^t e(\tau)\,d\tau $$

偏差の時間積分に比例した操作量を出力します。偏差が小さくても、長時間蓄積されると操作量が増えていくため、P制御で残った定常偏差を解消する効果があります。ただし、$K_i$ を大きくしすぎるとオーバーシュート(目標値を超えて振れる現象)が大きくなります。

D制御(微分制御)

$$ u_D(t) = K_d \frac{de(t)}{dt} $$

偏差の時間変化率に比例した操作量を出力します。偏差が急激に変化しているときに大きな修正を加え、偏差がこれ以上大きくなる前にブレーキをかける役割を果たします。オーバーシュートを抑制する効果がありますが、ノイズに敏感になるという欠点もあります。

PID制御の3つのゲイン $K_p$, $K_i$, $K_d$ を適切に調整すること(チューニング)が、良好な制御性能を得るための鍵になります。

Pythonで1次遅れ系のステップ応答をシミュレーション

それでは、Pythonを用いて1次遅れ系に対するステップ応答をシミュレーションしてみましょう。開ループ(制御器なし)の応答と、P制御による閉ループの応答を比較します。

1次遅れ系のプラント伝達関数を次のように設定します。

$$ G(s) = \frac{K}{\tau s + 1} $$

ここでは $K = 1$、$\tau = 2\,\mathrm{s}$ とします。

import numpy as np
import matplotlib.pyplot as plt

# --- シミュレーションパラメータ ---
dt = 0.01          # 時間刻み [s]
t_end = 15.0       # シミュレーション終了時刻 [s]
t = np.arange(0, t_end, dt)

# プラントパラメータ(1次遅れ系: dy/dt = (-y + K*u) / tau)
K_plant = 1.0      # プラントゲイン
tau = 2.0           # 時定数 [s]

# 目標値(ステップ入力: t >= 1 で r = 1)
r = np.where(t >= 1.0, 1.0, 0.0)

# --- P制御のゲインを変えて比較 ---
Kp_list = [0.0, 1.0, 5.0, 10.0]  # Kp=0 は開ループ相当(u=r)
labels = ['Open-loop ($K_p = 0$, $u = r$)',
          'P control ($K_p = 1$)',
          'P control ($K_p = 5$)',
          'P control ($K_p = 10$)']
colors = ['tab:gray', 'tab:blue', 'tab:green', 'tab:red']

fig, axes = plt.subplots(2, 1, figsize=(10, 8), sharex=True)

for idx, Kp in enumerate(Kp_list):
    y = np.zeros_like(t)   # 出力
    u = np.zeros_like(t)   # 操作量

    for i in range(1, len(t)):
        if Kp == 0.0:
            # 開ループ: 入力をそのままプラントに与える
            u[i] = r[i]
        else:
            # 閉ループ(P制御): u = Kp * (r - y)
            e = r[i] - y[i - 1]
            u[i] = Kp * e

        # プラントの微分方程式を前進オイラー法で数値積分
        # tau * dy/dt + y = K * u  →  dy/dt = (K * u - y) / tau
        dydt = (K_plant * u[i] - y[i - 1]) / tau
        y[i] = y[i - 1] + dydt * dt

    axes[0].plot(t, y, color=colors[idx], linewidth=2, label=labels[idx])
    axes[1].plot(t, u, color=colors[idx], linewidth=2, label=labels[idx])

# 目標値を破線で表示
axes[0].axhline(y=1.0, color='black', linestyle='--', linewidth=1, alpha=0.5, label='Reference $r = 1$')
axes[0].set_ylabel('Output $y(t)$', fontsize=13)
axes[0].set_title('Step Response of First-Order System with P Control', fontsize=14)
axes[0].legend(fontsize=10, loc='lower right')
axes[0].grid(True, alpha=0.3)
axes[0].set_ylim(-0.1, 1.5)

axes[1].set_xlabel('Time [s]', fontsize=13)
axes[1].set_ylabel('Control input $u(t)$', fontsize=13)
axes[1].set_title('Control Input', fontsize=14)
axes[1].legend(fontsize=10, loc='upper right')
axes[1].grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

このコードを実行すると、上段に出力 $y(t)$ の時間応答、下段に操作量 $u(t)$ が表示されます。

結果から、以下のことが確認できます。

  • 開ループ($K_p = 0$、$u = r$): 出力は目標値 1.0 にゆっくり近づきますが、プラントゲイン $K = 1$ なので最終的に $y = 1.0$ に収束します。応答が遅く、時定数 $\tau = 2$ s に支配されています。
  • P制御($K_p = 1$): 開ループより応答が速くなります。ただし定常偏差が残り、$y$ は 1.0 にぴったりとは到達しません。閉ループの定常値は $K_p K / (1 + K_p K) = 1/2 = 0.5$ になります。
  • P制御($K_p = 5$): ゲインを上げると応答がさらに速くなり、定常偏差も小さくなります。定常値は $5/(1+5) \approx 0.833$ です。
  • P制御($K_p = 10$): ゲインをさらに上げると、定常偏差はより小さくなります($10/11 \approx 0.909$)。ただし、さらにゲインを上げていくと振動的になるリスクがあります。

このように、P制御ではゲイン $K_p$ を上げることで応答速度と定常偏差のトレードオフを調整しますが、定常偏差を完全にゼロにすることはできません。定常偏差をゼロにするには、I(積分)制御を加えてPIまたはPID制御にする必要があります。

まとめ

本記事では、フィードバック制御の基本概念について解説しました。

  • 開ループ制御は出力を確認せず入力を加える方式、閉ループ制御(フィードバック制御)は出力を測定して偏差を修正する方式
  • フィードバック制御系は 目標値・偏差・制御器・プラント・センサ の5つの要素で構成される
  • ブロック線図は信号の流れを視覚的に表現する制御工学の共通言語
  • 伝達関数は入力を出力に変換するルールをラプラス領域で記述したもの
  • PID制御は比例・積分・微分の3つの操作を組み合わせた、最も広く使われる制御手法
  • P制御だけでは定常偏差が残り、I制御を加えることで定常偏差をゼロにできる

次の記事では、伝達関数をより深く掘り下げ、システムの周波数応答を解析するためのボード線図について解説していきます。