微分先行PID控制算法用C语言实现!

本文详细介绍了微分先行PID控制算法的原理及其在C语言中的实现方式,包括位置型和增量型两种实现方法。通过具体的代码示例,阐述了微分先行PID控制如何避免给定指令的频繁变化和高频干扰导致的超调问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.微分先行PID控制算法框图

 

2.微分先行PID控制算法公式

 

3.微分先行PID控制公式用C语言实现

微分先行的PID算法实现,包括位置型和增量型两种实现方式。

(1)位置型

void PIDRegulation(PID *vPID, float processValue)

{

  float thisError;

  float c1,c2,c3,temp;

  thisError=vPID->setpoint-processValue;

  vPID->integral+=thisError;



  temp= vPID-> gama * vPID-> derivativegain + vPID-> proportiongain;

  c3= vPID-> derivativegain/temp;

  c2=( vPID-> derivativegain+ vPID-> proportiongain)/temp;

  c1= vPID-> gama*c3;

  vPID->derivative=c1* vPID-> derivative+c2* processValue+c3* vPID-> lastPv;

  vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID-> derivative;

  vPID->lasterror=thisError;

  vPID-> lastPv= processValue;

}

/*定义结构体和公用体*/

typedef struct

{

  float setpoint;           //设定值

  float proportiongain;     //比例系数

  float integralgain;       //积分系数

  float derivativegain;     //微分系数

  float lasterror;          //前一拍偏差

  float result;             //输出值

  float integral;           //积分值

  float derivative;         //微分项

  float lastPv;             //前一拍的测量值

  float gama;               //微分先行滤波系数

}PID;

(2)增量型

void PIDRegulation(PID *vPID, float processValue)

{

  float thisError;

  float increment;

  float pError,iError;

  float c1,c2,c3,temp;

  float deltaPv;


  temp= vPID-> gama * vPID-> derivativegain + vPID-> proportiongain;

  c3= vPID-> derivativegain/temp;

  c2=( vPID-> derivativegain+ vPID-> proportiongain)/temp;

  c1= vPID-> gama*c3;

 

  deltaPv= processValue- vPID-> lastDeltaPv

  vPID-> deltadiff =c1* vPID-> deltadiff +c2* deltaPv +c3* vPID-> lastDeltaPv;

 

  thisError=vPID->setpoint-processValue; //得到偏差值

  pError=thisError-vPID->lasterror;

  iError=thisError;

  increment=vPID->proportiongain*pError+vPID->integralgain*iError+ vPID-> deltadiff;   //增量计算

 

  vPID->preerror=vPID->lasterror;  //存放偏差用于下次运算

  vPID->lastDeltaPv=deltaPv;

  vPID->lastPv= processValue;

  vPID->lasterror=thisError;

  vPID->result+=increment;

}

/*定义结构体和公用体*/
typedef struct

{
 
  float setpoint;                //设定值

  float proportiongain;         //比例系数

  float integralgain;           //积分系数

  float derivativegain;         //微分系数

  float lasterror;              //前一拍偏差

  float preerror;               //前两拍偏差

  float deadband;               //死区

  float result;                 //输出值

  float deltadiff;              /*微分增量*/

  float integralValue;          /*积分累计量*/

  float gama;                   /*微分先行滤波系数*/

  float lastPv;                 /*上一拍的过程测量值*/

  float lastDeltaPv;            /*上一拍的过程测量值增量*/

}PID;

微分先行PID控制是只对输出量进行微分,而对给定指令不起微分作用,因此它适合于给定指令频繁升降和高频干扰的场合,可以避免指令的改变导致超调过大。

(参考http://www.cnblogs.com/foxclever/p/9159677.html

以下是一个简单的微分先行PID控制器的C语言实现和例子说明: ```c // 定义PID结构体 typedef struct { float Kp; // 比例系数 float Ki; // 积分系数 float Kd; // 微分系数 float T; // 采样时间 float e0; // 当前误差 float e1; // 上一次误差 float e2; // 上上次误差 float u0; // 当前控制量 float u1; // 上一次控制量 } PID; // 初始化PID控制器 void pid_init(PID *pid, float Kp, float Ki, float Kd, float T) { pid->Kp = Kp; pid->Ki = Ki; pid->Kd = Kd; pid->T = T; pid->e0 = 0; pid->e1 = 0; pid->e2 = 0; pid->u0 = 0; pid->u1 = 0; } // 计算PID控制量 float pid_calc(PID *pid, float ref, float feedback) { // 计算误差 pid->e2 = pid->e1; pid->e1 = pid->e0; pid->e0 = ref - feedback; // 计算控制量 pid->u1 = pid->u0; pid->u0 = pid->u1 + pid->Kp * (pid->e0 - pid->e1 + pid->Kd * (pid->e0 - 2 * pid->e1 + pid->e2) / pid->T) + pid->Ki * pid->T * pid->e0; return pid->u0; } // 示例 int main() { PID pid; pid_init(&pid, 1, 0.1, 0.5, 0.1); // 初始化PID控制器,Kp=1, Ki=0.1, Kd=0.5, T=0.1 float ref = 10; // 设定值 float feedback = 0; // 实际反馈值 float u = 0; // 控制量 for (int i = 0; i < 1000; i++) { feedback = get_feedback(); // 获取实际反馈值 u = pid_calc(&pid, ref, feedback); // 计算控制量 set_control(u); // 设置控制量 delay(100); // 采样时间间隔 } return 0; } ``` 上面的代码中,PID结构体包括比例系数Kp、积分系数Ki、微分系数Kd、采样时间T、当前误差e0、上一次误差e1、上上次误差e2、当前控制量u0和上一次控制量u1。初始化PID控制器时需要指定这些参数,然后在循环中通过pid_calc函数计算控制量,并通过set_control函数设置控制量。在计算控制量时,需要先计算误差,然后根据比例项、微分先行项和积分项计算控制量。需要注意的是,微分先行项的计算需要使用上一次误差和上上次误差,因此需要在PID结构体中保存这些值。 以上是一个简单的微分先行PID控制器的C语言实现和例子说明,具体实现方式可以根据实际应用场景进行调整。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值