位相進み・遅れ補償器の設計手法

コーヒーに砂糖だけ入れると甘くなりますが、ミルクも入れると味がまろやかになります。制御系の設計でも、一つの補償器では改善できる特性に限りがありますが、異なる特性を持つ補償器を組み合わせることで、速い応答と高い精度を両立できます。

位相進み補償器(lead compensator)は高周波域のゲインを上げて位相を進め、応答の速さと安定余裕を改善します。位相遅れ補償器(lag compensator)は低周波域のゲインを上げて定常精度を改善しつつ、高周波域でゲインを下げて安定性を保ちます。そしてこの2つを組み合わせた位相進み遅れ補償器(lead-lag compensator)は、両方の利点を同時に実現できます。

位相進み・遅れ補償器を理解すると、以下のような応用が開けます。

  • 安定余裕の改善: 位相余裕やゲイン余裕が不足するシステムの安定余裕を増加できる
  • 定常精度の向上: 定常偏差を許容値以下に抑えられる
  • 応答速度の改善: 帯域幅を広げて応答を速くできる
  • PID制御の代替: PID制御では実現しにくい仕様も、位相補償器で達成できる場合がある

本記事の内容

  • 位相進み補償器の伝達関数と設計手順
  • 位相遅れ補償器の伝達関数と設計手順
  • 位相進み遅れ補償器の設計
  • Pythonでの設計と効果の検証

前提知識

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

位相進み補償器 — 位相を「前倒し」して安定余裕を改善

位相進み補償器の直感的イメージ

フィードバック制御系が不安定になる原因を一言でまとめると、「信号が一周して戻ってくるときに位相が $180^\circ$ 以上遅れて、かつゲインが1以上あると、正帰還と同じ状態になって発散する」ということです。位相余裕が小さいとは、その臨界状態にすれすれだということを意味します。

位相進み補償器のアイデアは、ゲイン交差周波数(ゲインが0 dBを切る周波数)の付近で位相を「前に進める」ことで、$-180^\circ$ から遠ざけるというものです。日常的なアナロジーで例えると、カーブを曲がるとき早めにハンドルを切れば車がスムーズに曲がれるのと似ています。信号がフィードバックループを一周するとき、ちょうどゲイン交差周波数の付近で「少し先回り」して位相を持ち上げてあげるのが位相進み補償器の役割です。

具体的には、位相進み補償器は分子に零点、分母に極を持つ1次の伝達関数です。零点が極よりも低い周波数に配置されるため、零点と極の間の周波数帯域でゲインが増大し、同時に位相が進みます。この位相が進む帯域をゲイン交差周波数に合わせることが設計の核心です。

伝達関数

位相進み補償器の伝達関数は

$$ \begin{equation} C_{\text{lead}}(s) = K_c \frac{Ts + 1}{\alpha Ts + 1} \quad (0 < \alpha < 1) \end{equation} $$

$\alpha < 1$ なので、零点 $s = -1/T$ が極 $s = -1/(\alpha T)$ より原点に近くなります。

ここで、なぜこの配置が位相を進めるのかを数式で追ってみましょう。$s = j\omega$ を代入すると

$$ C_{\text{lead}}(j\omega) = K_c \frac{j\omega T + 1}{j\omega \alpha T + 1} $$

となります。分子の位相角は $\angle(j\omega T + 1) = \arctan(\omega T)$、分母の位相角は $\angle(j\omega \alpha T + 1) = \arctan(\omega \alpha T)$ です。補償器全体の位相角は

$$ \angle C_{\text{lead}}(j\omega) = \arctan(\omega T) – \arctan(\omega \alpha T) $$

$\alpha < 1$ のとき $\omega T > \omega \alpha T$ なので、$\arctan(\omega T) > \arctan(\omega \alpha T)$ となり、位相角は常に正、つまり位相が進むことがわかります。

周波数応答を見ると、$C_{\text{lead}}(j\omega)$ は折れ点 $\omega = 1/T$ から $\omega = 1/(\alpha T)$ の間でゲインが増加し、位相が進みます。

最大位相進み角の導出

最大位相進み角の導出を丁寧に行います。位相角を $\phi(\omega)$ と書くと

$$ \phi(\omega) = \arctan(\omega T) – \arctan(\omega \alpha T) $$

加法定理を用いて1つの $\arctan$ にまとめると

