我正在编写一个动态系统仿真(固定步长,非实时;它在我的桌面上运行),并且我想对系统的一些组件(例如过滤器...)进行建模。通过scipy.signal提供的工具(例如dlsim)。对于这些分量,我知道它们在传递函数的经典形式中的表示。
使用scipy.signal,可以“静态”地模拟传递函数的输出,也就是在时间和输入向量已知的情况下;另一方面,我找不到在每个模拟步骤中计算它的方法。我的模拟器还包括一些闭环控制器,因此随着模拟的推进,输出会以动态方式变化。
有什么想法吗?
PS我发现这个帖子看起来很相似,但我必须承认我不理解作者给出的解决方案...:How to simulate one step to a transfer function in python
发布于 2021-08-25 14:21:20
问题How to simulate one step to a transfer function in python的描述解决方案如下所示。您仅为输入U(类似数组)和T(也类似于数组)生成两个模拟步骤。对于变量和系统,您可以调用函数scipy.signal.lsim (或离散系统的scipy.signal.dsim ),并设置系统状态X的初始值。因此,您将获得输出值和新状态Xn+1,并将其存储在X的状态变量中。
在下一个循环中,取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()
但是:
然而,正如你在图中看到的,结果并不相同,这就是问题所在,因为我不知道为什么。因此,我创建了一个新问题:Why does the result of a simulated step differ from the complete simulation?
资料来源:
@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}
}
https://stackoverflow.com/questions/65204167
复制相似问题