PID算法(1) PID算法的原理推导1

一、 PID的基本框图

PID 控制器以各种形式使用超过了 1 世纪,广泛应用在机械设备、气动设备 和电子设备.在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法

开环:输入量对输出量没有反馈作用;
闭环:输入量对输出量有反馈作用。
下面是一个闭环系统
在这里插入图片描述

二、 基本案例说明

在这里插入图片描述

目标值:回到家→即为距离家距离为0m
测量值:当前离家的距离,为10m
偏差:=目标值-测量值(0-10)m

比例:就是直接给偏差乘以一个比例系数
积分:就是在一段时间内偏差的累积
微分:偏差的变化率,反馈当前的变化速率的控制

三、 理论公式

教科书上面的公式
u t = K p [ e t + 1 T i ∫ 0 t e t d t + T d d e t d t ] (1) u_t = K_p[e_t + \frac{1}{T_i}\int_0^te_tdt + \frac{T_dde_t}{dt}]\tag{1} ut=Kp[et+Ti10tetdt+dtTddet](1)

u t u_t ut      : 输入
K P K_P KP     : 比例系数
T i T_i Ti       : 积分时间常数
T d T_d Td       : 微分时间常数
e t e_t et        : 误差
d t dt dt       : 采样周期
d e t de_t det      : 误差的变化斜率
∫ o t \int_o^t ot       : 误差的累计

因为 K p K_p Kp , T i T_i Ti , T d T_d Td是需调节的参数,整理一下得到以下方程!这样方便调节参数

u t = K p e t + K i ∫ 0 t e t d t + K d d e t d t (2) u_t= K_pe_t + K_i\int_0^te_tdt + Kd \frac{de_t}{dt}\tag{2} ut=Kpet+Ki0tetdt+Kddtdet(2)
u k = P × 偏差 + I × 偏差 + D × 偏差 (3) u_k = P \times 偏差 + I\times 偏差 + D\times 偏差\tag{3} uk=P×偏差+I×偏差+D×偏差(3)
K P K_P KP           比例系数
K i = K p 1 T i K_i = K_p \frac{1}{T_i} Ki=KpTi1          积分系数
K d = K p K d K_d = K_p K_d Kd=KpKd        微分系数

四、 P(比例)、I(积分)、D(微分)的详细理解

4.1 比例项的理解(P)

传感器获取的数值为 x 1 , x 2 , x 3 ⋯ x t x_1,x_2,x_3\dotsb x_t x1,x2,x3xt
设定值为 s t s_t st
把采样值和用户设置值之间的差值设为 e t e_t et,称之为误差
e t = s t − x t e_t = s_t-x_t et=stxt
在这里插入图片描述
在这里插入图片描述

绿色线为上述例子中从初始位置到目标位置的距离变化; 红色线为上述例子中从初始位置到目标位置的偏差变化,两者为互补的关系;

  • 分析 e t e_t et可以得到一下三个信息
    • e t > 0 e_t > 0 et>0 :说明当前状态值未达标
    • e t = 0 e_t = 0 et=0 :说明当前控制状态值正好满足要求
    • e t < 0 e_t < 0 et<0 :说明当前状态值已经超标

可以得出一个结论: e t e_t et反应了控制对象当前值与设定值的偏差程度,添加一个比例系数 k p k_p kp ,可以根据 e t e_t et 的大小对输出信号 P o u t Pout Pout 进行调整,偏差程度大OUT增大,偏差程度小OUT减小。即输出信号的强弱与当前偏差程度的大小成比例,所以根据 e t e_t et 的大小来给出控制信号 P o u t Pout Pout 的当前值的算法称为比例控制(Proportion)。用数学模型可以表示为:
P o u t = K p e t (4) Pout = K_pe_t\tag{4} Pout=Kpet(4)

4.2 积分项的理解(I)

过去一段时间的误差和设为 S t S_t St

S t = e 1 + e 2 + e 3 + ⋯ + e t S_t = e_1+e_2+e_3+\dotsb +e_t St=e1+e2+e3++et
在这里插入图片描述

