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

フィードバック制御は、システムの出力を測定し、目標値との差を利用して入力を自動的に調整する制御方式です。エアコンの温度調節から人工衛星の姿勢制御まで、あらゆる工学システムの基盤となる考え方です。

本記事では、開ループ制御と閉ループ制御の違い、フィードバック制御の利点、身近な具体例を通じて、この重要な概念を直感的に理解します。

本記事の内容

  • 開ループ制御と閉ループ制御の違い
  • フィードバック制御の利点(外乱抑制・頑健性)
  • 身近なフィードバック制御の例
  • Pythonでの簡単なシミュレーション

前提知識

この記事は古典制御の入門記事です。特別な前提知識は不要ですが、以下を知っていると理解が深まります。

  • 微分方程式の基本
  • ラプラス変換の初歩

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

制御の方式は大きく2つに分類されます。

開ループ制御(オープンループ制御)

開ループ制御は、出力を一切測定せず、あらかじめ決めた入力をそのまま加える方式です。

r(t) ---> [コントローラ] ---> u(t) ---> [プラント] ---> y(t)

典型的な例は洗濯機のタイマーです。「30分回す」と設定すれば、汚れが落ちているかどうかに関係なく30分動き続けます。

数式で書くと、制御入力 $u(t)$ は目標値 $r(t)$ のみの関数です。

$$ u(t) = f(r(t)) $$

開ループ制御は構造が単純ですが、以下の問題があります。

  • 外乱が加わっても修正できない
  • プラントの特性が変化すると性能が劣化する
  • 正確な数学モデルが必要

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

閉ループ制御は、出力を測定して目標値との偏差を計算し、その偏差に基づいて入力を決定する方式です。

r(t) -->[+]---> e(t) ---> [コントローラ C(s)] ---> u(t) ---> [プラント P(s)] ---> y(t)
         ^(-)                                                                    |
         |                                                                       |
         +-----------------------------<-----------------------------------------+

偏差 $e(t)$ は次のように定義されます。

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

制御入力は偏差の関数として決定されます。

$$ u(t) = C \cdot e(t) $$

出力が目標値を下回れば偏差が正になり制御入力が増え、上回れば偏差が負になり制御入力が減ります。このように、出力の情報を入力側に「フィードバック」するのが名前の由来です。

フィードバック制御の利点

フィードバック制御には、開ループ制御にはない3つの重要な利点があります。

利点1: 外乱の抑制

外乱 $d(t)$ がプラントに加わった場合を考えます。開ループ制御では外乱の影響がそのまま出力に現れますが、フィードバック制御では出力の変化を検知して補正できます。

閉ループ系における外乱から出力への伝達関数は

$$ \frac{Y(s)}{D(s)} = \frac{P(s)}{1 + P(s)C(s)} $$

開ループ伝達関数 $L(s) = P(s)C(s)$ のゲインが十分大きい帯域では $|L(s)| \gg 1$ となり、

$$ \frac{Y(s)}{D(s)} \approx \frac{P(s)}{P(s)C(s)} = \frac{1}{C(s)} $$

つまり、コントローラのゲインを大きくするほど外乱の影響を抑えられます。

利点2: パラメータ変動への頑健性

プラントのパラメータが変動しても、フィードバックにより性能をある程度維持できます。閉ループ伝達関数は

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

$|P(s)C(s)| \gg 1$ の帯域では

$$ G(s) \approx \frac{P(s)C(s)}{P(s)C(s)} = 1 $$

となり、プラント $P(s)$ の変動に対して出力がほとんど変わりません。

利点3: 定常偏差の低減

適切なコントローラを設計すれば、ステップ入力に対する定常偏差をゼロにできます。たとえば、コントローラに積分要素 $\frac{1}{s}$ を含めると、偏差が存在する限り制御入力が増え続け、最終的に偏差がゼロになります。

身近なフィードバック制御の例

目標値 出力(測定量) 制御入力
エアコン 設定温度 室温(温度センサ) 冷媒の流量
クルーズコントロール 設定速度 車速(車速センサ) スロットル開度
倒立振子 垂直位置 振子角度(エンコーダ) モータトルク
人体の体温調節 約37°C 体温(視床下部) 発汗・震え

いずれも「目標値と実際の値を比較して、差を小さくするように入力を調整する」という同じ原理で動いています。

