2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
23 #include "common/axis.h"
24 #include "common/filter.h"
25 #include "common/maths.h"
27 #include "drivers/gyro_sync.h"
29 #define BIQUAD_Q (1.0f / 1.41421356f) /* quality factor - butterworth (1 / sqrt(2)) */
31 /* sets up a biquad Filter */
32 void filterInitBiQuad(uint8_t filterCutFreq
, biquad_t
*newState
, int16_t samplingRate
)
34 float omega
, sn
, cs
, alpha
;
35 float a0
, a1
, a2
, b0
, b1
, b2
;
37 /* If sampling rate == 0 - use main loop target rate */
39 samplingRate
= 1000000 / targetLooptime
;
43 omega
= 2 * M_PIf
* (float)filterCutFreq
/ (float)samplingRate
;
44 sn
= sin_approx(omega
);
45 cs
= cos_approx(omega
);
46 alpha
= sn
/ (2 * BIQUAD_Q
);
55 /* precompute the coefficients */
56 newState
->b0
= b0
/ a0
;
57 newState
->b1
= b1
/ a0
;
58 newState
->b2
= b2
/ a0
;
59 newState
->a1
= a1
/ a0
;
60 newState
->a2
= a2
/ a0
;
62 /* zero initial samples */
63 newState
->d1
= newState
->d2
= 1;
66 /* Computes a biquad_t filter on a sample */
67 float filterApplyBiQuad(float sample
, biquad_t
*state
)
71 result
= state
->b0
* sample
+ state
->d1
;
72 state
->d1
= state
->b1
* sample
- state
->a1
* result
+ state
->d2
;
73 state
->d2
= state
->b2
* sample
- state
->a2
* result
;
78 // PT1 Low Pass filter (when no dT specified it will be calculated from the cycleTime)
79 float filterApplyPt1(float input
, filterStatePt1_t
*filter
, float f_cut
, float dT
)
81 // Pre calculate and store RC
83 filter
->RC
= 1.0f
/ ( 2.0f
* (float)M_PI
* f_cut
);
86 filter
->state
= filter
->state
+ dT
/ (filter
->RC
+ dT
) * (input
- filter
->state
);
90 // PT1 Low Pass filter (when no dT specified it will be calculated from the cycleTime)
91 // f_cut = cutoff frequency
92 // rate_limit = maximum rate of change of the output value in units per second
93 float filterApplyPt1WithRateLimit(float input
, filterStatePt1_t
*filter
, float f_cut
, float rate_limit
, float dT
)
95 // Pre calculate and store RC
97 filter
->RC
= 1.0f
/ ( 2.0f
* (float)M_PI
* f_cut
);
100 const float newState
= filter
->state
+ dT
/ (filter
->RC
+ dT
) * (input
- filter
->state
);
101 const float rateLimitPerSample
= rate_limit
* dT
;
102 filter
->state
= constrainf(newState
, filter
->state
- rateLimitPerSample
, filter
->state
+ rateLimitPerSample
);
104 return filter
->state
;
107 void filterResetPt1(filterStatePt1_t
*filter
, float input
)
109 filter
->state
= input
;
112 void filterUpdateFIR(int filterLength
, float *shiftBuf
, float newSample
)
114 // Shift history buffer and push new sample
115 for (int i
= filterLength
- 1; i
> 0; i
--)
116 shiftBuf
[i
] = shiftBuf
[i
- 1];
118 shiftBuf
[0] = newSample
;
121 float filterApplyFIR(int filterLength
, const float *shiftBuf
, const float *coeffBuf
, float commonMultiplier
)
125 for (int i
= 0; i
< filterLength
; i
++)
126 accum
+= shiftBuf
[i
] * coeffBuf
[i
];
128 return accum
* commonMultiplier
;