Skip to content

Commit 7c9415c

Browse files
Quick-FlashnerdCopter
authored andcommitted
choose ptn filter order for rc filtering
1 parent a6207a1 commit 7c9415c

File tree

7 files changed

+64
-17
lines changed

7 files changed

+64
-17
lines changed

src/main/cli/settings.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,7 @@ const clivalue_t valueTable[] = {
756756

757757
#ifdef USE_RC_SMOOTHING_FILTER
758758
{ PARAM_NAME_RC_SMOOTHING, VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_RX_CONFIG, offsetof(rxConfig_t, rc_smoothing_mode) },
759+
{ "rc_smoothing_order", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 1, 3 }, PG_RX_CONFIG, offsetof(rxConfig_t, rc_smoothing_mode) },
759760
{ PARAM_NAME_RC_SMOOTHING_AUTO_FACTOR, VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { RC_SMOOTHING_AUTO_FACTOR_MIN, RC_SMOOTHING_AUTO_FACTOR_MAX }, PG_RX_CONFIG, offsetof(rxConfig_t, rc_smoothing_auto_factor_rpy) },
760761
{ PARAM_NAME_RC_SMOOTHING_AUTO_FACTOR_THROTTLE, VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { RC_SMOOTHING_AUTO_FACTOR_MIN, RC_SMOOTHING_AUTO_FACTOR_MAX }, PG_RX_CONFIG, offsetof(rxConfig_t, rc_smoothing_auto_factor_throttle) },
761762
{ PARAM_NAME_RC_SMOOTHING_SETPOINT_CUTOFF, VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, UINT8_MAX }, PG_RX_CONFIG, offsetof(rxConfig_t, rc_smoothing_setpoint_cutoff) },

src/main/common/filter.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,37 @@ void simpleLPFilterInit(simpleLowpassFilter_t *filter, int32_t beta, int32_t fpS
309309
filter->beta = beta;
310310
filter->fpShift = fpShift;
311311
}
312+
313+
const float PTN_SCALE[3] = { 1.0f, 1.553773974f, 1.961459177f };
314+
315+
void ptnFilterInit(ptnFilter_t *filter, uint8_t order, uint16_t f_cut, float dT) {
316+
317+
// AdjCutHz = CutHz /(sqrtf(powf(2, 1/Order) -1))
318+
const float ScaleF[] = { 1.0f, 1.553773974f, 1.961459177f };
319+
float Adj_f_cut;
320+
321+
filter->order = (order > 3) ? 3 : order;
322+
for (int n = 1; n <= filter->order; n++) {
323+
filter->state[n] = 0.0f;
324+
}
325+
326+
Adj_f_cut = f_cut * PTN_SCALE[filter->order - 1];
327+
328+
filter->k = dT / ((1.0f / (2.0f * M_PIf * Adj_f_cut)) + dT);
329+
} // ptnFilterInit
330+
331+
FAST_CODE void ptnFilterUpdate(ptnFilter_t *filter, float f_cut, float dT) {
332+
float Adj_f_cut;
333+
Adj_f_cut = f_cut * PTN_SCALE[filter->order - 1];
334+
filter->k = dT / ((1.0f / (2.0f * M_PIf * Adj_f_cut)) + dT);
335+
}
336+
337+
FAST_CODE float ptnFilterApply(ptnFilter_t *filter, float input) {
338+
filter->state[0] = input;
339+
340+
for (int n = 1; n <= filter->order; n++) {
341+
filter->state[n] += (filter->state[n - 1] - filter->state[n]) * filter->k;
342+
}
343+
344+
return filter->state[filter->order];
345+
} // ptnFilterApply

src/main/common/filter.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ typedef struct laggedMovingAverage_s {
6363
bool primed;
6464
} laggedMovingAverage_t;
6565