$$ \phi(\omega) = \arctan\frac{\omega T – \omega \alpha T}{1 + \omega^2 \alpha T^2} = \arctan\frac{\omega T(1 – \alpha)}{1 + \omega^2 \alpha T^2} $$

$\phi(\omega)$ を最大化するには $\arctan$ の中身を最大化すればよいです。$u = \omega T$ と置くと

$$ f(u) = \frac{u(1-\alpha)}{1 + \alpha u^2} $$

$df/du = 0$ を計算すると

$$ \frac{(1-\alpha)(1+\alpha u^2) – u(1-\alpha) \cdot 2\alpha u}{(1+\alpha u^2)^2} = 0 $$

分子に着目して整理すると

$$ (1-\alpha)(1 + \alpha u^2 – 2\alpha u^2) = (1-\alpha)(1 – \alpha u^2) = 0 $$

$\alpha \neq 1$ なので $1 – \alpha u^2 = 0$ より $u = 1/\sqrt{\alpha}$ が得られます。$u = \omega T$ を代入すると、最大位相進みが生じる周波数は

$$ \omega_m = \frac{1}{T\sqrt{\alpha}} $$

この周波数での位相角を計算します。$\omega_m T = 1/\sqrt{\alpha}$ を代入すると

$$ f(1/\sqrt{\alpha}) = \frac{(1-\alpha)/\sqrt{\alpha}}{1 + \alpha \cdot 1/\alpha} = \frac{(1-\alpha)/\sqrt{\alpha}}{2} = \frac{1-\alpha}{2\sqrt{\alpha}} $$

よって最大位相進み角は

$$ \phi_m = \arctan\frac{1-\alpha}{2\sqrt{\alpha}} $$

これは $\arcsin$ の形でも表現できます。直角三角形を考えると、$\sin\phi_m = (1-\alpha)/(1+\alpha)$ が成り立つことが確認でき

$$ \begin{equation} \phi_m = \arcsin\frac{1 – \alpha}{1 + \alpha} \end{equation} $$

が得られます。

ゲインの変化量

$\omega_m$ における補償器のゲイン($K_c = 1$ とした部分)も重要です。

$$ |C_{\text{lead}}(j\omega_m)| = \left|\frac{j\omega_m T + 1}{j\omega_m \alpha T + 1}\right| = \sqrt{\frac{1 + \omega_m^2 T^2}{1 + \omega_m^2 \alpha^2 T^2}} $$

$\omega_m T = 1/\sqrt{\alpha}$ を代入すると

$$ = \sqrt{\frac{1 + 1/\alpha}{1 + \alpha}} = \sqrt{\frac{(1+\alpha)/\alpha}{1+\alpha}} = \frac{1}{\sqrt{\alpha}} $$

デシベルでは $20\log_{10}(1/\sqrt{\alpha}) = -10\log_{10}\alpha$ dBのゲイン増加が生じます。$\alpha = 0.1$ なら $10$ dB、$\alpha = 0.01$ なら $20$ dBのゲイン増加です。このゲイン増加によりゲイン交差周波数がシフトするため、設計時に考慮が必要です。

$\alpha$ が小さいほど最大位相進みが大きくなりますが、同時にゲインの増加も大きくなるため、通常 $\alpha \geq 0.05$($\phi_m \leq 65^\circ$)に制限します。以下に代表的な $\alpha$ の値と最大位相進み角の対応を示します。

$\alpha$ 最大位相進み $\phi_m$ ゲイン増加量
0.5 $19.5^\circ$ $3.0$ dB
0.2 $38.9^\circ$ $7.0$ dB
0.1 $54.9^\circ$ $10.0$ dB
0.05 $65.4^\circ$ $13.0$ dB

この表から、必要な位相進み角に対応する $\alpha$ を素早く選べます。

設計手順

位相進み補償器の設計手順を、各ステップの意図と合わせて説明します。

ステップ1: 定常偏差の仕様からゲイン $K_c$ を決定します。たとえば、1型システムの速度定数 $K_v$ の要求が $K_v \geq 10$ なら、$K_v = \lim_{s \to 0} sK_cG(s)$ から $K_c$ を求めます。

ステップ2: 補償前のシステムに $K_c$ を適用したときのゲイン交差周波数 $\omega_{gc}$ と位相余裕 $PM_0$ を計算します。ここで、$PM_0$ が目標位相余裕を下回っていることを確認します。

