Skip to content

Commit fec05f7

Browse files
authored
Merge pull request vedderb#315 from surfdado/bqfix
Balance App - biquad filters: add config/reset functions
2 parents b3c069a + 02caad3 commit fec05f7

File tree

1 file changed

+36
-34
lines changed

1 file changed

+36
-34
lines changed

applications/app_balance.c

+36-34
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ typedef struct{
7070
float z1, z2;
7171
} Biquad;
7272

73+
typedef enum {
74+
BQ_LOWPASS,
75+
BQ_HIGHPASS
76+
} BiquadType;
77+
7378
// Balance thread
7479
static THD_FUNCTION(balance_thread, arg);
7580
static THD_WORKING_AREA(balance_thread_wa, 2048); // 2kb stack for this thread
@@ -128,12 +133,33 @@ static void app_balance_sample_debug(void);
128133
static void app_balance_experiment(void);
129134

130135
// Utility Functions
131-
float biquad_process(float in, Biquad *biquad) {
136+
float biquad_process(Biquad *biquad, float in) {
132137
float out = in * biquad->a0 + biquad->z1;
133138
biquad->z1 = in * biquad->a1 + biquad->z2 - biquad->b1 * out;
134139
biquad->z2 = in * biquad->a2 - biquad->b2 * out;
135140
return out;
136141
}
142+
void biquad_config(Biquad *biquad, BiquadType type, float Fc) {
143+
float K = tanf(M_PI * Fc); // -0.0159;
144+
float Q = 0.707; // maximum sharpness (0.5 = maximum smoothness)
145+
float norm = 1 / (1 + K / Q + K * K);
146+
if (type == BQ_LOWPASS) {
147+
biquad->a0 = K * K * norm;
148+
biquad->a1 = 2 * biquad->a0;
149+
biquad->a2 = biquad->a0;
150+
}
151+
else if (type == BQ_HIGHPASS) {
152+
biquad->a0 = 1 * norm;
153+
biquad->a1 = -2 * biquad->a0;
154+
biquad->a2 = biquad->a0;
155+
}
156+
biquad->b1 = 2 * (K * K - 1) * norm;
157+
biquad->b2 = (1 - K / Q + K * K) * norm;
158+
}
159+
void biquad_reset(Biquad *biquad) {
160+
biquad->z1 = 0;
161+
biquad->z2 = 0;
162+
}
137163

138164
// Exposed Functions
139165
void app_balance_configure(balance_config *conf, imu_config *conf2) {
@@ -166,36 +192,15 @@ void app_balance_configure(balance_config *conf, imu_config *conf2) {
166192
}
167193
if(balance_conf.kd_biquad_lowpass > 0){
168194
float Fc = balance_conf.kd_biquad_lowpass / balance_conf.hertz;
169-
float Q = 0.707; // Flat response
170-
float K = tan(M_PI * Fc);
171-
float norm = 1 / (1 + K / Q + K * K);
172-
d_biquad_lowpass.a0 = K * K * norm;
173-
d_biquad_lowpass.a1 = 2 * d_biquad_lowpass.a0;
174-
d_biquad_lowpass.a2 = d_biquad_lowpass.a0;
175-
d_biquad_lowpass.b1 = 2 * (K * K - 1) * norm;
176-
d_biquad_lowpass.b2 = (1 - K / Q + K * K) * norm;
195+
biquad_config(&d_biquad_lowpass, BQ_LOWPASS, Fc);
177196
}
178197
if(balance_conf.kd_biquad_highpass > 0){
179198
float Fc = balance_conf.kd_biquad_highpass / balance_conf.hertz;
180-
float Q = 0.707; // Flat response
181-
float K = tan(M_PI * Fc);
182-
float norm = 1 / (1 + K / Q + K * K);
183-
d_biquad_highpass.a0 = 1 * norm;
184-
d_biquad_highpass.a1 = -2 * d_biquad_highpass.a0;
185-
d_biquad_highpass.a2 = d_biquad_highpass.a0;
186-
d_biquad_highpass.b1 = 2 * (K * K - 1) * norm;
187-
d_biquad_highpass.b2 = (1 - K / Q + K * K) * norm;
199+
biquad_config(&d_biquad_highpass, BQ_HIGHPASS, Fc);
188200
}
189201
if(balance_conf.torquetilt_filter > 0){ // Torquetilt Current Biquad
190202
float Fc = balance_conf.torquetilt_filter / balance_conf.hertz;
191-
float Q = 0.707; // Flat response
192-
float K = tan(M_PI * Fc);
193-
float norm = 1 / (1 + K / Q + K * K);
194-
torquetilt_current_biquad.a0 = K * K * norm;
195-
torquetilt_current_biquad.a1 = 2 * torquetilt_current_biquad.a0;
196-
torquetilt_current_biquad.a2 = torquetilt_current_biquad.a0;
197-
torquetilt_current_biquad.b1 = 2 * (K * K - 1) * norm;
198-
torquetilt_current_biquad.b2 = (1 - K / Q + K * K) * norm;
203+
biquad_config(&torquetilt_current_biquad, BQ_LOWPASS, Fc);
199204
}
200205

201206
// Variable nose angle adjustment / tiltback (setting is per 1000erpm, convert to per erpm)
@@ -283,10 +288,8 @@ static void reset_vars(void){
283288
yaw_last_proportional = 0;
284289
d_pt1_lowpass_state = 0;
285290
d_pt1_highpass_state = 0;
286-
d_biquad_lowpass.z1 = 0;
287-
d_biquad_lowpass.z2 = 0;
288-
d_biquad_highpass.z1 = 0;
289-
d_biquad_highpass.z2 = 0;
291+
biquad_reset(&d_biquad_lowpass);
292+
biquad_reset(&d_biquad_highpass);
290293
// Set values for startup
291294
setpoint = pitch_angle;
292295
setpoint_target_interpolated = pitch_angle;
@@ -295,8 +298,7 @@ static void reset_vars(void){
295298
torquetilt_target = 0;
296299
torquetilt_interpolated = 0;
297300
torquetilt_filtered_current = 0;
298-
torquetilt_current_biquad.z1 = 0;
299-
torquetilt_current_biquad.z2 = 0;
301+
biquad_reset(&torquetilt_current_biquad);
300302
turntilt_target = 0;
301303
turntilt_interpolated = 0;
302304
setpointAdjustmentType = CENTERING;
@@ -450,7 +452,7 @@ static void apply_noseangling(void){
450452
static void apply_torquetilt(void){
451453
// Filter current (Biquad)
452454
if(balance_conf.torquetilt_filter > 0){
453-
torquetilt_filtered_current = biquad_process(motor_current, &torquetilt_current_biquad);
455+
torquetilt_filtered_current = biquad_process(&torquetilt_current_biquad, motor_current);
454456
}else{
455457
torquetilt_filtered_current = motor_current;
456458
}
@@ -701,10 +703,10 @@ static THD_FUNCTION(balance_thread, arg) {
701703
derivative = derivative - d_pt1_highpass_state;
702704
}
703705
if(balance_conf.kd_biquad_lowpass > 0){
704-
derivative = biquad_process(derivative, &d_biquad_lowpass);
706+
derivative = biquad_process(&d_biquad_lowpass, derivative);
705707
}
706708
if(balance_conf.kd_biquad_highpass > 0){
707-
derivative = biquad_process(derivative, &d_biquad_highpass);
709+
derivative = biquad_process(&d_biquad_highpass, derivative);
708710
}
709711

710712
pid_value = (balance_conf.kp * proportional) + (balance_conf.ki * integral) + (balance_conf.kd * derivative);

0 commit comments

Comments
 (0)