我正在try 用Python语言或MatLab语言来模拟简单的具有PID控制器的闭环系统.在这两种情况下,我都遇到了使用拉普拉斯逆变换计算系统的时域响应的问题.

为了更好地说明这个问题,我下面的图片上的名字:

enter image description here

根据系统的传递函数,结果要么只在MatLab中计算,要么根本不计算.

这就是我所拥有的:

syms s t k_p T_i T_d D_d v real;
% controller transfer function
C_s = k_p * (1 + 1 / (T_i * s) + (T_d * s) / (D_d * s + 1));

% plant transfer function
G_s = 1 / ((s + 1) * (s + 2));

% closed loop transfer function
W_s = C_s  * G_s / (1 + C_s  * G_s);

% input signal
R_t = 4 * heaviside(t - 2) * (1 - heaviside(t - 5)) + ...
      6 * heaviside(t - 5) * (1 - heaviside(t - 6)) + ...
      2 * heaviside(t - 6);

R_s = laplace(R_t, t, s, noconds=True)

% PID-controller system response
C_res_s = C_s * R_s;
w_t = ilaplace(C_res_s , s, t)

% Closed loop system response
Y_s = W_s * R_s
y_t_closed_loop = ilaplace(Y_s, s, t)

% Parameters
k_p_val = 15;
T_i_val = 5;
T_d_val = 2;
D_d_val = 0.1;
time = linspace(0, 10, 1000);

% Convert symbolic expressions to MATLAB functions
w_t_param = matlabFunction(w_t, 'Vars', {t, k_p, T_i, T_d, D_d});

matlabFunction(y_t_closed_loop, 'File', 'y_t_closed_loop_func', 'Vars', {t, k_p, T_i, T_d, D_d});
w_t_param_closed_loop = str2func('y_t_closed_loop_func');

R_t_lam = matlabFunction(R_t, 'Vars', {t});

% Calculate system responses
solution = zeros(size(time));
solution_closed_loop = zeros(size(time));
for i = 1:length(time)
    solution(i) = w_t_param(time(i), k_p_val, T_i_val, T_d_val, D_d_val);
    solution_closed_loop(i) = w_t_param_closed_loop(time(i), k_p_val, T_i_val, T_d_val, D_d_val);
end

对于G_S=1/((S+1)*(S+2)),我有(似乎还可以):

enter image description here

对于G_S=1/((S+1))我有(看起来不太好):

enter image description here

对于G_S=1/((S+1)*(S+2)*(S+3)),我什么也没有,因为拉普拉斯逆变换从不计算.

以下是用Python编写的相同代码:

s, t, k_p, T_i, T_d, D_d, v = symbols("s t k_p T_i T_d D_d v", real=True)

#controller transfer function
C_s = k_p * (1 + 1 / (T_i * s) + (T_d * s) / (D_d * s + 1))

#plant transfer function
G_s = 1 / ((s + 1) * (s + 2))

#closed loop transfer function
W_s = C_s  * G_s / (1 + C_s  * G_s)

#input signal
R_t = 4 * Heaviside(t - 2) * (1 - Heaviside(t - 5)) + 6 * Heaviside(t - 5) * (1 - Heaviside(t - 6)) + 2 * Heaviside(t - 6)
R_s = laplace_transform(R_t, t, s, noconds=True)

# PID-controller system response
C_res_s = C_s * R_s
w_t = inverse_laplace_transform(C_res_s , s, t)

# Closed loop system response
Y_s = W_s * R_s
y_t_closed_loop = inverse_laplace_transform(Y_s, s, t)

Python代码陷入无穷无尽的循环,永远找不到y_t_闭合_循环的解决方案.

另外,由于某些原因,我的Windows机器上不能运行matlab代码.它只能在Linux上运行.

我是不是遗漏了什么?有没有什么方法可以确保计算出拉普拉斯逆变换?转会基金对我来说似乎很正常,但我有一种感觉,有些不对劲.

任何帮助都非常感谢!!

编辑: 我还try 在Python中使用sympy和control库,希望它能改变一些事情:

import sympy
import numpy
import matplotlib.pyplot as plt
from tbcontrol.loops import feedback

