[英]How to simulate the time response of a system transfer function with python-control (IVP problem)?
我試圖演示如何使用系統傳遞函數的定義和python-control
模塊來“求解”(模擬解)微分方程初值問題 (IVP)。 事實是,我真的是控制方面的新手。
我以這個簡單的微分為例: y'' - 4y' + 13y = 0
,具有以下初始條件: y(0) = 1
和y'(0) = 0
。
我手動實現了這個傳遞函數: Y(s) = (s - 4)/(s^2 - 4*s + 13)
。
所以,在 Python 中,我正在編寫這段代碼(注意y_ans
是這個差分 IVP 的答案,如下所示):
import numpy as np
import control as ctl
import matplotlib.pyplot as plt
t = np.linspace(0., 1.5, 100)
sys = ctl.tf([1.,-4.],[1.,-4.,13.])
T, yout, _ = ctl.forced_response(sys, T=t, X0=[1, 0])
y_ans = lambda x: 1/3*np.exp(2*x)*(3*np.cos(3*x) - 2*np.sin(3*x))
plt.plot(t, y_ans(t), '-.', color='gray', alpha=0.5, linewidth=3, label='correct answer')
plt.plot(T, yout, 'r', label='simulated')
plt.legend()
這段代碼讓我得到了這張圖:
但是,當我在前面插入一個負號yout
,我得到了,因為我想這是一個比賽:
plt.plot(T, -yout, 'r', label='simulated') ### yout with negative sign
我究竟做錯了什么? Python-control 文檔對我來說不是很清楚。 另外,我不知道我對control.forced_response
的X0
參數的解釋是否正確。 是否可以按照我的意圖進行?
歡迎任何可以闡明這個主題的人做出貢獻。
編輯
設置X0 = [0,0]
給我這個圖:
我認為在這里做的最好的事情是將您的系統轉換為狀態空間並看看發生了什么(有許多可能的狀態空間表示):
sys_tf = ctl.tf([1.,-4.],[1.,-4.,13.])
sys_ss = ctl.tf2ss(sys_tf)
print(sys_ss)
輸出:
A = [[ 4.00000000e+00 1.30000000e+00]
[-1.00000000e+01 1.33226763e-15]]
B = [[-1.]
[ 0.]]
C = [[-1. -0.4]]
D = [[0.]]
我們想要找到x(0)
使得y(0) = Cx(0) = 1
和y'(0) = CAx(0) = 0
。
我們可以寫出這些方程並手動求解,也可以使用線性代數:
A = np.vstack([sys_ss.C, sys_ss.C @ sys_ss.A])
b = np.array([[1], [0]])
x0 = np.linalg.solve(A, b)
print(x0)
給出:
[[-1.00000000e+00]
[-1.36642834e-15]]
因此,這應該有效:
T, yout = ctl.forced_response(sys_ss, T=t, X0=[-1, 0])
此外,由於您只對初始條件的瞬態響應(即u(t)=0
)感興趣,您可以使用initial_response
函數:
T, yout = ctl.initial_response(sys_ss, T=t, X0=[-1, 0])
感謝@LutzLehmann 的評論,我一直在思考“編碼兩次”的含義。 所以,回到第一個,我意識到這個傳遞函數包含輸入(時間或斜坡)和初始條件。 它實際上是一個輸出。 我需要某種拉普拉斯逆變換,或者,正如我開始認為的那樣,我只需要按原樣模擬它,而無需更多信息。
因此,我設法使用了一個脈沖輸入(拉普拉斯變換等於 1),並且我能夠得到一個與我及時模擬的 tf 完全相同的輸出。
import numpy as np
import control as ctl
import matplotlib.pyplot as plt
t = np.linspace(0., 1.5, 100)
sys = ctl.tf([1.,-4.],[1.,-4.,13.])
T, yout = ctl.impulse_response(sys, T=t) # HERE is what I wanted
y_ans = lambda x: 1/3*np.exp(2*x)*(3*np.cos(3*x) - 2*np.sin(3*x))
plt.plot(t, y_ans(t), '-.', color='gray', alpha=0.5, linewidth=3, label='correct answer')
plt.plot(T, yout, 'r', label='simulated')
plt.legend()
現在我想我可以展示如何使用 python-control 來間接模擬微分方程的答案。 :-D
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.