1

python-control我试图演示如何使用系统传递函数和模块的定义来“解决”(模拟解决方案)微分方程初始值问题(IVP) 。事实上,我真的是一个关于控制的新手。

我以这个简单的微分为例:y'' - 4y' + 13y = 0,具有这些初始条件:y(0) = 1y'(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 控制文档对我来说不是很清楚。另外,我不知道我对X0参数 for的解释control.forced_response是否正确。是否有可能按照我的意图做到这一点?

欢迎任何能对这个主题有所了解的人做出贡献。

编辑

设置X0 = [0,0]给了我这个图表:

在此处输入图像描述

4

2 回答 2

1

我认为最好的办法是将您的系统转换为状态空间并查看发生了什么(有许多可能的状态空间表示):

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) = 1y'(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])
于 2021-08-05T14:16:40.987 回答
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

于 2020-10-30T00:45:22.120 回答