简介面向信号与系统课程的Matlab仿真实验报告围绕RLC串联电路的阶跃响应与冲激响应展开适合电子信息类本专科生完成时域测量实验或复习动态电路分析。报告基于Matlab R2020a的Simulink环境详细给出微分电路和二阶电路模型涵盖欠阻尼、临界、过阻尼三种状态的波形绘制与参数标注包括上升时间、峰值时间、调节时间、最大超调量等动态指标并附有R135欧、632欧、985欧三组实测数据和结果分析便于对照理解电阻变化对响应状态的影响。资源为单个doc文件共397KB内容包含实验目的、原理推导、仿真步骤、数据表格和波形观察记录结构完整可直接参考或修改用于实验报告提交。已有6232人学习下载适合需要快速完成信号与系统实验报告、或通过具体案例巩固RLC电路响应知识的学习者。1. 阶跃响应与冲激响应两个信号读出一台设备的“性格”如果你正在做“实验一 阶跃响应与冲激响应”这份实验大概率桌上摆着一台待测系统或者一份传递函数。很多人跑完仿真、截完图就交差了但这两个响应真正值钱的地方是把系统的时间常数、阻尼比、超调量、稳态精度一口气读出来。它不挑领域——自动控制课的倒立摆、电路课的低通滤波器、传感器调理电路本质都在做同一件事给系统一个标准输入看它怎么回答。这套实验做扎实了后面做系统辨识、调控制器参数时能省下大量试错时间。这篇笔记按最常见的实验方案展开先用 Python 把两类典型系统跑出响应再从曲线反推参数最后列几个容易翻车的细节。2. 系统建模与环境准备从传递函数到能跑的仿真2.1 为什么偏选阶跃和冲激这两个输入线性时不变系统的全部动态信息其实都集中在传递函数 H(s) 里。输入 u(t) 的拉氏变换是 U(s)输出就是 Y(s)H(s)U(s)。阶跃信号 ε(t) 的拉氏变换是 1/s冲激信号 δ(t) 的变换是 1所以阶跃响应的拉氏变换Y_step(s)H(s)/s冲激响应的拉氏变换Y_imp(s)H(s)两者在频域只差一个“除以 s”在时域就对应积分关系冲激响应 h(t) 对时间的积分等于阶跃响应 s(t)反过来 h(t)ds(t)/dt。这意味着你只要测准其中一个就能推出另一个这个特性后面会用来做交叉验证。对一阶惯性系统 H(s)K/(Ts1)阶跃响应是 K(1−e^{−t/T})曲线从零单调爬到终值 KtT 时爬到 63.2%冲激响应是 (K/T)e^{−t/T}初值 K/T按指数衰减。对二阶系统 H(s)ωn²/(s²2ζωn sωn²)阶跃响应在欠阻尼时围绕终值衰减振荡超调量 σe^{−ζπ/√(1−ζ²)}振荡角频率接近 ωn√(1−ζ²)冲激响应同样按这个频率振荡但起始时刻有一个与 ωn 相关的跳变。系统类型传递函数从阶跃响应读什么从冲激响应读什么一阶惯性K/(Ts1)终值 K63.2% 处时间常数 T初值 K/T衰减速率 1/T二阶欠阻尼ωn²/(s²2ζωn sωn²)超调量→ζ峰值时间→ωn振荡频率→ωn√(1−ζ²)包络衰减→ζ实验脚本里通常会先给定系统对象再做这两种激励对比。目的不是“跑出两条曲线”而是建立“曲线形态→参数数值”的直觉看到平缓爬升就知道一阶主导看到振荡就知道至少二阶看到持续上升不回头就怀疑有积分环节。2.2 搭建最小仿真环境一组命令加一段验证代码我一般用 Python 的科学计算栈做这类实验免费、可复现改参数改完重跑即可。初次搭建只需要装四个库pip install numpy scipy matplotlib control装完先跑一个最小的验证脚本确认环境能用import numpy as np import matplotlib.pyplot as plt from control import TransferFunction, step_response, impulse_response # 一阶惯性系统K2T1.5 sys TransferFunction([2.0], [1.5, 1.0]) # 时间向量0~10 秒步长 0.01点数 1000 t np.linspace(0, 10, 1000) # 阶跃响应与冲激响应 t_step, y_step step_response(sys, Tt) t_imp, y_imp impulse_response(sys, Tt) print(阶跃终值:, y_step[-1]) print(冲激初值:, y_imp[0]) fig, axes plt.subplots(1, 2, figsize(10, 3.5)) axes[0].plot(t_step, y_step) axes[0].set_title(Step Response) axes[1].plot(t_imp, y_imp) axes[1].set_title(Impulse Response) plt.show()代码里TransferFunction([2.0], [1.5, 1.0])的分子是 [K][2.0]分母是 [T, 1][1.5, 1.0]对应 H(s)2.0/(1.5s1)。Tt是显式传入时间网格很多入门的人不传这个参数库会自己选时间上限曲线可能只画到 5 秒看不到完整收敛过程。这里 t 的上限取 10 秒是时间常数 T1.5 的 6.7 倍足够让响应进入稳态这个细节后面还会展开。运行后从阶跃曲线终端读终值约 2.0从冲激曲线首点读初值约 1.33K/T。这两组数字对上说明环境正常可以开始做正式实验。2.3 数学冲激与物理实验信号的差距正式实验里如果是在面包板或实验箱上测真实电路冲激信号并不能像仿真里那样给出完美的 δ(t)。物理上能做的事通常是给一个窄脉冲宽度要远小于系统的最小时间常数工程上习惯取系统带宽对应周期的十分之一以下。比如系统带宽 100 rad/s时间常数约 0.01 s脉冲宽度就得在 1 ms 附近。采样步长同样要跟上。仿真中 t 的步长决定了你能观察到的频率上限步长 0.1 s 的网格去测时间常数 0.01 s 的系统冲激峰值会被完全漏掉曲线异常矮胖。经验做法是步长不超过最小时间常数的 1/5必要时把点数提到几万再降下来看曲线有没有变化。这个“变参数不改变结果”的稳定性检查比任何理论判断都可靠。提示控制库的impulse_response在离散时间网格上输出的是连续冲激响应的采样值不需要自己额外乘采样周期但如果你用差分方程手写冲激响应就要注意离散脉冲的定义两者容易相差一个 1/Δt 的因子。3. 用 Python 实测两个典型系统从曲线读出参数3.1 一阶惯性环节从指数曲线读时间常数 T 和增益 K一阶系统是实验一里最常见的对象很多电路箱里的 RC 低通就是典型一阶。直接上代码import numpy as np import matplotlib.pyplot as plt from control import TransferFunction, step_response, impulse_response K, T 3.0, 2.0 sys TransferFunction([K], [T, 1]) t np.linspace(0, 15, 3000) t_step, y_step step_response(sys, Tt) t_imp, y_imp impulse_response(sys, Tt) # 读取 63.2% 对应时间 target 0.632 * K idx np.argmin(np.abs(y_step - target)) t_63 t_step[idx] print(f稳态终值: {y_step[-1]:.3f}) print(f63.2% 对应时间: {t_63:.3f} s理论 T{T} s) print(f冲激初值: {y_imp[0]:.3f}理论 K/T{K/T:.3f}) plt.figure(figsize(8, 3.5)) plt.plot(t_step, y_step, labelstep) plt.axhline(target, ls--, colorgray) plt.axvline(t_63, ls--, colorgray) plt.show()关键逻辑在np.argmin(np.abs(y_step - target))先算稳态值的 63.2%再用数组差值的绝对值最小值定位对应下标避免人工读数误差。这个方法在数据量大、曲线平缓时特别有用。冲激响应的首点值 K/T 是另一个自检指标如果仿真出来的初值明显偏离这个数多半是时间向量步长太大首点已经被平均掉了。需要说明的是阶跃响应的“终值”在脚本里取的是y_step[-1]这隐含一个前提——15 秒足够长。T2 时 5T10 秒15 秒已经覆盖 7.5T误差在小数点后四位。如果 T 改成 5时间向量没跟着改这个终值就不够准这就是下一章避坑清单里的头号问题。3.2 二阶系统欠阻尼振荡如何读阻尼比和固有频率二阶系统比一阶多一个振荡形态读参数也更讲究。给三种阻尼对比import numpy as np from control import TransferFunction, step_response wn 2.0 # 固有频率 rad/s for zeta in [0.3, 0.5, 0.7]: sys TransferFunction([wn**2], [1, 2*zeta*wn, wn**2]) t np.linspace(0, 10, 4000) t_step, y_step step_response(sys, Tt) # 超调量 (峰值-终值)/终值 peak np.max(y_step) final y_step[-1] sigma (peak - final) / final # 峰值时间y_step 最大值的第一个位置 tp t_step[np.argmax(y_step)] # 由超调量反算阻尼比 zeta_est -np.log(sigma) / np.sqrt(np.pi**2 np.log(sigma)**2) print(fzeta{zeta}: 超调 {sigma*100:.1f}%, tp{tp:.3f}s, fzeta_est{zeta_est:.3f}, wn_est{np.pi/(tp*np.sqrt(1-zeta_est**2)):.3f})代码中峰值位置用np.argmax(y_step)直接找峰值时间是第一个最大值的时刻。超调量取正值后反推阻尼比公式就是教科书上那个 σe^{−ζπ/√(1−ζ²)} 的逆运算。注意 ζ 很小的时候超调量接近 100%对数里出现负值会报错ζ 接近 1 时超调量接近 0反推公式也会失真。所以解析反推只建议在 0.1ζ0.8 的范围用超出这个范围就换成下一章的曲线拟合法。输出结果里 zeta_est 和 zeta 往往在小数点后第二位差一点原因在于峰值时间在离散网格上只能取到最近采样点步长越小越准。想让精度上来把 t 点数加到 8000 以上误差立刻压到 1% 以内。3.3 把指标批量算出来别再肉眼数格子手工从图形上读超调量、峰值时间、调节时间误差很大尤其是一阶系统 5% 调节时间那条水平线肉眼根本看不准。写一个小函数一劳永逸from numpy import np def step_metrics(t, y, y_finalNone, settle0.02): y np.asarray(y) if y_final is None: y_final y[-1] # 上升时间10% - 90% y10, y90 0.1*y_final, 0.9*y_final t10 t[np.argmin(np.abs(y - y10))] t90 t[np.argmin(np.abs(y - y90))] tr t90 - t10 # 超调量 peak np.max(y) overshoot (peak - y_final) / y_final # 峰值时间 tp t[np.argmax(y)] # 调节时间进入并保持 2% 误差带的最早时刻 band settle * y_final settle_idx np.where(np.abs(y - y_final) band)[0] ts t[settle_idx[-1]] if len(settle_idx) else 0.0 return {tr: tr, tp: tp, overshoot: overshoot, ts: ts} # 用法示例 t np.linspace(0, 10, 8000) sys TransferFunction([4.0], [1, 1.2, 4.0]) # wn2, zeta0.3 _, y step_response(sys, Tt) m step_metrics(t, y) print(m)上升时间这里用的是 10%~90% 定义调节时间用的是 2% 误差带。每个指标都有具体定义抄数据之前先确认实验指导书用哪套定义否则不同人算出来的指标对不上。这个小函数可以贯穿整个实验换参数、换系统跑完直接出数字截图里附上指标表比光画曲线有说服力得多。4. 从响应反推系统曲线拟合与结果验证4.1 一阶系统参数辨识最小二乘拟合实操中很多时候你拿到的是一个“黑匣子”——实验箱里的未知电路或者现场拆来的传感器模块你只有输出的响应数据。这时要做的是从数据反推传递函数。一阶系统最稳妥的办法是最小二乘拟合直接拟合时域表达式import numpy as np from scipy.optimize import curve_fit from control import TransferFunction, step_response # 模拟一次“实测”真实 K2.5, T1.8加上一点测量噪声 sys_true TransferFunction([2.5], [1.8, 1.0]) t np.linspace(0, 12, 2000) _, y_clean step_response(sys_true, Tt) y_meas y_clean np.random.normal(0, 0.01, sizet.shape) def first_order(t, K, T): return K * (1 - np.exp(-t / T)) popt, pcov curve_fit(first_order, t, y_meas, p0[1.0, 1.0]) K_fit, T_fit popt print(f辨识结果: K{K_fit:.3f}, T{T_fit:.3f}) # 拟合优度残差标准差 resid y_meas - first_order(t, *popt) print(f残差标准差: {resid.std():.4f})curve_fit需要初始猜测p0[1.0, 1.0]这个初值不要随便填 0否则梯度方向可能不对填 1 通常就够。辨识完后用残差标准差衡量拟合质量如果残差呈现明显的正弦波动而不是随机噪声说明系统不是一阶后面还有高阶环节需要换模型重试。拟合时有一个细节起始段数据如果靠近 t0模型表达式 K(1−e^{−t/T}) 在趋近 0 时为 0这一步没问题但如果你对待测系统叠加了初始偏置比如输出从 1V 而不是 0V 开始拟合模型就要改成 K0K(1−e^{−t/T})否则 K 会被偏置吃掉。实测数据里这个情况很常见盲拟合很容易得到一个离谱的时间常数。4.2 二阶系统辨识先解析后精修二阶系统如果响应有明显的欠阻尼振荡可以先用解析法快速估计 ζ 和 ωn再以这些估计为初值做一次非线性拟合。解析法上章已演示这里把两步串起来import numpy as np from scipy.optimize import curve_fit from control import TransferFunction, step_response # 模拟实测wn3, zeta0.4 sys_true TransferFunction([9.0], [1, 2*0.4*3, 9.0]) t np.linspace(0, 8, 4000) _, y_meas step_response(sys_true, Tt) # 解析初值 peak np.max(y_meas) final y_meas[-1] sigma (peak - final) / final zeta_guess -np.log(sigma) / np.sqrt(np.pi**2 np.log(sigma)**2) tp_guess t[np.argmax(y_meas)] wn_guess np.pi / (tp_guess * np.sqrt(1 - zeta_guess**2)) # 二阶欠阻尼时域表达式 def second_order_underdamped(t, wn, zeta): wd wn * np.sqrt(1 - zeta**2) return 1 - np.exp(-zeta*wn*t) * ( np.cos(wd*t) zeta*wn/wd * np.sin(wd*t) ) popt, _ curve_fit(second_order_underdamped, t, y_meas, p0[wn_guess, zeta_guess]) print(f解析初值: wn{wn_guess:.3f}, zeta{zeta_guess:.3f}) print(f拟合结果: wn{popt[0]:.3f}, zeta{popt[1]:.3f})这里关键是把解析解当成curve_fit的初值能避免优化器陷入局部极小。二阶系统的拟合目标函数对初值敏感从 0 附近的随机初值开始经常收敛到负数阻尼比输出一堆 NaN。先算解析解再拟合基本一次到位。拟合表达式里 ωdωn√(1−ζ²) 是实际振荡频率如果 ζ 非常接近 1ωd 趋近 0表达式里 sin/cos 退化这种数据不适合用欠阻尼模型描述应该换成临界或过阻尼形式重写表达式。4.3 交叉验证冲激积分对上阶跃数据才可信最后一个验证手段是利用第一节讲的积分关系冲激响应积分应该等于阶跃响应。这个检查能同时验证系统线性时不变假设是否成立、数据采集有没有丢段import numpy as np from scipy.integrate import cumulative_trapezoid from control import TransferFunction, step_response, impulse_response sys TransferFunction([4.0], [1, 1.0, 4.0]) t np.linspace(0, 10, 5000) _, y_step step_response(sys, Tt) _, y_imp impulse_response(sys, Tt) # 对冲激响应做累积积分 y_from_imp cumulative_trapezoid(y_imp, t, initial0) # 比较积分结果与阶跃响应 diff np.abs(y_from_imp - y_step) print(f最大偏差: {diff.max():.2e})cumulative_trapezoid(..., initial0)会保持输出数组长度和输入一致第一点补 0这是与朴素np.cumsum最大的区别——cumsum得到的是矩形积分冲激响应变化剧烈时误差明显梯形积分更准。输出最大偏差在 1e−2 以下说明两条响应曲线自洽偏差达到 0.1 量级就回头检查时间向量上限或者采样步长。这个验证放到真实实验里还有个好处有些实验箱的冲激输出幅度标定不准但积分后与阶跃响应对比能反推出标定系数。比如冲激曲线整体偏小 20%积分后阶跃响应也低 20%偏差曲线是一条明显的水平线这个信息比单纯调增益有用得多。5. 阶跃与冲激响应实验的 5 个常见坑与排查清单5.1 曲线没“稳住”就截断时间上限太短现象一阶系统阶跃响应读出来的终值明显低于理论 K比如理论终值 3.0数据里只到 2.5并且曲线尾部还在缓慢上升。原因时间向量上限取值太小比如只取到 2T系统才走到终值的 86% 就被截断。解决先把时间上限提到 10T 跑一次看终值是否变化再调整回合适区间也可以写一个循环从 5T、8T、10T 依次加大终值不再变化时的上限就是有效值。血泪经验是别在第一步省时间时间上限不够后面所有指标全是错的。5.2 采样步长过大冲激响应峰值“隐身”现象冲激响应曲线初值明显偏小峰值处变圆甚至出现锯齿和理论 K/T 对不上。原因步长大于系统最小时间常数的一半以上采样点落在脉冲快速衰减的区间里尖峰被漏掉。解决步长取系统最小时间常数的 1/10 以下或者直接看 t 数组的间隔判断标准是继续加密一倍步长后曲线不再变化这就是收敛了。5.3 对阶跃响应数值微分求冲激噪声炸出刺猬现象用np.diff(y_step)/dt求冲激响应曲线毛刺极大负值乱跳完全没法看。原因数值微分对高频噪声是放大操作阶跃响应里哪怕只有 1e−3 的随机噪声微分后噪声幅度也会被放大到和信号同量级。解决不要用微分法求冲激响应直接用库的impulse_response或者对原始数据先做低通滤波再微分但滤波会改变相位不如直接做系统辨识从模型里取冲激响应的解析表达式。5.4 稳态误差误判死区与量化让残差停在非零值现象响应残差一直停在 0.03以为系统存在 3% 稳态误差实际理论模型是无静差系统。原因仿真或采集链路里的量化步长、传感器死区、摩擦等非理想因素让信号永远达不到理想终值。解决判断稳态误差前先除以输入幅度得到相对稳态误差再设一个工程阈值比如 2%同时检查数据尾段的抖动是否在量化噪声范围内如果是直接取最后一段均值作为稳态值。5.5 控制库冲激响应幅值随采样时间变化现象同一个系统换两种时间步长impulse_response输出的峰值差了好几倍看起来像玄学。原因连续冲激在离散仿真里实现方式通常依赖库内部的离散化策略部分库会把 δ(t) 近似成宽度等于采样时间的等效脉冲导致幅度随步长变化。解决先明确当前实验关注的是“形态”还是“绝对幅值”形态用归一化曲线绝对幅值直接手写解析式比如一阶系统 h(0)K/T 直接代入计算不依赖库输出。这个坑不影响参数读取但会影响你在实验报告里填冲激初值的同学。6. 进阶用带宽与上升时间的经验关系做快速自检仿真和实测数据对上了但怎么知道整条链路没出系统性问题我习惯用带宽与上升时间的近似关系做最后一道自检。对一阶及多数二阶低通系统10%~90% 上升时间 t_r 与带宽 ω_b 的乘积接近一个常数ω_b·t_r ≈ 0.35二阶欠阻尼时在 0.34~0.36 之间浮动。操作方法是两条腿并行从阶跃响应按 3.3 节的函数拿到 t_r再用传递函数算带宽两者相乘看结果import numpy as np from control import TransferFunction, step_response, freqresp sys TransferFunction([9.0], [1, 1.2, 9.0]) # wn3, zeta0.2 t np.linspace(0, 5, 8000) t_step, y_step step_response(sys, Tt) m step_metrics(t, y_step) tr m[tr] # 扫频求带宽幅度降到直流幅度的 0.707 对应频率 w np.logspace(-1, 2, 2000) mag, phase, omega freqresp(sys, w) mag np.squeeze(mag) dc_mag mag[0] idx_bw np.argmin(np.abs(mag - 0.707 * dc_mag)) wb omega[idx_bw] print(f上升时间 tr{tr:.3f}s带宽 wb{wb:.3f} rad/s乘积{wb*tr:.3f})输出乘积落在 0.34~0.36 之间说明两条独立路径时域与频域得到的结论互相印证。偏离超过 0.1 就要警惕上升时间读数被噪声干扰或者系统存在明显的零极点对消阶跃响应被非主导极点牵着走这种情况单独看时域曲线很难发现。我现在做响应实验的习惯是先打印这个乘积再看超调量和稳态误差三组数据全对上才往报告里填。这套流程帮我挡掉过不少看似合理、实际采集链路有问题的数据集。实验一只是信号与系统分析里最基础的一环但这里养成的验证习惯会跟着你一直用到在线辨识和闭环整定上。希望帮到你。本文还有配套的精品资源点击获取