LowPassFilter.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. //
  2. /// @file LowPassFilter.cpp
  3. /// @brief A class to implement a low pass filter without losing precision even for int types
  4. /// the downside being that it's a little slower as it internally uses a float
  5. /// and it consumes an extra 4 bytes of memory to hold the constant gain
  6. #include "LowPassFilter.h"
  7. ////////////////////////////////////////////////////////////////////////////////////////////
  8. // DigitalLPF
  9. ////////////////////////////////////////////////////////////////////////////////////////////
  10. template <class T>
  11. DigitalLPF<T>::DigitalLPF() {
  12. // built in initialization
  13. _output = T();
  14. }
  15. // add a new raw value to the filter, retrieve the filtered result
  16. template <class T>
  17. T DigitalLPF<T>::apply(const T &sample, float cutoff_freq, float dt) {
  18. if (cutoff_freq <= 0.0f || dt <= 0.0f) {
  19. _output = sample;
  20. return _output;
  21. }
  22. float rc = 1.0f/(M_2PI*cutoff_freq);
  23. alpha = constrain_float(dt/(dt+rc), 0.0f, 1.0f);
  24. _output += (sample - _output) * alpha;
  25. return _output;
  26. }
  27. template <class T>
  28. T DigitalLPF<T>::apply(const T &sample) {
  29. _output += (sample - _output) * alpha;
  30. return _output;
  31. }
  32. template <class T>
  33. void DigitalLPF<T>::compute_alpha(float sample_freq, float cutoff_freq) {
  34. if (cutoff_freq <= 0.0f || sample_freq <= 0.0f) {
  35. alpha = 1.0;
  36. } else {
  37. float dt = 1.0/sample_freq;
  38. float rc = 1.0f/(M_2PI*cutoff_freq);
  39. alpha = constrain_float(dt/(dt+rc), 0.0f, 1.0f);
  40. }
  41. }
  42. // get latest filtered value from filter (equal to the value returned by latest call to apply method)
  43. template <class T>
  44. const T &DigitalLPF<T>::get() const {
  45. return _output;
  46. }
  47. template <class T>
  48. void DigitalLPF<T>::reset(T value) {
  49. _output = value;
  50. }
  51. ////////////////////////////////////////////////////////////////////////////////////////////
  52. // LowPassFilter
  53. ////////////////////////////////////////////////////////////////////////////////////////////
  54. // constructors
  55. template <class T>
  56. LowPassFilter<T>::LowPassFilter() :
  57. _cutoff_freq(0.0f) {}
  58. template <class T>
  59. LowPassFilter<T>::LowPassFilter(float cutoff_freq) :
  60. _cutoff_freq(cutoff_freq) {}
  61. template <class T>
  62. LowPassFilter<T>::LowPassFilter(float sample_freq, float cutoff_freq)
  63. {
  64. set_cutoff_frequency(sample_freq, cutoff_freq);
  65. }
  66. // change parameters
  67. template <class T>
  68. void LowPassFilter<T>::set_cutoff_frequency(float cutoff_freq) {
  69. _cutoff_freq = cutoff_freq;
  70. }
  71. template <class T>
  72. void LowPassFilter<T>::set_cutoff_frequency(float sample_freq, float cutoff_freq) {
  73. _cutoff_freq = cutoff_freq;
  74. _filter.compute_alpha(sample_freq, cutoff_freq);
  75. }
  76. // return the cutoff frequency
  77. template <class T>
  78. float LowPassFilter<T>::get_cutoff_freq(void) const {
  79. return _cutoff_freq;
  80. }
  81. template <class T>
  82. T LowPassFilter<T>::apply(T sample, float dt) {
  83. return _filter.apply(sample, _cutoff_freq, dt);
  84. }
  85. template <class T>
  86. T LowPassFilter<T>::apply(T sample) {
  87. return _filter.apply(sample);
  88. }
  89. template <class T>
  90. const T &LowPassFilter<T>::get() const {
  91. return _filter.get();
  92. }
  93. template <class T>
  94. void LowPassFilter<T>::reset(T value) {
  95. _filter.reset(value);
  96. }
  97. /*
  98. * Make an instances
  99. * Otherwise we have to move the constructor implementations to the header file :P
  100. */
  101. template class LowPassFilter<int>;
  102. template class LowPassFilter<long>;
  103. template class LowPassFilter<float>;
  104. template class LowPassFilter<Vector2f>;
  105. template class LowPassFilter<Vector3f>;