ステップ3: 必要な位相進み角 $\phi_m$ を計算します。

$$ \phi_m = PM_{\text{target}} – PM_0 + \Delta \quad (\Delta = 5^\circ \sim 12^\circ) $$

安全マージン $\Delta$ を加える理由は、位相進み補償器がゲインを増加させるためゲイン交差周波数がシフトし、シフト先での位相がさらに低下する可能性があるからです。

ステップ4: $\phi_m$ から $\alpha$ を逆算します。$\sin\phi_m = (1-\alpha)/(1+\alpha)$ を $\alpha$ について解くと

$$ \alpha = \frac{1 – \sin\phi_m}{1 + \sin\phi_m} $$

ステップ5: 最大位相進みが新しいゲイン交差周波数で発生するように $\omega_m$ と $T$ を決めます。補償器は $\omega_m$ で $-10\log_{10}\alpha$ dBのゲインを加えるため、補償前の開ループゲインが $10\log_{10}\alpha$ dBとなる周波数を $\omega_m$ に設定します。そして

$$ T = \frac{1}{\omega_m\sqrt{\alpha}} $$

から $T$ を求めます。

ステップ6: 結果をボード線図で検証し、位相余裕が仕様を満たしているか確認します。満たさない場合は $\Delta$ を調整するか、2段の位相進み補償器を直列に配置することを検討します。

数値計算例

具体的な数値で設計手順を確認しましょう。プラントが $G(s) = 10/[s(s+1)]$ で、目標が「位相余裕 $50^\circ$ 以上」のケースを考えます。

ステップ1: $K_c = 1$(プラントにゲインが含まれている)。

ステップ2: 開ループ伝達関数 $L(s) = 10/[s(s+1)]$ のゲイン交差周波数を求めます。$|L(j\omega)| = 1$ より

$$ \frac{10}{\omega\sqrt{1+\omega^2}} = 1 \quad \Rightarrow \quad \omega^2(1+\omega^2) = 100 $$

$\omega^4 + \omega^2 – 100 = 0$ を解くと $\omega^2 = (-1 + \sqrt{401})/2 \approx 9.51$ より $\omega_{gc} \approx 3.08$ rad/s。このときの位相は

$$ \angle L(j\omega_{gc}) = -90^\circ – \arctan(3.08) \approx -90^\circ – 72.0^\circ = -162.0^\circ $$

よって位相余裕は $PM_0 = 180^\circ – 162.0^\circ = 18.0^\circ$ です。

ステップ3: $\phi_m = 50^\circ – 18.0^\circ + 10^\circ = 42.0^\circ$

ステップ4: $\alpha = (1 – \sin 42^\circ)/(1 + \sin 42^\circ) = (1 – 0.669)/(1 + 0.669) = 0.331/1.669 \approx 0.198$

ステップ5: 補償器のゲイン増加は $-10\log_{10}(0.198) \approx 7.0$ dBです。補償前にゲインが $-7.0$ dBとなる周波数を探し、$\omega_m \approx 4.5$ rad/s と設定します。

$$ T = \frac{1}{4.5\sqrt{0.198}} = \frac{1}{4.5 \times 0.445} \approx 0.499 \text{ s} $$

ステップ6: 得られた補償器 $C(s) = (0.499s + 1)/(0.0988s + 1)$ を開ループに加え、ボード線図で位相余裕を再確認します。

このように、各ステップでは明確な数式に基づいてパラメータが一意に決まるため、設計手順は体系的です。

位相進み補償器は位相余裕の改善には有効ですが、ゲインを増加させるため、高周波ノイズが増幅される可能性があります。定常精度の改善には、次に述べる位相遅れ補償器が適しています。

位相遅れ補償器 — 低周波ゲインを上げて精度を改善

位相遅れ補償器の直感的イメージ

位相進み補償器がゲイン交差周波数付近で位相を進める「攻め」の設計だったのに対し、位相遅れ補償器は「守り」の設計と考えることができます。

位相遅れ補償器の考え方を日常の例で説明すると、次のようになります。テスト勉強で全教科を均等にやると時間が足りませんが、得意科目(高周波域)は最低限にして苦手科目(低周波域=定常精度)に集中すれば全体の点数が上がります。位相遅れ補償器はまさにこの戦略で、低周波域のゲインを上げて定常精度を改善し、高周波域のゲインを抑えて安定性を保つのです。