閉ループ伝達関数の導出

フィードバック制御系の最も基本的な式を導出します。プラント $P(s)$、コントローラ $C(s)$ のフィードバック系を考えます。

出力は

$$ Y(s) = P(s) \cdot U(s) = P(s) \cdot C(s) \cdot E(s) $$

偏差は

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

$E(s)$ を代入すると

$$ Y(s) = P(s) C(s) \bigl[ R(s) – Y(s) \bigr] $$

展開して整理すると

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

$$ Y(s) \bigl[ 1 + P(s)C(s) \bigr] = P(s)C(s) R(s) $$

したがって、閉ループ伝達関数は

$$ \begin{equation} G(s) = \frac{Y(s)}{R(s)} = \frac{P(s)C(s)}{1 + P(s)C(s)} \end{equation} $$

この式は制御工学の最も重要な式の一つです。

Pythonでの実装

python-controlライブラリを用いて、開ループと閉ループの応答を比較します。

開ループ vs 閉ループのステップ応答

import numpy as np
import matplotlib.pyplot as plt
import control as ctrl

# プラント: 1次遅れ系 P(s) = 1/(s+1)
P = ctrl.tf([1], [1, 1])

# 比例コントローラ C(s) = K
gains = [1, 5, 10, 50]

plt.figure(figsize=(10, 6))

# 開ループ応答
t, y_ol = ctrl.step_response(P, T=np.linspace(0, 6, 500))
plt.plot(t, y_ol, 'k--', linewidth=2, label='Open-loop')

# 異なるゲインでの閉ループ応答
for K in gains:
    C = ctrl.tf([K], [1])
    G_cl = ctrl.feedback(P * C, 1)
    t, y_cl = ctrl.step_response(G_cl, T=np.linspace(0, 6, 500))
    ss = K / (1 + K)
    plt.plot(t, y_cl, linewidth=2, label=f'Closed-loop K={K} (ss={ss:.2f})')

plt.axhline(y=1.0, color='gray', linestyle=':', alpha=0.5, label='Target')
plt.xlabel('Time [s]')
plt.ylabel('Output y(t)')
plt.title('Open-loop vs Closed-loop Step Response')
plt.legend()
plt.grid(True, alpha=0.3)
plt.xlim([0, 6])
plt.ylim([0, 1.2])
plt.tight_layout()
plt.show()

閉ループ制御ではゲイン $K$ を大きくするほど定常値が目標値 $1$ に近づきます。ただし比例制御のみでは定常偏差 $\frac{1}{1+K}$ が残ります。

外乱応答の比較

import numpy as np
import matplotlib.pyplot as plt
import control as ctrl

# プラントとコントローラ
P = ctrl.tf([1], [1, 1])
K = 10
C = ctrl.tf([K], [1])

# 外乱伝達関数
G_dist_ol = P                      # 開ループ: P(s)
G_dist_cl = ctrl.feedback(P, C)    # 閉ループ: P/(1+PC)

t = np.linspace(0, 6, 500)
t_ol, y_ol = ctrl.step_response(G_dist_ol, T=t)
t_cl, y_cl = ctrl.step_response(G_dist_cl, T=t)

plt.figure(figsize=(10, 5))
plt.plot(t_ol, y_ol, linewidth=2, label='Open-loop (disturbance)')
plt.plot(t_cl, y_cl, linewidth=2, label=f'Closed-loop K={K} (disturbance)')
plt.xlabel('Time [s]')
plt.ylabel('Output (disturbance response)')
plt.title('Disturbance Rejection: Open-loop vs Closed-loop')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

閉ループ制御では、外乱による出力変動が大幅に抑制されていることがわかります。開ループでは定常値が $1$ に達するのに対し、閉ループでは $\frac{1}{1+K} \approx 0.09$ に抑えられます。

まとめ

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

  • 開ループ制御は出力を測定しないため外乱やパラメータ変動に弱い
  • 閉ループ(フィードバック)制御は出力を測定し偏差を修正することで頑健性を得る
  • 閉ループ伝達関数は $G(s) = \frac{P(s)C(s)}{1 + P(s)C(s)}$ で表される
  • 外乱抑制、パラメータ変動への頑健性、定常偏差の低減がフィードバックの主な利点

次のステップとして、以下の記事も参考にしてください。