LowPassFilter.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. //
  14. /// @file LowPassFilter.h
  15. /// @brief A class to implement a low pass filter without losing precision even for int types
  16. /// the downside being that it's a little slower as it internally uses a float
  17. /// and it consumes an extra 4 bytes of memory to hold the constant gain
  18. /*
  19. Note that this filter can be used in 2 ways:
  20. 1) providing dt on every sample, and calling apply like this:
  21. // call once
  22. filter.set_cutoff_frequency(frequency_hz);
  23. // then on each sample
  24. output = filter.apply(sample, dt);
  25. 2) providing a sample freq and cutoff_freq once at start
  26. // call once
  27. filter.set_cutoff_frequency(sample_freq, frequency_hz);
  28. // then on each sample
  29. output = filter.apply(sample);
  30. The second approach is more CPU efficient as it doesn't have to
  31. recalculate alpha each time, but it assumes that dt is constant
  32. */
  33. #pragma once
  34. #include <AP_Math/AP_Math.h>
  35. #include "FilterClass.h"
  36. // DigitalLPF implements the filter math
  37. template <class T>
  38. class DigitalLPF {
  39. public:
  40. DigitalLPF();
  41. // add a new raw value to the filter, retrieve the filtered result
  42. T apply(const T &sample, float cutoff_freq, float dt);
  43. T apply(const T &sample);
  44. void compute_alpha(float sample_freq, float cutoff_freq);
  45. // get latest filtered value from filter (equal to the value returned by latest call to apply method)
  46. const T &get() const;
  47. void reset(T value);
  48. private:
  49. T _output;
  50. float alpha = 1.0f;
  51. };
  52. // LPF base class
  53. template <class T>
  54. class LowPassFilter {
  55. public:
  56. LowPassFilter();
  57. LowPassFilter(float cutoff_freq);
  58. LowPassFilter(float sample_freq, float cutoff_freq);
  59. // change parameters
  60. void set_cutoff_frequency(float cutoff_freq);
  61. void set_cutoff_frequency(float sample_freq, float cutoff_freq);
  62. // return the cutoff frequency
  63. float get_cutoff_freq(void) const;
  64. T apply(T sample, float dt);
  65. T apply(T sample);
  66. const T &get() const;
  67. void reset(T value);
  68. void reset(void) { reset(T()); }
  69. protected:
  70. float _cutoff_freq;
  71. private:
  72. DigitalLPF<T> _filter;
  73. };
  74. // Uncomment this, if you decide to remove the instantiations in the implementation file
  75. /*
  76. template <class T>
  77. LowPassFilter<T>::LowPassFilter() : _cutoff_freq(0.0f) {
  78. }
  79. // constructor
  80. template <class T>
  81. LowPassFilter<T>::LowPassFilter(float cutoff_freq) : _cutoff_freq(cutoff_freq) {
  82. }
  83. */
  84. // typedefs for compatibility
  85. typedef LowPassFilter<int> LowPassFilterInt;
  86. typedef LowPassFilter<long> LowPassFilterLong;
  87. typedef LowPassFilter<float> LowPassFilterFloat;
  88. typedef LowPassFilter<Vector2f> LowPassFilterVector2f;
  89. typedef LowPassFilter<Vector3f> LowPassFilterVector3f;