如何使用Scipy绘制带输入时延的一阶传递函数?
用Scipy绘制带输入时延的一阶传递函数阶跃响应
嘿,我来帮你搞定这个问题!你已经掌握了无延迟一阶系统的绘制方法,而Scipy本身并没有像Matlab那样直接支持传递函数的输入时延参数,不过我们可以手动模拟这个延迟效果——本质上,输入延迟就是让系统的阶跃响应在时间轴上整体右移,延迟时间段内输出保持为0。
下面是完整的实现代码,我会一步步解释:
from scipy import signal import matplotlib.pyplot as plt import numpy as np # 定义系统参数 Kp = 3.0 # 增益 taup = 2.0 # 时间常数 tau_delay = 10.0 # 输入时延(对应Matlab里的InputDelay=10) # 创建无延迟的一阶传递函数 num = [Kp] den = [taup, 1] sys_no_delay = signal.TransferFunction(num, den) # 获取无延迟系统的阶跃响应 t_no_delay, y_no_delay = signal.step(sys_no_delay) # 构造包含时延的完整时间轴,范围要覆盖延迟+无延迟响应的总时长 t_total = np.linspace(0, t_no_delay[-1] + tau_delay, 1000) # 生成带时延的阶跃响应 y_with_delay = np.zeros_like(t_total) # 找到时间超过时延的索引 delay_idx = t_total >= tau_delay # 计算对应的无延迟时间点(减去时延) t_shifted = t_total[delay_idx] - tau_delay # 用插值匹配时间点,得到平滑的响应曲线 y_with_delay[delay_idx] = np.interp(t_shifted, t_no_delay, y_no_delay) # 绘图对比 plt.figure(figsize=(8, 5)) plt.plot(t_total, y_with_delay, 'r-', linewidth=3, label=f'With Input Delay ({tau_delay}s)') plt.plot(t_no_delay, y_no_delay, 'b--', linewidth=2, label='No Delay') plt.xlabel('Time (s)') plt.ylabel('System Output') plt.title('Step Response of First-Order System') plt.legend() plt.grid(True) plt.show()
关键逻辑说明:
- Scipy的
signal.TransferFunction没有内置的输入时延参数,所以我们手动模拟:在时延tau_delay之前,系统输出为0;时延过后,输出和无延迟系统在t - tau_delay时刻的响应完全一致。 - 用
np.interp做插值是为了让时间点匹配更平滑,避免直接拼接数组可能出现的折线感。如果你追求简单,也可以直接拼接时间和响应数组:# 简单拼接的方式(可选) t_delay = np.concatenate([np.linspace(0, tau_delay, 50), t_no_delay + tau_delay]) y_delay = np.concatenate([np.zeros(50), y_no_delay])
这样得到的结果就和Matlab里tf(num, den, 'InputDelay', 10)的阶跃响应完全一致啦!
内容的提问来源于stack exchange,提问作者Euler Fonseca