s = sympy.Symbol('s')
t = sympy.Symbol('t', positive=True)
tau = sympy.Symbol('tau', positive=True)


K_p = sympy.Symbol('K_p')
T_i = sympy.Symbol('T_i')
T_d = sympy.Symbol('T_d')
D_d = sympy.Symbol('D_d')

G_p = 1/(s+1)
G_c = K_p * (1 + 1 / (T_i * s) + (T_d * s) / (D_d * s + 1))
G_OL = G_p*G_c
G_CL = feedback(G_OL, 1).cancel()
general_timeresponse = sympy.inverse_laplace_transform(sympy.simplify(G_CL/s), s, t)

和以前一样,General_timeresponse永远不会执行.

推荐答案

注意:我不能分享我的代码,但我可以给您重现它的步骤(这需要一些工作).这个程序的优点是,你不必处理时间延迟的Pade近似,它使用的是Sensy的inverse_laplace_transform.主要的缺点是您需要花费一些时间对其进行编码和测试.

  1. 得到输出Y_s后,插入数值:

    sd = { k_p: 15, T_i: 5, T_d: 2, D_d: 0.1 }
    tmp = Y_s.subs(sd).nsimplify().simplify().expand().together()
    tmp
    

    enter image description here

    请注意最后一个时间延迟exp(-6*s),它呈现在分子上,但实际上位于表达式的分母上.

  2. 提取分子和分母.时间延迟应全部在分子上:

    n, d = fraction(tmp)
    n = (n * exp(-6*s)).expand()
    d = d / exp(6*s)
    display(n, d)
    

    enter image description here

  3. 请注意,分子是加法.我们可以应用线性,并在单加数上工作:

    args = [a / d for a in n.args]
    display(args)
    

    enter image description here

  4. 这就是你必须投入工作的地方.我们需要创建一个函数func(expr),它执行以下步骤:

    I.给定一个加数func(a),看看a是否包含时间延迟.如果有,就把它go 掉.(你可以用delay = a.find(exp).pop()....

    二.提取分子和分母:n, d = fraction(a).

    三、从分子和分母中提取系数.例如,对于分子:cn = Poly(n, s).all_coeffs().

    四、使用scipy.signal中的residue函数,这将创建一个数值部分分数展开.

    V.从残数new_expr建立一个新的符号表达式.这可能是最困难的一步.

    六.计算new_expr的拉普拉斯逆变换.一定要使用new_expr.nsimplify().如果不这样做,计算可能需要更长的时间.

    七.如果在点i上发现时间延迟,则将时间延迟应用于out.subs(t, t+time_delay),其中time_delay=delay.args[0]/s.

    八.返回结果.

  5. 循环加数并运行在步骤3.outs = [func(a) for a in args]中创建的函数.

  6. 创建输出信号,并绘制它(我使用SymPy Plotting Backed:

    from spb import plot
    out = sum(outs)
    plot((out, "closed loop res"), (R_t, "R_t"), (t, -1, 10))
    

    enter image description here

Python相关问答推荐

numba jitClass,记录类型为字符串

如何根据参数推断对象的返回类型?

将数据框架与导入的Excel文件一起使用

OR—Tools CP SAT条件约束

梯度下降:简化要素集的运行时间比原始要素集长

调用decorator返回原始函数的输出

我的字符串搜索算法的平均时间复杂度和最坏时间复杂度是多少?

如何在达到end_time时自动将状态字段从1更改为0

pandas:对多级列框架的列进行排序/重新排序

为什么常规操作不以其就地对应操作为基础?

Python避免mypy在相互引用中从另一个类重定义类时失败

Gekko中基于时间的间隔约束

Python—在嵌套列表中添加相同索引的元素,然后计算平均值

需要帮助使用Python中的Google的People API更新联系人的多个字段'

Python OPCUA,modbus通信代码运行3小时后出现RuntimeError

利用SCIPY沿第一轴对数组进行内插

对于标准的原始类型注释,从键入`和`从www.example.com `?

PYTHON中的selenium不会打开 chromium URL

如何在表单中添加管理员风格的输入(PDF)

大Pandas 中的群体交叉融合