伝達関数とインパルス応答

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

伝達関数とインパルス応答
伝達関数とインパルス応答

▼ はじめて制御工学を学ぶのにおすすめな書籍

伝達関数とは

入力と出力と伝達関数
入力と出力と伝達関数

伝達関数とは、複素数領域sにおいてシステムに\(X(s)\)を入力したときの出力\(Y(s)\)との比である。つまり、伝達関数を\(G(s)\)とすれば次の式で表される。

$$G(s)=\frac{Y(s)}{X(s)}$$

具体的にRCローパスフィルタ回路の伝達関数をラプラス変換を使って導き出してみよう。

ラプラス変換(複素数領域s)の話はこちらの記事を参考に。

RCローパスフィルタの伝達関数

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間隔で足し合わせたもである。

py
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
ax.grid(ls=':')

if __name__ == '__main__':
    F1 = np.arange(1, 11, 1)
    F2 = np.arange(1, 10001, 1)
    T = np.arange(-1, 1, 0.001)
    Y1 = [0]*len(T)
    Y2 = [0]*len(T)

    for f in F1:
        for i in range(len(T)):
            Y1[i] += np.cos(2 * np.pi * f * T[i])

    for f in F2:
        for i in range(len(T)):
            Y2[i] += np.cos(2 * np.pi * f * T[i])

    plt.plot(T, Y1, label='{} times'.format(len(F1)))
    #plt.plot(T, Y2, label='{} times'.format(len(F2)))

    plt.legend()
    plt.show()

現実的なインパルス信号
現実的なインパルス信号

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

スイカとインパルス応答
スイカとインパルス応答

冒頭にも述べた通り、実はインパルス応答による測定はごく身近なところで当たり前のように使っている。例えば、電車のレールや機械などをハンマーで叩いて音の反響を聞き取っているシーンを映像で見たことがあるだろう。これは打音検査と呼ばれ、まさにインパルス応答で機械に異常がないか人間の耳で判定しているわけである。

また、誰もいないコンサートホールで手を叩いて残響を調べる姿を見たことは無いだろうか。これもインパルス応答を使って、コンサートホールの特徴を調べているわけである。

もっと身近なところでは、スーパーなどで大根やスイカをコンコンと叩いて野菜の中の具合を調べたりしたことが誰しもあるかと思う。これもインパルス応答による測定に他ならない。

Pythonで過渡応答

Pythonを使えば伝達関数から過渡応答を簡単に調べることができる。RCローパスフィルタ回路の伝達関数を使って、ステップ応答を調べてみよう。

必要なライブラリnumpycontrolmatplotlibを、pip3でインストールしておこう。

ここでゲインKと時定数Tを使って次のように表すと、

$$G(s)=\frac{K}{1+Ts}$$

となり、この形になるシステムを「一次遅れ系」と呼んでいる。

RCローパスフィルタ回路の伝達関数は

$$G(s)=\frac{1}{1+RCs}$$

であったのでこれに当てはめると、\(K=1\)、\(T=RC\)である。

さて、Pythonで伝達関数を表現するにはtf関数を使う。一時遅れ系では次のようにしてKとTを決めて代入すれば良い。

py
G = tf([0, K], [T, 1])

またステップ応答を調べるにはstep関数を使う。第一引数に伝達関数を代入し、第二引数には調べたい時間の配列を設定する。次のプロググラムは0秒から0.01秒までを0.0001秒刻みでステップ応答を計算させることを意味する。

py
step(G, np.arange(0, 0.01, 0.0001))

実際にステップ応答を調べてみたプログラムがこちら。抵抗R=1kΩ、ステップ電圧5Vとし、コンデンサの容量を1μF、0.5μF、0.1μF、0.05μF、0.01μFに設定したときのそれぞれのステップ応答をグラフ化させている。

py
from control.matlab import *
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
ax.grid(ls=':')

if __name__ == '__main__':
    R = 1 * pow(10, 3) # 1kΩ
    C = [1, 0.5, 0.1, 0.05, 0.01]
    K = 5  # ゲイン(電圧)
    for i in range(len(C)):
        T = R * C[i] * pow(10, -6)
        G = tf([0, K], [T, 1])  # 一次遅れ系
        y, t = step(G, np.arange(0, 0.01, 0.0001))  # ステップ応答、0秒から1秒までを0.001s刻みで
        plt.plot(t, y, label='R={}μF'.format(C[i]))

    plt.legend()
    plt.show()

RCローパスフィルタのステップ応答
RCローパスフィルタのステップ応答

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

次の記事では、伝達関数から周波数特性を調べてみた。

関連記事

最後までご覧いただきありがとうございます!

▼ 記事に関するご質問やお仕事のご相談は以下よりお願いいたします。
お問い合わせフォーム

Pandasで画像・動画処理をはじめよう!
Python学習にオススメの本をご紹介!
関連記事