1

我正在编写动态系统模拟(固定步骤,非实时;它在我的桌面上运行),我想通过 scipy.signal 提供的工具(例如dlsim)。对于这些组件,我知道它们以经典形式的传递函数表示。

使用 scipy.signal,“静态”模拟传递函数的输出非常简单直接,即在已知时间和输入向量的情况下;另一方面,我找不到在每个模拟步骤中计算它的方法。我的模拟器还包括一些闭环控制器,因此随着模拟的进行,输出会发生动态变化。

有任何想法吗?

PS我发现this thread似乎很相似,但我必须承认我不明白作者给出的解决方案......:如何在python中模拟一个传递函数的一步

4

1 回答 1

0

问题的描述的解决方案如何在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()        

然而:

但是,正如您在图中看到的那样,结果并不相同,这就是问题所在,因为我不知道为什么。因此,我提出了一个新问题:为什么模拟步骤的结果与完整的模拟不同? 在此处输入图像描述

资料来源:

@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}
}
于 2021-08-25T14:21:19.707 回答