ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Python-control实战:从传递函数建模到PID整定的完整控制工程链

Python-control实战:从传递函数建模到PID整定的完整控制工程链 简介本资源是一份面向自动化、控制工程专业学生及初阶工程师的Python控制系统实践资料包聚焦利用Python科学计算生态开展控制系统建模、仿真与分析。资源涵盖SISO/MIMO系统建模、根轨迹与频率响应分析、PID控制器设计等核心内容有效 bridging 控制理论与工程实现。压缩包共135个文件以64个Python源码含实验脚本与算法实现和65张结果图如系统响应曲线、根轨迹图、Bode图等为主辅以XML配置、项目元数据文件整体仅1.64MB轻量易用且结构清晰便于按实验模块快速定位代码与可视化结果。已有1164人学习下载适合课堂实验延伸、课程设计参考或自学巩固。读者可直接运行代码复现经典控制分析流程获取完整可执行的仿真实验链路、带注释的算法实现及对应图形化验证结果显著降低从理论到代码落地的学习门槛。1. 这不是 Python 教程是控制系统工程师的「可执行论文」用python-control库从传递函数建模、根轨迹绘制、PID 整定到闭环仿真全链路跑通你手头有一份控制系统课程设计任务书要求画出某电机驱动系统的根轨迹、设计超调小于15%的 PID 控制器、给出阶跃响应曲线并标注调节时间——但 MATLAB 许可证没续费Simulink 模型打不开而你刚学完《自动控制原理》却卡在“怎么把课本公式变成能跑的代码”这一步。别急这不是理论推导题而是一份带源码、带注释、带验证逻辑的 Python 控制系统实战论文它不讲 Laplace 变换定义只做一件事——用python-control官方库名control把传递函数G(s) 100/(s^2 5s 100)从建模、分析、设计到闭环验证走完完整闭环。它面向的是正在赶课设 deadline 的本科生、需要快速验证控制器参数的嵌入式开发者以及想甩掉 MATLAB 依赖转战 Python 工程栈的控制工程师。所有代码块均可直接复制粘贴运行所有图表均附坐标轴标注与性能指标计算逻辑所有参数修改点都标出物理含义。这不是“Python 能不能做控制”的科普而是“今天下午三点前你就能交出一份带仿真图和数据表的 PDF 报告”的实操路径。2. 从零构建控制系统模型control.tf()与control.ss()的选型逻辑与建模实操控制系统建模是后续所有分析与设计的地基。python-control提供两种核心建模方式传递函数TF与状态空间SS。选哪个不是看谁更“高级”而是看你的原始问题来源——若题目给的是微分方程或框图化简结果如Y(s)/U(s) (2s1)/(s^34s^25s2)用control.tf()最直觉若你已有 A/B/C/D 矩阵比如从 Simulink 线性化导出、或从机械臂动力学推导而来则control.ss()是唯一选择。二者本质等价但转换过程会暴露数值精度陷阱这点我们放在第 4 章深挖。现在先聚焦建模本身。2.1 用control.tf()构建经典二阶系统并验证零极点假设课程设计中某温度控制系统被简化为标准二阶模型G(s) ω_n² / (s² 2ζω_n s ω_n²)其中自然频率ω_n 10 rad/s阻尼比ζ 0.4。我们需要生成该传递函数对象并立刻验证其零极点是否符合预期这是防止手敲系数出错的第一道防线import control as ct import numpy as np # 定义参数 wn 10.0 zeta 0.4 # 构建传递函数分子为 [wn²]分母为 [1, 2*zeta*wn, wn²] num [wn**2] den [1, 2*zeta*wn, wn**2] G ct.tf(num, den) # 打印零极点验证建模正确性 print(零点, G.zeros()) print(极点, G.poles())逻辑说明ct.tf()接收两个列表num是分子多项式系数按 s 的降幂排列den是分母系数。此处num[100]对应100den[1, 8, 100]对应s² 8s 100。G.zeros()返回空数组因分子为常数无零点G.poles()应返回共轭复数对-4 ± j9.165其模长即ω_n10实部绝对值除以ω_n即ζ0.4。参数说明wn和zeta是物理可调参数后续整定 PID 时将直接修改它们观察响应变化而非硬编码系数。2.2 从状态空间矩阵构建同一系统并对比等效性现在我们用状态空间形式重写同一系统。对标准二阶系统常用可控规范型Controllable Canonical FormA [[0, 1], [-ω_n², -2ζω_n]], B [[0], [1]], C [[ω_n², 0]], D 0构建后必须验证其与 TF 模型完全等价——这是避免“以为建对了实则矩阵符号搞反”的关键步骤# 构建状态空间矩阵 A np.array([[0, 1], [-wn**2, -2*zeta*wn]]) B np.array([[0], [1]]) C np.array([[wn**2, 0]]) D 0 G_ss ct.ss(A, B, C, D) # 验证 TF 与 SS 模型是否等价比较脉冲响应 t np.linspace(0, 2, 1000) t_tf, y_tf ct.impulse_response(G, Tt) t_ss, y_ss ct.impulse_response(G_ss, Tt) # 检查响应最大误差应远小于 1e-10 max_error np.max(np.abs(y_tf - y_ss)) print(fTF 与 SS 脉冲响应最大误差{max_error:.2e}) assert max_error 1e-10, TF 与 SS 模型不等价检查矩阵构造逻辑说明ct.ss()接收四元组(A, B, C, D)顺序不可颠倒。impulse_response()是最严苛的等价性检验——因为脉冲响应完全由系统极点决定若两者响应一致则零极点必然相同。参数说明Tt指定仿真时间向量t必须是等间距一维数组np.linspace保证否则impulse_response会报错或返回错误结果。此处t覆盖 0~2 秒步长约 2ms足够捕捉二阶系统动态。2.3 处理实际工程中的非标准模型含纯延迟与多输入多输出MIMO真实系统常含纯延迟e^(-sT)或多个输入输出通道。python-control原生不支持符号延迟但提供pade()函数进行帕德近似。例如某液位控制系统有 0.5 秒传输延迟# 添加 0.5 秒延迟3阶帕德近似 delay_num, delay_den ct.pade(0.5, 3) # 返回延迟近似的分子分母系数 G_delayed ct.series(G, ct.tf(delay_num, delay_den)) # 串联延迟 # 验证延迟效果比较阶跃响应起始时间 t_step, y_step ct.step_response(G, Tnp.linspace(0, 3, 1000)) t_delayed, y_delayed ct.step_response(G_delayed, Tnp.linspace(0, 3, 1000)) # 检查延迟后响应起始时间是否≈0.5秒取y0.01的第一个时刻 start_idx np.argmax(y_delayed 0.01) delay_estimated t_delayed[start_idx] print(f估计延迟时间{delay_estimated:.3f} 秒目标 0.5 秒)逻辑说明ct.pade(T, n)生成n阶帕德近似传递函数T为延迟时间。ct.series()实现模块串联。参数说明n3是工程常用折中——阶数太低如 n1近似误差大太高如 n10引入虚假高频极点导致仿真不稳定。此处n3在 0.5 秒延迟下误差可控。对于 MIMO 系统ct.tf()支持二维分子分母列表如G_mimo ct.tf([[[1], [2]], [[3], [4]]], [[[1,1], [1,2]], [[1,3], [1,4]]])表示 2x2 传递函数矩阵但需确保每个子项维度匹配。3. 根轨迹与频域分析root_locus()与bode_plot()的参数精调与物理意义解读建模完成后必须回答两个核心问题系统稳定吗如何通过调整参数如 PID 增益使其满足性能指标根轨迹Root Locus和伯德图Bode Plot是控制工程师的“X 光机”——它们不告诉你具体怎么调但清晰显示“往哪调、调多少、会变什么样”。python-control的绘图函数默认设置常导致关键信息丢失必须手动干预参数。3.1 绘制高保真根轨迹规避默认范围失真与分支断裂对前述二阶系统G(s) 100/(s² 5s 100)添加比例控制器K后开环传函为K*G(s)。根轨迹显示所有可能的闭环极点位置。但默认root_locus()会自动缩放坐标轴导致关键区域如虚轴附近被压缩甚至遗漏分支import matplotlib.pyplot as plt # 创建开环系统 K*G(s) G_open ct.tf([100], [1, 5, 100]) # 关键手动指定 K 的范围和点数避免默认采样过粗 K_range np.logspace(-2, 3, 1000) # K 从 0.01 到 1000对数均匀采样 rlist, klist ct.root_locus(G_open, kvectK_range, plotFalse) # 手动绘制强制坐标轴范围覆盖关键区域 plt.figure(figsize(8, 6)) plt.plot(rlist.real, rlist.imag, b-, linewidth1.2, label根轨迹) plt.axhline(y0, colork, linewidth0.8, linestyle--) # 实轴 plt.axvline(x0, colork, linewidth0.8, linestyle--) # 虚轴 plt.xlim(-15, 5) # 强制 x 范围覆盖左半平面稳定区及右半平面不稳定区 plt.ylim(-15, 15) # 强制 y 范围确保共轭极点对可见 plt.xlabel(实部) plt.ylabel(虚部) plt.title(根轨迹图K 从 0.01 到 1000) plt.grid(True, alpha0.3) plt.legend() plt.show()逻辑说明kvectK_range显式指定增益向量plotFalse禁用默认绘图以便手动控制。plt.xlim/ylim是核心——默认范围常以极点为中心缩放而我们关心的是极点是否穿越虚轴稳定性边界。参数说明K_range用np.logspace而非np.linspace因为根轨迹在小 K 和大 K 区域变化剧烈程度不同对数采样能更好捕捉临界点如分离点、与虚轴交点。此处(-2,3)覆盖典型工程增益范围。3.2 伯德图增益裕度与相位裕度的自动化提取伯德图用于判断系统鲁棒性。python-control的margin()函数可直接计算增益裕度GM和相位裕度PM但需注意其输入必须是开环系统且margin()返回的频率单位是 rad/s非 Hz易被忽略# 计算开环系统 G_open 的频域裕度 gm, pm, wg, wp ct.margin(G_open) print(f增益裕度 GM {gm:.2f} (线性值)即 {20*np.log10(gm):.1f} dB) print(f相位裕度 PM {pm:.1f}°) print(f增益穿越频率 wg {wg:.2f} rad/s ({wg/(2*np.pi):.2f} Hz)) print(f相位穿越频率 wp {wp:.2f} rad/s ({wp/(2*np.pi):.2f} Hz)) # 绘制伯德图并标注裕度点 plt.figure(figsize(10, 6)) ct.bode_plot(G_open, omega_limits(0.1, 100), dBTrue, degTrue) plt.show()逻辑说明ct.margin()返回四个值gm增益裕度线性值、pm相位裕度度数、wg增益穿越频率 rad/s、wp相位穿越频率 rad/s。20*np.log10(gm)将线性值转为工程常用的 dB 值。参数说明omega_limits(0.1, 100)强制伯德图横轴范围避免默认范围遗漏低频或高频段dBTrue和degTrue确保纵轴为 dB 和度符合行业习惯。注意wg和wp是 rad/s若需 Hz必须除以2π。3.3 尼科尔斯图Nichols Chart与闭环带宽的关联分析当需要评估系统对参考信号的跟踪能力如伺服系统时闭环带宽Bandwidth比开环穿越频率更具物理意义。尼科尔斯图可直观定位带宽点闭环幅值下降 3dB 处# 计算闭环系统 T(s) G(s)/(1G(s)) 的频率响应 T_closed ct.feedback(G_open, 1) # 单位负反馈 # 获取闭环频率响应 omega np.logspace(-1, 2, 1000) # 0.1 到 100 rad/s mag, phase, _ ct.freqresp(T_closed, omega) # 找到闭环带宽|T(jω)| 1/√2 ≈ 0.707 (即 -3dB) mag_db 20 * np.log10(mag) bandwidth_idx np.argmax(mag_db -3.0) # 第一个低于 -3dB 的点 bandwidth_omega omega[bandwidth_idx] print(f闭环带宽 {bandwidth_omega:.2f} rad/s ({bandwidth_omega/(2*np.pi):.2f} Hz)) # 绘制尼科尔斯图需安装 control 库 0.9.0 try: ct.nichols_plot(G_open, gridTrue) plt.title(尼科尔斯图开环频率响应) plt.show() except AttributeError: print(当前 control 版本不支持 nichols_plot使用 bode 替代)逻辑说明ct.feedback(G, 1)默认实现单位负反馈T G/(1G)。freqresp()返回闭环系统在指定omega下的幅值mag和相位phase。带宽定义为闭环幅值首次降至 -3dB 的频率。参数说明omega必须用np.logspace覆盖足够宽的频段否则可能找不到带宽点np.argmax(mag_db -3.0)利用布尔索引找到第一个满足条件的索引比np.interp插值更鲁棒。4. PID 控制器设计与整定control.pid()的底层实现与手动整定避坑指南python-control不提供黑箱 PID 自动整定函数如 MATLAB 的pidtune但这恰是优势——它迫使你理解 PID 参数的物理作用。我们用control.pid()创建控制器对象再通过series()与被控对象串联最后用feedback()构成闭环。但直接套用教科书公式如 Ziegler-Nichols常翻车原因在于模型失配与离散化效应。4.1 用control.pid()构建标准 PID 并验证离散化一致性control.pid()默认生成连续时间 PID但实际部署常需离散化如单片机。python-control的c2d()函数支持多种离散化方法其中 Tustin双线性变换在中频段精度最高# 创建连续 PID 控制器Kp10, Ki2, Kd1 C_cont ct.pid(Kp10, Ki2, Kd1, Tf0.1) # Tf 为微分滤波时间常数 # 离散化采样周期 Ts0.01sTustin 方法 Ts 0.01 C_disc ct.c2d(C_cont, Ts, methodtustin) # 验证离散化后 DC 增益是否一致关键 s_cont ct.tf([1, 0], [1]) # s operator dc_gain_cont ct.dcgain(C_cont) # 连续 PID 的 DC 增益Ki/0 → ∞故为 inf # 离散 PID 的 DC 增益应为 sum of coefficients dc_gain_disc C_disc.dcgain() print(f离散 PID DC 增益 {dc_gain_disc:.2f}) # 更实用的验证比较阶跃响应连续 vs 离散 t_sim np.linspace(0, 2, 2000) t_cont, y_cont ct.step_response(C_cont, Tt_sim) t_disc, y_disc ct.step_response(C_disc, Tt_sim) # 计算响应均方误差MSE mse np.mean((y_cont - y_disc)**2) print(f连续与离散 PID 阶跃响应 MSE {mse:.2e})逻辑说明ct.pid()的Tf参数至关重要——它限制微分作用的高频增益防止噪声放大。ct.c2d()的methodtustin是首选zoh零阶保持在低频好但中高频相位滞后大。参数说明Ts0.01对应 100Hz 采样率是常见嵌入式系统上限Tf0.1意味着微分作用在 10 rad/s 以上被衰减平衡响应速度与抗噪性。4.2 手动整定 PID基于根轨迹的“三步法”与性能指标映射教科书 Ziegler-Nichols 法要求先找到临界比例度但实际系统可能不稳定。更稳健的方法是1) 用根轨迹确定使闭环极点位于期望阻尼比 ζ0.70745°线和自然频率 ω_n15 rad/s 的 Kp2) 加入积分消除稳态误差3) 加入微分抑制超调。以下为完整流程# 步骤1仅用比例控制根轨迹上找 Kp 使主导极点满足 ζ0.707, ω_n15 G_open_p ct.tf([100], [1, 5, 100]) rlist_p, klist_p ct.root_locus(G_open_p, kvectnp.logspace(-1, 2, 500), plotFalse) # 寻找最接近期望极点 (-10.6, ±10.6) 的实际极点ζ0.707 σω_n/√210.6 target_real -10.6 target_imag 10.6 distances np.sqrt((rlist_p.real - target_real)**2 (rlist_p.imag - target_imag)**2) best_idx np.argmin(distances) Kp_desired klist_p[best_idx] print(f步骤1Kp {Kp_desired:.2f} 使主导极点接近 ζ0.707, ω_n15) # 步骤2加入积分控制PI设计 Ki 使稳态误差为0且不显著恶化动态 C_pi ct.tf([Kp_desired, Kp_desired*0.5], [1, 0]) # Ki Kp*0.5经验初值 G_open_pi ct.series(C_pi, G_open_p) t_pi, y_pi ct.step_response(ct.feedback(G_open_pi, 1), Tnp.linspace(0, 2, 1000)) ess_pi 1 - y_pi[-1] # 稳态误差 print(f步骤2PI 控制后稳态误差 {ess_pi:.4f}) # 步骤3加入微分PIDKd0.1*Kp 抑制超调 C_pid ct.tf([Kp_desired*0.1, Kp_desired, Kp_desired*0.5], [1, 0.1]) # Kd0.1*Kp, Tf0.1 G_open_pid ct.series(C_pid, G_open_p) t_pid, y_pid ct.step_response(ct.feedback(G_open_pid, 1), Tnp.linspace(0, 2, 1000)) # 计算性能指标 overshoot (np.max(y_pid) - 1) * 100 ts_2percent t_pid[np.argmax(y_pid 0.98)] # 2% 调节时间 print(f步骤3PID 后超调 {overshoot:.1f}%, 调节时间 {ts_2percent:.3f}s)逻辑说明此“三步法”将抽象指标ζ, ω_n映射到具体参数。Kp由根轨迹确定Ki由稳态误差需求反推Kd由超调抑制需求设定。参数说明Ki Kp*0.5是经验起点若稳态误差仍大可增大 KiKd 0.1*Kp是保守初值若超调仍高可增至0.2*Kp但需警惕噪声放大。4.3 避坑PID 整定中五个血泪教训与排查方案现象 → 原因 → 解决现象加入 PID 后系统振荡加剧甚至发散。原因Kd过大或Tf过小导致微分作用在高频段增益过高放大测量噪声并激发未建模模态。解决立即减小Kd至原值 1/3同时增大Tf至1/(10*Kd)量级用bode_plot(C_pid)检查微分环节在 100 rad/s 以上是否仍具高增益。现象阶跃响应中存在缓慢爬升的“尾巴”非单调收敛。原因积分时间常数Ti Kp/Ki过大导致积分作用太弱无法及时消除稳态误差。解决将Ki增大 2~3 倍重新仿真若超调随之增大则同步微调Kp降低至原值 0.8 倍。现象离散 PID 在采样率Ts0.02s下响应正常但Ts0.005s时出现高频抖动。原因c2d()的 Tustin 方法在ω_s 10*ω_cω_c为系统带宽时数值不稳定Ts过小导致离散化后极点靠近单位圆外侧。解决改用zoh方法重离散化或对C_cont先加一阶低通滤波ct.tf([1], [0.01, 1])再离散化。现象ct.feedback(G, C)与ct.feedback(C, G)结果不同且后者导致仿真崩溃。原因ct.feedback()默认sign-1负反馈但若控制器C本身含负号如某些状态反馈结构误用ct.feedback(G, C)会形成正反馈。解决始终显式指定ct.feedback(G, C, sign-1)用ct.minreal()对闭环系统降阶检查是否有极点在右半平面。现象root_locus()绘制的轨迹在 K 很大时出现“断点”或虚线。原因kvect采样点过少高增益区极点移动剧烈线性插值失效。解决将kvect改为np.logspace(-1, 4, 2000)并用plt.plot(rlist.real, rlist.imag, b., markersize0.5)以散点图替代连线避免误导。5. 闭环系统仿真与性能验证forced_response()与自定义性能指标计算设计完控制器必须用真实激励非理想阶跃验证其鲁棒性。python-control的forced_response()支持任意输入信号而不仅是step_response()或impulse_response()。更重要的是性能指标超调、调节时间、稳态误差必须用代码精确计算而非目测图表——这是工程报告可信度的底线。5.1 用forced_response()仿真真实工况含噪声与扰动的输入实际系统面临传感器噪声与负载扰动。我们用forced_response()注入白噪声与阶跃扰动观察闭环系统抑制能力# 构建闭环系统PID 控制下的被控对象 C_final ct.tf([1.0, 10.0, 5.0], [1, 0.1]) # Kp10, Ki5, Kd1, Tf0.1 G_cl ct.feedback(ct.series(C_final, G_open_p), 1) # 生成时间向量10000 点覆盖 0~10 秒 t_sim np.linspace(0, 10, 10000) dt t_sim[1] - t_sim[0] # 构建复合输入参考信号0~2s 阶跃2~4s 斜坡4~10s 正弦 扰动4s 时加入 0.2 幅值阶跃 u_ref np.zeros_like(t_sim) u_ref[(t_sim 0) (t_sim 2)] 1.0 u_ref[(t_sim 2) (t_sim 4)] (t_sim[(t_sim 2) (t_sim 4)] - 2) * 0.5 1.0 u_ref[t_sim 4] 1.0 0.5 * np.sin(2*np.pi*0.5*(t_sim[t_sim 4] - 4)) u_dist np.zeros_like(t_sim) u_dist[t_sim 4] 0.2 # 4s 时加入 0.2 幅值扰动 # 总输入 参考 扰动注意扰动通常加在被控对象输入端故需重构系统 # 此处简化将扰动作为额外输入用 superposition 原理叠加响应 _, y_ref ct.forced_response(G_cl, Tt_sim, Uu_ref) _, y_dist ct.forced_response(G_cl, Tt_sim, Uu_dist) # 注意此用法需 G_cl 为 SISO且扰动通道已建模 y_total y_ref y_dist # 线性系统叠加原理 # 添加传感器白噪声SNR40dB noise_power np.var(y_total) / (10**(40/10)) y_noisy y_total np.random.normal(0, np.sqrt(noise_power), len(y_total)) # 绘制结果 plt.figure(figsize(12, 8)) plt.subplot(2,1,1) plt.plot(t_sim, u_ref, g-, label参考输入, linewidth1.2) plt.plot(t_sim, y_noisy, b-, label含噪输出, linewidth1.2) plt.grid(True, alpha0.3) plt.legend() plt.ylabel(幅值) plt.title(复合工况仿真参考信号 扰动 噪声) plt.subplot(2,1,2) plt.plot(t_sim, y_noisy - u_ref, r-, label跟踪误差, linewidth1.2) plt.axhline(y0, colork, linestyle--, alpha0.5) plt.grid(True, alpha0.3) plt.xlabel(时间 (s)) plt.ylabel(误差) plt.legend() plt.show()逻辑说明forced_response()的U参数接受一维数组长度必须与T相同。superposition原理在此成立因系统线性。参数说明dt由t_sim间隔隐含影响数值积分精度SNR40dB是典型工业传感器信噪比noise_power计算确保噪声功率与信号功率比为10^(-40/10)0.01。5.2 自定义性能指标函数超调、调节时间、稳态误差的鲁棒计算目测图表误差大必须用代码量化。以下函数处理常见异常响应未达稳态、存在振荡、噪声干扰def compute_performance_metrics(t, y, ref_funcNone, threshold0.02): 计算闭环系统性能指标 :param t: 时间向量 :param y: 输出响应向量 :param ref_func: 参考信号函数若为 None 则假设为单位阶跃 :param threshold: 调节时间阈值如 0.02 表示 2% :return: dict 包含 overshoot, ts, ess, rise_time if ref_func is None: y_ref np.ones_like(y) else: y_ref ref_func(t) error y - y_ref # 超调仅对阶跃响应定义 if ref_func is None or (callable(ref_func) and ref_func(0)ref_func(1)): overshoot max(0, (np.max(y) - 1) * 100) else: overshoot 0.0 # 上升时间10% 到 90% y_min, y_max np.min(y_ref), np.max(y_ref) y10 y_min 0.1*(y_max - y_min) y90 y_min 0.9*(y_max - y_min) idx_10 np.argmax(y y10) idx_90 np.argmax(y y90) rise_time t[idx_90] - t[idx_10] if idx_90 idx_10 else np.nan # 调节时间进入 ±threshold 带内不再出来 band_upper y_ref threshold * np.abs(y_ref) band_lower y_ref - threshold * np.abs(y_ref) in_band (y band_upper) (y band_lower) # 找到最后一个连续 in_band 的起始点 last_out_idx np.where(~in_band)[0] if len(last_out_idx) 0: ts t[-1] else: last_out last_out_idx[-1] ts t[np.argmax(in_band[last_out:]) last_out] if np.any(in_band[last_out:]) else np.nan # 稳态误差最后 10% 时间段的平均误差 tail_len int(0.1 * len(y)) ess np.mean(np.abs(error[-tail_len:])) return { overshoot_percent: round(overshoot, 2), rise_time_sec: round(rise_time, 3), settling_time_sec: round(ts, 3), steady_state_error: round(ess, 4) } # 使用示例对前述复合仿真结果计算指标 metrics compute_performance_metrics(t_sim, y_noisy, ref_funclambda t: np.piecewise(t, [t2, (t2)(t4), t4], [1, lambda t: (t-2)*0.51, lambda t: 10.5*np.sin(2*np.pi*0.5*(t-4))]), threshold0.02) print(性能指标, metrics)逻辑说明该函数处理三种典型场景纯阶跃、斜坡、正弦参考。threshold0.02对应 2% 调节时间标准。参数说明ref_func用np.piecewise构建分段函数compute_performance_metrics内部用np.argmax和布尔索引确保计算鲁棒即使响应未完全收敛也返回合理值如tsnp.nan。5.3 生成符合课程设计要求的 PDF 报告Matplotlib 导出与 LaTeX 公式嵌入最终交付物常为本文还有配套的精品资源点击获取
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表