Skip to content

Commit 6bd7e3e

Browse files
committed
lulu: use union, add coeff function, optimize for constant substitution
1 parent 210f668 commit 6bd7e3e

File tree

3 files changed

+75
-78
lines changed

3 files changed

+75
-78
lines changed

src/flight/filter.c

Lines changed: 59 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -90,98 +90,90 @@ float filter_lp_pt3_step(filter_lp_pt3 *filter, filter_state_t *state, float in)
9090
return state->delay_element[0];
9191
}
9292

93-
void filter_lp_lulu_init(filter_t *filter, filter_state_t *filter_state, uint8_t count, float hz) {
94-
//The window value is half the wavelength of the wave that it filters. So if the wavelength of the cutoff frequency is 2 samples, the N value should be 1. If the wavelength is 4, N should be 2. Etc.
93+
void filter_lp_lulu_coeff(filter_lp_lulu *filter, float hz) {
94+
if (filter->hz == hz && filter->sample_period_us == state.looptime_autodetect) {
95+
return;
96+
}
97+
filter->hz = hz;
98+
filter->sample_period_us = state.looptime_autodetect;
99+
100+
// The window value is half the wavelength of the wave that it filters. So if the wavelength of the cutoff frequency is 2 samples, the N value should be 1. If the wavelength is 4, N should be 2. Etc.
95101
float cutoff_wave_length = 1.0f / hz / 4.0f;
96102
float loop_wave_length = state.looptime_autodetect * 1e-6f;
97-
uint32_t window_half_length = cutoff_wave_length / loop_wave_length;
98-
99-
filter->lp_lulu.num_samples = constrain(window_half_length, 1, 12);
100-
filter->lp_lulu.window_size = filter->lp_lulu.num_samples * 2 + 1;
101-
filter_init_state(filter_state, count);
103+
uint8_t window_half_length = cutoff_wave_length / loop_wave_length;
104+
105+
filter->num_samples = constrain(window_half_length, 1, 12);
106+
filter->window_size = filter->num_samples * 2 + 1;
102107
}
103108

104-
static float fix_road(float *series, float *series_b, int32_t index, int32_t filter_n, int32_t window_size) {
105-
float cur_val = 0;
106-
float cur_val_b = 0;
107-
for (int32_t N = 1; N <= filter_n; N++) {
108-
int32_t index_neg = (index + window_size - 2 * N) % window_size;
109-
int32_t cur_index = (index_neg + 1) % window_size;
109+
void filter_lp_lulu_init(filter_lp_lulu *filter, filter_state_t *state, uint8_t count, float hz) {
110+
filter_lp_lulu_coeff(filter, hz);
111+
filter_init_state(state, count);
112+
}
113+
114+
static float fix_road(float *series, float *series_b, uint8_t index, uint8_t filter_n, uint8_t window_size) {
115+
for (uint32_t N = 1; N <= filter_n; N++) {
116+
const uint32_t index_neg = (index + window_size - 2 * N) % window_size;
117+
110118
float prev_val = series[index_neg];
111119
float prev_val_b = series_b[index_neg];
112-
int32_t index_pos = (cur_index + N) % window_size;
113-
for (int32_t i = window_size - 2 * N; i < window_size - N; i++) {
114-
if (index_pos >= window_size) {
115-
index_pos = 0;
116-
}
117-
if (cur_index >= window_size) {
118-
cur_index = 0;
119-
}
120-
121-
cur_val = series[cur_index];
122-
cur_val_b = series_b[cur_index];
123-
float next_val = series[index_pos];
124-
float next_val_b = series_b[index_pos];
125120

121+
uint32_t cur_index = (index_neg + 1) % window_size;
122+
uint32_t index_pos = (cur_index + N) % window_size;
123+
for (uint32_t i = window_size - 2 * N; i < window_size - N; i++) {
124+
const float cur_val = series[cur_index];
125+
const float next_val = series[index_pos];
126126
if (prev_val < cur_val && cur_val > next_val) {
127-
float maxValue = max(prev_val, next_val);
128-
series[cur_index] = maxValue;
127+
series[cur_index] = max(prev_val, next_val);
129128
}
129+
prev_val = cur_val;
130130

131+
const float cur_val_b = series_b[cur_index];
132+
const float next_val_b = series_b[index_pos];
131133
if (prev_val_b < cur_val_b && cur_val_b > next_val_b) {
132-
float maxValue = max(prev_val_b, next_val_b);
133-
series_b[cur_index] = maxValue;
134+
series_b[cur_index] = max(prev_val_b, next_val_b);
134135
}
135-
prev_val = cur_val;
136136
prev_val_b = cur_val_b;
137-
cur_index++;
138-
index_pos++;
137+
138+
cur_index = (cur_index + 1) % window_size;
139+
index_pos = (index_pos + 1) % window_size;
139140
}
140141

141-
cur_index = (index_neg + 1) % window_size;
142142
prev_val = series[index_neg];
143143
prev_val_b = series_b[index_neg];
144-
index_pos = (cur_index + N) % window_size;
145-
for (int32_t i = window_size - 2 * N; i < window_size - N; i++) {
146-
if (index_pos >= window_size) {
147-
index_pos = 0;
148-
}
149-
if (cur_index >= window_size) {
150-
cur_index = 0;
151-
}
152-
153-
cur_val = series[cur_index];
154-
cur_val_b = series_b[cur_index];
155-
float next_val = series[index_pos];
156-
float next_val_b = series_b[index_pos];
157144

145+
cur_index = (index_neg + 1) % window_size;
146+
index_pos = (cur_index + N) % window_size;
147+
for (uint32_t i = window_size - 2 * N; i < window_size - N; i++) {
148+
const float cur_val = series[cur_index];
149+
const float next_val = series[index_pos];
158150
if (prev_val > cur_val && cur_val < next_val) {
159-
float minValue = min(prev_val, next_val);
160-
series[cur_index] = minValue;
151+
series[cur_index] = min(prev_val, next_val);
161152
}
153+
prev_val = cur_val;
162154

155+
const float cur_val_b = series_b[cur_index];
156+
const float next_val_b = series_b[index_pos];
163157
if (prev_val_b > cur_val_b && cur_val_b < next_val_b) {
164-
float minValue = min(prev_val_b, next_val_b);
165-
series_b[cur_index] = minValue;
158+
series_b[cur_index] = min(prev_val_b, next_val_b);
166159
}
167-
prev_val = cur_val;
168160
prev_val_b = cur_val_b;
169-
cur_index++;
170-
index_pos++;
161+
162+
cur_index = (cur_index + 1) % window_size;
163+
index_pos = (index_pos + 1) % window_size;
171164
}
172165
}
173-
int32_t final_index = (index + window_size - filter_n) % window_size;
174-
cur_val = series[final_index];
175-
cur_val_b = series_b[final_index];
176-
return (cur_val - cur_val_b) / 2;
166+
167+
const uint8_t final_index = (index + window_size - filter_n) % window_size;
168+
return (series[final_index] - series_b[final_index]) / 2;
177169
}
178170

179-
float filter_lp_lulu_step(filter_t *filter, filter_state_t *filter_state, float in) {
180-
int32_t window_index = filter_state->lulu_state.window_buf_index;
181-
filter_state->lulu_state.window_buf_index = (window_index + 1) % filter->lp_lulu.window_size;
182-
filter_state->lulu_state.interim[window_index] = in;
183-
filter_state->lulu_state.interim_b[window_index] = -in;
184-
return fix_road(filter_state->lulu_state.interim, filter_state->lulu_state.interim_b, window_index, filter->lp_lulu.num_samples, filter->lp_lulu.window_size);
171+
float filter_lp_lulu_step(filter_lp_lulu *filter, filter_state_t *state, float in) {
172+
const uint8_t window_index = state->window_buf_index;
173+
state->window_buf_index = (window_index + 1) % filter->window_size;
174+
state->interim[window_index] = in;
175+
state->interim_b[window_index] = -in;
176+
return fix_road(state->interim, state->interim_b, window_index, filter->num_samples, filter->window_size);
185177
}
186178

187179
void filter_biquad_notch_init(filter_biquad_notch_t *filter, filter_biquad_state_t *state, uint8_t count, float hz) {
@@ -303,6 +295,9 @@ void filter_coeff(filter_type_t type, filter_t *filter, float hz) {
303295
case FILTER_LP_PT3:
304296
filter_lp_pt3_coeff(&filter->lp_pt3, hz);
305297
break;
298+
case FILTER_LP_LULU:
299+
filter_lp_lulu_coeff(&filter->lp_lulu, hz);
300+
break;
306301
default:
307302
// no filter, do nothing
308303
break;

src/flight/filter.h

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,17 @@ typedef enum {
1212
FILTER_LP_LULU,
1313
} __attribute__((__packed__)) filter_type_t;
1414

15-
typedef struct {
15+
typedef union {
16+
struct {
17+
float delay_element[3];
18+
};
19+
struct {
1620
float interim[32];
1721
float interim_b[32];
18-
int32_t window_buf_index;
19-
} filter_lulu_state_t;
20-
21-
typedef struct {
22-
float delay_element[3];
23-
filter_lulu_state_t lulu_state;
22+
uint8_t window_buf_index;
23+
};
2424
} filter_state_t;
2525

26-
2726
typedef struct {
2827
float x1;
2928
float x2;
@@ -52,10 +51,13 @@ typedef struct {
5251
float alpha;
5352
} filter_lp_pt3;
5453

55-
//Max N = 15
54+
// Max N = 15
5655
typedef struct {
57-
int window_size;
58-
int num_samples;
56+
float hz;
57+
uint32_t sample_period_us;
58+
59+
uint8_t window_size;
60+
uint8_t num_samples;
5961
} filter_lp_lulu;
6062

6163
typedef struct {
@@ -113,8 +115,9 @@ void filter_lp_pt3_init(filter_lp_pt3 *filter, filter_state_t *state, uint8_t co
113115
void filter_lp_pt3_coeff(filter_lp_pt3 *filter, float hz);
114116
float filter_lp_pt3_step(filter_lp_pt3 *filter, filter_state_t *state, float in);
115117

116-
void filter_lp_lulu_init(filter_t *filter, filter_state_t *state, uint8_t count, float hz);
117-
float filter_lp_lulu_step(filter_t *filter, filter_state_t *lulu_state, float in);
118+
void filter_lp_lulu_init(filter_lp_lulu *filter, filter_state_t *state, uint8_t count, float hz);
119+
void filter_lp_lulu_coeff(filter_lp_lulu *filter, float hz);
120+
float filter_lp_lulu_step(filter_lp_lulu *filter, filter_state_t *state, float in);
118121

119122
void filter_biquad_notch_init(filter_biquad_notch_t *filter, filter_biquad_state_t *state, uint8_t count, float hz);
120123
void filter_biquad_notch_coeff(filter_biquad_notch_t *filter, float hz);

src/flight/sixaxis.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ static float rot_mat[3][3] = {
4242

4343
static filter_t filter[FILTER_MAX_SLOTS];
4444
static filter_state_t filter_state[FILTER_MAX_SLOTS][3];
45-
static filter_lulu_state_t lulu_filter_state_gyro[3];
4645

4746
static sdft_t gyro_sdft[SDFT_AXES];
4847
static filter_biquad_notch_t notch_filter[SDFT_AXES][SDFT_PEAKS];

0 commit comments

Comments
 (0)