もう少し制御工学的に言うと、定常精度を改善するにはゲイン $K_c$ を上げる必要がありますが、ゲインを上げるとゲイン交差周波数がシフトして位相余裕が減少し、不安定になりやすくなります。位相遅れ補償器は、低周波域では $\beta$ 倍のゲインを提供しつつ、高周波域(ゲイン交差周波数付近)ではゲインが1倍に戻るように設計されます。これにより、見かけ上のゲインを $\beta$ 倍にしながら、安定性には影響を与えないのです。

伝達関数

位相遅れ補償器の伝達関数は

$$ \begin{equation} C_{\text{lag}}(s) = K_c \frac{Ts + 1}{\beta Ts + 1} \quad (\beta > 1) \end{equation} $$

$\beta > 1$ なので、極 $s = -1/(\beta T)$ が零点 $s = -1/T$ より原点に近くなります。

周波数特性の解析

$s = j\omega$ を代入して周波数特性を調べます。

$$ C_{\text{lag}}(j\omega) = K_c \frac{j\omega T + 1}{j\omega \beta T + 1} $$

3つの周波数帯域に分けて考えると動作原理がよくわかります。

低周波域($\omega \ll 1/(\beta T)$): $j\omega T \approx 0$, $j\omega \beta T \approx 0$ なので

$$ C_{\text{lag}}(j\omega) \approx K_c \cdot \frac{1}{1} = K_c $$

ゲインは $K_c$、位相角は $0^\circ$ です。

中間帯域($1/(\beta T) \ll \omega \ll 1/T$): 分母の $j\omega \beta T$ は1に比べて大きく、分子の $j\omega T$ はまだ小さいので

$$ C_{\text{lag}}(j\omega) \approx K_c \cdot \frac{1}{j\omega \beta T} $$

ゲインは周波数に反比例して減少し($-20$ dB/decの傾き)、位相は $-90^\circ$ に近づきます。この帯域で位相遅れが生じます。

高周波域($\omega \gg 1/T$): 分子・分母とも $j\omega T$ 項が支配的なので

$$ C_{\text{lag}}(j\omega) \approx K_c \cdot \frac{j\omega T}{j\omega \beta T} = \frac{K_c}{\beta} $$

ゲインは $K_c/\beta$、位相角は $0^\circ$ に戻ります。

まとめると、位相遅れ補償器の動作原理は、低周波域のゲインを $K_c$ に保ちつつ、高周波域のゲインを $K_c/\beta$ に下げることです。低周波と高周波のゲイン差は $\beta$ 倍($20\log_{10}\beta$ dB)です。等価的に、低周波域のゲインが $\beta$ 倍に増加したことと同じ効果が得られ、定常精度が改善されます。

ただし中間帯域で位相遅れが発生するため、この帯域がゲイン交差周波数に近いと位相余裕を悪化させてしまいます。設計上の重要なポイントは、位相遅れが生じる帯域をゲイン交差周波数から十分に離すことです。

設計手順

位相遅れ補償器の設計手順を、各ステップの根拠と合わせて説明します。

ステップ1: 定常偏差の仕様から必要なゲイン $K_c \cdot \beta$ を決定します。たとえば1型システムで速度定数 $K_v \geq K_v^*$ が要求される場合、$K_v = \lim_{s \to 0} s \cdot K_c \cdot C_{\text{lag}}(s) \cdot G(s)$ で、$\omega \to 0$ では $C_{\text{lag}} \to K_c$ なので、$K_c$ を定めます。高周波域では実効ゲインが $K_c/\beta$ になるため、$\beta = K_c / K_c’$ と設定します($K_c’$ は安定性を満たすゲイン)。

ステップ2: まず $K_c’ = K_c/\beta$ のゲインだけを使ったシステムで、ゲイン交差周波数 $\omega_{gc}$ と位相余裕を確認します。この位相余裕が目標を満たすことを確認します(もし満たさなければ $\beta$ を大きくして $K_c’$ を下げます)。

ステップ3: 折れ点周波数(零点 $1/T$)をゲイン交差周波数の $1/5 \sim 1/10$ に設定します。

$$ \frac{1}{T} = \frac{\omega_{gc}}{5} \sim \frac{\omega_{gc}}{10} \quad \Rightarrow \quad T = \frac{5}{\omega_{gc}} \sim \frac{10}{\omega_{gc}} $$

