控制系统——PID相关

PID相关笔记


PID相关参考


位置式PID

  • 位置式PID在 \(k\) 时刻的直接输出控制量 \( u(k) \),其离散形式为:
    $$
    u(k) = K_p \color{blue}{e(k)} + K_i \color{blue}{\sum_{j=0}^{k} e(j)} + K_d \color{blue}{\left[ e(k) - e(k-1) \right]}
    $$
  • 其中:
    • \( K_p, K_i, K_d \) 分别为比例、积分、微分系数;
    • \( e(k) \) 为当前时刻误差;
    • \( \sum_{j=0}^{k} e(j) \) 为历史误差累加(积分项)
  • 进阶:
    • \( K_i = K_p \frac{T}{T_i} \):积分系数(\( T_i \)为积分时间常数,\( T \)为采样时间)
    • \( K_d = K_p \frac{T_d}{T} \):微分系数(\( T_d \)为微分时间常数)

增量式PID

  • 增量式PID输出控制量的增量
    $$ \Delta u(k) = u(k) - u(k-1) $$
  • 类似位置式PID增量式PID在 \(k\) 时刻的 \(u(k)\) 可定义为如下:
    $$
    \begin{align}
    u(k) &= u(k-1) + \color{red}{\Delta u(k)} \\
    u(k) &= u(k-1) + (K_p + K_i + K_d) \color{red}{e(k)} - (K_p + 2K_d) \color{red}{e(k-1)} + K_d \color{red}{e(k-2)} \\
    u(k) &= u(k-1) + A \color{red}{e(k)} + B \color{red}{e(k-1)} + C \color{red}{e(k-2)}
    \end{align}
    $$
  • 注:一般提到增量式PID ,我们一般认为输出是 控制量的增量 \(\Delta u(k)\)

位置式PID到增量式PID的推导

  • 位置式PID增量式PID完全等价,只是形式不同,通过对位置式PID一阶差分 ,即可得到增量式PID
  • 位置式在 \( k-1 \) 时刻的输出 \( u(k-1) \) 为:
    $$
    u(k-1) = K_p e(k-1) + K_i \sum_{j=0}^{k-1} e(j) + K_d \left[ e(k-1) - e(k-2) \right]
    $$
  • 将 \( u(k) \) 和 \( u(k-1) \) 相减等到增量 \( \Delta u(k) = u(k) - u(k-1) \):
    $$
    \Delta u(k) = K_p \left[ e(k) - e(k-1) \right] + K_i e(k) + K_d \left[ e(k) - 2e(k-1) + e(k-2) \right]
    $$
  • 整理后得到增量式PID公式:
    $$
    \Delta u(k) = (K_p + K_i + K_d) e(k) - (K_p + 2K_d) e(k-1) + K_d e(k-2)
    $$

增量式PID到位置式PID的推导

  • 已知增量式PID的参数为A、B、C,其增量输出公式为:
    $$\Delta u(k) = A \color{red}{e(k)} + B \color{red}{e(k-1)} + C \color{red}{e(k-2)}$$
  • 通过对比位置式PID的差分形式,可以推导出位置式PID参数(Kp、Ki、Kd)与增量式参数的关系如下:
  • 位置式PID的输出为:
    $$u(k) = K_p \color{blue}{e(k)} + K_i \color{blue}{\sum_{j=0}^{k} e(j)} + K_d \color{blue}{\left[ e(k) - e(k-1) \right]}$$
  • 增量式PID的输出是位置式的差分:
    $$\Delta u(k) = u(k) - u(k-1).$$
    • 将位置式公式代入差分表达式并整理,得到:
      $$\Delta u(k) = \left(K_p + K_i + K_d\right)e(k) + \left(-K_p - 2K_d\right)e(k-1) + K_d e(k-2).$$
  • 对比系数 ,得到方程组:
    $$
    \begin{align}
    A &= K_p + K_i + K_d,\\
    B &= -K_p - 2K_d,\\
    C &= K_d
    \end{align}
    $$
  • 解方程组位置式PID的参数为:
    $$
    \begin{align}
    \color{red}{K_p} &= -B - 2C,\\
    \color{red}{K_i} &= A + B + C,\\
    \color{red}{K_d} &= C
    \end{align}
    $$

增量式PID和位置式PID简单对比

