pid.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #ifndef _PID_SOURCE_
  2. #define _PID_SOURCE_
  3. #include <iostream>
  4. #include <cmath>
  5. #include <QDebug>
  6. #include "pid.h"
  7. using namespace std;
  8. class PIDImpl
  9. {
  10. public:
  11. PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki );
  12. ~PIDImpl();
  13. double calculate( double setpoint, double pv );
  14. private:
  15. double _dt;
  16. double _max;
  17. double _min;
  18. double _Kp;
  19. double _Kd;
  20. double _Ki;
  21. double _pre_error;
  22. double _integral;
  23. };
  24. PID::PID( double dt, double max, double min, double Kp, double Kd, double Ki )
  25. {
  26. pimpl = new PIDImpl(dt,max,min,Kp,Kd,Ki);
  27. }
  28. double PID::calculate( double setpoint, double pv )
  29. {
  30. return pimpl->calculate(setpoint,pv);
  31. }
  32. PID::~PID()
  33. {
  34. delete pimpl;
  35. }
  36. /**
  37. * Implementation
  38. */
  39. PIDImpl::PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki ) :
  40. _dt(dt),
  41. _max(max),
  42. _min(min),
  43. _Kp(Kp),
  44. _Kd(Kd),
  45. _Ki(Ki),
  46. _pre_error(0),
  47. _integral(0)
  48. {
  49. }
  50. double PIDImpl::calculate( double setpoint, double pv )
  51. {
  52. // Calculate error
  53. double error = setpoint - pv;
  54. // Proportional term
  55. double Pout = _Kp * error;
  56. // Integral term
  57. if(abs(error) > 3.0){
  58. _integral = 0;
  59. }else{
  60. double _error = 0;
  61. if(_integral > 30){
  62. if(error >=0 )
  63. _error = 0;
  64. else
  65. _error = error;
  66. }else{
  67. _error = error;
  68. }
  69. _error = error;
  70. _integral += _error * _dt;
  71. }
  72. double Iout = _Ki * _integral;
  73. // Derivative term
  74. double derivative = (error - _pre_error) / _dt;
  75. double Dout = _Kd * derivative;
  76. //qDebug("calculate : pOut : %f, Iout: %f, Dout: %f ", Pout, Iout, Dout);
  77. // Calculate total output
  78. double output = Pout + Iout + Dout;
  79. // Restrict to max/min
  80. if( output > _max )
  81. output = _max;
  82. else if( output < _min )
  83. output = _min;
  84. // Save error to previous error
  85. _pre_error = error;
  86. return output;
  87. }
  88. PIDImpl::~PIDImpl()
  89. {
  90. }
  91. #endif