彻底搞懂PID|控制算法详解,附工程实践要点

640.webp

为了将算法知识真正转化为解决问题的能力,我们开设了《算法详解》专栏。每一期我们都会深度拆解一个核心算法,不只讲公式,更讲原理、局限,以及它们在真实系统里怎么落地。

第一期,从最经典也最基础的 PID 开始。

 

 

深蓝AI

 

 

1
PID 首先是⼀种反馈控制
PID 的核心是"反馈控制",而反馈控制最干净的形态,就是只控制一个变量、不受其他因素耦合。
相较于在平地上相对稳定的汽车或变化缓慢的温控系统,无人机是一个更直观、也更“苛刻”的控制对象。它天生不稳定——如果没有任何控制输入,它会立刻在重力作用下坠落。这使得“反馈控制”的必要性变得一目了然。

假设让一架无人机从地面升到10 m。最直觉的做法是:不断看它离10 m还差多少,差得多就多给点推力,差得少就少给点。但真这么干,无人机大概率会冲过10 m,再掉回来,在目标高度附近反复振荡。

问题出在哪?同样是距离目标高度0.2 m,无人机可能在快速上升,也可能被一阵持续向下的风压住。前者需要提前收力,后者反而要继续增加推力。只看“现在还差多少”——信息不够。

PID 比纯比例控制多想两件事:误差持续了多久,以及它变化得有多快。

640 (1).webp

图1| 同样是距离目标⾼度 0.2 m,左侧⽆⼈机正在快速上升,需要提前收力;右侧无人机受到持续向下的风,需要增加补偿。图源:作者自制。©【深蓝 AI】编译

把这个控制过程拆开:
  • 目标值:希望无人机到达的高度,也就是 10 m;
  • 测量值:传感器测到的实际高度;
  • 误差:目标高度与实际高度之差;
  • 控制量:控制器为了缩小误差给出的推力修正。
通常把误差定义为:
其中, 是目标值, 是测量值。
这里的正负号并不是天然规定。也可以把误差定义成“实际值减目标值”,只要控制器增益和执行器方向与这个约定保持⼀致即可。 把信号连起来,就是⼀个最基本的反馈回路:
640 (2).webp
控制器增加推后,无人机有没有真的上升、是否已经越过 10 m,都要重新测量。PID 不会⼀次算出⼀个“完美推力”,它只是在每个控制周期里根据新误差继续纠偏。这就是反馈。
严格来说,无人机还需要⼀部分基础推力来抵消重,PID 算出的往往只是基础推之外的修正量。
这个区别后面讲自动驾驶时还会碰到:反馈控制量通常不是车辆最终执行的全部控制量。

 

 

深蓝AI

 

 

2
P、I、D 为什么都要存在?

PID 的连续形式为:

右侧三项最终都要落到同一种控制量上,才能相加。

 

P:偏得越远,纠正得越用力

比例项为:

无人机刚离开地面时,误差很大,P项会给出较强的向上修正;越接近目标,P项越“温柔”。说白了,当前差多少,就按一定比例纠正多少。

 增大后,系统通常会响应得更快,但控制动作也会更激进。真实系统存在惯性和延迟,控制器看到误差变小的时候,无人机可能还在继续向上运动。 过大,结果往往不是更快停在 10 m,而是超调甚至振荡。

但有些系统维持目标状态本身就需要额外控制量。假设持续向下的风需要增加 5 N 推力才能抵消,而 P 只有在存在高度误差时才会给出这 5 N。结果可能是无人机停在 9.8 m:0.2 m 的误差刚好换来抵消风力的推力,误差却不再继续缩小。这就是稳态误差。

 

I:小误差⼀直不消失,就继续累积补偿

积分项为:

I 项单看公式不太直观,继续看刚才那阵风。如果无人机长期停在 9.8 m,每个控制周期都有 0.2 m 的正误差。⼀次不大,但它连续存在 1s、2s、3s,积分值就会不断增加,直到补偿足以把无人机推回10m。

所以 I 不只是模糊地“记住过去”,它是在算⼀笔账:

这份没有被解决的误差,累计起来到底有多少?

当误差回到 0 时,P 项输出也会回到 0;I 项此前积累的控制量却可以保留下来,用于抵消持续风力。这正是积分能够消除稳态误差的原因。

