pid.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "pid.h"
  2. //用于初始化pid参数的函数
  3. void PID_Init(PID *pid, float p, float i, float d, float maxI, float maxOut, float minOut)
  4. {
  5. pid->kp = p;
  6. pid->ki = i;
  7. pid->kd = d;
  8. pid->maxIntegral = maxI;
  9. pid->maxOutput = maxOut;
  10. pid->minOutput = minOut;
  11. pid->error = 0;
  12. pid->error1 = 0;
  13. pid->error2 = 0;
  14. pid->integral = 0;
  15. pid->output = 0;
  16. }
  17. //位置式PID
  18. //pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]
  19. //setvalue : 设置值(期望值)
  20. //actualvalue: 实际值
  21. //由于全量输出,每次输出均与过去状态有关,计算时要对ek累加,计算量大
  22. float PID_Location(PID *pid, float setvalue, float feedback, float dt)
  23. {
  24. //更新数据
  25. pid->error1 = pid->error; //将旧error存起来
  26. pid->error = setvalue - feedback; //计算新error
  27. //计算微分
  28. float dout = (pid->error - pid->error1)/dt * pid->kd;
  29. //计算比例
  30. float pout = pid->error * pid->kp;
  31. //计算积分
  32. pid->integral += pid->error*dt * pid->ki;
  33. //积分限幅
  34. if(pid->integral > pid->maxIntegral)
  35. pid->integral = pid->maxIntegral;
  36. else if(pid->integral < -pid->maxIntegral)
  37. pid->integral = -pid->maxIntegral;
  38. //计算输出
  39. pid->output = pout+dout + pid->integral;
  40. //输出限幅
  41. if(pid->output > pid->maxOutput)
  42. pid->output = pid->maxOutput;
  43. if(pid->output < pid->minOutput)
  44. pid->output = pid->minOutput;
  45. return pid->output;
  46. }
  47. //增量式PID
  48. //pidout+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
  49. //setvalue : 设置值(期望值)
  50. //feedback: 实际值
  51. float PID_Increment(PID *pid, float setvalue, float feedback)
  52. {
  53. //更新数据
  54. pid->error2 = pid->error1; //将旧error1存起来
  55. pid->error1 = pid->error; //将旧error存起来
  56. pid->error = setvalue - feedback; //计算新error
  57. //计算微分
  58. float dout = (pid->error - 2*pid->error1 + pid->error2) * pid->kd;
  59. //计算比例
  60. float pout = (pid->error - pid->error1 )* pid->kp;
  61. //计算积分
  62. pid->integral = pid->error * pid->ki;
  63. //计算输出
  64. pid->output += (pout+dout + pid->integral);
  65. //输出限幅
  66. // if(pid->output > pid->maxOutput)
  67. // pid->output = pid->maxOutput;
  68. // if(pid->output < pid->minOutput)
  69. // pid->output = pid->minOutput;
  70. return pid->output;
  71. }