![

红色曲线阴影部分面积即为积分作用的结果,其不断累积的误差.

  • 分析 S t S_t St

    • S t > 0 St>0 St>0:过去大多数时候未达标
    • S t = 0 St=0 St=0:过去控制效果较理想
    • S t < 0 St<0 St<0:过去大多数时候已经超标
  • 可以得出两个结论:
     

    • S t S_t St是对过去的控制效果进行评估,体现了控制算法按照原来的方式输出的控制信号导致了现在的控制结果,所以应该利用这个值来对当前要输出的控制信号OUT进行修正,以确保控制对象会在将来的一小段时间尽快达到用户设定的值。
       
    • S t S_t St实际上是过去每个时间点的误差相加,与数学上的定积分运算类似,因此根据 S t S_t St 对输出信号进行调节的算法称积分(integral)算法。添加一个比例系数 K i K_i Ki,所以积分控制的数学模型为:
      I o u t = K i S t \begin{align*} Iout = &K_iS_t \end{align*} Iout=KiSt

S t 的连续表达式为 ∫ 0 t e t d t S_t的连续表达式为 \int_0^te_tdt St的连续表达式为0tetdt, ( K i = K p 1 T i K_i = K_p\frac{1}{T_i} Ki=KpTi1) 转换一下公式得到:

I o u t = K p 1 T i ∫ 0 t e t d t (5) Iout = K_p\frac{1}{T_i}\int_0^te_tdt\tag{5} Iout=KpTi10tetdt(5)
这里解释下为什么会有 K p , T i K_p,T_i Kp,Ti为什么会在分母上面, T i T_i Ti 代表什么

  • 为什么会有 K p K_p Kp
    K p K_p Kp 的存在确保了对于每个部分都有适当的权重,而不仅仅侧重于比例项或其他项。这使得调节 K p K_p Kp可以直接影响整个系统的性能,

  所以为什么这就是比例项为什么必须要的原因

  • 为什么 T i T_i Ti会在分母上?

    • T i T_i Ti为积分时间常数,他的取值范围是>1,不可能是[0,1],就比如说"前面 2.3次数据",没有这样的说法。
    • K p 1 T i K_p\frac{1}{T_i} KpTi1代表的是积分强度
      • 越大:增大积分项的影响强度
      • 越小:减小积分项的影响强度
    • 直接使用 T i T_i Ti作为积分增益可能导致增益过大,引发系统的稳定性问题。通过使用 1 T i \frac{1}{T_i} Ti1形式,可以更灵活地调整增益的大小而避免潜在的过度响应或不稳定性。
       
    • T i T_i Ti 放在分母上是为了方便理解和调整 PID 控制器的参数,以实现更好的控制性能。这种选择在工程实践中更为常见,但在特定情况下,根据实际需求和设计者的偏好,也可以选择将 T i T_i Ti 放在分子上
  • T i T_i Ti 代表什么?

    • T i T_i Ti 代表控制积分时间常数,用于控制积分项的响应速度,影响着积分项对系统误差的累积速度。

    • 通俗理解:就是你不可能把开机以来的误差都作为分析,这样没有意义,要选取一个时间段来分析。

    4.3 微分项的理解(D)

    误差的微分就是误差的变化速率,误差变化越快,其微分绝对值越大。误差增大时,其微分为正;误差减小时,其微分为负。控制器输出量的微分部分与误差的微分成正比,反映了被控量变化的趋势。
     

  • 设两次连续的误差设为 D t D_t Dt
    D t = e t − e t − 1 D_t = e_t - e_{t-1} Dt=etet1
    在这里插入图片描述

    从图中可知,当偏差变化过快,微分环节会输出较大的负数,作为抑制输出继续上升,从而抑制过冲。
     

  • 分析 D t D_t Dt

    • D t > 0 D_t>0 Dt>0:说明从上一采样时刻到当前误差有增大趋势
    • D t = 0 D_t=0 Dt=0:说明从上一采样时刻到当前误差平稳
    • D t < 0 D_t<0 Dt<0:说明从上一采样时刻到当前误差有减小趋势
       
  • 可以得出两个结论:

    • D t D_t Dt 能够说明从上次采样到当前采样的这段时间被控制对象的状态变化趋势,这种变化的趋势很可能会在一定程度上延续到下一个采样时间点,所以可以根据这个变化趋势( D t D_t Dt 的值)对输出信号 D o u t Dout Dout 进行调整,达到提前控制的目的。
    • D t D_t Dt 形如数学上的微分运算,反应了控制对象在一段时间内的变化趋势及变化量,所以利用Dt对控制器输出信号进行调节的算法称为微分(differential)算法。可以用数学模型表达为
      D o u t = K d D t Dout = K_dD_t Dout=KdDt

D t D_t Dt的连续表达式为 K d d e t d t K_d\frac{de_t}{dt} Kddtdet, ( K d = K p T d K_d = K_pT_d Kd=KpTd) 转换一下公式得到:
D o u t = K p T d d e t d t (6) Dout = K_pT_d\frac{de_t}{dt}\tag{6} Dout=KpTddtdet(6)
这里解释一下 T d , K p T_d,K_p Td,Kp

  • 为什么会有 K p K_p Kp?
    和积分项为什么会有 K p K_p Kp是一样的。
  • T d T_d Td 代表什么?
    T d T_d Td 是一个微分项,用于控制微分项的响应速度。影响着微分项对系统误差变化率的响应,较小的 T d T_d Td 表示微分项对误差变化率的响应较快,系统对误差的变化更为敏感。较大的 T d T_d Td 表示微分项对误差变化率的响应较慢,系统对误差变化的敏感性相对减弱。

五、公式推导

PID的输出需要把比例、积分、微分的输出加起来。

P I D o u t = P o u t + I o u t + D o u t PIDout = Pout+Iout+Dout PIDout=Pout+Iout+Dout

  • P I D o u t PIDout PIDout 设为 u t u_t ut ( 4 ) , ( 5 ) , ( 6 ) (4),(5),(6) (4),(5),(6)代入得:
    u t = K p ( e t + 1 T i ∫ 0 t e t d t + T d d e t d t ) u_t = K_p(e_t+ \frac{1}{T_i}\int_0^te_tdt + T_d\frac{de_t}{dt}) ut=Kp(et+Ti10tetdt+Tddtdet)

回来看 ( 2 ) , ( 3 ) (2),(3) (2),(3)公式就能理解了。这里都是连续的表达式,我们要转成离散的表达式,离散的方式方便代码的实现。
 

  • 公式 ( 2 ) (2) (2) 连续 ⟶ \longrightarrow 离散
    u k = K p e k + K i ∑ k = 1 k e k Δ t + K d e k − e k − 1 Δ t u_k = K_pe_k+K_i\sum_{k = 1}^k{e_k}\Delta{t} + K_d\frac{e_k - e_{k-1}}{\Delta{t}} uk=Kpek+Kik=1kekΔt+KdΔtekek1
  • 如果我们的采样时间是固定的话, K i Δ t , K d 1 Δ t K_i \Delta{t},K_d \frac{1}{\Delta{t}} KiΔt,KdΔt1可以整合在一起,可以整合成以下公式
    u k = P e k + I ∑ k = 1 k e k + D ( e k − e k − 1 ) u_k = Pe_k+I\sum_{k = 1}^k{e_k} + D(e_k - e_{k-1}) uk=Pek+Ik=1kek+D(ekek1)
    注意!我们后续都是基于这个公式作为分析
    这个章节主要是讲PID的算法原理,下一章节讲PID的应用

文章是自己总结而记录,有些知识点没说明白的,请各位看官多多提意见,多多交流,欢迎大家留言

如果技术交流可以加以下群,方便沟通

  • 23
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
### 回答1: PID算法是一种常用的控制算法,用于实现系统的稳定控制。它采用比例(P)、积分(I)和微分(D)三个部分来调节控制器的输出。下面我来对PID算法的资料进行汇总,并附上一个简单的PID控制器实例源代码。 首先,PID算法的资料可以分为理论资料和应用实例。理论资料主要包括PID算法原理、公式推导、参数调整方法等内容,可以从控制理论书籍、学术论文和网络资源中获取。应用实例则是指针对不同系统的PID控制器的具体应用案例和实现代码,可以从控制工程实践书籍、控制论坛和开源项目中找到。 对于PID算法实例源代码,这里给出一个简单的示例供参考: ```python # PID控制器实例代码 class PIDController: def __init__(self, Kp, Ki, Kd): self.Kp = Kp self.Ki = Ki self.Kd = Kd self.previous_error = 0 self.integral = 0 def control(self, setpoint, process_variable): error = setpoint - process_variable self.integral += error derivative = error - self.previous_error output = self.Kp * error + self.Ki * self.integral + self.Kd * derivative self.previous_error = error return output # 使用PID控制器进行控制 pid_controller = PIDController(Kp=1.0, Ki=0.5, Kd=0.2) setpoint = 50.0 # 设定值 process_variable = 0.0 # 过程变量 for _ in range(100): control_signal = pid_controller.control(setpoint, process_variable) process_variable += control_signal print(process_variable) ``` 这段代码定义了一个PID控制器类,包括构造方法和控制方法。在示例中,我们设定了一个目标值setpoint和初始过程变量process_variable,然后循环执行控制方法,计算得到控制信号并更新过程变量,最终输出结果。 综上所述,PID算法的资料汇总包括理论资料和应用实例。PID控制器实例源代码可以根据具体需求进行调整和优化,提高系统的控制性能。 ### 回答2: pid算法是一种操作系统中用于进程调度的算法。其全称为进程标识符(Process Identifier)算法,通过给每个进程分配一个唯一的标识符来管理和调度进程,以保证操作系统能够正确地管理和运行多个进程。 pid算法的基本原理是在每个进程创建时,为其分配一个唯一的进程标识符。这个标识符是一个非负整数,通常从0开始递增分配。当一个进程终止时,其进程标识符将被回收,可以用于分配给新创建的进程。这样,通过唯一的进程标识符,操作系统可以针对不同的进程进行管理和调度。 pid算法的实现通常包括两个主要步骤:进程创建和进程终止。进程创建时,操作系统会分配一个可用的标识符给新进程,并为其分配资源。进程终止时,操作系统会回收进程所占用的资源,并将其进程标识符标记为可用状态,以供下次分配给新进程使用。 下面是一个简单的pid算法的实例源代码: ```c++ #include <iostream> #include <vector> class Process { public: Process(int id) : pid(id) {} int getPID() const { return pid; } private: int pid; }; class PIDManager { public: int allocate() { int pid = getNextAvailablePID(); if(pid != -1) { pids[pid] = true; return pid; } return -1; // 如果没有可用的pid } void deallocate(int pid) { if(pid >= 0 && pid < pids.size()) { pids[pid] = false; } // 释放资源等操作 } private: int getNextAvailablePID() { for(int i = 0; i < pids.size(); ++i) { if(!pids[i]) { return i; } } return -1; } std::vector<bool> pids = std::vector<bool>(1000, false); // 假设操作系统最多支持1000个进程 }; int main() { PIDManager manager; int pid1 = manager.allocate(); int pid2 = manager.allocate(); std::cout << "PID1: " << pid1 << std::endl; std::cout << "PID2: " << pid2 << std::endl; manager.deallocate(pid1); manager.deallocate(pid2); return 0; } ``` 这段示例代码演示了一个简单的pid算法的实现。PIDManager类负责管理pid的分配和回收,allocate函数尝试分配一个可用的pid,deallocate函数用于回收不再使用的pid。在主函数中,我们可以看到该算法的使用流程。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

^Lim

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值