位置式PID与增量式PID

位置式PID与增量式PID

位置式与增量式PID

位置式PID与增量式PID的介绍和代码实现

增量式pid和位置式pid

增量式pid和位置式pid相比各有什么优缺点?

*PID*调参的实用方法和经验有哪些?

在设计PID控制器时,什么时候用增量式PID,什么时候用位置式PID

位置式PID

  • 因为有误差积分 ∑e(i),一直累加,也就是当前的输出u(k)与过去的所有状态都有关系,用到了误差的累加值
  • 输出的u(k)对应执行机构的实际位置,一旦控制输出出错(控制对象的当前的状态值出现问题 ),u(k)的大幅变化会引起系统的大幅变化
  • 位置式PID在积分项达到饱和时,误差仍然会在积分作用下继续累积,一旦误差开始反向变化,系统需要一定时间从饱和区退出,所以在u(k)达到最大和最小时,要停止积分作用,并且要有积分限幅和输出限幅
  • 当输出限幅的时候,积分累加部分也应同时进行限幅,以防输出不变而积分项继续累加,也即所谓的积分饱和过深
  • 在使用位置式PID时,一般我们直接使用PD控制
  • 位置式 PID 适用于执行机构不带积分部件的对象,如舵机和平衡小车的直立和温控系统的控制
  • 位置式PID是一种非递推式算法,可直接控制执行机构(如平衡小车),u(k)的值和执行机构的实际位置(如小车当前角度)是一一对应的,因此在执行机构不带积分部件的对象中可以很好应用
  • 位置式PID每次输出均与过去的状态有关,计算时要对e(k)进行累加,运算工作量大

代码示例

//pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]
typedef struct PID
{ 
  float kp;
  float ki;
  float kd;
  float ek;     //当前误差
  float ek_1;   //上一次误差
  float ek_sum; //误差总和
  float limit;  //限幅
}PID;
 
static PID pid;
 
void PID_Init()
{
    pid.kp = 0.1;
    pid.ki = 0.2;
    pid.kd = 0.3;
    pid.limit = 1000;
    pid.ek = 0;
    pid.ek_1 = 0;
    pid.ek_sum = 0;
}
 
// 位置式PID控制
float PID_Postion(int Encoder,int Target)
{
    float pwm = 0;
    pid.ek = Target - Encoder; // 计算当前误差
    pid.ek_sum += pid.ek;      //求出偏差的积分
    pwm = pid.kp*pid.ek + pid.ki*pid.ek_sum + pid.kd*(pid.ek - pid.ek_1);   //位置式PID控制器
    pid.ek_1 = pid.ek;   //保存上一次偏差 
    if(pwm > pid.limit)
    {
      pwm =  pid.limit;
    }
    else if(pwm < -pid.limit)
    {
      pwm =  -pid.limit;
    }
    return pwm;
}

增量式PID

  • ▲u(k)对应的是近几次位置误差的增量,而不是对应与实际位置的偏差,没有误差累加
  • 增量式PID中不需要累加,控制增量Δu(k)的确定仅与最近3次的采样值有关,容易通过加权处理获得比较好的控制效果,并且在系统发生问题时,增量式不会严重影响系统的工作
  • 增量式PID误动作时影响小,必要时可用逻辑判断的方法去掉出错数据
  • 手动/自动切换时冲击小,便于实现无扰动切换。当计算机故障时,仍能保持原值
  • 积分截断效应大,有稳态误差
  • 溢出的影响大,有的被控对象用增量式则不太好

代码示例

//根据增量式离散PID公式 
//pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
//e(k)代表本次偏差 
//e(k-1)代表上一次的偏差  以此类推 
//e(k-2)代表上上次的偏差
//pwm代表增量输出
 
typedef struct PID
{ 
  float kp;
  float ki;
  float kd;
  float ek;     //当前误差
  float ek_1;   //上一次误差
  float ek_2;   //上上一次误差
  float limit;  //限幅
}PID;
 
static PID pid;
 
void PID_Init()
{
    pid.kp = 0.1;
    pid.ki = 0.2;
    pid.kd = 0.3;
    pid.limit = 1000;
    pid.ek = 0;
    pid.ek_1 = 0;
    pid.ek_2 = 0;
}
 
// 增量式PID控制
float PID_Increase(int Encoder,int Target)
{
    float pwm = 0;
    pid.ek = Target - Encoder; // 计算当前误差
    pid.ek_sum += pid.ek;      //求出偏差的积分
    pwm = pid.kp*(pid.ek - pid.ek_1) + pid.ki*pid.ek + pid.kd*(pid.ek - 2*pid.ek_1 + pid.ek_2);   //增量式PID控制器
    pid.ek_1 = pid.ek;   //保存上一次偏差 
    pid.ek_2 = pid.ek_1; //保存上上一次的偏差
    if(pwm > pid.limit)
    {
      pwm =  pid.limit;
    }
    else if(pwm < -pid.limit)
    {
      pwm =  -pid.limit;
    }
    return pwm;
}

联系与区别

  • 增量式算法不需要做累加,控制量增量的确定仅与最近几次偏差采样值有关,计算误差对控制 量计算的影响较小。而位置式算法要用到过去偏差的累加值,容易产生较大的累加误差
  • 增量式算法得出的是控制量的增量,例如在阀门控制中,只输出阀门开度的变化部分,误动作 影响小,必要时还可通过逻辑判断限制或禁止本次输出,不会严重影响系统的工作。 而位置式的输出直接对应对象的输出,因此对系统影响较大
  • 在进行PID控制时,位置式PID需要有积分限幅和输出限幅,而增量式PID只需输出限幅

推荐书籍

《自动控制原理的故事》

《由入门到精通吃透PID》

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2023年5月8日
下一篇 2023年5月8日

相关推荐