什么是PID/PID算法
什么是PID?
一、PID的基本概念
PID控制算法通过计算误差(即系统输出与期望值之间的差值),并基于该误差进行比例、积分和微分运算,来调整系统的控制输入,以实现快速、准确的控制。PID控制因其结构简单、稳定性好、工作可靠、调整方便等特点,成为工业控制中的主要技术之一。
详情了解视频pid控制算法讲解
二、PID的三个组成部分及其作用
比例控制器(P):
作用:根据控制误差的大小,以比例放大的方式对反馈信号进行修正。比例常数(Kp)决定了修正的幅度。当误差增大时,修正幅度也会增大,有助于加快系统的响应速度并抑制系统震荡。
特点:比例控制提供了快速的响应能力,但单独使用时可能无法完全消除稳态误差。
积分控制器(I):
作用:根据控制误差的积分(即误差的累积值),以增量放大的方式对反馈信号进行修正。积分项可以消除稳态误差,使系统的响应更为平滑。积分常数(Ki)决定了修正的速度。
特点:积分控制有助于减小系统的稳态误差,但在系统存在较大波动时可能导致积分饱和,影响系统的稳定性。
微分控制器(D):
作用:根据控制误差的变化率(即误差的变化速度),以微分放大的方式对反馈信号进行修正。微分项可以预测误差的变化趋势,从而提前采取控制措施,抑制系统的超调和振荡。微分常数(Kd)决定了修正的灵敏度。
特点:微分控制具有预见性,能够提前调整控制输入以应对误差的变化,提高系统的稳定性和响应速度。
三、PID的应用领域
PID控制算法因其广泛的适用性和良好的控制效果,被广泛应用于工业自动化、机器人控制、飞行器导航、医疗设备、汽车电子、家用电器等多个领域。在这些领域中,PID控制用于调节温度、压力、速度、位置等物理量,以实现精确的控制目标。
四、PID参数的调整与优化
PID参数的调整是控制工程中的一个重要问题。传统的方法是通过试错法和经验进行参数调整,但这种方法往往效率较低。近年来,随着优化算法和自适应控制方法的发展,人们开始将这些方法应用于PID控制器的设计中,以实现更快、更准确的参数调节和控制系统性能的优化。
综上所述,PID是一种基于比例、积分和微分运算的反馈控制算法,通过综合调整比例、积分和微分控制器的输出,实现对系统的精确控制。它在工业控制和其他多个领域中发挥着重要作用。
常见的PID的算法及代码示例
PID(比例-积分-微分)算法是控制系统中常用的一种反馈控制算法,它通过计算误差的比例、积分和微分来调整控制输入,以达到预定的控制目标。以下是一些常见的PID算法及代码示例:
一、常见的PID算法
位置式PID算法
位置式PID算法直接计算控制量的绝对值,每次输出都与过去的状态有关,因此计算量相对较大。其计算公式为:u(k)=Kpe(k)+Ki∑j=0ke(j)+Kd[e(k)−e(k−1)]
其中,u(k) 是第 k 次的控制量,e(k) 是第 k 次的误差,Kp、Ki、Kd 分别是比例、积分、微分系数。
增量式PID算法
增量式PID算法只计算控制量的增量,即本次控制量与上一次控制量之差,因此计算量相对较小,且更易于实现无扰动切换。其计算公式为:Δu(k)=Kp[e(k)−e(k−1)]+Kie(k)+Kd[e(k)−2e(k−1)+e(k−2)]
实际应用中,控制量 u(k) 可通过累加增量 Δu(k) 来获得。
二、代码示例
pid.c
#include "stm32f10x.h"
#include <math.h>
#include "sys.h"
#include "pid.h"
#define PID_LIMIT_MIN -10000 //PID输出最低值
#define PID_LIMIT_MAX 10000 //PID输出最大值
//注意:PID结构体必须定义为全局变量或静态变量,然后在函数中给KP,KI,KD赋值
/************************采样周期未知且不变************************************/
//位置式PID
//pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]
//setvalue : 设置值(期望值)
//actualvalue: 实际值
//由于全量输出,每次输出均与过去状态有关,计算时要对ek累加,计算量大
float PID_location(float setvalue, float actualvalue, PID_LocTypeDef *PID)
{
PID->ek =setvalue-actualvalue;
PID->location_sum += PID->ek; //计算累计误差值
if((PID->ki!=0)&&(PID->location_sum>(PID_LIMIT_MAX/PID->ki))) PID->location_sum=PID_LIMIT_MAX/PID->ki;
if((PID->ki!=0)&&(PID->location_sum<(PID_LIMIT_MIN/PID->ki))) PID->location_sum=PID_LIMIT_MIN/PID->ki;//积分限幅
PID->out=PID->kp*PID->ek+(PID->ki*PID->location_sum)+PID->kd*(PID->ek-PID->ek1);
PID->ek1 = PID->ek;
if(PID->out<PID_LIMIT_MIN) PID->out=PID_LIMIT_MIN;
if(PID->out>PID_LIMIT_MAX) PID->out=PID_LIMIT_MAX;//PID->out限幅
return PID->out;
}
//增量式PID
//pidout+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
//setvalue : 设置值(期望值)
//actualvalue: 实际值
float PID_increment(float setvalue, float actualvalue, PID_LocTypeDef *PID)
{
PID->ek =setvalue-actualvalue;
PID->out+=PID->kp*(PID->ek-PID->ek1)+PID->ki*PID->ek+PID->kd*(PID->ek-2*PID->ek1+PID->ek2);
// PID->out+=PID->kp*PID->ek-PID->ki*PID->ek1+PID->kd*PID->ek2;
PID->ek2 = PID->ek1;
PID->ek1 = PID->ek;
if(PID->out<PID_LIMIT_MIN) PID->out=PID_LIMIT_MIN;
if(PID->out>PID_LIMIT_MAX) PID->out=PID_LIMIT_MAX;//限幅
return PID->out;
}
pid.h
#ifndef __PID_H
#define __PID_H
#include "stm32f10x.h"
#include <math.h>
#include "sys.h"
typedef struct
{
float kp; //比例系数Proportional
float ki; //积分系数Integral
float kd; //微分系数Derivative
// float ti; //积分时间常数
// float td; //微分时间常数
// float period; //采样周期
float ek; //当前误差
float ek1; //前一次误差e(k-1)
float ek2; //再前一次误差e(k-2)
float location_sum; //累计积分位置
float out; //PID输出值
}PID_LocTypeDef;
float PID_location(float setvalue, float actualvalue, PID_LocTypeDef *PID);
float PID_increment(float setvalue, float actualvalue, PID_LocTypeDef *PID);
#endif
注意:上述代码,在实际应用中,可能需要使用操作系统的定时器或中断来实现。