PID.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /// @file PID.cpp
  2. /// @brief Generic PID algorithm
  3. #include <cmath>
  4. #include "PID.h"
  5. #include <AP_HAL/AP_HAL.h>
  6. #include <AP_Math/AP_Math.h>
  7. extern const AP_HAL::HAL& hal;
  8. const AP_Param::GroupInfo PID::var_info[] = {
  9. // @Param: P
  10. // @DisplayName: PID Proportional Gain
  11. // @Description: P Gain which produces an output value that is proportional to the current error value
  12. AP_GROUPINFO("P", 0, PID, _kp, 0),
  13. // @Param: I
  14. // @DisplayName: PID Integral Gain
  15. // @Description: I Gain which produces an output that is proportional to both the magnitude and the duration of the error
  16. AP_GROUPINFO("I", 1, PID, _ki, 0),
  17. // @Param: D
  18. // @DisplayName: PID Derivative Gain
  19. // @Description: D Gain which produces an output that is proportional to the rate of change of the error
  20. AP_GROUPINFO("D", 2, PID, _kd, 0),
  21. // @Param: IMAX
  22. // @DisplayName: PID Integral Maximum
  23. // @Description: The maximum/minimum value that the I term can output
  24. AP_GROUPINFO("IMAX", 3, PID, _imax, 0),
  25. AP_GROUPEND
  26. };
  27. float PID::get_pid(float error, float scaler)
  28. {
  29. uint32_t tnow = AP_HAL::millis();
  30. uint32_t dt = tnow - _last_t;
  31. float output = 0;
  32. float delta_time;
  33. if (_last_t == 0 || dt > 1000) {
  34. dt = 0;
  35. // if this PID hasn't been used for a full second then zero
  36. // the intergator term. This prevents I buildup from a
  37. // previous fight mode from causing a massive return before
  38. // the integrator gets a chance to correct itself
  39. reset_I();
  40. }
  41. _last_t = tnow;
  42. delta_time = (float)dt / 1000.0f;
  43. // Compute proportional component
  44. _pid_info.P = error * _kp;
  45. output += _pid_info.P;
  46. // Compute derivative component if time has elapsed
  47. if ((fabsf(_kd) > 0) && (dt > 0)) {
  48. float derivative;
  49. if (isnan(_last_derivative)) {
  50. // we've just done a reset, suppress the first derivative
  51. // term as we don't want a sudden change in input to cause
  52. // a large D output change
  53. derivative = 0;
  54. _last_derivative = 0;
  55. } else {
  56. derivative = (error - _last_error) / delta_time;
  57. }
  58. // discrete low pass filter, cuts out the
  59. // high frequency noise that can drive the controller crazy
  60. float RC = 1/(2*M_PI*_fCut);
  61. derivative = _last_derivative +
  62. ((delta_time / (RC + delta_time)) *
  63. (derivative - _last_derivative));
  64. // update state
  65. _last_error = error;
  66. _last_derivative = derivative;
  67. // add in derivative component
  68. _pid_info.D = _kd * derivative;
  69. output += _pid_info.D;
  70. }
  71. // scale the P and D components
  72. output *= scaler;
  73. _pid_info.D *= scaler;
  74. _pid_info.P *= scaler;
  75. // Compute integral component if time has elapsed
  76. if ((fabsf(_ki) > 0) && (dt > 0)) {
  77. _integrator += (error * _ki) * scaler * delta_time;
  78. if (_integrator < -_imax) {
  79. _integrator = -_imax;
  80. } else if (_integrator > _imax) {
  81. _integrator = _imax;
  82. }
  83. _pid_info.I = _integrator;
  84. output += _integrator;
  85. }
  86. _pid_info.target = output;
  87. return output;
  88. }
  89. void
  90. PID::reset_I()
  91. {
  92. _integrator = 0;
  93. // we use NAN (Not A Number) to indicate that the last
  94. // derivative value is not valid
  95. _last_derivative = NAN;
  96. _pid_info.I = 0;
  97. }
  98. void PID::reset() {
  99. memset(&_pid_info, 0, sizeof(_pid_info));
  100. reset_I();
  101. }
  102. void
  103. PID::load_gains()
  104. {
  105. _kp.load();
  106. _ki.load();
  107. _kd.load();
  108. _imax.load();
  109. }
  110. void
  111. PID::save_gains()
  112. {
  113. _kp.save();
  114. _ki.save();
  115. _kd.save();
  116. _imax.save();
  117. }