Pythonで学ぶ制御工学　第9弾：時間応答（2次遅れ系）

# #Pythonで学ぶ制御工学< 時間応答（2次遅れ系） >

##はじめに
基本的な制御工学をPythonで実装し，復習も兼ねて制御工学への理解をより深めることが目的である．
その第9弾として「時間応答（2次遅れ系）」を扱う．

##時間応答（2次遅れ系）
時間応答の2次遅れ系について，図を使っての説明を以下に示す．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/caf592c5-fa62-61db-34b8-16b85b1d5176.png)

続いては，RLC回路を例に1次遅れ系を導出する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/01f13406-c819-92fe-0261-75cc8063af74.png)

このようにして，2次遅れ系の形にした時に，対応する部分がゲイン，固有角振動数および減衰係数となる．

##実装
ここでは，適当なゲイン，固有角振動数および減衰係数を指定し，ステップ応答の図を出力するプログラムを実装する．なお，出力する図は4つあり，ステップ応答・減衰係数を変化させたステップ応答・固有角振動数を変化させたステップ応答・ゲインを変化させたステップ応答である．

#####ソースコード
```step.py
"""
2021/02/27
@Yuya Shimizu

時間応答（2次遅れ系）
"""

from control.matlab import *
import matplotlib.pyplot as plt
import numpy as np
from for_plot import *    #自分で定義した関数をインポート
#定義した関数について (https://qiita.com/Yuya-Shimizu/items/f811317d733ee3f45623)


##2次遅れ系のステップ応答

zeta, omega_n, K = 0.4, 5, 1   #減衰係数と固有角振動数とゲインの設定
P = tf([0, K*omega_n**2], [1, 2*zeta*omega_n, omega_n**2])  #2次遅れ系
y, t = step(P, np.arange(0, 5, 0.01))   #ステップ応答（0~5秒で，0.01刻み）

fig1, ax1 = plt.subplots()
ax1.plot(t, y)
plot_set(ax1, 't', 'y') #グリッドやラベルを与える関数(自作のfor_plotライブラリより)
plt.title(f"$\zeta$={zeta}, $\omega_n$={omega_n}, K={K}")
plt.show()


##2次遅れ系のステップ応答（減衰係数zetaを変化させる）
zeta = (-0.1, 0, 0.3, 1)   #4種類の減衰係数を用意
omega_n = 5
K = 1

#図示の準備
fig2, ax2 = plt.subplots()
LS = linestyle_generator()  #線種を与える関数(自作のfor_plotライブラリより)

for i in range(len(zeta)):
    P = tf([0, K*omega_n**2], [1, 2*zeta[i]*omega_n, omega_n**2])  #2次遅れ系
    y, t = step(P, np.arange(0, 3, 0.01))   #ステップ応答（0~3秒で，0.01刻み）
    ax2.plot(t, y, ls=next(LS), label=f"$\zeta$={zeta[i]}")

plot_set(ax2, 't', 'y', 'best')
plt.title(f"$\zeta$={zeta}, $\omega_n$={omega_n}, K={K}")
plt.show()


##2次遅れ系のステップ応答（固有角振動数omega_nを変化させる）
zeta = 0.7
omega_n = (1, 5, 10)   #3種類の固有角振動数を用意
K = 1

#図示の準備
fig3, ax3 = plt.subplots()
LS = linestyle_generator()  #線種を与える関数(自作のfor_plotライブラリより)

for i in range(len(omega_n)):
    P = tf([0, K*omega_n[i]**2], [1, 2*zeta*omega_n[i], omega_n[i]**2])  #2次遅れ系
    y, t = step(P, np.arange(0, 5, 0.01))   #ステップ応答（0~5秒で，0.01刻み）
    ax3.plot(t, y, ls=next(LS), label=f"$\omega_n$={omega_n[i]}")

plot_set(ax3, 't', 'y', 'best')
plt.title(f"$\zeta$={zeta}, $\omega_n$={omega_n}, K={K}")
plt.show()


##2次遅れ系のステップ応答（ゲインKを変化させる）
zeta = 0.7
omega_n = 5
K = (1, 2, 3)   #3種類のゲインを用意

#図示の準備
fig3, ax3 = plt.subplots()
LS = linestyle_generator()  #線種を与える関数(自作のfor_plotライブラリより)

for i in range(len(K)):
    P = tf([0, K[i]*omega_n**2], [1, 2*zeta*omega_n, omega_n**2])  #2次遅れ系
    y, t = step(P, np.arange(0, 5, 0.01))   #ステップ応答（0~5秒で，0.01刻み）
    ax3.plot(t, y, ls=next(LS), label=f"K={K[i]}")

plot_set(ax3, 't', 'y', 'best')
plt.title(f"$\zeta$={zeta}, $\omega_n$={omega_n}, K={K}")
plt.show()
```

#####出力①：ステップ応答
![step.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/49f51c47-fb98-b029-e7c0-73804880541c.png)

#####出力②：減衰係数を変化させたステップ応答
![changed_zeta.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/73f6a5e5-5d80-f3c9-8075-5a6635c9edc9.png)

#####出力③：固有角振動数を変化させたステップ応答
![changed_omega_n.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/50e74b3c-de97-1b07-3906-c703e18b73d7.png)

#####出力④：ゲインを変化させたステップ応答
![changed_K.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/78553c3c-9ba2-090e-b273-becb8d7092f6.png)

##結果
はじめの説明でもあったように，減衰係数$\zeta$を負値にすると一定値に収束せず**発散**してしまい，0だと**持続振動**，0~1なら**オーバーシュートが生じる**．さらに詳しく述べると，小さな値ほど，そのオーバーシュートは大きくなる．1以上ならば，**オーバーシュートは生じない**．また，固有角振動数$\omega_n$は1次遅れ系のときの時定数と同様と説明したとおり，変化させることによって**応答性が変わっている**ことが分かる．しかし，1次遅れ系の時定数と違って，**固有角振動数は大きくなるほど，応答が速くなる**．ゲインKは定常値を変化させる．

##感想
前回に引き続き，今回は2次遅れ系ということで，固有角振動数や減衰係数，ゲインの意味と特徴を知り，また固有角振動数や減衰係数，ゲインが制御対象によって中身は変わるということを知った．またPythonでの実装を通して，グラフでの意味のとらえ方にも触れることができた．

##参考文献
Pyhtonによる制御工学入門　　南 祐樹　著　　オーム社