特性 位置式PID 增量式PID
输出形式 绝对控制量(如阀门开度) 控制增量(如步进脉冲)
积分处理 显式累加误差,易饱和 隐式累加,天然抗饱和
计算复杂度 需存储所有误差,计算量大 仅需最近几次误差,计算量小
等效性 通过差分可转化为增量式 通过累加可转化为位置式

附录:现实场景中的一些trick

常用形式一:使用了 \( \lambda(k-1) \)的位置式PID

  • 适用场景:在一些场景中,控制变量 \( \lambda \) 需要平滑调整 ,而非完全重新计算(比如oCPX出价中)
  • 常用位置式PID来输出某个变量的增量(直接计算全量 \( \lambda(k) \) 可能导致相邻时间片的出价跳跃,而基于前一时刻的 \( \lambda(k-1) \) 进行增量调整,可以保证控制量的连续性),工程师可能会将位置式PID改写为以下形式:
    $$
    \begin{align}
    \lambda(k) &= \lambda(k-1) + \color{red}{\Delta \lambda(k)} \\
    \lambda(k) &= \lambda(k-1) + \color{red}{u(k)} \\
    \lambda(k) &= \lambda(k-1) + \color{red}{\left[ K_p e(k) + K_i \sum e(k) + K_d (e(k)-e(k-1)) \right]} \\
    \end{align}
    $$
    • 理解:这是一个位置式PID ,其中 \(\lambda\) 与PID无关,属于被控对象的一部分,其中PID输出为该变量的增量:
      $$ u(k) = \color{red}{\Delta \lambda(k)} = \color{red}{\left[ K_p e(k) + K_i \sum e(k) + K_d (e(k)-e(k-1)) \right]} $$
    • 问题:当 \(e(t)\) 为0时,由于积分项的存在,\(\color{red}{\Delta \lambda(k)}\) 可能不为0,\(u(k)\) 还会持续变化,这个是否符合预期?这个问题的简单理解如下:
      • 对于系统需要 \(u(k)\) 持续增加的场景,比如系统是一个压力越来越大的弹簧,\(u(k)\) 是施加的反向力,需要逐步增大,则这种情况天然适配这种设计,持续增加的 \(u(k)\) 能与系统逐步增加的压力抵消,保持稳态
      • 对于系统不需要 \(u(k)\) 持续增加的场景,假设 \(\color{red}{\Delta \lambda(k)} > 0\),则 \(u(k)\) 会继续增大,超调以后,积分项会逐步减少,同时 \(e(t) \neq 0\),也会开始减小 \(\color{red}{\Delta \lambda(k)} \),逐步地,\(\color{red}{\Delta \lambda(k)} = 0\),然后逐步变成负值,直到 \(e(t)\) 再次为0时,此时的积分项比上一轮更小了,\(\color{red}{\Delta \lambda(k)}\) 也更小了,甚至为负,也就是说,对于积分项逐步地应该也会收敛到0
  • 注:由于\(\lambda(k-1)\)中其实包含了累计误差的信息,可以进一步不考虑积分项(微分项一般不用考虑,这里顺便消除了),甚至可以简化为下面的公式形式:
    $$\lambda(k) = \lambda(k-1) + \color{blue}{K_p} \color{red}{e(k)}$$
    • 这种形式的优点:一定程度上,\(\lambda(k-1)\)中其实包含了累计误差的信息,可以在不包含 \(K_i\)的情况下实现类似积分项效果,存储和更新 \( \lambda(k-1) \) 比维护全局积分项 \( \sum e(k) \) 更简单(后者需持久化历史状态)
    • 此时也可以用增量式PID来理解这种公式,本文下面会聊到增量式PID下这种形式的含义

附录:增量式PID的实际使用简化

  • 增量式PID可能简化为只保留 \(e_t\) 相关的项,即:
    $$u(k) = u(k-1) + \color{blue}{A} \color{red}{e(k)}$$
  • 对照增量式PID的公式:
    $$
    \begin{align}
    u(k) &= u(k-1) + \color{red}{\Delta u(k)} \\
    u(k) &= u(k-1) + (K_p + K_i + K_d) \color{red}{e(k)} - (K_p + 2K_d) \color{red}{e(k-1)} + K_d \color{red}{e(k-2)} \\
    u(k) &= u(k-1) + A \color{red}{e(k)} + B \color{red}{e(k-1)} + C \color{red}{e(k-2)}
    \end{align}
    $$
  • 可以看出此时相当于没有 \(C = K_d = 0\),结合 \(B = - (K_p + 2K_d) = 0\),进一步有 \(K_p = 0\),最终可得:
    $$ \color{blue}{A} = K_i $$
  • 也就是说,此时相当于只包含 \(K_i\) 项的位置式PID
    • 进一步理解:其实只包含 \(K_i\) 项位置式PID ,本质上可以等价于包含 \(K_i,K_p\) 项位置式PID(但需要 \(K_i,K_p\) 系数服从某种关系)