この配置により、ゲイン交差周波数付近では補償器のゲインはほぼ $K_c/\beta$ に収束しており、位相遅れの影響も $-5^\circ$ 以下に抑えられます。

ステップ4: 結果をボード線図とステップ応答で検証し、位相余裕・ゲイン余裕・定常偏差が仕様を満たすか確認します。

数値計算例

プラントが $G(s) = 1/[s(s+1)(0.5s+1)]$ で、「$K_v \geq 5$、位相余裕 $40^\circ$ 以上」の仕様を考えます。

ステップ1: $K_v = \lim_{s \to 0} s \cdot K \cdot G(s) = K \cdot 1/(1 \cdot 0.5) = 2K$ なので、$K_v = 5$ には $K = 2.5$ が必要です。

ステップ2: $K = 2.5$ の開ループのゲイン交差周波数を求めます。しかしこの高ゲインでは位相余裕が不十分(たとえば $PM \approx 15^\circ$)です。そこで $K_c’ = 0.5$ のときの位相余裕を調べると $PM \approx 50^\circ$ で十分です。$\beta = K/K_c’ = 2.5/0.5 = 5$ と設定します。

ステップ3: $K_c’ = 0.5$ のときのゲイン交差周波数が $\omega_{gc} \approx 0.5$ rad/sなら、$T = 10/0.5 = 20$ sとします。

ステップ4: 補償器は $C_{\text{lag}}(s) = (20s+1)/(100s+1)$ となり、ボード線図で位相余裕が $40^\circ$ 以上であることを確認します。

位相進み補償器と位相遅れ補償器の比較

ここまで2つの補償器を学んできたので、それぞれの特徴を比較表にまとめます。

特徴 位相進み補償器 位相遅れ補償器
パラメータ $0 < \alpha < 1$ $\beta > 1$
主な改善対象 位相余裕(安定性) 定常精度
帯域幅 広がる(応答が速くなる) 狭くなるか変化なし
高周波ノイズ 増幅する(注意が必要) 抑制する
応答速度 速くなる 変化なしか遅くなる
設計の自由度 $\phi_m \leq 65^\circ$(1段あたり) $\beta$ に上限なし(理論上)

実際のシステム設計では、両方の改善が必要な場合が多く、後述する位相進み遅れ補償器で2つの利点を同時に実現します。

それでは、Pythonで実際に設計・検証してみましょう。

Pythonでの実装と検証

位相進み補償器の設計と効果

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

# プラント: G(s) = 1/[s(s+1)]
plant = ctrl.TransferFunction([1], [1, 1, 0])

# 目標: 位相余裕 50度以上
# 補償前の位相余裕確認
K_c = 4  # ゲイン設定
L_uncomp = K_c * plant
gm0, pm0, wcg0, wcp0 = ctrl.margin(L_uncomp)
print(f"補償前: PM = {pm0:.1f} deg at wgc = {wcp0:.2f} rad/s")

# 位相進み補償器の設計
phi_m_target = 50 - pm0 + 10  # 安全マージン10度
phi_m_rad = np.radians(phi_m_target)
alpha = (1 - np.sin(phi_m_rad)) / (1 + np.sin(phi_m_rad))
print(f"必要な位相進み: {phi_m_target:.1f} deg, alpha = {alpha:.4f}")

# omega_mを新しいゲイン交差周波数に設定
# 補償器のゲイン上昇 -10log10(alpha) dBを考慮
omega_m = wcp0 * np.sqrt(1 / alpha)**0.5  # 近似
T_lead = 1 / (omega_m * np.sqrt(alpha))

C_lead = K_c * ctrl.TransferFunction([T_lead, 1], [alpha * T_lead, 1])
L_lead = C_lead * plant

gm_lead, pm_lead, wcg_lead, wcp_lead = ctrl.margin(L_lead)
print(f"補償後: PM = {pm_lead:.1f} deg at wgc = {wcp_lead:.2f} rad/s")

# ボード線図の比較
omega = np.logspace(-2, 2, 1000)
fig, axes = plt.subplots(2, 2, figsize=(14, 9))

# ボード線図
for idx, (L, label, color) in enumerate([
    (L_uncomp, "Without compensator", "steelblue"),
    (L_lead, "With lead compensator", "red")
]):
    mag, phase, w = ctrl.frequency_response(L, omega)
    axes[0, 0].semilogx(w, 20*np.log10(np.abs(mag)), linewidth=2,
                         color=color, label=label)
    axes[1, 0].semilogx(w, np.degrees(np.angle(mag)), linewidth=2,
                         color=color, label=label)

