Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
adaptive_notch_filter.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Dennis van Wijngaarden
3  * Ewoud Smeur
4  *
5  * This file is part of paparazzi.
6  *
7  * paparazzi is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * paparazzi is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with paparazzi; see the file COPYING. If not, write to
19  * the Free Software Foundation, 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22 
28 #ifndef ADAPTIVE_NOTCH_FILTER_H
29 #define ADAPTIVE_NOTCH_FILTER_H
30 
31 #include "std.h"
34 
36  float Ts; // Sample time
37  float lp_cutoff_f; // Lowpass cutoff frequency
38  float hp_cutoff_f; // Highpass cutoff frequency
39  float r; // Stop-band filter's bandwidth
40  float r2; // Stop-band filter's bandwidth squared
41  float lambda; // Learning gain
42 
43  float a_est; // estimated notch frequency
44  float y[2]; // Notch filtered measurement vector
45  float y_est[2]; // Notch filtered estimation vector
46 
47  struct SecondOrderNotchFilter output_n_filter; // Output notch filter
48  Butterworth2LowPass lp_filter; // Lowpass filter for the lower bound of the bandpass filter
49  Butterworth2LowPass hp_filter; // Lowpass filter for the higher bound of the bandpass filter
50 
51  float xband[3]; // Bandpassed measurement signals signals
52 };
53 
65 static inline void adaptive_notch_filter_init(struct AdaptiveNotchFilter *filter, float sample_time,
66  float low_freq_bound, float high_freq_bound, float bandwidth, float lambda, float a_ini, float value)
67 {
68  // Init filter parameters
69  filter->Ts = sample_time;
70  filter->lp_cutoff_f = low_freq_bound;
71  filter->hp_cutoff_f = high_freq_bound;
72  filter->r = bandwidth;
73  filter->lambda = lambda;
74 
75  // Initialize initial filter values
76  filter->y[0] = filter->y[1] = filter->y_est[0] = filter->y_est[1] = value;
77  filter->a_est = a_ini;
78 
79  filter->xband[0] = filter->xband[1] = filter->xband[2] = value;
80 
81  // Init output notch filter
82  float fs = 1. / filter->Ts;
83  notch_filter_init(&filter->output_n_filter, filter->a_est, filter->r, fs);
84 
85  // Init lowpass filter
86  float lp_tau = 1.0 / (2.0 * M_PI * filter->lp_cutoff_f);
87  init_butterworth_2_low_pass(&filter->lp_filter, lp_tau, filter->Ts, 0.0);
88 
89  // Init highpass filter
90  float hp_tau = 1.0 / (2.0 * M_PI * filter->hp_cutoff_f);
91  init_butterworth_2_low_pass(&filter->hp_filter, hp_tau, filter->Ts, 0.0);
92 
93 }
94 
102 static inline void adaptive_notch_filter_update(struct AdaptiveNotchFilter *filter, float value, float *output_signal)
103 {
104  // Propagate Butterworth lowpass and hightpass filters for a bandpass signal
105  update_butterworth_2_low_pass(&filter->lp_filter, value);
106  update_butterworth_2_low_pass(&filter->hp_filter, value);
107 
108  filter->xband[2] = filter->xband[1];
109  filter->xband[1] = filter->xband[0];
110  filter->xband[0] = value - filter->lp_filter.o[0] - (value - filter->hp_filter.o[0]);
111 
112  // Run output notch filter
114  notch_filter_update(&filter->output_n_filter, &value, output_signal);
115 
116  // Run estimation notch filter
117  float out_est = filter->xband[0] - filter->a_est * filter->xband[1] + filter->xband[2] + filter->r * filter->a_est *
118  filter->y_est[0] - filter->r2 * filter->y_est[1];
119 
120  float beta = -filter->xband[1] + filter->r * filter->y_est[1];
121  filter->a_est = filter->a_est - filter->lambda * filter->Ts * filter->y_est[0] * beta;
122  // Bound estimation frequency to the bandpass cutoff frequencies to be safe
123  Bound(filter->a_est, filter->lp_cutoff_f, filter->hp_cutoff_f);
124 
125  filter->y[1] = filter->y[0];
126  filter->y[0] = *output_signal;
127  filter->y_est[1] = filter->y_est[0];
128  filter->y_est[0] = out_est;
129 
130 }
131 
138 static inline float adaptive_notch_filter_get_output(struct AdaptiveNotchFilter *filter)
139 {
140  return filter->y_est[0];
141 }
142 
143 
144 #endif // ADAPTIVE_NOTCH_FILTER_H
static void adaptive_notch_filter_update(struct AdaptiveNotchFilter *filter, float value, float *output_signal)
Update a second order adaptive notch filter.
Butterworth2LowPass hp_filter
static void adaptive_notch_filter_init(struct AdaptiveNotchFilter *filter, float sample_time, float low_freq_bound, float high_freq_bound, float bandwidth, float lambda, float a_ini, float value)
Init a adaptive notch filter.
struct SecondOrderNotchFilter output_n_filter
static float adaptive_notch_filter_get_output(struct AdaptiveNotchFilter *filter)
Return the latest second order adaptive notch filter output.
Butterworth2LowPass lp_filter
Simple first order low pass filter with bilinear transform.
float o[2]
output history
static void init_butterworth_2_low_pass(Butterworth2LowPass *filter, float tau, float sample_time, float value)
Init a second order Butterworth filter.
static float update_butterworth_2_low_pass(Butterworth2LowPass *filter, float value)
Update second order Butterworth low pass filter state with a new value.
Second order low pass filter structure.
static void notch_filter_update(struct SecondOrderNotchFilter *filter, int32_t *input_signal, int32_t *output_signal)
Notch filter propagate.
Definition: notch_filter.h:83
static void notch_filter_set_filter_frequency(struct SecondOrderNotchFilter *filter, float frequency)
Set notch filter frequency in Hz.
Definition: notch_filter.h:68
static void notch_filter_init(struct SecondOrderNotchFilter *filter, float cutoff_frequency, float bandwidth, uint16_t sample_frequency)
Initialize second order notch filter.
Definition: notch_filter.h:119
float lambda