附录:oCPX下PID的理想设计方式

  • oCPX的真正目标oCPX的最终目标是保整个投放周期内的ROI满足约束
  • 应该如何设计误差项 \(e(t)\)?
    • 如果 \(e(t)\) 表示时间片 \(t\) 的达成情况 ,则其值是根据时间片 \(t\) 内的消耗和收入计算出来的,则以真正满足全天ROI达成;此外,实际场景中,单个时间片数据可能会非常稀疏 ,特别是oCPX的场景计算ROI需要用到订单数据,中小广告主的订单数据往往是非常稀疏的
      • 存在稀疏的情况。解决思路:一个思路改进是可以考虑用预估值去代替真实值,从而缓解稀疏问题
      • 难以达成全站ROI目标。解决思路:在原有PID基础上,引入累计偏差补偿项 \(\gamma \cdot \text{Global}_\text{Error}\),确保全天ROI收敛
    • 如果 \(e(t)\) 表示截止到时间片 \(t\) 的达成情况 ,值是根据投放周期开始到 \(t\) 时间片的消耗和收入计算出来的,则 \(e(t)\) 直接表达了截止到时间片 \(t\) 的ROI达成情况,这种设计下 \(e(t)=0\) 时说明全天刚好达成
      • 可以缓解稀疏问题
      • 更贴近oCPX产品的目标
    • 结论:
      • 订单稠密的场景可以考虑使用时间片 \(t\) 的达成情况 ,再增加引入累计偏差补偿项 \(\gamma \cdot \text{Global}_\text{Error}\),确保全天ROI收敛
      • 订单稀疏的场景使用截止到时间片 \(t\) 的达成情况 ,可以缓解稀疏问题
  • 对于无法获取分时间特征(无法计算位置式PID的积分项),且无法存储上一时间片的PID输出(无法用增量式PID)的情况,如何设计PID?
    • 一个思路是使用截止到时间片 \(t\) 的达成情况 ,且仅使用 \(K_p\) 参数,这样至少目标是达成全天的ROI目标,这种方法可能导致商家存在稳态误差(因为没有积分项)
  • 其他优化点:
    • 可以对 \(e(t)\) 做一个量纲映射,比如除以目标ROI以保证误差在指定范围内(特别是对于保CPS的场景,不同商家的CPS甚至不在统一量纲,想用相同的 \(K_p,K_i,K_d\) 参数来控制所有商家是困难的):
      $$ e(t) = \frac{真实ROI-目标ROI}{\color{red}{目标ROI}}$$
    • 初期数据量较少时不要调控,因为数据还不够准确,初期就开始调控可能导致商家初期出价波动较大
    • 可以统计过去一天或多天的PID输出作为下一天的初始出价 K 值,使得PID更容易达成,也让商家初期的消耗更符合ROI目标

附录:PID的其他优化

积分限幅

  • 现象:当因为不可抗力影响系统时,误差积分会一直增加,为了防止不可抗力消失的瞬间出现问题,可以给误差积分增加一个限制幅度(最大值)
  • 举例:无人机中这个现象可以看做一段时间内是有人压着无人机不许升高;在智能算力场景可以看做是非高峰期间,无论PID如何调整,TP999都到不了目标值
  • 解法:对误差积分项加一个上限,称为“积分限幅”

积分分离

  • 现象:目标有修改时,误差会突然增加,短时间内误差非常大,容易出现超调
  • 解法:对误差做一个条件判断,如果瞬间出现较大误差(比如超过一个阈值),可以让KI项的系数为0(注意不是清空KI项),只使用Kp项来调节;直到误差重新回到阈值以下,KI再生效

Kp上调下调差异化

  • 在一些场景上,如果对超成本和欠成本有倾向,可以通过设置上调和下调不同Kp来实现,比如,对于厌恶超成本的场景,可以适当增大下调系数,提升上调系数