axes[0, 0].axhline(0, color="black", linestyle="--", alpha=0.4)
axes[0, 0].set_ylabel("Gain [dB]", fontsize=11)
axes[0, 0].set_title("Bode Plot: Gain", fontsize=12)
axes[0, 0].legend(fontsize=9)
axes[0, 0].grid(True, which="both", alpha=0.3)

axes[1, 0].axhline(-180, color="black", linestyle="--", alpha=0.4)
axes[1, 0].set_ylabel("Phase [deg]", fontsize=11)
axes[1, 0].set_xlabel(r"$\omega$ [rad/s]", fontsize=11)
axes[1, 0].set_title("Bode Plot: Phase", fontsize=12)
axes[1, 0].legend(fontsize=9)
axes[1, 0].grid(True, which="both", alpha=0.3)

# ステップ応答の比較
t = np.linspace(0, 8, 500)
G_cl_uncomp = ctrl.feedback(L_uncomp)
G_cl_lead = ctrl.feedback(L_lead)

ax = axes[0, 1]
t1, y1 = ctrl.step_response(G_cl_uncomp, T=t)
t2, y2 = ctrl.step_response(G_cl_lead, T=t)
ax.plot(t1, y1, linewidth=2, color="steelblue", label="Without compensator")
ax.plot(t2, y2, linewidth=2, color="red", label="With lead compensator")
ax.axhline(1, color="black", linestyle="--", alpha=0.4)
ax.set_xlabel("Time [s]", fontsize=11)
ax.set_ylabel("Output", fontsize=11)
ax.set_title("Closed-loop Step Response", fontsize=12)
ax.legend(fontsize=9)
ax.grid(True, alpha=0.3)

# 補償器のボード線図
ax = axes[1, 1]
mag_c, phase_c, w_c = ctrl.frequency_response(C_lead / K_c, omega)
ax.semilogx(w_c, 20*np.log10(np.abs(mag_c)), linewidth=2,
            color="green", label="Gain")
ax2 = ax.twinx()
ax2.semilogx(w_c, np.degrees(np.angle(mag_c)), linewidth=2,
             color="purple", linestyle="--", label="Phase")
ax.set_xlabel(r"$\omega$ [rad/s]", fontsize=11)
ax.set_ylabel("Gain [dB]", fontsize=11, color="green")
ax2.set_ylabel("Phase [deg]", fontsize=11, color="purple")
ax.set_title("Lead Compensator", fontsize=12)
ax.grid(True, which="both", alpha=0.3)

plt.tight_layout()
plt.savefig("lead_compensator.png", dpi=150, bbox_inches="tight")
plt.show()

この結果から、位相進み補償器の効果が明確に確認できます。

  1. ボード線図(左): 位相進み補償器の追加により、ゲイン交差周波数付近で位相が進み、位相余裕が増加しています。ゲイン交差周波数も右にシフトし、帯域幅が広がっています。帯域幅の拡大は、システムがより高い周波数の指令値にも追従できるようになったことを意味します

  2. ステップ応答(右上): 補償前は大きなオーバーシュートと振動が見られますが、補償後はオーバーシュートが大幅に抑制され、整定時間も短縮されています。位相余裕の改善が過渡応答の改善に直結していることがわかります。一般に、位相余裕が $40^\circ \sim 60^\circ$ のとき、過渡応答のオーバーシュートは $25\%$ 以下に抑えられます

  3. 補償器特性(右下): 位相進み補償器は、特定の周波数帯域でゲインを上げ(緑)、位相を進めています(紫)。最大位相進みが設計通りの周波数で生じていることが確認できます。また、低周波域と高周波域ではゲイン・位相ともにほぼ影響がなく、狙った帯域だけに作用していることが確認できます

位相進み補償器の設計結果を確認できたところで、次は位相遅れ補償器の設計と効果をPythonで検証してみましょう。

位相遅れ補償器の設計と効果

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

# プラント: G(s) = 1/[s(s+1)(s+5)]
plant = ctrl.TransferFunction([1], np.polymul([1, 0], np.polymul([1, 1], [1, 5])))

# 定常偏差仕様: Kv >= 5 (速度定数)
# 現在のKv = lim s->0 s*K*G(s) = K/5
# Kv = 5 → K = 25
K_c = 25

