尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

PID控制原理——P/I/D三项各自的物理意义

PID控制原理——P/I/D三项各自的物理意义 前面几篇把控制理论的基础知识铺垫了一遍——建模、传递函数、系统响应、稳定性分析。从这篇开始终于到了控制理论中最实用、面试考得最多的部分PID控制。PID控制器是工业界使用最广泛的控制器没有之一。据统计工业过程控制中超过90%的控制回路用的是PID或者它的变种。你面试机器人岗位面试官问你PID不是因为他想考你教科书知识而是因为这是你入职后天天要用的东西。PID的公式很简单u(t) Kpe(t) Ki∫e(τ)dτ Kd*de(t)/dt。但每一项背后的物理意义、工程直觉很多人其实没搞清楚。今天掰开了讲。P项——比例控制看到偏差就动手比例控制是最直觉的控制方式。偏差越大控制量越大。偏差为零控制量为零。# 比例控制 def p_control(error, Kp): return Kp * error # 例子控制电机转速 Kp 2.0 target_speed 100 # rpm actual_speed 70 # rpm error target_speed - actual_speed output p_control(error, Kp) print(f控制输出: {output}) # 60P项的物理意义是什么它相当于一个弹簧——把输出拉向目标值。偏差越大弹簧拉得越紧。P项让系统有趋向目标的趋势但光靠P项往往不够。为什么因为纯比例控制存在稳态误差。你想想如果系统需要一定的控制量来维持某个状态比如对抗重力、克服摩擦力那偏差必须不为零才能产生这个控制量。这个必须存在的偏差就是稳态误差。举个例子。你要让电机维持在100rpm但负载需要5V的电压才能维持这个转速。纯比例控制下Kp0.5那需要偏差e5/0.510rpm才能输出5V。所以稳态转速只能是90rpm永远差10rpm。面试的时候如果面试官问纯比例控制为什么有稳态误差你就用这个例子回答——因为维持某个状态需要非零的控制量而比例控制的输出正比于偏差所以偏差必须不为零。I项——积分控制消灭稳态误差积分控制就是为了解决稳态误差而生的。它的逻辑是只要偏差存在就不断累积累积到足够大一定能把偏差消除掉。# 积分控制 class IController: def __init__(self, Ki, dt): self.Ki Ki self.dt dt self.integral 0 def update(self, error): self.integral error * self.dt return self.Ki * self.integral # 例子消除稳态误差 Ki 0.5 dt 0.01 ic IController(Ki, dt) # 假设有持续的稳态误差 for i in range(1000): error 10 # 持续偏差 output ic.update(error) print(f积分累积后输出: {output:.1f}) # 50.0I项的物理意义是什么它相当于一个记忆——记住过去所有的偏差然后把这些偏差的总和用来纠正系统。只要偏差存在过积分项就不会是零它会一直作用直到偏差彻底消失。但积分项有个副作用——它会让系统变慢甚至引起振荡。因为积分项累积的是过去的偏差当系统已经接近目标时积分项可能已经累积了很大的值导致控制量过大冲过目标。这就是所谓的积分饱和问题后面专门有一篇讲。D项——微分控制预测未来微分控制是三项中最聪明的。它不看当前偏差的大小而是看偏差变化的速度——偏差在快速减小那别太猛准备刹车。偏差在快速增大赶紧加大纠正力度。# 微分控制 class DController: def __init__(self, Kd, dt): self.Kd Kd self.dt dt self.prev_error 0 def update(self, error): derivative (error - self.prev_error) / self.dt self.prev_error error return self.Kd * derivative # 例子偏差快速变化时D项的作用 Kd 0.1 dt 0.01 dc DController(Kd, dt) errors [10, 8, 5, 1, -2, -5] # 偏差在快速变化 for e in errors: output dc.update(e) print(f误差{e:3d}, 微分输出{output:6.1f})D项的物理意义是什么它相当于一个阻尼器——预测偏差的变化趋势提前施加反作用力。当偏差快速减小时系统快速接近目标D项产生反向力矩来减速防止超调。当偏差快速增大时D项加大纠正力度。D项最大的好处是增加系统的阻尼减小超调让系统更平稳地到达目标。但D项有个致命弱点——它对噪声极其敏感。因为微分运算会放大高频信号传感器噪声正好是高频的。如果传感器信号有抖动D项的输出会剧烈波动。这个问题后面专门有一篇讲怎么处理。三项配合PID的完整形态把P、I、D三项组合起来就是完整的PID控制器class PIDController: def __init__(self, Kp, Ki, Kd, dt): self.Kp Kp self.Ki Ki self.Kd Kd self.dt dt self.integral 0 self.prev_error 0 def update(self, error): # P项 p_term self.Kp * error # I项 self.integral error * self.dt i_term self.Ki * self.integral # D项 derivative (error - self.prev_error) / self.dt self.prev_error error d_term self.Kd * derivative return p_term i_term d_term # 使用示例 pid PIDController(Kp2.0, Ki0.5, Kd0.1, dt0.01) target 100.0 measured 0.0 for i in range(500): error target - measured control pid.update(error) # 简化的系统模型 measured (control - 0.5 * measured) * 0.01 print(f最终值: {measured:.2f})面试的时候面试官问P/I/D各自的作用你可以这样回答P项提供即时的纠正力相当于弹簧让系统趋向目标但有稳态误差。I项累积历史偏差消除稳态误差但会让系统变慢、可能引起振荡。D项预测偏差趋势相当于阻尼器增加系统稳定性、减小超调但对噪声敏感。之前面试一家做无人车的公司面试官问了一个很有意思的问题如果只让你用两项你选哪两项我选了PI——因为P提供基本控制I消除稳态误差。大部分场景没有D也能跑只是超调大一些。但如果你需要快速精准跟踪比如机械臂轨迹跟踪D项就很重要了它能显著减小超调。补充一个PID三项配合使用的实战技巧。在实际调参时我建议按P→D→I的顺序来调。先只开P项调到一个能接受的比例增益有超调但不至于失控。然后加D项把超调压下来。最后加I项消除稳态误差。这个顺序的好处是每一步的效果都很清晰——P调响应速度D调稳定性I调精度。如果一开始就三项全开出了问题你分不清是哪个参数导致的。另外I项的积分限幅一定要设不然在目标值大幅切换时积分项会累积到很大的值积分饱和导致系统严重超调甚至失控。限幅值一般设为控制输出的最大值的50%-80%。下一篇讲PID调参实战——从Ziegler-Nichols方法到实际工程经验。如果这篇文章对你有帮助欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。「机器人软件开发面试·从入门到精通」连载系列上一篇第181篇 稳定性分析——系统会不会发散的判定方法 下一篇预告第183篇 PID调参实战——从Ziegler-Nichols到实际工程经验有任何问题欢迎评论区留言我会尽量回复。
返回列表