伝達関数とインパルス応答
インパルス応答は身近なところで日常的に使っている。電車のレールや機械をハンマーで叩いて音の反響を聞き取る打音検査、これはインパルス応答で異常がないか調べているわけだ。そしてこのインパルス応答をラプラス変換したものが伝達関数である。この記事ではそんな伝達関数とインパルス応答について詳しく解説していく。

伝達関数とは

伝達関数とは、複素数領域sにおいてシステムに(X(s))を入力したときの出力(Y(s))との比である。つまり、伝達関数を(G(s))とすれば次の式で表される。 \[G(s)=\frac{Y(s)}{X(s)}\]
具体的にRCローパスフィルタ回路の伝達関数をラプラス変換を使って導き出してみよう。
RCローパスフィルタの伝達関数

時間領域tにおいては、回路図より次の式が成り立つ。
\[v_{in}(t)=Ri(i)+v_{out}(t),~~~i(t)=C\frac{dv_{out}(t)}{dt}\]
よって \[v_{in}(t)=RC\frac{dv_{out}(t)}{dt}+V{out(t)}\]
である。これをラプラス変換して複素数領域sへ書き換えると \[V_{in}(s)=RC(sV_{out} - v_{out}(0)) + V_{out}(s)\]
(t=0)のとき(v_{out}=0)とすれば、
\[V_{in}(s)=RCsV_{out} + V_{out}(s)\]
よって、RCローパスフィルタの伝達関数(G(s))は
\[G(s)=\frac{V_{out}(s)}{V_{in}(s)}=\frac{1}{1+RCs}\] である。
ここで(V_{in}=1)となる入力を与えたときの過渡応答が伝達関数(G(s))である。複素数領域sで1となる関数はインパルス関数(δ(t))である。つまりインパルス応答をラプラス変換したものが伝達関数である。
\[G(s)=\mathcal{L}[δ(t)]\]
インパルス関数とは
インパルス関数とは、時間幅が無限小で高さが無限大のパルス信号である。またすべての時間領域において、積分値が1となる。数学ではディラックのデルタ関数、制御工学ではインパルス関数と呼ばれる。
\[δ(t)=\begin{cases}\infty~(t=0)\\0~~~(t\neq0)\end{cases}\]
実は、インパルス関数はさまざまな周波数の余弦波を足し合わせることによって作り出すことができる。つまり、すべての周波数成分を含んだ信号と考えることができるのだ。
Pythonでインパルス関数を作ってみよう!
図の左側が、1Hzkから11Hzまでの余弦波を1Hz間隔で足し合わせたものである。右側が1Hzkから10001Hzまでの余弦波を1Hz間隔で足し合わせたもである。
import matplotlib.pyplot as plt
import numpy as np
= plt.subplots()
fig, ax =':')
ax.grid(ls
if __name__ == '__main__':
= np.arange(1, 11, 1)
F1 = np.arange(1, 10001, 1)
F2 = np.arange(-1, 1, 0.001)
T = [0]*len(T)
Y1 = [0]*len(T)
Y2
for f in F1:
for i in range(len(T)):
+= np.cos(2 * np.pi * f * T[i])
Y1[i]
for f in F2:
for i in range(len(T)):
+= np.cos(2 * np.pi * f * T[i])
Y2[i]
='{} times'.format(len(F1)))
plt.plot(T, Y1, label#plt.plot(T, Y2, label='{} times'.format(len(F2)))
plt.legend() plt.show()

現実には、無限大の大きさなるようなインパルス信号は存在しないため、図のように面積1となるようなごく短時間のパルス信号で代用する。

冒頭にも述べた通り、実はインパルス応答による測定はごく身近なところで当たり前のように使っている。例えば、電車のレールや機械などをハンマーで叩いて音の反響を聞き取っているシーンを映像で見たことがあるだろう。これは打音検査と呼ばれ、まさにインパルス応答で機械に異常がないか人間の耳で判定しているわけである。
また、誰もいないコンサートホールで手を叩いて残響を調べる姿を見たことは無いだろうか。これもインパルス応答を使って、コンサートホールの特徴を調べているわけである。
もっと身近なところでは、スーパーなどで大根やスイカをコンコンと叩いて野菜の中の具合を調べたりしたことが誰しもあるかと思う。これもインパルス応答による測定に他ならない。
Pythonで過渡応答
Pythonを使えば伝達関数から過渡応答を簡単に調べることができる。RCローパスフィルタ回路の伝達関数を使って、ステップ応答を調べてみよう。
必要なライブラリnumpy
・control
・matplotlib
を、pip3
でインストールしておこう。
ここでゲインKと時定数Tを使って次のように表すと、 \[G(s)=\frac{K}{1+Ts}\] となり、この形になるシステムを「一次遅れ系」と呼んでいる。
RCローパスフィルタ回路の伝達関数は \[G(s)=\frac{1}{1+RCs}\] であったのでこれに当てはめると、(K=1)、(T=RC)である。
さて、Pythonで伝達関数を表現するにはtf
関数を使う。一時遅れ系では次のようにしてKとTを決めて代入すれば良い。
= tf([0, K], [T, 1]) G
またステップ応答を調べるにはstep
関数を使う。第一引数に伝達関数を代入し、第二引数には調べたい時間の配列を設定する。次のプロググラムは0秒から0.01秒までを0.0001秒刻みでステップ応答を計算させることを意味する。
0, 0.01, 0.0001)) step(G, np.arange(
実際にステップ応答を調べてみたプログラムがこちら。抵抗R=1kΩ、ステップ電圧5Vとし、コンデンサの容量を1μF、0.5μF、0.1μF、0.05μF、0.01μFに設定したときのそれぞれのステップ応答をグラフ化させている。
from control.matlab import *
import matplotlib.pyplot as plt
import numpy as np
= plt.subplots()
fig, ax =':')
ax.grid(ls
if __name__ == '__main__':
= 1 * pow(10, 3) # 1kΩ
R = [1, 0.5, 0.1, 0.05, 0.01]
C = 5 # ゲイン(電圧)
K for i in range(len(C)):
= R * C[i] * pow(10, -6)
T = tf([0, K], [T, 1]) # 一次遅れ系
G = step(G, np.arange(0, 0.01, 0.0001)) # ステップ応答、0秒から1秒までを0.001s刻みで
y, t ='R={}μF'.format(C[i]))
plt.plot(t, y, label
plt.legend() plt.show()

このようにステップ応答がグラフ化できた。以前の記事では、わざわざ逆ラプラス変換して過渡応答特性を調べたが、Pythonを使えば伝達関数だけで調べることができて大変便利だ。