|
9 | 9 | * easy signal processing. |
10 | 10 | * |
11 | 11 | * Below is the list of filters supported by @ref qssmoother : |
12 | | -* |
| 12 | +* |
13 | 13 | * @section qssmoother_lpf1 First Order Low Pass Filter |
14 | | -* |
15 | | -* \ref qlibs::smootherLPF1 is first-order low-pass filter that passes signals |
16 | | -* with a frequency lower than a chosen cutoff frequency and reduces signals |
17 | | -* with frequencies higher than the cutoff. This results in a smoother signal |
| 14 | +* |
| 15 | +* \ref qlibs::smootherLPF1 is first-order low-pass filter that passes signals |
| 16 | +* with a frequency lower than a chosen cutoff frequency and reduces signals |
| 17 | +* with frequencies higher than the cutoff. This results in a smoother signal |
18 | 18 | * by removing short-term fluctuations and highlighting longer-term trends. |
19 | 19 | * The discrete-time equation of this filter is defined as follows, where \f$w\f$ |
20 | 20 | * is the cut-off frequency given in \f$rad/seg\f$ |
|
43 | 43 | * @endcode |
44 | 44 | * |
45 | 45 | * @section qssmoother_lpf2 Second Order Low Pass Filter |
46 | | -* |
| 46 | +* |
47 | 47 | * \ref qlibs::smootherLPF2 is a filter with similar properties to the 1st order low pass filter. The main |
48 | 48 | * difference is that the stop band roll-off will be twice the 1st order filters |
49 | 49 | * at 40dB/decade (12dB/octave) as the operating frequency increases above the |
|
74 | 74 | * // error, smooth filter cant be configured |
75 | 75 | * } |
76 | 76 | * @endcode |
77 | | -* |
78 | 77 | * |
79 | | -* @section qssmoother_mwm1 Moving Window Median Filter O(n) |
80 | | -* |
| 78 | +* |
| 79 | +* @section qssmoother_mwm1 Moving Window Median Filter O(n) |
| 80 | +* |
81 | 81 | * \ref qlibs::smootherMWM1 is a low-pass filter that calculates the moving median of the input signal over |
82 | 82 | * time using the sliding window method. A window of a specified length is moved |
83 | 83 | * sample by sample and the median of the data in the window is computed. |
|
92 | 92 | * |
93 | 93 | * <center> \f$ \frac{1}{N}\sum_{i=0}^{N-1}y(t-i)=\frac{1}{N}[ y(t) + y(t-1) + ... + y(t-N-1) ] \f$ </center> |
94 | 94 | * |
95 | | -* This filter has a time complexity of \f$O(n)\f$ |
| 95 | +* This filter has a time complexity of \f$O(n)\f$ |
96 | 96 | * |
97 | 97 | * @subsection qssmoother_ex3 Example: setting up a moving window median filter: |
98 | 98 | * @code{.c} |
99 | | -* smootherMWM1 filter; |
| 99 | +* smootherMWM1 filter; |
100 | 100 | * real_t m_window[ 20 ] = { 0.0f }; |
101 | 101 | * bool ret; |
102 | 102 | * |
|
107 | 107 | * @endcode |
108 | 108 | * |
109 | 109 | * |
110 | | -* @section qssmoother_mwm2 Moving Window Median Filter O(1) |
111 | | -* |
| 110 | +* @section qssmoother_mwm2 Moving Window Median Filter O(1) |
| 111 | +* |
112 | 112 | * \ref qlibs::smootherMWM2 is a filter that operates on the same principle as the previous filter. The main |
113 | 113 | * difference is the treatment of the sliding window, which is implemented as a |
114 | 114 | * TDL (Tapped Delay Line) using a circular queue. |
|
126 | 126 | * |
127 | 127 | * @subsection qssmoother_ex4 Example: Setting up a moving window median filter: |
128 | 128 | * @code{.c} |
129 | | -* smootherMWM2 filter; |
| 129 | +* smootherMWM2 filter; |
130 | 130 | * real_t m_window[ 150 ] = { 0.0f }; |
131 | 131 | * bool ret; |
132 | 132 | * |
|
137 | 137 | * @endcode |
138 | 138 | * |
139 | 139 | * |
140 | | -* @section qssmoother_mor1 Moving Outlier Removal Filter O(n) |
141 | | -* |
| 140 | +* @section qssmoother_mor1 Moving Outlier Removal Filter O(n) |
| 141 | +* |
142 | 142 | * The \ref qlibs::smootherMOR1 filter detects and removes outliers in the input signal by computing the |
143 | 143 | * median of a moving window for each sample. If a new incoming sample deviates |
144 | 144 | * from the median by a specified margin \f$\alpha\f$, it is replaced by the |
|
152 | 152 | * \f$ \text{else}=x(k) \f$ |
153 | 153 | * </center> |
154 | 154 | * |
155 | | -* This filter has a time complexity of \f$O(n)\f$ |
| 155 | +* This filter has a time complexity of \f$O(n)\f$ |
156 | 156 | * |
157 | 157 | * @subsection qssmoother_ex5 Example: setting up an outlier removal filter: |
158 | 158 | * @code{.c} |
159 | | -* smootherMOR1 smoother; |
| 159 | +* smootherMOR1 smoother; |
160 | 160 | * real_t alpha = 0.8f; |
161 | 161 | * real_t m_window[ 10 ] = { 0.0f }; |
162 | 162 | * bool ret; |
|
168 | 168 | * @endcode |
169 | 169 | * |
170 | 170 | * |
171 | | -* @section qssmoother_mor2 Moving Outlier Removal Filter O(1) |
172 | | -* |
173 | | -* The \ref qlibs::smootherMOR2 is similar to the previous filter, but with a constant time complexity of \f$O(1)\f$ |
| 171 | +* @section qssmoother_mor2 Moving Outlier Removal Filter O(1) |
| 172 | +* |
| 173 | +* The \ref qlibs::smootherMOR2 is similar to the previous filter, but with a constant time complexity of \f$O(1)\f$ |
174 | 174 | * by using a \ref qlibs::tdl data structure. |
175 | 175 | * |
176 | 176 | * @subsection qssmoother_ex6 Example: setting up an outlier removal filter: |
177 | 177 | * @code{.c} |
178 | | -* smootherMOR2 smoother; |
| 178 | +* smootherMOR2 smoother; |
179 | 179 | * real_t alpha = 0.8f; |
180 | 180 | * real_t m_window[ 100 ] = { 0.0f }; |
181 | 181 | * bool ret; |
|
191 | 191 | * |
192 | 192 | * \ref qlibs::smootherGMWF is a filter that uses a kernel for smoothing, which defines the shape of the function |
193 | 193 | * that is used to take the average of the neighboring points. A Gaussian kernel |
194 | | -* has the shape of a Gaussian curve with a normal distribution. |
| 194 | +* has the shape of a Gaussian curve with a normal distribution. |
195 | 195 | * |
196 | 196 | * The coefficients of the kernel are computed from the following equation: |
197 | 197 | * |
|
210 | 210 | * const real_t sigma = 0.5f; |
211 | 211 | * const real_t centerOffset = SMOOTHER_WINDOW_SIZE/2.0f; |
212 | 212 | * |
213 | | -* smootherGMWF filter; |
| 213 | +* smootherGMWF filter; |
214 | 214 | * real_t window[ SMOOTHER_WINDOW_SIZE ] = { 0.0f }; |
215 | 215 | * real_t kernel[ SMOOTHER_WINDOW_SIZE ] = { 0.0f }; |
216 | 216 | * bool ret; |
|
222 | 222 | * @endcode |
223 | 223 | * |
224 | 224 | * |
225 | | -* @section qssmoother_expw Exponential Weighting filter |
| 225 | +* @section qssmoother_expw Exponential Weighting filter |
226 | 226 | * |
227 | 227 | * The \ref qlibs::smootherEXPW filter uses a weighting factor that is computed and applied to the input |
228 | 228 | * signal in a recursive manner. The weighting factor decreases exponentially as |
|
244 | 244 | * |
245 | 245 | * @subsection qssmoother_ex8 Example: setting up an exponential weighting filter: |
246 | 246 | * @code{.c} |
247 | | -* smootherEXPW filter; |
| 247 | +* smootherEXPW filter; |
248 | 248 | * real_t lambda = 0.8f; |
249 | 249 | * bool ret; |
250 | 250 | * |
|
255 | 255 | * @endcode |
256 | 256 | * |
257 | 257 | * |
258 | | -* @section qssmoother_klmn Scalar Kalman filter |
| 258 | +* @section qssmoother_klmn Scalar Kalman filter |
259 | 259 | * |
260 | 260 | * The \ref qlibs::smootherKLMN (Kalman Filter) is an efficient optimal estimator that provides a recursive |
261 | 261 | * computational methodology for getting the state of a signal from measurements |
262 | 262 | * that are typically noisy, while providing an estimate of the uncertainty of |
263 | 263 | * the estimate. Here, the scalar or one-dimensional version is provided |
264 | 264 | * and only three design parameters are required, the initial covariance \f$P(0)\f$, |
265 | 265 | * the signal noise covariance \f$Q\f$ and the measurement uncertainty \f$r\f$. |
266 | | -* |
267 | | -* The recursive equations used by this scalar version are: |
| 266 | +* |
| 267 | +* The recursive equations used by this scalar version are: |
268 | 268 | * |
269 | 269 | * predict |
270 | 270 | * |
|
283 | 283 | * <center> \f$ P(k) = ( 1 - K(k)H )P(k-1) \f$ </center> |
284 | 284 | * |
285 | 285 | * Where |
286 | | -* |
| 286 | +* |
287 | 287 | * \f$A\f$ is the state transition model, \f$H\f$ the observation model, \f$x(k)\f$ |
288 | 288 | * the filter output (state estimation), \f$P(k)\f$ the covariance of the predicted |
289 | 289 | * state, \f$u(k)\f$ the signal measurement and \f$K(k)\f$ the kalman gain. |
290 | | -* |
| 290 | +* |
291 | 291 | * @subsection qssmoother_ex9 Example: setting up a scalar Kalman filter: |
292 | 292 | * @code{.c} |
293 | 293 | * smootherKLMN filter; |
|
303 | 303 | * @section qssmoother_desf Double Exponential Smoothing |
304 | 304 | * |
305 | 305 | * The \ref qlibs::smootherDESF is a time series forecasting filter used to analyze and predict trends in |
306 | | -* data. It is an extension of simple exponential smoothing that incorporates |
| 306 | +* data. It is an extension of simple exponential smoothing that incorporates |
307 | 307 | * trend information into the forecast. |
308 | | -* |
| 308 | +* |
309 | 309 | * The double exponential smoothing filter calculates two smoothing coefficients, |
310 | 310 | * one for the level of the series and one for the trend. These coefficients are |
311 | | -* used to give more weight to recent observations and dampen the effect of |
312 | | -* older observations. The level and trend are then updated using the following |
| 311 | +* used to give more weight to recent observations and dampen the effect of |
| 312 | +* older observations. The level and trend are then updated using the following |
313 | 313 | * equations: |
314 | 314 | * |
315 | 315 | * Level: |
|
318 | 318 | * Trend: |
319 | 319 | * <center> \f$ T(t) = \beta [ L(t-1) + T(t-1) ] + ( 1 - \beta ) T(t-1) \f$ </center> |
320 | 320 | * |
321 | | -* where \f$\alpha\f$ and \f$\beta\f$ are the smoothing coefficients for the |
| 321 | +* where \f$\alpha\f$ and \f$\beta\f$ are the smoothing coefficients for the |
322 | 322 | * level and trend, respectively. |
323 | | -* |
| 323 | +* |
324 | 324 | * The double exponential smoothing filter can be used to generate forecasts by |
325 | 325 | * extrapolating the level and trend components into the future. The forecast for |
326 | 326 | * time \f$t+k\f$ is given by: |
327 | | -* |
| 327 | +* |
328 | 328 | * <center> \f$ F(t+k) = L(t) + kT(t) \f$ </center> |
329 | | -* |
| 329 | +* |
330 | 330 | * Where \f$k\f$ is the number of time periods into the future. |
331 | 331 | * |
332 | | -* Overall, double exponential smoothing is a simple but effective technique |
| 332 | +* Overall, double exponential smoothing is a simple but effective technique |
333 | 333 | * for forecasting time series data with trends. It can be easily implemented 3 |
334 | | -* and provides accurate forecasts for short-term predictions. However, it may |
335 | | -* not perform well for longer-term forecasts or for data with complex seasonal |
| 334 | +* and provides accurate forecasts for short-term predictions. However, it may |
| 335 | +* not perform well for longer-term forecasts or for data with complex seasonal |
336 | 336 | * patterns. |
337 | 337 | * |
| 338 | +* @subsection qssmoother_ex10 Example: setting up the Double Exponential Smoothing: |
| 339 | +* @code{.c} |
| 340 | +* smootherDESF filter; |
| 341 | +* bool ret; |
| 342 | +* |
| 343 | +* ret = filter.setup( 0.08f, 0.085f, 10.0f ); |
| 344 | +* if ( !ret ) { |
| 345 | +* // error, smooth filter cant be configured |
| 346 | +* } |
| 347 | +* @endcode |
| 348 | +* |
338 | 349 | * @section qssmoother_alnf Adaptive Linear Filter |
339 | 350 | * |
340 | 351 | * The \ref qlibs::smootherALNF is a digital filter that adjusts its parameters based on the |
341 | 352 | * characteristics of the input signal and the desired output signal. |
342 | | -* |
| 353 | +* |
343 | 354 | * The adaptive linear filter works by using an algorithm to iteratively adjust |
344 | 355 | * the filter coefficients in response to changes in the input signal \f$x(t)\f$. |
345 | 356 | * The algorithm seeks to minimize the difference between the filter output and |
346 | | -* the desired output, known as the error signal \f$ e(t)\f$. This is done by |
347 | | -* adjusting the filter coefficients \f$w_i(t)\f$ in the direction that reduces |
348 | | -* the error signal. For this, the Least Mean Squares (LMS) algorithm is being |
349 | | -* used. The LMS algorithm updates the filter coefficients by multiplying the |
350 | | -* error signal by the input signal and a small step size parameter, and then |
| 357 | +* the desired output, known as the error signal \f$ e(t)\f$. This is done by |
| 358 | +* adjusting the filter coefficients \f$w_i(t)\f$ in the direction that reduces |
| 359 | +* the error signal. For this, the Least Mean Squares (LMS) algorithm is being |
| 360 | +* used. The LMS algorithm updates the filter coefficients by multiplying the |
| 361 | +* error signal by the input signal and a small step size parameter, and then |
351 | 362 | * adding this product to the existing filter coefficients. |
352 | | -* |
353 | | -* It is particularly useful in situations where the characteristics of the |
| 363 | +* |
| 364 | +* It is particularly useful in situations where the characteristics of the |
354 | 365 | * input signal are unknown or change over time, as it can adapt to these changes |
355 | 366 | * and continue to provide accurate filtering or modeling. |
356 | 367 | * |
357 | | -* One potential drawback of the adaptive linear filter is that it can be |
358 | | -* computationally intensive, especially if the input signal is large or the |
359 | | -* filter has many coefficients. Additionally, the performance of the filter |
360 | | -* can be sensitive to the choice of step size parameter, which must be |
| 368 | +* One potential drawback of the adaptive linear filter is that it can be |
| 369 | +* computationally intensive, especially if the input signal is large or the |
| 370 | +* filter has many coefficients. Additionally, the performance of the filter |
| 371 | +* can be sensitive to the choice of step size parameter, which must be |
361 | 372 | * carefully chosen to balance convergence speed with stability. |
362 | 373 | * |
363 | 374 | * The adaptation rule for every filter coefficient is given by |
364 | 375 | * <center> \f$ \Delta w(t) = \alpha e(t) x(t) + \mu \Delta w(t-1) \f$ </center> |
365 | 376 | * |
366 | 377 | * <center> \f$ w(t) = w(t-1) x(t) + \Delta w(t) \f$ </center> |
367 | 378 | * |
368 | | -* The equation also includes a momentum term that adds a fraction of the |
369 | | -* previous coefficient update to the current coefficient update. This can help |
| 379 | +* The equation also includes a momentum term that adds a fraction of the |
| 380 | +* previous coefficient update to the current coefficient update. This can help |
370 | 381 | * to reduce oscillations in the filter output and improve convergence speed. |
371 | 382 | * |
372 | 383 | * @section qssmoother_ex10 Example of signal smoothing |
|
392 | 403 | * constexpr uint32_t SMOOTHER_SAMPLE_TIME = 100; |
393 | 404 | * constexpr real_t GAUSS_SIGMA = 0.5f; |
394 | 405 | * constexpr real_t GAUSS_CENTER = SMOOTHER_WINDOW_SIZE/2.0f; |
395 | | -* |
| 406 | +* |
396 | 407 | * void xTaskSignalProcessing( void *arg ) |
397 | 408 | * { |
398 | 409 | * smootherGMWF *filter = static_cast<smootherGMWF *>( arg ); |
|
405 | 416 | * vTaskDelay( SMOOTHER_SAMPLE_TIME / portTICK_RATE_MS ) ; |
406 | 417 | * } |
407 | 418 | * } |
408 | | -* |
| 419 | +* |
409 | 420 | * int main( int argc, char *argv[] ) |
410 | 421 | * { |
411 | 422 | * smootherGMWF filter; |
412 | 423 | * real_t window[ SMOOTHER_WINDOW_SIZE ] = { 0.0f }; |
413 | 424 | * real_t kernel[ SMOOTHER_WINDOW_SIZE ] = { 0.0f }; |
414 | 425 | * bool ret; |
415 | | -* |
| 426 | +* |
416 | 427 | * BSP_SystemInit( ); |
417 | 428 | * ret = filter.setup( GAUSS_SIGMA, GAUSS_CENTER, window, kernel ); |
418 | 429 | * if ( !ret ) { |
|
0 commit comments