66+
typedef struct simpleLowpassFilter_s {
67+
int32_t fp;
68+
int32_t beta;
69+
int32_t fpShift;
70+
} simpleLowpassFilter_t;
71+
72+
typedef struct ptnFilter_s {
73+
float state[4];
74+
float k;
75+
uint8_t order;
76+
} ptnFilter_t;
77+
6678
typedef enum {
6779
FILTER_PT1 = 0,
6880
FILTER_BIQUAD,
@@ -111,11 +123,9 @@ float pt3FilterApply(pt3Filter_t *filter, float input);
111123
void slewFilterInit(slewFilter_t *filter, float slewLimit, float threshold);
112124
float slewFilterApply(slewFilter_t *filter, float input);
113125

114-
typedef struct simpleLowpassFilter_s {
115-
int32_t fp;
116-
int32_t beta;
117-
int32_t fpShift;
118-
} simpleLowpassFilter_t;
119-
120126
int32_t simpleLPFilterUpdate(simpleLowpassFilter_t *filter, int32_t newVal);
121127
void simpleLPFilterInit(simpleLowpassFilter_t *filter, int32_t beta, int32_t fpShift);
128+
129+
void ptnFilterInit(ptnFilter_t *filter, uint8_t order, uint16_t f_cut, float dT);
130+
void ptnFilterUpdate(ptnFilter_t *filter, float f_cut, float dt);
131+
float ptnFilterApply(ptnFilter_t *filter, float input);

src/main/fc/rc.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -345,25 +345,25 @@ FAST_CODE_NOINLINE void rcSmoothingSetFilterCutoffs(rcSmoothingFilter_t *smoothi
345345
for (int i = 0; i < PRIMARY_CHANNEL_COUNT; i++) {
346346
if (i < THROTTLE) { // Throttle handled by smoothing rcCommand
347347
if (!smoothingData->filterInitialized) {
348-
pt3FilterInit(&smoothingData->filter[i], pt3FilterGain(smoothingData->setpointCutoffFrequency, dT));
348+
ptnFilterInit(&smoothingData->filter[i], rxConfig()->rc_smoothing_order, smoothingData->setpointCutoffFrequency, dT);
349349
} else {
350-
pt3FilterUpdateCutoff(&smoothingData->filter[i], pt3FilterGain(smoothingData->setpointCutoffFrequency, dT));
350+
ptnFilterUpdate(&smoothingData->filter[i], smoothingData->setpointCutoffFrequency, dT);
351351
}
352352
} else {
353353
if (!smoothingData->filterInitialized) {
354-
pt3FilterInit(&smoothingData->filter[i], pt3FilterGain(smoothingData->throttleCutoffFrequency, dT));
354+
ptnFilterInit(&smoothingData->filter[i], rxConfig()->rc_smoothing_order, smoothingData->throttleCutoffFrequency, dT);
355355
} else {
356-
pt3FilterUpdateCutoff(&smoothingData->filter[i], pt3FilterGain(smoothingData->throttleCutoffFrequency, dT));
356+
ptnFilterUpdate(&smoothingData->filter[i], smoothingData->throttleCutoffFrequency, dT);
357357
}
358358
}
359359
}
360360

361361
// initialize or update the Level filter
362362
for (int i = FD_ROLL; i < FD_YAW; i++) {
363363
if (!smoothingData->filterInitialized) {
364-
pt3FilterInit(&smoothingData->filterDeflection[i], pt3FilterGain(smoothingData->setpointCutoffFrequency, dT));
364+
ptnFilterInit(&smoothingData->filterDeflection[i], rxConfig()->rc_smoothing_order, smoothingData->setpointCutoffFrequency, dT);
365365
} else {
366-
pt3FilterUpdateCutoff(&smoothingData->filterDeflection[i], pt3FilterGain(smoothingData->setpointCutoffFrequency, dT));
366+
ptnFilterUpdate(&smoothingData->filterDeflection[i], smoothingData->setpointCutoffFrequency, dT);
367367
}
368368
}
369369
}
@@ -541,7 +541,7 @@ static FAST_CODE void processRcSmoothingFilter(void)
541541
for (int i = 0; i < PRIMARY_CHANNEL_COUNT; i++) {
542542
float *dst = i == THROTTLE ? &rcCommand[i] : &setpointRate[i];
543543
if (rcSmoothingData.filterInitialized) {
544-
*dst = pt3FilterApply(&rcSmoothingData.filter[i], rxDataToSmooth[i]);
544+
*dst = ptnFilterApply(&rcSmoothingData.filter[i], rxDataToSmooth[i]);
545545
} else {
546546
// If filter isn't initialized yet, as in smoothing off, use the actual unsmoothed rx channel data
547547
*dst = rxDataToSmooth[i];
@@ -552,7 +552,7 @@ static FAST_CODE void processRcSmoothingFilter(void)
552552
bool smoothingNeeded = (FLIGHT_MODE(ANGLE_MODE) || FLIGHT_MODE(HORIZON_MODE)) && rcSmoothingData.filterInitialized;
553553
for (int axis = FD_ROLL; axis <= FD_YAW; axis++) {
554554
if (smoothingNeeded && axis < FD_YAW) {
555-
rcDeflectionSmoothed[axis] = pt3FilterApply(&rcSmoothingData.filterDeflection[axis], rcDeflection[axis]);
555+
rcDeflectionSmoothed[axis] = ptnFilterApply(&rcSmoothingData.filterDeflection[axis], rcDeflection[axis]);
556556
} else {
557557
rcDeflectionSmoothed[axis] = rcDeflection[axis];
558558
}
@@ -581,7 +581,7 @@ FAST_CODE void processRcCommand(void)
581581
#endif
582582

583583
float angleRate;
584-
584+
585585
#ifdef USE_GPS_RESCUE
586586
if ((axis == FD_YAW) && FLIGHT_MODE(GPS_RESCUE_MODE)) {
587587
// If GPS Rescue is active then override the setpointRate used in the

src/main/fc/rc_controls.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ typedef struct rcSmoothingFilterTraining_s {
9595

9696
typedef struct rcSmoothingFilter_s {
9797
bool filterInitialized;
98-
pt3Filter_t filter[4];
99-
pt3Filter_t filterDeflection[2];
98+
ptnFilter_t filter[4];
99+
ptnFilter_t filterDeflection[2];
100100
uint8_t setpointCutoffSetting;
101101
uint8_t throttleCutoffSetting;
102102
uint16_t setpointCutoffFrequency;

src/main/pg/rx.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ void pgResetFn_rxConfig(rxConfig_t *rxConfig)
6060
.airModeActivateThreshold = 25,
6161
.max_aux_channel = DEFAULT_AUX_CHANNEL_COUNT,
6262
.rc_smoothing_mode = 1,
63+
.rc_smoothing_order = 3,
6364
.rc_smoothing_setpoint_cutoff = 0,
6465
.rc_smoothing_feedforward_cutoff = 0,
6566
.rc_smoothing_throttle_cutoff = 0,

src/main/pg/rx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ typedef struct rxConfig_s {
5050
uint8_t rssi_src_frame_errors; // true to use frame drop flags in the rx protocol
5151
int8_t rssi_offset; // offset applied to the RSSI value before it is returned
5252
uint8_t rc_smoothing_mode; // Whether filter based rc smoothing is on or off
53+
uint8_t rc_smoothing_order; // choose from pt1-pt4 for rc smoothing
5354
uint8_t rc_smoothing_setpoint_cutoff; // Filter cutoff frequency for the setpoint filter (0 = auto)
5455
uint8_t rc_smoothing_feedforward_cutoff; // Filter cutoff frequency for the feedforward filter (0 = auto)
5556
uint8_t rc_smoothing_throttle_cutoff; // Filter cutoff frequency for the setpoint filter (0 = auto)

0 commit comments

Comments
 (0)