伝達関数は、線形時不変(LTI)システムの入出力関係を $s$ 領域で表現する関数です。制御工学の中核をなす概念であり、システムの安定性・応答特性・周波数特性のすべてが伝達関数から読み取れます。
本記事では、伝達関数の定義、微分方程式からの導出方法、極と零点の意味、Pythonでの実装までを解説します。
本記事の内容
- 伝達関数の定義とラプラス変換との関係
- 微分方程式から伝達関数を求める方法
- 極と零点の定義と安定性との関係
- 伝達関数の直列・並列結合
- Python-controlでの定義と可視化
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
伝達関数とは
ラプラス変換との関係
時間領域の関数 $f(t)$ のラプラス変換は次のように定義されます。
$$ F(s) = \mathcal{L}[f(t)] = \int_0^{\infty} f(t) e^{-st} dt $$
ラプラス変換の重要な性質として、微分がかけ算に変換されます。
$$ \mathcal{L}\left[\frac{df}{dt}\right] = sF(s) – f(0) $$
初期値をゼロとすると $\mathcal{L}\left[\frac{df}{dt}\right] = sF(s)$ となり、微分方程式が代数方程式に帰着します。
伝達関数の定義
伝達関数 $G(s)$ は、初期値をすべてゼロとしたときの、入力のラプラス変換 $U(s)$ から出力のラプラス変換 $Y(s)$ への比として定義されます。
$$ \begin{equation} G(s) = \frac{Y(s)}{U(s)} \end{equation} $$
入出力の関係は
$$ Y(s) = G(s) \cdot U(s) $$
つまり、時間領域の畳み込みが $s$ 領域ではかけ算になるという、ラプラス変換の性質を利用しています。
微分方程式からの導出
$n$ 階線形定係数微分方程式で記述されるシステムを考えます。
$$ a_n \frac{d^n y}{dt^n} + a_{n-1} \frac{d^{n-1} y}{dt^{n-1}} + \cdots + a_1 \frac{dy}{dt} + a_0 y = b_m \frac{d^m u}{dt^m} + \cdots + b_1 \frac{du}{dt} + b_0 u $$
初期値ゼロでラプラス変換すると $\frac{d^k}{dt^k} \to s^k$ となるため、
$$ (a_n s^n + a_{n-1} s^{n-1} + \cdots + a_0) Y(s) = (b_m s^m + b_{m-1} s^{m-1} + \cdots + b_0) U(s) $$
したがって伝達関数は
$$ \begin{equation} G(s) = \frac{Y(s)}{U(s)} = \frac{b_m s^m + b_{m-1} s^{m-1} + \cdots + b_0}{a_n s^n + a_{n-1} s^{n-1} + \cdots + a_0} \end{equation} $$
物理的に実現可能なシステムでは $m \leq n$(プロパーな伝達関数)が成り立ちます。
導出例: ばね-ダンパ系
質量 $m$、ダンパ(減衰係数 $c$)、ばね(ばね定数 $k$)からなる1自由度振動系を考えます。外力 $f(t)$ が入力、変位 $x(t)$ が出力です。
運動方程式は
$$ m \ddot{x} + c \dot{x} + k x = f(t) $$
ラプラス変換すると(初期値ゼロ)
$$ (ms^2 + cs + k) X(s) = F(s) $$
したがって伝達関数は
$$ G(s) = \frac{X(s)}{F(s)} = \frac{1}{ms^2 + cs + k} $$
$m = 1$, $c = 2$, $k = 5$ の場合
$$ G(s) = \frac{1}{s^2 + 2s + 5} $$
極と零点
定義
伝達関数を因数分解した形で書くと
$$ G(s) = K \frac{(s – z_1)(s – z_2) \cdots (s – z_m)}{(s – p_1)(s – p_2) \cdots (s – p_n)} $$
- 極(pole): 分母 $= 0$ の根 $p_1, p_2, \ldots, p_n$
- 零点(zero): 分子 $= 0$ の根 $z_1, z_2, \ldots, z_m$
極と安定性
システムが安定であるための必要十分条件は
$$ \begin{equation} \text{Re}(p_i) < 0 \quad \forall i = 1, 2, \ldots, n \end{equation} $$
すなわち、すべての極が複素 $s$ 平面の左半面にあることです。
極の位置と時間応答
極の位置からシステムの時間応答の性質がわかります。
| 極の位置 | 時間応答 | 安定性 |
|---|---|---|
| 負の実軸上 $p = -a$ | 指数減衰 $e^{-at}$ | 安定 |
| 複素共役 $p = -\sigma \pm j\omega$ | 減衰振動 $e^{-\sigma t}\sin(\omega t + \phi)$ | 安定 |
| 虚軸上 $p = \pm j\omega$ | 持続振動 $\sin(\omega t)$ | 安定限界 |
| 正の実軸上 $p = a > 0$ | 指数発散 $e^{at}$ | 不安定 |
| 右半面 $p = \sigma \pm j\omega, \sigma > 0$ | 発散振動 $e^{\sigma t}\sin(\omega t)$ | 不安定 |
零点の役割
零点は応答の形状に影響を与えます。零点が左半面にあるシステムを最小位相系、右半面に零点があるシステムを非最小位相系と呼びます。非最小位相系のステップ応答は、最初に逆方向に動く「逆応答」が生じます。
伝達関数の結合
直列結合
$$ G(s) = G_1(s) \cdot G_2(s) $$
並列結合
$$ G(s) = G_1(s) + G_2(s) $$
フィードバック結合
$$ G(s) = \frac{G_1(s)}{1 + G_1(s) G_2(s)} $$
Pythonでの実装
伝達関数の定義と極零点
import numpy as np
import matplotlib.pyplot as plt
import control as ctrl
# 伝達関数の定義: G(s) = (s+2) / (s^2 + 2s + 5)
G = ctrl.tf([1, 2], [1, 2, 5])
print("伝達関数:", G)
# 極と零点
poles = ctrl.poles(G)
zeros = ctrl.zeros(G)
print(f"極: {poles}")
print(f"零点: {zeros}")
# 極零点配置図
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
# 極零点マップ
ax1.plot(poles.real, poles.imag, 'rx', markersize=12, markeredgewidth=2, label='Poles')
ax1.plot(zeros.real, zeros.imag, 'bo', markersize=12, markeredgewidth=2,
fillstyle='none', label='Zeros')
ax1.axvline(x=0, color='k', linewidth=0.5)
ax1.axhline(y=0, color='k', linewidth=0.5)
# 左半面を薄く塗る
ax1.axvspan(-5, 0, alpha=0.1, color='green', label='Stable region')
ax1.set_xlabel('Real')
ax1.set_ylabel('Imaginary')
ax1.set_title('Pole-Zero Map')
ax1.legend()
ax1.grid(True, alpha=0.3)
ax1.set_aspect('equal')
ax1.set_xlim([-4, 1])
ax1.set_ylim([-3, 3])
# ステップ応答
t, y = ctrl.step_response(G, T=np.linspace(0, 6, 500))
ax2.plot(t, y, linewidth=2)
ax2.set_xlabel('Time [s]')
ax2.set_ylabel('Output y(t)')
ax2.set_title('Step Response')
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
極の位置による安定性の違い
import numpy as np
import matplotlib.pyplot as plt
import control as ctrl
# 異なる極の位置を持つシステム
systems = {
'Stable (p=-1,-2)': ctrl.tf([1], [1, 3, 2]),
'Oscillatory (p=-1±2j)': ctrl.tf([5], [1, 2, 5]),
'Marginal (p=±2j)': ctrl.tf([4], [1, 0, 4]),
'Unstable (p=1, -2)': ctrl.tf([1], [1, 1, -2]),
}
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
colors = ['blue', 'green', 'orange', 'red']
for (name, G), color in zip(systems.items(), colors):
poles = ctrl.poles(G)
# 極零点プロット
axes[0].plot(poles.real, poles.imag, 'x', markersize=10,
markeredgewidth=2, color=color, label=name)
# ステップ応答(不安定系は短い時間で)
T = 5 if all(p.real <= 0 for p in poles) else 3
t, y = ctrl.step_response(G, T=np.linspace(0, T, 500))
axes[1].plot(t, y, linewidth=2, color=color, label=name)
axes[0].axvline(x=0, color='k', linewidth=0.5)
axes[0].axhline(y=0, color='k', linewidth=0.5)
axes[0].axvspan(-5, 0, alpha=0.05, color='green')
axes[0].set_xlabel('Real')
axes[0].set_ylabel('Imaginary')
axes[0].set_title('Pole Locations')
axes[0].legend(fontsize=8)
axes[0].grid(True, alpha=0.3)
axes[0].set_aspect('equal')
axes[1].set_xlabel('Time [s]')
axes[1].set_ylabel('Output y(t)')
axes[1].set_title('Step Response')
axes[1].legend(fontsize=8)
axes[1].grid(True, alpha=0.3)
axes[1].set_ylim([-5, 10])
plt.tight_layout()
plt.show()
まとめ
本記事では、伝達関数の定義と基本性質について解説しました。
- 伝達関数は $G(s) = Y(s) / U(s)$ で定義され、初期値ゼロの条件下で LTI システムの入出力関係を表す
- 微分方程式からラプラス変換を用いて伝達関数を導出できる
- 極はシステムの安定性を決定し、すべての極が左半面にあれば安定
- 零点は応答の形状に影響し、右半面の零点は逆応答を引き起こす
- 直列結合は積、並列結合は和、フィードバック結合は $G/(1+GH)$
次のステップとして、以下の記事も参考にしてください。