资讯动态

自动控制原理课件(吴麒)仿真验证:从传递函数到PID整定与频域校正

发布时间:2026/10/15 16:10:49 来源:尧图企业网站定制
简介这份资源是吴麒教授编著的《自动控制原理》第二版配套课件面向自动化、电子工程、航空航天等专业的本科生与考研学习者帮助系统掌握控制系统的建模、分析与设计方法。压缩包共收录140个文件以102个MATLAB脚本.m和23个PPT课件为主体辅以10个Flash动画演示、3份Word文档及2个Simulink模型文件整体约16.48MB覆盖课堂讲授、仿真验证与习题演算等环节。课件内容从控制系统定义与分类、微分方程与传递函数建模延伸到劳斯判据、根轨迹、伯德图与尼奎斯特曲线等稳定性与频率响应分析并涉及PID控制器设计、超前滞后校正、非线性系统描述函数法、离散时间系统Z变换以及状态空间与最优控制等现代控制理论还结合飞机自动驾驶、机器人控制等工程案例。目前已有598人学习适合课堂同步复习、考研梳理与仿真实践参考。1. 自动控制原理课件吴麒从一份讲义到能跑通的仿真链路很多做控制方向的朋友第一次接触自动控制原理课件吴麒这类资料时都会陷入一个误区把它当成考前突击的复习提纲翻两页公式就丢到一边。但真正做过控制系统落地的人会告诉你这份课件的价值不在公式本身而在于它把经典控制理论从时域、复域到频域的推演逻辑串成了一条完整的线。你如果正在准备考研、做课程设计或者刚转行做嵌入式控制、运动控制这份课件能帮你把根轨迹、伯德图、奈奎斯特判据这些概念从“会算题”拉到“能调参”的层面。问题在于课件里的例题大多是手工推导缺少可复现的仿真验证导致很多人学完还是不知道PID参数怎么整定、截止频率怎么选。这篇笔记就按我自己的使用路径把这份课件拆成一条能动手跑的链路。2. 自动控制原理课件吴麒的知识骨架与仿真映射2.1 课件里真正值得反复看的三块内容自动控制原理课件吴麒通常覆盖八大章节但真正在工程里高频使用的只有三块系统建模与传递函数、时域响应分析、频域校正。建模部分讲的是如何从物理系统写出微分方程再拉氏变换这一步决定了你后面仿真模型对不对。时域部分的核心是一阶、二阶系统的阶跃响应指标超调量、调节时间、峰值时间这三个量直接对应你调PID时的直观感受。频域部分则是伯德图和相位裕度的计算它决定了你的闭环系统有没有足够的稳定余量。我一般会建议先把课件的第二章和第四章吃透因为这两章是后面所有校正设计的基础。很多新手一上来就翻根轨迹结果连开环传递函数的标准形式都写不对根轨迹画出来全是错的。课件的例题里有一类典型题给一个电机模型让你判断加入比例控制器后系统的稳态误差和动态性能。这种题在课件里是手算但在实际项目里你需要用仿真工具把同样的过程跑一遍才能理解参数变化对系统的影响。2.2 从课件例题到Python仿真最小验证环境课件里的例题大多以“已知开环传递函数求闭环响应”的形式出现。要复现这些例题最轻量的方式是Python加control库和matplotlib。下面这段代码是我常用的模板用来验证课件里二阶系统的阶跃响应。import control as ctrl import matplotlib.pyplot as plt import numpy as np # 定义二阶系统自然频率wn2 rad/s阻尼比zeta0.5 wn 2.0 zeta 0.5 # 课件中常见的标准二阶传递函数 G(s) wn^2 / (s^2 2*zeta*wn*s wn^2) num [wn**2] den [1, 2*zeta*wn, wn**2] sys ctrl.TransferFunction(num, den) # 计算阶跃响应时间范围0到10秒 t, y ctrl.step_response(sys, Tnp.linspace(0, 10, 1000)) # 计算超调量和调节时间2%误差带 overshoot (max(y) - 1.0) * 100 settling_idx np.where(np.abs(y - 1.0) 0.02)[0] settling_time t[settling_idx[-1]] if len(settling_idx) 0 else 0 print(f超调量: {overshoot:.2f}%) print(f调节时间(2%): {settling_time:.3f} s) plt.plot(t, y) plt.axhline(1.0, colorr, linestyle--, linewidth0.8) plt.xlabel(Time (s)) plt.ylabel(Amplitude) plt.title(Second-order System Step Response) plt.grid(True) plt.show()这段代码的逻辑很直接先用control.TransferFunction把课件的传递函数搬进来再用step_response算时域曲线最后用numpy反推超调量和调节时间。参数说明上wn决定响应速度zeta决定超调大小。课件里常说的“阻尼比0.707是最佳工程值”你把这个值代进去跑一遍就能看到超调量大约4.3%调节时间在2%误差带下约为4/(zeta*wn)。这种对照能帮你把公式和曲线对应起来。2.3 频域分析的仿真验证伯德图与相位裕度课件里频域校正部分的核心是伯德图。手画伯德图靠的是渐近线近似但实际系统的相位裕度需要精确计算。下面这段代码用来画开环伯德图并计算相位裕度。import control as ctrl import matplotlib.pyplot as plt # 开环传递函数 G(s) 10 / (s*(s1)*(s2)) num [10] den [1, 3, 2, 0] # s*(s1)*(s2) s^3 3s^2 2s sys ctrl.TransferFunction(num, den) # 计算幅值裕度和相位裕度 gm, pm, wcg, wcp ctrl.margin(sys) print(f幅值裕度: {20*np.log10(gm):.2f} dB (at {wcg:.3f} rad/s)) print(f相位裕度: {pm:.2f} deg (at {wcp:.3f} rad/s)) # 画伯德图 ctrl.bode_plot(sys, dBTrue, HzFalse, degTrue) plt.show()这里的关键是ctrl.margin函数它返回的pm就是相位裕度。课件里讲“相位裕度大于45度系统才稳定”你把这个开环传函代进去会发现相位裕度大约只有20多度说明系统需要校正。常见的做法是加超前校正网络把截止频率附近的相位抬起来。课件里给的超前校正公式是Gc(s) (1a*T*s)/(1T*s)其中a决定最大相位超前角T决定中心频率。你可以把校正前后的伯德图画在一起对比直观看到相位裕度的变化。3. 用课件方法整定PID从手工计算到仿真迭代3.1 课件里的PID表达式与工程实现的差异自动控制原理课件吴麒里讲的PID是理想形式u(t) Kp*e(t) Ki*∫e(t)dt Kd*de(t)/dt。但在实际嵌入式代码里你不可能直接这样写因为积分项会累积饱和微分项对噪声极其敏感。我一般会采用增量式PID或者带抗饱和的位置式PID。课件里有一道例题是给一个二阶系统设计PID控制器要求超调量小于10%调节时间小于2秒。手算的思路是先根据稳态误差确定Ki再根据超调量确定Kp和Kd。但实际调参时你会发现理论值和仿真值能差出30%以上因为课件忽略了执行器饱和和采样延迟。下面是一个带抗饱和的增量式PID实现我用它来复现课件里的例题。class PID: def __init__(self, Kp, Ki, Kd, dt, u_min, u_max): self.Kp Kp self.Ki Ki self.Kd Kd self.dt dt self.u_min u_min self.u_max u_max self.integral 0.0 self.prev_error 0.0 self.prev_u 0.0 def update(self, setpoint, measured): error setpoint - measured # 比例项 P self.Kp * error # 积分项带抗饱和只有输出未饱和时才累积 if self.u_min self.prev_u self.u_max: self.integral self.Ki * error * self.dt # 微分项对测量值微分避免设定值突变导致微分冲击 D self.Kd * (error - self.prev_error) / self.dt u P self.integral D # 输出限幅 u max(self.u_min, min(self.u_max, u)) self.prev_error error self.prev_u u return u这段代码里Kp、Ki、Kd就是课件里的三个参数但实现上做了两处工程化处理积分抗饱和和微分先行。参数说明上dt是采样周期一般取系统最小时间常数的1/10到1/20。u_min和u_max是执行器物理限幅比如电机PWM占空比0到100%。你把这个PID接到课件的二阶模型上用dt0.01跑一遍会发现超调量比手算值大因为离散化引入了相位滞后。这时候你需要把Kd稍微调大或者把dt减小。3.2 用仿真迭代代替手算一个完整的整定流程课件里的整定方法是“先比例、后积分、再微分”但实际项目中我更喜欢用仿真扫参。具体做法是固定Ki和Kd让Kp从0.1到10按对数间隔扫一遍记录每个Kp下的超调量和调节时间然后画成曲线找拐点。下面这段代码就是干这个的。import numpy as np import control as ctrl import matplotlib.pyplot as plt # 被控对象课件里的二阶系统 wn 2.0 zeta 0.5 plant ctrl.TransferFunction([wn**2], [1, 2*zeta*wn, wn**2]) # 扫参范围 Kp_list np.logspace(-1, 1, 20) overshoots [] settling_times [] for Kp in Kp_list: # 闭环系统G_cl Kp*G / (1 Kp*G) sys_cl ctrl.feedback(Kp * plant, 1) t, y ctrl.step_response(sys_cl, Tnp.linspace(0, 15, 2000)) overshoot (max(y) - 1.0) * 100 overshoots.append(overshoot) # 调节时间最后一次进入2%误差带的时间 idx np.where(np.abs(y - 1.0) 0.02)[0] settling_times.append(t[idx[-1]] if len(idx) 0 else 0) # 画图 fig, ax1 plt.subplots() ax1.semilogx(Kp_list, overshoots, b-o, labelOvershoot (%)) ax1.set_xlabel(Kp) ax1.set_ylabel(Overshoot (%), colorb) ax2 ax1.twinx() ax2.semilogx(Kp_list, settling_times, r-s, labelSettling Time (s)) ax2.set_ylabel(Settling Time (s), colorr) plt.title(Kp Sweep: Overshoot vs Settling Time) plt.grid(True) plt.show()这段代码的输出是一张双纵轴图横轴是Kp的对数值。你会看到超调量随Kp增大而增大调节时间先减小后增大。拐点大概在Kp2到Kp5之间具体取决于你对超调量的容忍度。课件里说“比例增益增大可以减小稳态误差但会降低稳定性”这张图就是最直观的证据。我一般会选超调量在10%到20%之间的Kp然后再加积分项消除稳态误差。3.3 课件例题的仿真复现一个直流电机速度控制案例课件里有一道经典例题直流电机速度控制系统给定电机参数要求设计PID控制器使转速在1秒内达到设定值的95%。我把这道题改成了一个可运行的仿真脚本。import control as ctrl import numpy as np import matplotlib.pyplot as plt # 直流电机模型简化为一阶惯性环节 积分环节 # 传递函数 G(s) K / (tau*s 1) * (1/s) K_motor 10.0 # 电机增益 tau 0.5 # 机电时间常数 plant ctrl.TransferFunction([K_motor], [tau, 1, 0]) # PID控制器参数根据课件方法初调 Kp 3.0 Ki 5.0 Kd 0.1 pid ctrl.TransferFunction([Kd, Kp, Ki], [1, 0]) # 开环和闭环 open_loop pid * plant closed_loop ctrl.feedback(open_loop, 1) # 阶跃响应 t, y ctrl.step_response(closed_loop, Tnp.linspace(0, 5, 1000)) # 找95%上升时间 idx_95 np.where(y 0.95)[0] rise_time_95 t[idx_95[0]] if len(idx_95) 0 else None print(f95%上升时间: {rise_time_95:.3f} s) plt.plot(t, y) plt.axhline(0.95, colorr, linestyle--, linewidth0.8) plt.xlabel(Time (s)) plt.ylabel(Speed (pu)) plt.title(DC Motor Speed Control with PID) plt.grid(True) plt.show()这里plant是电机模型pid是理想PID的传递函数形式。ctrl.feedback自动算闭环。运行后你会看到上升时间大约0.6秒满足课件要求。但如果你把Kp调到10上升时间会缩短到0.3秒但超调量会超过30%。这就是课件里反复强调的“快速性与稳定性矛盾”。实际调参时我一般会先用仿真找到满足上升时间的Kp下限再在这个基础上微调Ki和Kd。4. 避坑与排查课件学习到工程落地的五个翻车点4.1 传递函数系数写错导致仿真结果完全不对现象仿真出来的阶跃响应发散或者稳态值不是1。原因课件的传递函数通常写成G(s) K/(Ts1)但你在代码里写den [T, 1]时如果T是时间常数那num应该是[K]而不是[K*T]。很多人会把增益和时间常数混在一起。解决每次写完传递函数先用ctrl.dcgain(sys)算一下直流增益看是否等于K。如果不等于说明系数写错了。4.2 离散化周期选得太大导致相位裕度丢失现象仿真里调好的PID参数烧到单片机里就跑飞。原因仿真用的是连续域实际控制器是离散的。如果采样周期dt大于系统最小时间常数的1/5离散化引入的相位滞后会吃掉大量相位裕度。解决先用ctrl.sample_system把连续控制器离散化看离散前后的伯德图差多少。我一般要求dt小于tau_min/10其中tau_min是被控对象最小时间常数。4.3 积分饱和导致启动时超调巨大现象系统启动时输出直接冲到最大限幅然后长时间降不下来。原因位置式PID的积分项在误差大时快速累积等误差反向时积分项已经饱和需要很长时间才能退饱和。解决用增量式PID或者给积分项加限幅。上面代码里的if self.u_min self.prev_u self.u_max就是抗饱和逻辑。另外设定值突变时可以用斜坡函数代替阶跃给系统一个缓冲。4.4 微分项对噪声敏感导致输出抖动现象电机静止时PWM占空比一直在抖或者仿真里微分项一加就振荡。原因微分项对误差的差分放大了测量噪声。课件里的理想微分在实际中不可实现。解决用不完全微分即在微分项后面串一个一阶低通滤波器截止频率取采样频率的1/5到1/10。或者直接用“微分先行”只对测量值微分不对设定值微分。4.5 忽略执行器饱和导致仿真和实物差距大现象仿真里超调量10%实物超调量50%。原因仿真里PID输出没有限幅实物里电机驱动电压有限幅。解决在仿真里加入饱和模块把PID输出限制在实际执行器范围内。control库可以用ctrl.saturating或者自己写一个非线性环节。我一般会在仿真里把限幅设得比实际稍紧一点留出安全余量。5. 从课件到工程一个可复用的仿真验证习惯自动控制原理课件吴麒最大的价值不是那些公式而是它提供了一套从时域指标到频域指标的映射关系。我现在的习惯是每拿到一个新的被控对象先按课件的方法写出传递函数然后用Python跑一遍阶跃响应和伯德图把超调量、调节时间、相位裕度这三个量记下来。接着用PID扫参找到满足指标的参数组合最后把离散化和饱和加进去再验证一遍。这个过程大概花半小时但能避免后面几天的反复调试。如果你想把课件里的校正方法用起来我建议从超前校正入手。课件里超前校正的步骤是先根据稳态误差确定开环增益再根据相位裕度要求计算最大超前角然后确定校正网络的零极点位置。你可以用下面这段代码验证校正效果。import control as ctrl import numpy as np import matplotlib.pyplot as plt # 未校正系统 num [10] den [1, 3, 2, 0] sys ctrl.TransferFunction(num, den) # 超前校正网络Gc(s) (1 a*T*s) / (1 T*s) # 设最大超前角对应的a5中心频率取截止频率附近 a 5.0 T 0.2 Gc ctrl.TransferFunction([a*T, 1], [T, 1]) # 校正后开环 sys_comp Gc * sys # 计算校正前后相位裕度 gm1, pm1, _, _ ctrl.margin(sys) gm2, pm2, _, _ ctrl.margin(sys_comp) print(f校正前相位裕度: {pm1:.2f} deg) print(f校正后相位裕度: {pm2:.2f} deg) # 画伯德图对比 plt.figure() ctrl.bode_plot(sys, dBTrue, degTrue, labelUncompensated) ctrl.bode_plot(sys_comp, dBTrue, degTrue, labelCompensated) plt.legend() plt.show()运行后你会看到相位裕度从20多度提升到50度左右截止频率也往高频移动了。这就是课件里说的“超前校正提高相位裕度加快响应速度”。但要注意超前校正会放大高频噪声如果系统噪声大a不能取太大一般不超过10。我自己的经验是先按课件公式算出理论值然后在仿真里把a和T各扫一遍找相位裕度和带宽的平衡点。这个习惯帮我省了很多试错时间希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