# 補償前
L_uncomp = K_c * plant
gm0, pm0, wcg0, wcp0 = ctrl.margin(L_uncomp)
print(f"補償前: PM = {pm0:.1f} deg, GM = {20*np.log10(gm0):.1f} dB")

# 位相遅れ補償器の設計
# 新しいゲイン交差周波数を位相余裕50度が得られる点に設定
# beta = K_c / K_new (ゲインをK_newに下げ、betaで低周波ゲインを補償)
beta = 10  # 低周波ゲイン 20dB増加
T_lag = 10.0  # 折れ点をゲイン交差周波数の1/10以下に

C_lag = ctrl.TransferFunction([T_lag, 1], [beta * T_lag, 1])
L_lag = K_c * C_lag * plant

gm_lag, pm_lag, wcg_lag, wcp_lag = ctrl.margin(L_lag)
print(f"補償後: PM = {pm_lag:.1f} deg, GM = {20*np.log10(gm_lag):.1f} dB")

# 比較
omega = np.logspace(-3, 2, 1000)
fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# ステップ応答
t = np.linspace(0, 15, 500)
ax = axes[0]

for L, label, color in [
    (K_c * plant, "Gain only (K=25)", "steelblue"),
    (L_lag, "With lag compensator", "red"),
]:
    G_cl = ctrl.feedback(L)
    poles = ctrl.poles(G_cl)
    if all(p.real < 0 for p in poles):
        t_out, y_out = ctrl.step_response(G_cl, T=t)
        ax.plot(t_out, y_out, linewidth=2, color=color, label=label)
    else:
        ax.text(0.5, 0.5, f"{label}: UNSTABLE", transform=ax.transAxes,
                fontsize=12, color=color, ha="center")

ax.axhline(1, color="black", linestyle="--", alpha=0.4)
ax.set_xlabel("Time [s]", fontsize=12)
ax.set_ylabel("Output", fontsize=12)
ax.set_title("Step Response Comparison", fontsize=13)
ax.legend(fontsize=9)
ax.grid(True, alpha=0.3)

# ボード線図
ax = axes[1]
for L, label, color in [
    (K_c * plant, "Gain only", "steelblue"),
    (L_lag, "With lag comp.", "red"),
]:
    mag, phase, w = ctrl.frequency_response(L, omega)
    ax.semilogx(w, 20*np.log10(np.abs(mag)), linewidth=2,
                color=color, label=label)

ax.axhline(0, color="black", linestyle="--", alpha=0.4)
ax.set_xlabel(r"$\omega$ [rad/s]", fontsize=12)
ax.set_ylabel("Gain [dB]", fontsize=12)
ax.set_title("Open-loop Gain Comparison", fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, which="both", alpha=0.3)

plt.tight_layout()
plt.savefig("lag_compensator.png", dpi=150, bbox_inches="tight")
plt.show()

この結果から、位相遅れ補償器の効果が確認できます。

  1. ステップ応答(左図): ゲインのみ($K=25$)の場合は不安定または大きな振動を示しますが、位相遅れ補償器を追加すると安定な応答が得られます。定常偏差がほぼゼロに改善されつつ、安定な過渡応答が実現されています

  2. ゲイン線図(右図): 位相遅れ補償器は低周波域のゲインを維持しつつ、高周波域でゲインを下げています。これによりゲイン交差周波数が低下し、位相余裕が確保されています。低周波ゲインの維持が定常精度の改善に、高周波ゲインの低下が安定性の確保に寄与しています。定量的には、低周波ゲインが $20\log_{10}\beta$ dB高い状態を保ちながら、ゲイン交差周波数付近では補償前と同程度のゲインに戻っていることが読み取れます

2つのシミュレーション結果を見比べると、位相進み補償器は「応答を速く・安定にする」効果が顕著で、位相遅れ補償器は「定常精度を上げつつ安定性を保つ」効果が顕著であることがわかります。

位相進み遅れ補償器 — 両方の利点を同時に実現

構造と伝達関数

実際の制御系では、「応答速度と安定余裕を改善したい」かつ「定常精度も改善したい」という要求が同時に出ることが少なくありません。このような場合に使うのが位相進み遅れ補償器です。

位相進み遅れ補償器は、位相進み部と位相遅れ部を直列に接続したものです。

