改进PID(抗积分饱和法)——C语言实现

前言

       积分饱和现象是指若系统存在一个方向的偏差,PID控制器的输出由于积分作用不断累加而增大,超出执行机构的极限位置。计算机输出的控制量超出正常运行范围而进入饱和区。。


目录

前言

一、抗积分饱和算法

二、算法实现

1.结构体定义与参数初始化

2.算法实现

3.主函数


一、抗积分饱和算法

        基本思路:在计算控制量时,首先判断上一时刻的控制量是否超出限制范围。若超出最大值,则只进行负偏差的累加;若上一时刻的控制量小于最小值,则只进行正偏差的累加。

二、算法实现

1.结构体定义与参数初始化

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

struct pid
{
    float SetSpeed;          //设定值
    float ActualSpeed;       //实际输出值
    float err;               //偏差值
    float err_last;          //上一时刻偏差值
    float Kp,Ki,Kd;          //定义比例系数、积分系数和微分系数
    float ut;                //定义控制量
    float interal;           //定义积分项
    float umax;              //执行机构的最大值和最小值
    float umin;
}pid;

void PID_init();
float PID_realize(float speed);

void PID_init()             //参数初始化
{
    pid.SetSpeed = 0.0;
    pid.ActualSpeed = 0.0;
    pid.err = 0.0;
    pid.err_last = 0.0;
    pid.Kd = 0.2;
    pid.Ki = 0.1;
    pid.Kp = 0.2;
    pid.ut = 0.0;
    pid.interal = 0.0;
    pid.umax = 400;
    pid.umin = -200;
}

2.算法实现

float PID_realize(float speed)   //本算法实现中未引入实际受控对象,故控制量ut与实际输出值ActualSpeed相等
{
  pid.SetSpeed =  speed;
  pid.err = pid.SetSpeed - pid.ActualSpeed;
  int index;
  if(pid.ut >= pid.umax)        // 如果控制量超出执行机构最大值
  {
      if(pid.err >= 0)          // 若偏差为正值,停止积分
      {
          index = 0;
      }
      else                      // 若偏差为负值,执行负偏差的累加
      {
          index = 1;
          pid.interal += pid.err;
      }
      
  }
  else if(pid.voltage <= pid.umin)  // 如果控制量小于执行机构的最小值
  {
      if(pid.err <= 0)              // 若偏差为负值,停止积分
      {
          index = 0;
      }
      else                          // 若偏差为正值,执行正偏差的累加
      {
          index = 1;
          pid.interal += pid.err;
      }
  }
  else                             // 其他情况下,正常执行积分
  {
      index = 1;  
      pid.interal += pid.err;
  }

// 抗积分饱和控制规律
  pid.ut = pid.Kp*pid.err + index*pid.Ki*pid.interal + pid.Kd*(pid.err - pid.err_last);   

//参数更新
  pid.err_last = pid.err;
  pid.ActualSpeed = pid.ut;
  return pid.ActualSpeed;
}

3.主函数

int main()
{
    PID_init();
    int count;
    while(count<1000)
    {
        float speed = PID_realize(200);
        printf("%f\n",speed);
        count++;
    }
    return 0;
}

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值