ボード線図の描き方と読み方を解説

ボード線図(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° が望ましい

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