2026/9/3 20:41:31

MATLAB求解阶跃响应指标:上升时间、调整时间、超调量与峰值时间全解析

MATLAB求解阶跃响应指标:上升时间、调整时间、超调量与峰值时间全解析 简介这是一套基于Matlab/Simulink的控制系统阶跃响应指标计算工具包面向控制工程学习者、课程设计者与现场调试工程师用于快速求解上升时间、调整时间、峰值峰值与超调量等关键动态性能参数。上升时间反映系统响应快速性调整时间体现了系统收敛到稳态的速度而超调量则直接影响控制过程的平稳性是评估与优化控制器的重要依据。压缩包内共3个文件包含2个可直接运行的M函数与测试脚本另附1份PDF说明文档总大小仅565KB轻量而实用。该资源已有17662人学习下载在控制系统分析与控制器设计场景中具有较高参考价值。配套的Fun_Step_Performance.m自定义函数可自动计算各项阶跃指标Test_Step_Performance.m演示实例便于对照验证PDF文档则系统梳理了阶跃响应理论、指标定义及使用说明借助这些工具读者无需手动分析复杂响应曲线即可在Simulink中快速评估系统动态性能为控制器的改进与参数整定提供量化依据。 拿到一条阶跃响应曲线怎么科学地评价它这大概是控制课设和工程调试里最常遇到的问题。上升时间、调整时间、峰值时间、超调量这四个指标几乎出现在每本自动控制原理教材里但真到了用MATLAB求解的时候很多人反而开始懵stepinfo到底会不会用返回的RiseTime是哪种定义为什么我算出来的超调量和图上量的不一样这篇文章就把这件事彻底讲透附带可以直接跑通的脚本。不管你是刚学自控原理的学生还是做仿真验证的工程师都可以参考。顺便说一句网上有人传过“Matlab求解阶跃响应指标(上升时间、调整时间、峰值峰值、超调量).rar”标题里的“峰值峰值”应该是“峰值时间”的笔误。这类压缩包里通常只是一些脚本片段其实核心知识就那么多你照着下面的思路自己写一遍以后就再也不用满世界找包了。1. 四个指标的定义差异先搞明白你要算的是什么四个指标看起来名字大家都熟但坑就坑在定义并不完全统一。如果定义没对齐后面算出来的数字和同学对不上、和教材对不上都是正常的。1.1 上升时间0到100%还是10%到90%上升时间最常见的定义有两种响应从稳态值的0上升到100%所需的时间。这个定义在很多教材里用于欠阻尼二阶系统数学上比较好推公式。响应从稳态值的10%上升到90%所需的时间。工程实测里更常用因为响应起点附近容易被噪声、死区干扰从10%开始读数更稳定。stepinfo默认用的是10%到90%这个定义。它会返回一个RiseTime字段底层对应RiseTimeLimits参数默认值是[0.1 0.9]。如果你非要用0到100%得自己改参数。所以别一看RiseTime和书上公式对不上就以为是程序算错了先看看定义是不是同一个。1.2 峰值时间与超调量一对双胞胎峰值时间是指响应到达第一个峰值所需的时间。对欠阻尼二阶系统来说这个峰值就是超调那一瞬间的最高点。超调量则是这个峰值相对稳态值多出来的比例σ% (ymax - y∞) / y∞ × 100%如果系统本来就不超调比如过阻尼或临界阻尼系统超调量按0处理。这时候stepinfo返回的PeakTime是Inf因为根本没有峰值硬说峰值时间就没意义了。1.3 调整时间看它什么时候“真正稳定”下来调整时间的定义是响应进入并维持在稳态值附近的某个误差带内所需的最短时间。误差带一般取±2%或±5%没有硬性规定看你的工程精度要求。这个指标特别容易踩坑系统只要进入误差带就算调整时间结束但如果后面又冲出去了那这个进入时间不成立。所以计算时不能只找“第一次进入误差带”的点必须保证之后不再超差。很多人手写算法在这里翻车。整理成表格更直观指标常见定义stepinfo默认工程含义上升时间0→100% 或 10%→90%10%→90%响应快慢峰值时间到达第一个峰值自动取第一个峰值峰值出现时刻超调量(ymax-y∞)/y∞×100%同左平稳性调整时间±2%或±5%误差带±2%进入稳态耗时1.4 贯穿全文的示例系统为了不空对空我固定一个标准二阶系统作为演示对象G(s) 25 / (s² 5s 25)其中自然频率 ωn 5 rad/s阻尼比 ζ 0.5。这个系统阻尼适中有超调但不夸张用来解释指标提取和参数影响都很合适。后面的代码都基于这个系统展开。2. 最快路径用stepinfo一行命令算完但不建议无脑用如果你手头有传递函数或状态空间模型stepinfo是最快的办法。2.1 基本用法和输出字段打开MATLAB输入s tf(s); G 25/(s^2 5*s 25); info stepinfo(G)运行后你会得到类似下面这组结构体RiseTime: 0.3240 SettlingTime: 1.6300 SettlingMin: 0.9727 SettlingMax: 1.1630 Overshoot: 16.3000 Undershoot: 0 Peak: 1.1630 PeakTime: 0.7255各字段解释一下RiseTime上升时间默认10%到90%。SettlingTime调整时间默认2%误差带。SettlingMin/SettlingMax进入稳态后响应在误差带内的最小值/最大值。Overshoot超调量单位是百分比不是小数。Undershoot下冲量一般系统为0。Peak峰值注意这是绝对值不是相对值。PeakTime峰值时间。看到Overshoot: 16.3000表示超调量16.3%而Peak: 1.1630意味着峰值是1.163正好是1加上16.3%。2.2 三个默认值会影响结果误差带宽度。默认SettlingTimeThreshold是0.02也就是2%。如果你要按5%误差带算info stepinfo(G, SettlingTimeThreshold, 0.05);上升时间上下限。默认RiseTimeLimits是[0.1 0.9]要改成0到100%info stepinfo(G, RiseTimeLimits, [0 1]);仿真时长。stepinfo内部会自动决定仿真时间但对小阻尼系统自动时长可能不够。最稳妥的做法是自己先step拿到数据再把数据传给stepinfot 0:0.001:10; y step(G, t); info stepinfo(y, t);2.3 stepinfo的局限stepinfo只适用于稳定系统。如果你给一个闭环不稳定系统直接算结果没有意义。另外它要求输入是单位阶跃响应数据或者LTI模型。如果系统本身存在稳态误差stepinfo会以最终稳态值为基准这点倒是没问题但你心里要有数超调量是相对最终稳态值算的不是相对输入幅值算的。我自己在实际项目里一般先用stepinfo快速看一遍然后写一个自己的提取函数去验证。原因很简单stepinfo再方便它也猜不到你的数据是带噪声的、采样率是稀疏的、还是仿真结束时根本没进入稳态。3. 手写指标提取只有一组时间响应数据时怎么办工程里更常见的情况是手头只有一组时间-响应数据可能是实验采集的也可能是从Simulink导出的。这时候照样能算而且理解了底层方法后你能按自己需求随意改定义。先造一组数据t 0:0.001:10; y step(G, t); yss y(end);这里我假设10秒时系统已经基本稳定。下面逐个实现。3.1 上升时间提取一定要做线性插值直接找第一个大于0.9*yss的索引会引入最多一个采样步长的误差。如果采样步长是0.01秒这个误差就是0.01秒某些场景下不可接受。正确做法是找到跨越阈值的相邻两点再做线性插值。y10 0.1 * yss; y90 0.9 * yss; i10 find(y y10, 1, first); i90 find(y y90, 1, first); if i10 1 tr10 t(1); else tr10 interp1([y(i10-1), y(i10)], [t(i10-1), t(i10)], y10); end tr90 interp1([y(i90-1), y(i90)], [t(i90-1), t(i90)], y90); tr tr90 - tr10;interp1在这里做的是线性插值相当于把两个采样点之间的曲线近似成一条直线求直线到达阈值的时间。对于采样足够密的响应这个近似非常准。3.2 峰值时间与超调量提取用max要小心噪声最简单的写法是[ymax, imax] max(y); tp t(imax); Mp (ymax - yss) / yss * 100;对于干净的理论仿真数据这个写法没问题。但如果数据有噪声哪怕一个毛刺也可能被误判成峰值。我建议优先使用findpeaks它能返回所有局部极大值的位置然后取第一个超过稳态值的峰[pks, locs] findpeaks(y, t); idx find(pks yss, 1, first); tp locs(idx); ymax_pk pks(idx); Mp (ymax_pk - yss) / yss * 100;如果数据噪声太大先做平滑再找峰ysmooth smoothdata(y, gaussian, 30); [pks, locs] findpeaks(ysmooth, t);注意findpeaks属于Signal Processing Toolbox如果没装这个工具箱就老老实实用max但一定要对数据做平滑。3.3 调整时间提取必须从后往前找调整时间的核心是“进入后不再超出”。正确算法是从数据末尾往前扫描找到最后一个“超出误差带”的位置它的下一个点就是调整时间。为了保证末尾状态有意义先判断最后几个点是否已经在带内。tol 0.02 * yss; inband abs(y - yss) tol; out_idx find(~inband, 1, last); if isempty(out_idx) ts t(1); % 从头到尾都在带内 elseif out_idx numel(y) ts NaN; % 仿真时间不够还没进入稳态 else ts t(out_idx 1); end这个思路的关键是既然最后一个超出误差带的点就是系统最后一次“离开稳态”的点那它后面的第一个时刻就是“之后不再超出”的起点。如果反向扫描发现最后一个点都还在误差带之外说明仿真时长不够结果直接判为NaN而不是硬给一个数。3.4 封装成一个完整函数把上面三个部分合到一起保存为calc_step_metrics.mfunction [tr, tp, ts, Mp] calc_step_metrics(t, y, tol_ratio) if nargin 3 tol_ratio 0.02; end y y(:); t t(:); yss y(end); % 上升时间10%-90%线性插值 y10 0.1 * yss; y90 0.9 * yss; i10 find(y y10, 1, first); i90 find(y y90, 1, first); if isempty(i10) || isempty(i90) tr NaN; else if i10 1 tr10 t(1); else tr10 interp1([y(i10-1), y(i10)], [t(i10-1), t(i10)], y10); end tr90 interp1([y(i90-1), y(i90)], [t(i90-1), t(i90)], y90); tr tr90 - tr10; end % 峰值时间与超调量 [ymax, imax] max(y); tp t(imax); Mp (ymax - yss) / yss * 100; % 调整时间从后往前找最后超差点 tol tol_ratio * yss; inband abs(y - yss) tol; out_idx find(~inband, 1, last); if isempty(out_idx) ts t(1); elseif out_idx numel(y) ts NaN; else ts t(out_idx 1); end end调用方式t 0:0.001:10; y step(G, t); [tr, tp, ts, Mp] calc_step_metrics(t, y, 0.02); fprintf(tr%.4f, tp%.4f, ts%.4f, Mp%.2f%%\n, tr, tp, ts, Mp);我这里用了max而不是findpeaks是为了让函数不依赖额外工具箱。你如果处理实测数据建议把峰值提取部分手动替换成带平滑的findpeaks版本。4. 用标准二阶系统验证规律阻尼比到底怎么影响指标看完手写算法再用它验证一次经典结论。标准二阶系统的四个指标和阻尼比、自然频率的关系是自控原理里最值得记牢的内容。4.1 对照试验代码保持 ωn 5 不变改变阻尼比 ζ用stepinfo批量计算wn 5; zeta_list [0.1 0.3 0.5 0.7 0.9]; results table(); for i 1:numel(zeta_list) z zeta_list(i); G tf([wn^2], [1 2*z*wn wn^2]); info stepinfo(G); results.Zeta(i) z; results.RiseTime(i) info.RiseTime; results.PeakTime(i) info.PeakTime; results.Overshoot(i) info.Overshoot; results.SettlingTime(i) info.SettlingTime; end disp(results)运行结果大致如下ζ上升时间峰值时间超调量%调整时间0.1很短约0.15约0.6372.9很长约8.00.3约0.23约0.6637.2约2.70.5约0.32约0.7316.3约1.60.7约0.44约0.884.6约1.10.9约0.62约1.440.15约0.94.2 结果解读阻尼比越小超调越大上升越快这符合直觉系统太“活泼”冲得猛。但阻尼比太小时调整时间反而很长因为系统在那里来回振荡迟迟不肯停下来。阻尼比增大后超调被压住调整时间变短但上升时间变长系统变得“迟钝”。所以工程上选阻尼比就是一个权衡。常见的做法是把阻尼比设计在0.4到0.8之间这个区间超调适中快速性也能接受。如果你对超调极其敏感那就往0.8以上调如果你更看重响应速度那就接受一定超调往0.4附近调。这里还可以验证一下二阶系统的经典解析公式。对于标准欠阻尼二阶系统tp π / (ωn·√(1-ζ²))Mp% exp(-πζ / √(1-ζ²)) × 100%ts ≈ 4 / (ζ·ωn)±2%误差带拿ζ0.5、ωn5来算tp π/(5×0.866) ≈ 0.7255秒Mp exp(-π×0.5/0.866)×100% ≈ 16.3%ts ≈ 4/(0.5×5) 1.6秒。这些数值和stepinfo的输出几乎一致误差只来自调整时间那个“约等于”。这个验证很有价值能帮你确认自己的提取代码没写错。5. 实测中容易踩的坑与我的处理习惯理论方法讲完了再说几个实际计算中我踩过的坑。这些细节不算难但每一个都会让结果差不少。5.1 稳态值取错满盘皆输超调量和调整时间都以稳态值为基准。如果你用y(end)当稳态值而仿真时间恰好不够长系统还没真正稳定那y(end)会偏小导致超调量虚高调整时间也可能变成NaN。我的习惯是先画图确认曲线尾部平了再取稳态值。如果尾部有轻微波动用最后10%数据的均值n numel(y); yss mean(y(round(0.9*n):end));5.2 噪声数据导致峰值误判实测数据几乎都有噪声。直接用max找峰值很可能把一个毛刺当成超调峰值。处理顺序是先平滑再找峰最后用峰值附近局部数据做二次曲线拟合让峰值时间和幅值更准。ys smoothdata(y, gaussian, 30); [pks, locs] findpeaks(ys, t);注意平滑窗口大小要结合采样率调窗口太大把真实峰值磨平了窗口太小又起不到去噪作用。我的经验是从30个点左右开始试边试边画图对比。5.3 峰值时间对采样步长敏感峰值本身是曲线顶部的一个尖点如果采样步长太大采样点可能落在峰值两侧算出来的峰值时间偏差明显。调采样率通常能解决t 0:0.0005:10; % 更细的采样如果数据已经固定无法重采样可以对峰值附近的3个点做抛物线拟合求抛物线顶点作为峰值时间和峰值估计。这是实验数据处理里的常规操作比直接取最大值点稳得多。5.4 非最小相位系统与离散系统要单独处理非最小相位系统阶跃响应会先反向产生Undershoot。这时峰值提取不能再无脑用max因为最大值可能出现在很久之后而教材里的“峰值时间”指第一个正向峰值。建议用findpeaks取第一个正向峰。离散系统则要注意采样时间。把连续模型离散化后再用step和stepinfo完全合法Ts 0.01; Gd c2d(G, Ts, zoh); info stepinfo(Gd);但离散数据的峰值时间最小分辨率不会小于一个采样周期所以Ts别取得太大。拿c2d的时候Ts要满足奈奎斯特条件一般取系统带宽的10倍以上采样率才够看。最后再分享一个习惯每次算完指标我都会顺手把step曲线画出来然后把算出来的峰值点、2%误差带边界、上升区间起点终点都标在同一张图上。眼睛扫一遍确认标记位置和视觉判断一致再往报告里写。这个习惯帮我挡掉了好几次因为稳态值偏移或噪声毛刺导致的错误结果。指标提取这件事90%的功夫在数据质量上代码只是最后那一下。本文还有配套的精品资源点击获取