积分也可能记得太多。例如电机已经达到最⼤推力,无人机仍然无法上升,误差就会持续存在。如果积分器还在累加,等外部限制消失后,过⼤的控制量会把无人机猛地推过目标。这就是积分饱和,也叫 windup。

⼯程里常用条件积分、积分限幅、积分分离和反计算等⽅法处理它。

注意:简单粗暴地给积分项限幅有时能用,但不等于所有 anti-windup 方法都只是“加⼀个限幅”。

 

D:误差还没归零,也可能已经该收力了

微分项为:
关心误差变化得有多快。无人机位于 9.5 m 时,如果它正在快速上升,高度误差会迅速减小。虽然误差仍为正,项已经在提醒控制器:该收力了。 
这和开车接近停线很像。只看距离,还不能决定踩多深的刹;同样距离下,⻋速越快,越需要提前减速。 经常有人说 D 可以预测未来。方便理解,但并不严格。没有预测后续状态,只是让控制器对当前的运动趋势更敏感。 
它的代价也很明显:微分会放大高频噪声。高度测量只是轻微抖动,相邻两个采样点做差后也可能得到很大的变化率。因此实际代码里常会给 D 加低通滤波,或者对测量值求微分,避免目标值突变带来的微分冲击。

如果误差仍定义为 ,并且目标值在这一小段时间内不变,那么:

因此,对测量值求微分时要带负号:

这两个式子只在目标值不变时等价。目标值突然变化时,对误差微分会产生很大的瞬时冲击;对测量值微分则可以避开这次设定值跳变。

 

 

深蓝AI

 

 

3
控制器不一定非得是完整 PID
PI不是三个必须同时打开的开关。
  • 简单直接;
  • PI 多了消除持续偏差的能力,在速度、转速、温度等控制中很常见;
  • PD 更关注运动趋势,常用于增加阻尼、减少超调;
  • 完整 PID 则要同时处理积分饱和、微分噪声和参数耦合。 
多⼀项不⼀定多⼀分效果。我更愿意把这些组合看成针对问题选工具,而不是控制器的等级排名。

 

 

深蓝AI

 

 

4
从公式到代码,中间还差什么?
教科书里只有一行公式,真实系统先会撞上器限幅、控制延迟和传感器噪声。
电机、油门和制动都不可能无限输出;从测量到执器真正动作也需要时间;项还会把测量抖动放大。参数调得再漂亮,这些问题没处理,车上仍然不好用。
反馈之外还需要前馈。既然规划已经告诉车辆接下来要加速,或者已经知道道路正在上坡,就没必要等速度掉下来 以后再靠 PID 补救。常见形式是:

前馈利用已知信息提前动作,反馈负责收拾模型不准、外部扰动和执行误差。

至于调参,我不太赞成只记“先 P、再 D、最后 I”这一类口诀。

它可以作为某些系统的起点,却不是通用流程。至少要先弄清输入输出、量纲、控制周期、执行器范围和评价指标,再决定观察什么曲线、增加哪一项。 否则参数调了半天,最后可能只是用 PID 在补偿错误的符号、延迟的信号,甚至一张不准确的标定表。

实际程序以控制周期  运行。用最直观的前向差分写法,PID 可以离散成:

这只是便于理解的一种写法。真实代码可能用梯形积分、带滤波的微分,还要对  和  做 anti-windup 与限幅。

 

 

深蓝AI

 

 

5
为什么自动驾驶纵向控制常用双环?
把无人机换成汽车以后,问题多了⼀层。规划模块给出的轨迹不只有速度,还包含车辆在某个时刻应该到达的位置。假设辆起步晚了1s,比规划位置落后10m。之后规划速度和实际速度都稳定在10 m/s
640 (3).webp
只看速度环,它会认为车辆已经跟上目标。但这 10 m 的位置差会⼀直保留下去。 
⼀种常见处理方式,是把位置环放在外层,把速度环放在内层。
640 (4).webp
2| 位置外环把位置误差转换成速度修正,速度内环再把速度误差转换成反馈加速度。图源:作者⾃制。©【深蓝 AI】编译

位置外环先计算纵向位置误差:

它的输出不是油门,而是速度修正量:

这里先用最简单的P位置环说明。更完整的实现也可以是PI、PID,或者带限幅和增益调度的控制器。车辆落后2 m时,如果外环比例增益取,便得到的速度修正:

注意:这里不是PID把“米”神奇地变成了“米每秒”,也不是对位置误差求了一次导数,而是控制器增益承担了量纲和时间尺度的映射。

速度修正量与规划参考速度相加,形成新的目标速度:

速度内环再计算目标速度与实际速度的误差:

经过速度控制器后得到反馈加速度:

这里同样先写成最简单的 P 形式。如果速度环采用 PI 或 PID,还要加上速度误差的积分项和微分项。在本文定义的“速度误差输入、加速度修正输出”下,比例增益  的单位为 ,因此可以把  的速度误差映射成  的加速度修正:

如果控制器直接输出油门、制动或归⼀化指令,增益的单位也会随输入、输出的定义一起改变。 
所以双环 PID 不是连续做了两次数学单位转换,而是在做分工: 
  • 位置外环判断车辆在道路进度上落后或超前多少; 
  • 速度内环负责让车辆尽快、稳定地跟上修正后的速度目标。 
内环通常需要比外环更快。如果外环不断修改速度目标,内环却迟迟跟不上,两个环就会互相拉扯。实际调试时也通常先把速度内环调稳,再打开位置外环。

 

 

深蓝AI

 

 

6
得到加速度以后,车辆就知道怎么踩油门了吗?
经过位置外环和速度内环,我们得到的是一个反馈加速度。但它还不是车辆最终执行的油门或制动指令。 
规划轨迹通常已经包含参考加速度,这部分信息可以作为前馈,让车辆在误差真正出现之前提前动作。道路坡度已知时,也可以增加相应的坡度补偿。于是,目标加速度可以简单写成:
反馈修正实际状态与规划目标之间的偏差,前馈利用规划信息提前加速或减速,坡度补偿则处理上下坡带来的持续影响。具体实现会变,但能提前做的别等误差出现,剩下的交给反馈是很常见的思路。 
得到目标加速度以后,系统仍要完成⼀次从“车辆应该产⽣多⼤加速度油门或制动应该给多少的转换。常见做法是根据当前⻋速和目标加速度查询车辆标定表,也可以结合车辆模型进行计算。 
整条链路可以简化为:
640 (5).webp
这也是 PID 最容易被讲简单、又最容易在工程里变复杂的地方。
算出加速度,不等于车辆已经知道油门该踩多少。 同⼀个目标加速度,在不同车速、坡度、载荷甚至电量下,可能对应完全不同的执行器指令。

 

 

深蓝AI

 

 

7
写在最后
PID 的公式不难,难的是把它放回真实系统。
  • 车辆上坡起步出现后溜,究竟是坡度补偿不足、制动释放过早,还是驱动建立得太慢?

  • 低速跟车出现顿挫,是速度环参数太激进、标定表不连续,还是油门与制动切换逻辑有问题?

  • 无人机在阵风中高度抖振,是 D 项放大了传感器噪声、D 项加的低通滤波不够,还是前馈没有及时补偿风速变化?

真正有用的不是背下三个公式,而是看到一个控制现象后,知道沿着哪条信号继续往下找。这也决定了一个系统只是"能动",还是足够平顺、稳定。

PID告诉我们的核心道理是:不建模,也能控。但问题随之而来——如果手里有了系统的模型,能不能控得更好、更省力?

参考资料
1. Nicolas Minorsky, Directional Stability of Automatically Steered Bodieshttps://doi.org/10.1111/j.1559-358 4.1922.tb04958.x
2. MathWorks, PID Control Overview: https://www.mathworks.com/discovery/pid-control.html
3. MathWorks, Improve PID Controller to Handle Plant Constraints: https://www.mathworks.com/help/slc ontrol/ug/improve-pid-to-handle-plant-constraints.html

【深蓝学院】技术交流群

?致力于帮助各位朋友「打破隐形的墙」,共建一个更自由、更有深度、更有价值的交流生态社区!在各大企业工作的,可以相互内推,互通有无;在学校读研读博的,可以交流想法,携手合作。

扫码添加阿蓝,选择想要加入的交流群即可

(按照提交顺序邀请,请尽早选择)

?

image.png