$$ \begin{equation} C(s) = K_c \underbrace{\frac{T_1 s + 1}{\alpha T_1 s + 1}}_{\text{位相進み部}} \cdot \underbrace{\frac{T_2 s + 1}{\beta T_2 s + 1}}_{\text{位相遅れ部}} \end{equation} $$

ただし $0 < \alpha < 1$、$\beta > 1$ です。

設計の考え方

位相進み遅れ補償器の設計では、2つの部分が互いに干渉しないように周波数帯域を分離することが重要です。

  • 位相遅れ部の折れ点: 低い周波数帯域に配置($1/(\beta T_2)$ と $1/T_2$ がゲイン交差周波数の $1/10$ 以下)
  • 位相進み部の折れ点: ゲイン交差周波数付近に配置($1/T_1$ と $1/(\alpha T_1)$ がゲイン交差周波数を挟む)

この分離により、位相遅れ部の位相遅れがゲイン交差周波数に影響を与えず、位相進み部が効果的に位相余裕を改善できます。

設計手順は以下の通りです。

  1. まず位相遅れ部を設計し、定常精度と低周波特性を確定する
  2. 位相遅れ部を適用した状態で、位相進み部を設計して安定余裕を改善する
  3. 全体を組み合わせて最終検証を行う

この手順に従えば、2つの補償器の独立した設計が可能で、パラメータ調整も容易です。

応用例 — 産業・研究での活用

位相進み・遅れ補償器は、PID制御と並んで古典制御の基本ツールです。以下のような場面で広く使われています。

モータ制御

DCモータやACサーボモータの速度制御・位置制御では、位相進み補償器によって帯域幅を拡大し、外乱に対する応答性を高めます。たとえばロボットアームの関節駆動では、位相余裕 $45^\circ$ 以上を確保しつつ帯域幅 $50$ Hz以上が要求されることがあり、位相進み補償器が不可欠です。

航空宇宙のオートパイロット

航空機のピッチ角制御やヨー角制御では、位相進み遅れ補償器が古くから使われています。機体のダイナミクスは速度や高度によって変化しますが、位相補償器のパラメータを飛行条件に応じてスケジューリング(ゲインスケジューリング)することで、広い飛行領域で安定した制御を実現します。

プロセス制御

化学プラントの温度制御や流量制御では、応答が遅い(時定数が数十秒〜数分)システムが多く、定常精度が重視されます。位相遅れ補償器で定常偏差を抑えつつ、安定性を維持する設計が標準的です。

PID制御との関係

PID制御器 $C(s) = K_p + K_i/s + K_d s$ を周波数領域で見ると、積分項 $K_i/s$ は低周波ゲインを上げる位相遅れ的な作用、微分項 $K_d s$ は高周波域で位相を進める位相進み的な作用を持っています。つまりPID制御は、位相進み遅れ補償の一種と見なすことができます。ただしPID制御器は微分項が理想的(improper)であるのに対し、位相進み補償器は必ずプロパーな伝達関数になっており、実装上の利点があります。

まとめ

本記事では、位相進み・遅れ補償器の設計手法を解説しました。

  • 位相進み補償器 $C(s) = K_c(Ts+1)/(\alpha Ts+1)$($\alpha < 1$): 位相を進めて安定余裕を改善し、帯域幅を広げて応答を速くする
  • 位相遅れ補償器 $C(s) = K_c(Ts+1)/(\beta Ts+1)$($\beta > 1$): 低周波ゲインを上げて定常精度を改善しつつ、高周波ゲインを下げて安定性を維持する
  • 位相進み補償器の最大位相進み角は $\phi_m = \arcsin[(1-\alpha)/(1+\alpha)]$
  • 設計はボード線図上で行い、所望の位相余裕やゲイン余裕を満たすようにパラメータを決定する
  • 両者を組み合わせた位相進み遅れ補償器 $C(s) = K_c \cdot \frac{T_1 s + 1}{\alpha T_1 s + 1} \cdot \frac{T_2 s + 1}{\beta T_2 s + 1}$ は、速い応答と高い精度を同時に実現できる
  • PID制御は位相進み遅れ補償の一種と見なすことができるが、位相補償器はプロパーな伝達関数であり実装上の利点がある
  • 設計は各ステップが明確な数式に基づいており体系的に行える。ただし1段の位相進み補償器で得られる最大位相進みは約 $65^\circ$ に制限されるため、それ以上の位相進みが必要な場合は多段構成を検討する

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