[英]Simulating a sub-system in a Python (non real-time) simulation environment through a transfer function
我正在編寫動態系統模擬(固定步驟,非實時;它在我的桌面上運行),我想通過 scipy.signal 提供的工具(例如dlsim)。 對於這些組件,我知道它們以經典形式的傳遞函數表示。
使用 scipy.signal,“靜態”模擬傳遞函數的 output 非常簡單直接,即在已知時間和輸入向量的情況下; 另一方面,我找不到在每個模擬步驟中計算它的方法。 我的模擬器還包括一些閉環控制器,因此隨着模擬的進行,輸出會發生動態變化。
有任何想法嗎?
PS我發現這個線程似乎很相似,但我必須承認我不明白作者給出的解決方案......: 如何模擬一步轉移python中的function
問題的描述的解決方案如何模擬一個步驟到 python 中的轉移 function 的工作原理如下。 您只為輸入 U(類似數組)和 T(也類似數組)生成兩個模擬步驟。 With both variables and your system you call the function scipy.signal.lsim (or scipy.signal.dsim for discrete systems) and you set also the initial values for the system states X. As result you get the output values and the new states Xn+1 存儲在 X 的 state 變量中。
在下一個循環中,您獲取 U 和 T 的最后一個值並添加下一個輸入和時間步長。 現在您再次調用 lsim,但這次使用最后一次迭代的狀態 X 等等。
(對不起,它不漂亮,但它有效。)
import math
import numpy as np
import scipy.signal as signal
import matplotlib.pyplot as plt
class TwoMassSystem:
def __init__(self):
# Source: Feiler2003
JM = 0.166 # kgm^2 moment of inertia (drive-mass)
JL = 0.333 # kgm^2 moment of inertia (load-mass)
d = 0.025 # Nms/rad damping coefficient (elastic shaft)
c = 410.0 # NM/rad stiffness (elastic shaft)
self.A = np.array([[-d/JM, -c/JM, d/JM],
[ 1.0, 0.0, -1.0],
[ d/JL, c/JL, -d/JL]] )
self.B = np.array([[ 1/JM, 0.0, 0.0],
[ 0.0, 0.0, 0.0],
[ 0.0, 0.0,-1/JL]] )
self.C = np.array([ 0.0, 0.0, 1.0 ])
self.D = np.array([ 0.0, 0.0, 0.0 ] )
self.X = np.array([ 0.0, 0.0, 0.0 ] )
self.T = np.array([ 0.0])
self.U = np.array([[0.0, 0.0, 0.0]])
self.sys1 = signal.StateSpace(self.A, self.B, self.C, self.D)
def resetStates(self):
self.X = np.array([ 0.0, 0.0, 0.0 ] )
self.T = np.array([ 0.0])
self.U = np.array([[0.0, 0.0, 0.0]])
def test_sim(self):
self.resetStates()
h = 0.1
ts = np.arange(0,10,h)
u = []
t = []
for i in ts:
uM = 1.0
if i > 1:
uL = 1.0
else:
uL = 0.0
u.append([ uM,
0.0,
uL])
t.append(i)
tout, y, x = signal.lsim(self.sys1, u, t, self.X)
return t, y
def test_step(self, uM, uL, tn):
"""
test_step(uM, uL, tn)
The call of the object instance simulates the two mass system with
the given input values for a discrete time step.
Parameters
----------
uM : float
input drive torque
uL : float
input load torque
tn : float
time step
Returns
-------
nM : float
angular velocity of the drive
nL : float
angular velocity of the load
"""
u_new = [ uM,
0.0,
uL]
self.T = np.array([self.T[-1], tn])
self.U = np.array([self.U[-1], u_new])
tout, y, x = signal.lsim(self.sys1, self.U, self.T, self.X)
# x and y contains 2 simulation points the newer one is the correct one.
self.X = x[-1] # update state
return y[-1] #
if __name__ == "__main__":
a = TwoMassSystem()
tsim, ysim = a.test_sim()
h = 0.1
ts = np.arange(h,10,h)
ys = []
a.resetStates()
for i in ts:
uM = 1.0
if i > 1:
uL = 1.0
else:
uL = 0.0
ys.append(a.test_step(uM, uL, i))
plt.plot(tsim, ysim, ts, ys)
plt.show()
但是,正如您在 plot 中看到的那樣,結果並不相同,這就是問題所在,因為我不知道為什么。 因此,我提出了一個新問題: 為什么模擬步驟的結果與完整的模擬不同?
@InProceedings{Feiler2003,
author = {Feiler, M. and Westermaier, C. and Schroder, D.},
booktitle = {Proceedings of 2003 IEEE Conference on Control Applications, 2003. CCA 2003.},
title = {Adaptive speed control of a two-mass system},
year = {2003},
pages = {1112-1117 vol.2},
volume = {2},
doi = {10.1109/CCA.2003.1223166}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.