ボード線図(Bode plot)は、システムの周波数応答をゲインと位相の2つのグラフで表す図です。制御系の設計や安定性解析において最も重要なツールの一つであり、ゲイン余裕や位相余裕を視覚的に読み取ることができます。
本記事では、ボード線図の基本的な描き方・読み方から、安定余裕の概念、Pythonでの作成までを解説します。
本記事の内容
- 周波数応答とボード線図の基本
- ゲイン線図と位相線図の描き方
- ゲイン余裕・位相余裕の読み方
- Pythonによるボード線図の作成
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
周波数応答とは
LTIシステムに正弦波入力 $u(t) = A \sin(\omega t)$ を加えると、定常状態での出力は
$$ y(t) = A |G(j\omega)| \sin(\omega t + \angle G(j\omega)) $$
となります。ここで $G(j\omega)$ は伝達関数 $G(s)$ の $s = j\omega$ としたものです。
- $|G(j\omega)|$: ゲイン(振幅比)
- $\angle G(j\omega)$: 位相(位相の遅れ/進み)
ボード線図の構成
ボード線図は以下の2つのグラフからなります。
ゲイン線図(上段): – 横軸: 角周波数 $\omega$ [rad/s](対数スケール) – 縦軸: ゲイン $20 \log_{10} |G(j\omega)|$ [dB]
位相線図(下段): – 横軸: 角周波数 $\omega$ [rad/s](対数スケール) – 縦軸: 位相 $\angle G(j\omega)$ [deg]
デシベル(dB)は対数スケールのゲインで、
$$ \text{Gain [dB]} = 20 \log_{10} |G(j\omega)| $$
| ゲイン比 | dB値 |
|---|---|
| 1 | 0 dB |
| 2 | 6 dB |
| 10 | 20 dB |
| 100 | 40 dB |
| 0.1 | -20 dB |
基本要素のボード線図
比例要素: $G(s) = K$
$$ |G(j\omega)| = K, \quad \angle G(j\omega) = 0° $$
ゲイン線図は $20\log_{10}K$ の水平線、位相は0°の水平線です。
積分要素: $G(s) = \frac{1}{s}$
$$ |G(j\omega)| = \frac{1}{\omega}, \quad \angle G(j\omega) = -90° $$
ゲイン線図は $-20$ dB/dec の直線(1デカードあたり-20 dBの傾き)、位相は $-90°$ の水平線です。
1次遅れ要素: $G(s) = \frac{1}{\tau s + 1}$
$$ |G(j\omega)| = \frac{1}{\sqrt{1 + (\omega \tau)^2}} $$
$$ \angle G(j\omega) = -\arctan(\omega \tau) $$
折点周波数 $\omega_c = \frac{1}{\tau}$ でゲインが $-3$ dB になります。
- $\omega \ll \omega_c$: ゲイン $\approx 0$ dB、位相 $\approx 0°$
- $\omega = \omega_c$: ゲイン $= -3$ dB、位相 $= -45°$
- $\omega \gg \omega_c$: ゲインは $-20$ dB/dec で減衰、位相 $\to -90°$
2次振動要素: $G(s) = \frac{\omega_n^2}{s^2 + 2\zeta\omega_n s + \omega_n^2}$
$$ |G(j\omega)| = \frac{1}{\sqrt{\left(1 – \left(\frac{\omega}{\omega_n}\right)^2\right)^2 + \left(2\zeta \frac{\omega}{\omega_n}\right)^2}} $$
$\zeta < \frac{1}{\sqrt{2}}$ のとき、共振ピークが現れます。共振周波数は
$$ \omega_r = \omega_n \sqrt{1 – 2\zeta^2} $$
ゲイン余裕と位相余裕
安定な閉ループ系を設計するために重要な指標が安定余裕です。
位相交差周波数 $\omega_{pc}$: 位相が $-180°$ になる周波数
ゲイン交差周波数 $\omega_{gc}$: ゲインが $0$ dB になる周波数
$$ \begin{equation} \text{ゲイン余裕 (GM)} = -20\log_{10} |G(j\omega_{pc})| \quad \text{[dB]} \end{equation} $$
$$ \begin{equation} \text{位相余裕 (PM)} = 180° + \angle G(j\omega_{gc}) \end{equation} $$
安定なシステムでは GM > 0 dB かつ PM > 0° です。一般的には GM > 6 dB、PM > 30° 〜 60° が望ましいとされます。
Pythonでの実装
基本要素のボード線図
import numpy as np
import matplotlib.pyplot as plt
import control as ctrl
# 基本要素の伝達関数
G_prop = ctrl.tf([5], [1]) # 比例: K=5
G_int = ctrl.tf([1], [1, 0]) # 積分: 1/s
G_first = ctrl.tf([1], [0.5, 1]) # 1次遅れ: 1/(0.5s+1)
G_second = ctrl.tf([4], [1, 0.8, 4]) # 2次系: wn=2, zeta=0.2
systems = [G_prop, G_int, G_first, G_second]
labels = ['Proportional (K=5)', 'Integrator (1/s)',
'1st Order (τ=0.5)', '2nd Order (ζ=0.2, ωn=2)']
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
for ax_pair, G, label in zip(axes.T, [G_first, G_second],
['1st Order (τ=0.5)', '2nd Order (ζ=0.2, ωn=2)']):
# ボード線図を手動で描画
omega = np.logspace(-2, 2, 1000)
mag, phase, _ = ctrl.frequency_response(G, omega)
ax_pair[0].semilogx(omega, 20 * np.log10(np.abs(mag)), linewidth=2)
ax_pair[0].set_ylabel('Gain [dB]')
ax_pair[0].set_title(f'Bode Plot: {label}')
ax_pair[0].grid(True, which='both', alpha=0.3)
ax_pair[0].axhline(y=0, color='k', linewidth=0.5)
ax_pair[1].semilogx(omega, np.degrees(np.angle(mag)), linewidth=2)
ax_pair[1].set_xlabel('Frequency [rad/s]')
ax_pair[1].set_ylabel('Phase [deg]')
ax_pair[1].grid(True, which='both', alpha=0.3)
ax_pair[1].axhline(y=-180, color='r', linewidth=0.5, linestyle='--')
plt.tight_layout()
plt.show()
ゲイン余裕・位相余裕の可視化
import numpy as np
import matplotlib.pyplot as plt
import control as ctrl
# 開ループ伝達関数: L(s) = 10 / (s(s+1)(0.5s+1))
L = ctrl.tf([10], [0.5, 1.5, 1, 0])
# ゲイン余裕・位相余裕の計算
gm, pm, wpc, wgc = ctrl.margin(L)
print(f'ゲイン余裕: {20*np.log10(gm):.2f} dB (at {wpc:.2f} rad/s)')
print(f'位相余裕: {pm:.2f} deg (at {wgc:.2f} rad/s)')
# ボード線図
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
omega = np.logspace(-2, 2, 1000)
mag, phase, _ = ctrl.frequency_response(L, omega)
mag_db = 20 * np.log10(np.abs(mag))
phase_deg = np.degrees(np.unwrap(np.angle(mag)))
# ゲイン線図
ax1.semilogx(omega, mag_db, 'b', linewidth=2)
ax1.axhline(y=0, color='k', linewidth=0.5)
ax1.axvline(x=wpc, color='r', linestyle='--', alpha=0.7, label=f'ω_pc={wpc:.2f}')
ax1.axvline(x=wgc, color='g', linestyle='--', alpha=0.7, label=f'ω_gc={wgc:.2f}')
ax1.set_ylabel('Gain [dB]')
ax1.set_title('Bode Plot with Stability Margins')
ax1.legend()
ax1.grid(True, which='both', alpha=0.3)
# 位相線図
ax2.semilogx(omega, phase_deg, 'b', linewidth=2)
ax2.axhline(y=-180, color='r', linewidth=0.5, linestyle='--')
ax2.axvline(x=wpc, color='r', linestyle='--', alpha=0.7)
ax2.axvline(x=wgc, color='g', linestyle='--', alpha=0.7)
ax2.set_xlabel('Frequency [rad/s]')
ax2.set_ylabel('Phase [deg]')
ax2.grid(True, which='both', alpha=0.3)
plt.tight_layout()
plt.show()
まとめ
本記事では、ボード線図の描き方と読み方について解説しました。
- ボード線図はゲイン線図と位相線図からなり、周波数応答を対数スケールで表現する
- 基本要素(比例・積分・1次遅れ・2次系)のボード線図を組み合わせて複雑なシステムを解析できる
- ゲイン余裕と位相余裕により閉ループ系の安定性を定量的に評価できる
- 一般にゲイン余裕 > 6 dB、位相余裕 > 30° が望ましい
次のステップとして、以下の記事も参考にしてください。