简介:这份《自动控制原理实验报告》面向电子信息类与电气类本科生,提供课程实验的完整模板与数据分析参考,帮助读者规范完成实验记录、曲线绘制与思考题解答。内容覆盖典型环节电路模拟与Matlab仿真、二阶系统阶跃响应、稳定性分析、根轨迹分析,以及频率特性测量与线性系统串联校正,涉及比例、惯性、积分、微分等环节的传递函数、SIMULINK模型与阶跃响应波形对比,并给出超调量、峰值时间、调节时间等指标的估算思路。资源包共1个doc文件,约1.28MB,可直接作为实验报告撰写与预习复习的参考底稿。目前已有4274人学习下载,适合需要对照实验流程、理解参数物理意义并完成仿真与电路结果比对的电气自动化方向学生使用。
1. 自动控制原理实验报告:从纸面推导到 Matlab 仿真跑通
带过几届自动控制原理实验课之后,我发现一个很稳定的现象:学生交上来的实验报告,理论推导部分往往写得工工整整,一到 Matlab 仿真曲线就对不上。阶跃响应超调量算出来是 16.3%,仿真跑出来却是 25% 还带振荡;根轨迹画出来和手算的分离点差了一大截。问题不在推导,在于从传递函数到仿真模型这一步,中间有一堆默认参数和建模习惯没人讲清楚。
这篇笔记就围绕「自动控制原理实验报告」这个场景,把典型实验从理论计算、Matlab 建模、参数设置到曲线验证的完整链路拆开讲。适合正在做自动控制原理课程实验、需要交实验报告,或者想用 Matlab 把经典控制理论重新跑一遍的人。核心工具是 Matlab 和 Simulink,核心方法是「先算后仿、以算验仿」。热搜里常出现的自动控制原理、Matlab、仿真这几个词,本质上说的就是这条链路。
2. 实验报告里最常出现的四类实验与建模选择
2.1 时域分析实验:二阶系统阶跃响应为什么是重灾区
时域分析实验通常给一个标准二阶系统,传递函数写成 G(s) = ωn² / (s² + 2ζωn·s + ωn²)。理论部分要算自然频率 ωn、阻尼比 ζ、超调量 σ%、峰值时间 tp、调节时间 ts。仿真部分用 Matlab 跑阶跃响应,然后对比两条曲线。
问题出在两个地方。第一,理论公式里的超调量 σ% = e^(-πζ/√(1-ζ²)) × 100% 只在 0 < ζ < 1 时成立,很多报告不管 ζ 取值直接套,ζ ≥ 1 时根本没有超调,公式算出来却是正数。第二,Matlab 的 step 函数默认仿真时间是根据系统极点自动选的,有时候截断太早,调节时间还没到就结束了,曲线看着像收敛了,实际没到 2% 误差带。
我一般会显式指定仿真时间,并且把误差带画出来:
% 二阶系统时域分析:显式指定仿真时间与误差带 wn = 10; % 自然频率 rad/s zeta = 0.5; % 阻尼比 num = wn^2; den = [1, 2*zeta*wn, wn^2]; sys = tf(num, den); t = 0:0.001:2; % 显式时间向量,避免自动截断 [y, t_out] = step(sys, t); % 理论值计算 sigma_theory = exp(-pi*zeta/sqrt(1-zeta^2)) * 100; % 超调量 % tp_theory = pi / (wn*sqrt(1-zeta^2)); % 峰值时间 s ts_theory = 4 / (zeta*wn); % 2% 调节时间 s % 仿真值提取 [y_peak, idx_peak] = max(y); sigma_sim = (y_peak - 1) * 100; tp_sim = t_out(idx_peak); fprintf('超调量 理论 %.2f%% 仿真 %.2f%%\n', sigma_theory, sigma_sim); fprintf('峰值时间 理论 %.4f s 仿真 %.4f s\n', tp_theory, tp_sim);这段代码的关键在 t 向量。step(sys, t) 会强制在指定时间点上求解,不会自动截断。误差带用 4/(ζωn) 是 2% 标准的近似,ζ 很小时这个近似会偏乐观,报告里最好注明用的是 2% 还是 5% 误差带。仿真值和理论值对不上时,先检查 ζ 是不是落在 (0,1) 区间,再看时间向量够不够长。
2.2 根轨迹实验:分离点和渐近线的手算与仿真对照
根轨迹实验的核心是画 K 从 0 到 ∞ 变化时闭环极点的轨迹。理论部分要算渐近线角度、分离点、与虚轴交点。仿真用 rlocus 函数。这里最常见的翻车是分离点算错。
分离点满足 dK/ds = 0,等价于开环传递函数分母导数乘分子减分子导数乘分母等于零。手算时容易漏掉重根情况。Matlab 里可以用 rlocus 配合 rlocfind 找特定 K 下的极点,但分离点本身不会直接标出来。
% 根轨迹分离点验证 num = [1, 2]; % 开环零点 den = conv([1, 0], [1, 4, 8]); % 开环极点 s(s^2+4s+8) sys = tf(num, den); rlocus(sys); hold on; % 数值法找分离点:扫描 K,找实轴上极点重合的位置 K_range = 0:0.01:50; real_axis_points = []; for k = K_range cl_poles = roots(den + k*num); if all(abs(imag(cl_poles)) < 1e-6) % 全部为实数极点 real_axis_points = [real_axis_points; k, sort(real(cl_poles))']; end end % 分离点出现在两个实极点最接近的 K 处 [~, idx] = min(abs(real_axis_points(:,2) - real_axis_points(:,3))); fprintf('分离点 K ≈ %.3f, s ≈ %.4f\n', ... real_axis_points(idx,1), real_axis_points(idx,2));扫描法的精度取决于 K 的步长,0.01 的步长在分离点附近够用,但报告里如果要精确到小数点后四位,得用 fminbnd 做局部优化。分离点手算结果和扫描结果差超过 5% 时,先检查 den 的展开有没有漏项,conv 的用法是不是把 s 的系数搞错了。
2.3 频域分析实验:Bode 图与稳定裕度的读取
频域实验要画 Bode 图,读幅值裕度 Gm 和相位裕度 Pm。Matlab 的 margin 函数直接给出这两个值,但报告里需要解释它们对应的频率。常见错误是把 margin 返回的 Gm 当成绝对值,实际上 Gm 是以 dB 为单位的,换算成倍数要 10^(Gm/20)。
% 频域稳定裕度读取 num = 10; den = conv([1, 1], conv([1, 2], [1, 5])); sys = tf(num, den); [Gm, Pm, Wcg, Wcp] = margin(sys); fprintf('幅值裕度 %.2f dB (%.3f 倍) @ %.3f rad/s\n', ... Gm, 10^(Gm/20), Wcg); fprintf('相位裕度 %.2f deg @ %.3f rad/s\n', Pm, Wcp); % 手动验证:在 Wcp 处看幅值是否为 0 dB [mag, phase] = bode(sys, Wcp); fprintf('穿越频率处幅值 %.4f dB\n', 20*log10(mag));margin 返回的 Wcg 是相位穿越频率(相位 -180° 处的频率),Wcp 是幅值穿越频率(幅值 0 dB 处的频率)。这两个容易搞反。报告里写「幅值裕度对应的频率」时,指的是 Wcg。手动验证那一步是后悔药,如果 margin 的结果和 bode 手动读出来的对不上,多半是系统有右半平面极点,margin 对非最小相位系统的判断会失效。
2.4 离散系统实验:Z 变换与采样周期的影响
离散系统实验涉及 Z 变换、脉冲传递函数、采样周期 T 的选择。理论部分要算闭环脉冲传递函数,仿真用 c2d 做连续到离散的转换。采样周期选得太大,离散化后的系统可能和连续系统行为差很远,甚至不稳定。
% 连续系统离散化对比 sys_c = tf([1], [1, 2, 1]); % 连续系统 1/(s+1)^2 for T = [0.01, 0.1, 0.5] sys_d = c2d(sys_c, T, 'zoh'); % 零阶保持器离散化 [y, t] = step(sys_d, 0:0.01:10); info = stepinfo(y, t); fprintf('T=%.2f s: 超调 %.2f%%, 调节时间 %.3f s\n', ... T, info.Overshoot, info.SettlingTime); endc2d 的第三个参数是离散化方法,'zoh' 是零阶保持器,最常用;'tustin' 是双线性变换,频域特性更好但时域可能有畸变。采样周期 T 一般取系统最小时间常数的 1/10 到 1/20。T=0.5 时如果系统已经不稳定,说明采样太慢,报告里要解释这是采样导致的稳定性退化,不是理论算错。
3. 用 Matlab 把实验报告跑通:从脚本到 Simulink 的完整流程
3.1 脚本结构:一个实验一个函数,参数集中管理
我见过太多实验报告里的 Matlab 代码是一整段流水账,改一个参数要翻半天。推荐的做法是每个实验写成一个函数,参数放在函数开头,输出结构体包含理论值和仿真值。
function result = exp_second_order(wn, zeta, t_end) % 二阶系统时域分析实验 % 输入: wn 自然频率, zeta 阻尼比, t_end 仿真结束时间 % 输出: result 结构体,含理论值和仿真值 num = wn^2; den = [1, 2*zeta*wn, wn^2]; sys = tf(num, den); t = 0:0.001:t_end; [y, t_out] = step(sys, t); % 理论值 if zeta > 0 && zeta < 1 result.sigma_theory = exp(-pi*zeta/sqrt(1-zeta^2)) * 100; result.tp_theory = pi / (wn*sqrt(1-zeta^2)); else result.sigma_theory = 0; result.tp_theory = NaN; end result.ts_theory = 4 / (zeta*wn); % 仿真值 [y_peak, idx] = max(y); result.sigma_sim = (y_peak - 1) * 100; result.tp_sim = t_out(idx); result.y = y; result.t = t_out; end这个结构的好处是,换一组 ωn 和 ζ 只需要改调用参数,不用动内部逻辑。报告里附代码时,函数签名和参数说明要写清楚,答辩时被问到「你这个 ζ 改了会怎样」可以直接跑。
3.2 Simulink 建模:Transfer Fcn 模块的参数设置
Simulink 建模适合展示系统结构,尤其是多回路系统。Transfer Fcn 模块的 Numerator 和 Denominator 要填系数向量,格式和 Matlab 的 tf 一致。常见错误是分母系数漏掉最高次项前面的 1,比如 s² + 2s + 1 填成 [2, 1] 而不是 [1, 2, 1]。
% 用脚本创建 Simulink 模型并设置 Transfer Fcn 参数 model = 'exp_ctrl'; new_system(model); open_system(model); add_block('simulink/Continuous/Transfer Fcn', [model '/Plant']); set_param([model '/Plant'], 'Numerator', '[10]'); set_param([model '/Plant'], 'Denominator', '[1, 2, 10]'); add_block('simulink/Sources/Step', [model '/Step']); add_block('simulink/Sinks/Scope', [model '/Scope']); add_line(model, 'Step/1', 'Plant/1'); add_line(model, 'Plant/1', 'Scope/1'); set_param(model, 'StopTime', '5'); save_system(model);set_param 设置 Denominator 时,字符串里的向量格式要和 Matlab 一致。StopTime 默认是 10,对于快速系统可能太长,对于慢速系统可能太短。仿真步长在 Configuration Parameters 里设,默认是变步长,报告里如果要固定步长,改成 Fixed-step 并指定步长。
3.3 数据导出与报告图表:从 Scope 到工作区
Simulink 的 Scope 默认不把数据存到工作区,需要在 Configuration Parameters 里勾选「Save simulation output as single object」,或者给信号加 To Workspace 模块。我一般用 To Workspace,变量名设成 yout,格式选 Structure with time,这样在脚本里可以直接 plot。
% 仿真后从工作区取数据画图 sim('exp_ctrl'); t = yout.time; y = yout.signals.values; figure; plot(t, y, 'LineWidth', 1.5); grid on; xlabel('时间 (s)'); ylabel('幅值'); title('二阶系统阶跃响应'); % 标注超调量和峰值时间 [y_peak, idx] = max(y); hold on; plot(t(idx), y_peak, 'ro', 'MarkerSize', 8); text(t(idx), y_peak, sprintf(' 峰值 %.3f', y_peak));To Workspace 的采样时间如果设成 -1,表示继承上游信号的采样时间。如果上游是连续模块,导出的数据是变步长的,plot 出来可能不均匀。报告里如果要精确计算超调量,最好在仿真设置里指定固定步长,或者用 interp1 重采样。
4. 避坑与排查:实验报告里那些对不上的曲线
4.1 超调量仿真值比理论值大很多
现象:理论算出来 16%,仿真跑出来 25% 以上,曲线还带高频振荡。
原因:最常见的是仿真步长太大,变步长求解器在快速变化段没采到真正的峰值。其次是传递函数系数写错,比如把 2ζωn 写成了 2ζ。
解决:把求解器改成 ode45 并限制最大步长,或者直接用 step 函数指定时间向量。检查 den 的系数,用 damp(sys) 看极点的阻尼比和自然频率是否和输入一致。
4.2 根轨迹的分离点手算和 rlocus 对不上
现象:手算分离点在 s = -1.5,rlocus 图上看着在 -1.2 附近。
原因:rlocus 的坐标轴是自动缩放的,视觉误差很大。另外手算时如果开环传递函数有零点,分离点的方程要包含零点的影响。
解决:不要靠肉眼读图,用 rlocfind 或者数值扫描法精确计算。手算时把 dK/ds = 0 的方程完整写出来,分子分母都求导,别漏项。
4.3 Bode 图的相位裕度是负的但系统稳定
现象:margin 返回 Pm = -20°,但阶跃响应收敛。
原因:系统是非最小相位系统,或者有右半平面零点。margin 对这类系统的判断不可靠。
解决:用 nyquist 图看包围情况,或者直接跑阶跃响应验证。报告里要注明系统类型,非最小相位系统的稳定裕度不能只看 margin。
4.4 离散化后系统不稳定
现象:连续系统阶跃响应收敛,c2d 离散化后阶跃响应发散。
原因:采样周期太大,离散化后的极点跑到单位圆外。
解决:减小采样周期,一般取系统最小时间常数的 1/10 以下。如果必须用大采样周期,考虑用 'tustin' 方法或者加零阶保持器补偿。
4.5 Simulink 仿真报代数环错误
现象:Simulink 报「Algebraic loop」错误,仿真跑不起来。
原因:系统里有直接馈通的回路,比如 Transfer Fcn 的输出直接反馈到输入,中间没有延迟或积分环节。
解决:在反馈回路里加一个 Memory 模块或者 Unit Delay 模块,打断代数环。或者改用状态空间模型,状态空间天然没有代数环问题。
5. 进阶技巧:用脚本自动生成实验报告的数据表
实验报告最后要附数据表,手动抄仿真结果容易出错。我一般写一个汇总脚本,把所有实验的参数、理论值、仿真值、误差百分比输出成表格,直接复制到报告里。
% 批量运行实验并汇总结果 experiments = { % wn, zeta, t_end 10, 0.3, 3; 10, 0.5, 3; 10, 0.7, 3; 20, 0.5, 2; }; fprintf('%-6s %-6s %-10s %-10s %-10s %-10s\n', ... 'wn', 'zeta', 'sigma理论', 'sigma仿真', 'tp理论', 'tp仿真'); for i = 1:size(experiments, 1) wn = experiments{i, 1}; zeta = experiments{i, 2}; t_end = experiments{i, 3}; r = exp_second_order(wn, zeta, t_end); fprintf('%-6.1f %-6.2f %-10.2f %-10.2f %-10.4f %-10.4f\n', ... wn, zeta, r.sigma_theory, r.sigma_sim, ... r.tp_theory, r.tp_sim); end这个脚本的输出可以直接粘到实验报告的表格里。误差百分比可以再加一列,计算 (仿真值 - 理论值) / 理论值 × 100%。如果某一行的误差超过 5%,回去检查那组参数是不是踩了前面说的坑。
还有一个习惯:每次跑完仿真,把 figure 用 saveas 存成 png,文件名带上参数,比如step_wn10_zeta0.5.png。报告里插图时不用重新跑,直接引用。这个习惯帮我省了很多重复劳动,尤其是答辩前临时要改参数的时候。
做自动控制原理实验报告这件事,说到底就是让理论推导和仿真曲线互相验证。理论算对了,仿真跑通了,两条曲线贴在一起,报告自然就有说服力。我自己的经验是,每次跑出对不上的曲线,先别急着改理论值,多半是仿真参数或者建模细节出了问题。希望帮到你。
本文还有配套的精品资源,点击获取