pid.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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. void clear();
  15. private:
  16. double _dt;
  17. double _max;
  18. double _min;
  19. double _Kp;
  20. double _Kd;
  21. double _Ki;
  22. double _pre_error;
  23. double _integral;
  24. double _pre_out;
  25. };
  26. PID::PID( double dt, double max, double min, double Kp, double Kd, double Ki )
  27. {
  28. pimpl = new PIDImpl(dt,max,min,Kp,Kd,Ki);
  29. }
  30. double PID::calculate( double setpoint, double pv )
  31. {
  32. return pimpl->calculate(setpoint,pv);
  33. }
  34. void PID::clear()
  35. {
  36. pimpl->clear();
  37. }
  38. PID::~PID()
  39. {
  40. delete pimpl;
  41. }
  42. /**
  43. * Implementation
  44. */
  45. PIDImpl::PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki ) :
  46. _dt(dt),
  47. _max(max),
  48. _min(min),
  49. _Kp(Kp),
  50. _Kd(Kd),
  51. _Ki(Ki),
  52. _pre_error(0),
  53. _integral(0),
  54. _pre_out(0)
  55. {
  56. }
  57. double PIDImpl::calculate( double setpoint, double pv )
  58. {
  59. // Calculate error
  60. double error = setpoint - pv;
  61. // Proportional term
  62. double Pout = _Kp * error;
  63. // Integral term
  64. if(abs(error) > 3.0){
  65. _integral = 0;
  66. }else{
  67. double _error = 0;
  68. if(_integral > 30){
  69. if(error >=0 )
  70. _error = 0;
  71. else
  72. _error = error;
  73. }else{
  74. _error = error;
  75. }
  76. _error = error;
  77. _integral += _error * _dt;
  78. }
  79. double Iout = _Ki * _integral;
  80. // Derivative term
  81. double derivative = (error - _pre_error) / _dt;
  82. double Dout = _Kd * derivative;
  83. //qDebug("calculate : pOut : %f, Iout: %f, Dout: %f ", Pout, Iout, Dout);
  84. // Calculate total output
  85. double output = Pout + Iout + Dout;
  86. // Restrict to max/min
  87. if( output > _max )
  88. output = _max;
  89. else if( output < _min )
  90. output = _min;
  91. if(output < _pre_out){
  92. if((_pre_out - output) > 1.0){
  93. output = _pre_out - 1.0;
  94. }
  95. }else if(output > _pre_out){
  96. if((output - _pre_out) > 1.0){
  97. output = _pre_out + 1.0;
  98. }
  99. }
  100. _pre_out = output;
  101. // Save error to previous error
  102. _pre_error = error;
  103. return output;
  104. }
  105. void PIDImpl::clear()
  106. {
  107. _pre_error = 0;
  108. _integral = 0;
  109. _pre_out = 0;
  110. }
  111. PIDImpl::~PIDImpl()
  112. {
  113. }
  114. #endif