@@ -64,6 +64,8 @@ float rcCommandDelta[XYZ_AXIS_COUNT];
6464#endif
6565static float rawSetpoint [XYZ_AXIS_COUNT ];
6666static float setpointRate [3 ], rcDeflection [3 ], rcDeflectionAbs [3 ];
67+ FAST_DATA_ZERO_INIT float lastRcDeflection [4 ], rcVelocity [4 ];
68+ static float rcDeflectionSmoothed [3 ];
6769static bool reverseMotors = false;
6870static applyRatesFn * applyRates ;
6971static uint16_t currentRxRefreshRate ;
@@ -328,32 +330,55 @@ FAST_CODE_NOINLINE int calcAutoSmoothingCutoff(int avgRxFrameTimeUs, uint8_t aut
328330
329331// Initialize or update the filters base on either the manually selected cutoff, or
330332// the auto-calculated cutoff frequency based on detected rx frame rate.
331- FAST_CODE_NOINLINE void rcSmoothingSetFilterCutoffs (rcSmoothingFilter_t * smoothingData )
333+ FAST_CODE_NOINLINE void rcSmoothingAutoRxRateCutoffs (rcSmoothingFilter_t * smoothingData )
332334{
333- const float dT = targetPidLooptime * 1e-6f ;
334- uint16_t oldCutoff = smoothingData -> setpointCutoffFrequency ;
335-
336335 if (smoothingData -> setpointCutoffSetting == 0 ) {
337336 smoothingData -> setpointCutoffFrequency = MAX (RC_SMOOTHING_CUTOFF_MIN_HZ , calcAutoSmoothingCutoff (smoothingData -> averageFrameTimeUs , smoothingData -> autoSmoothnessFactorSetpoint ));
338337 }
339338 if (smoothingData -> throttleCutoffSetting == 0 ) {
340339 smoothingData -> throttleCutoffFrequency = MAX (RC_SMOOTHING_CUTOFF_MIN_HZ , calcAutoSmoothingCutoff (smoothingData -> averageFrameTimeUs , smoothingData -> autoSmoothnessFactorThrottle ));
341340 }
341+ if (rcSmoothingData .ffCutoffSetting == 0 ) {
342+ smoothingData -> feedforwardCutoffFrequency = MAX (RC_SMOOTHING_CUTOFF_MIN_HZ , calcAutoSmoothingCutoff (smoothingData -> averageFrameTimeUs , smoothingData -> autoSmoothnessFactorSetpoint ));
343+ }
344+ // todo add the rc velocity filter boost to ff
345+ if (!smoothingData -> filterInitialized ) {
346+ pidInitFeedforwardLpf (smoothingData -> feedforwardCutoffFrequency , smoothingData -> debugAxis );
347+ } else {
348+ pidUpdateFeedforwardLpf (smoothingData -> feedforwardCutoffFrequency );
349+ }
350+ }
342351
352+ FAST_CODE_NOINLINE void rcSmoothingVelocityCutoffAdjustment (rcSmoothingFilter_t * smoothingData ) {
353+ const float dT = targetPidLooptime * 1e-6f ;
354+ float filterVelocityBoost [4 ];
343355 // initialize or update the Setpoint filter
344- if (( smoothingData -> setpointCutoffFrequency != oldCutoff ) || !smoothingData -> filterInitialized ) {
356+ if (!smoothingData -> filterInitialized ) {
345357 for (int i = 0 ; i < PRIMARY_CHANNEL_COUNT ; i ++ ) {
358+ // rcVelocity of 1 matches to moving your stick to the end of its travel in 1 second
359+ if (i != 3 ) {
360+ rcVelocity [i ] = ABS (rcDeflection [i ] - lastRcDeflection [i ]) / (smoothingData -> averageFrameTimeUs * 1e-6f );
361+ lastRcDeflection [i ] = rcDeflection [i ];
362+
363+ } else {
364+ float throttle = (rcCommand [i ] / 1000.0 );
365+ rcVelocity [i ] = ABS (throttle - lastRcDeflection [i ]) / (smoothingData -> averageFrameTimeUs * 1e-6f );
366+ lastRcDeflection [i ] = throttle ;
367+ }
368+ rcVelocity [i ] = pt1FilterApply (& smoothingData -> rcVelocityFilter [i ], rcVelocity [i ]);
369+ filterVelocityBoost [i ] = MAX (5.0 , rcVelocity [i ] * rxConfig ()-> rcVelocityCutoffBoost / 100.0f );
370+
346371 if (i < THROTTLE ) { // Throttle handled by smoothing rcCommand
347372 if (!smoothingData -> filterInitialized ) {
348373 ptnFilterInit (& smoothingData -> filter [i ], rxConfig ()-> rc_smoothing_order , smoothingData -> setpointCutoffFrequency , dT );
349374 } else {
350- ptnFilterUpdate (& smoothingData -> filter [i ], smoothingData -> setpointCutoffFrequency , dT );
375+ ptnFilterUpdate (& smoothingData -> filter [i ], smoothingData -> setpointCutoffFrequency * filterVelocityBoost [ i ] , dT );
351376 }
352377 } else {
353378 if (!smoothingData -> filterInitialized ) {
354379 ptnFilterInit (& smoothingData -> filter [i ], rxConfig ()-> rc_smoothing_order , smoothingData -> throttleCutoffFrequency , dT );
355380 } else {
356- ptnFilterUpdate (& smoothingData -> filter [i ], smoothingData -> throttleCutoffFrequency , dT );
381+ ptnFilterUpdate (& smoothingData -> filter [i ], smoothingData -> throttleCutoffFrequency * filterVelocityBoost [ i ] , dT );
357382 }
358383 }
359384 }
@@ -363,21 +388,10 @@ FAST_CODE_NOINLINE void rcSmoothingSetFilterCutoffs(rcSmoothingFilter_t *smoothi
363388 if (!smoothingData -> filterInitialized ) {
364389 ptnFilterInit (& smoothingData -> filterDeflection [i ], rxConfig ()-> rc_smoothing_order , smoothingData -> setpointCutoffFrequency , dT );
365390 } else {
366- ptnFilterUpdate (& smoothingData -> filterDeflection [i ], smoothingData -> setpointCutoffFrequency , dT );
391+ ptnFilterUpdate (& smoothingData -> filterDeflection [i ], smoothingData -> setpointCutoffFrequency * filterVelocityBoost [ i ] , dT );
367392 }
368393 }
369394 }
370-
371- // update or initialize the FF filter
372- oldCutoff = smoothingData -> feedforwardCutoffFrequency ;
373- if (rcSmoothingData .ffCutoffSetting == 0 ) {
374- smoothingData -> feedforwardCutoffFrequency = MAX (RC_SMOOTHING_CUTOFF_MIN_HZ , calcAutoSmoothingCutoff (smoothingData -> averageFrameTimeUs , smoothingData -> autoSmoothnessFactorSetpoint ));
375- }
376- if (!smoothingData -> filterInitialized ) {
377- pidInitFeedforwardLpf (smoothingData -> feedforwardCutoffFrequency , smoothingData -> debugAxis );
378- } else if (smoothingData -> feedforwardCutoffFrequency != oldCutoff ) {
379- pidUpdateFeedforwardLpf (smoothingData -> feedforwardCutoffFrequency );
380- }
381395}
382396
383397FAST_CODE_NOINLINE void rcSmoothingResetAccumulation (rcSmoothingFilter_t * smoothingData )
@@ -426,11 +440,13 @@ static FAST_CODE void processRcSmoothingFilter(void)
426440 static FAST_DATA_ZERO_INIT timeMs_t validRxFrameTimeMs ;
427441 static FAST_DATA_ZERO_INIT bool calculateCutoffs ;
428442
443+ const float dT = targetPidLooptime * 1e-6f ;
444+
429445 // first call initialization
430446 if (!initialized ) {
431447 initialized = true;
432448 rcSmoothingData .filterInitialized = false;
433- rcSmoothingData .averageFrameTimeUs = 0 ;
449+ rcSmoothingData .averageFrameTimeUs = 2000 ;
434450 rcSmoothingData .autoSmoothnessFactorSetpoint = rxConfig ()-> rc_smoothing_auto_factor_rpy ;
435451 rcSmoothingData .autoSmoothnessFactorThrottle = rxConfig ()-> rc_smoothing_auto_factor_throttle ;
436452 rcSmoothingData .debugAxis = rxConfig ()-> rc_smoothing_debug_axis ;
@@ -440,6 +456,10 @@ static FAST_CODE void processRcSmoothingFilter(void)
440456 rcSmoothingResetAccumulation (& rcSmoothingData );
441457 rcSmoothingData .setpointCutoffFrequency = rcSmoothingData .setpointCutoffSetting ;
442458 rcSmoothingData .throttleCutoffFrequency = rcSmoothingData .throttleCutoffSetting ;
459+ for (int i = 0 ; i < PRIMARY_CHANNEL_COUNT ; i ++ ) {
460+ pt1FilterInit (& rcSmoothingData .rcVelocityFilter [i ], pt1FilterGain (rxConfig ()-> rcVelocityCutoff , dT ));
461+ }
462+
443463 if (rcSmoothingData .ffCutoffSetting == 0 ) {
444464 // calculate and use an initial derivative cutoff until the RC interval is known
445465 const float cutoffFactor = 1.5f / (1.0f + (rcSmoothingData .autoSmoothnessFactorSetpoint / 10.0f ));
@@ -454,7 +474,8 @@ static FAST_CODE void processRcSmoothingFilter(void)
454474
455475 // if we don't need to calculate cutoffs dynamically then the filters can be initialized now
456476 if (!calculateCutoffs ) {
457- rcSmoothingSetFilterCutoffs (& rcSmoothingData );
477+ rcSmoothingAutoRxRateCutoffs (& rcSmoothingData );
478+ rcSmoothingVelocityCutoffAdjustment (& rcSmoothingData );
458479 rcSmoothingData .filterInitialized = true;
459480 }
460481 }
@@ -500,12 +521,14 @@ static FAST_CODE void processRcSmoothingFilter(void)
500521 if (rcSmoothingAccumulateSample (& rcSmoothingData , currentRxRefreshRate )) {
501522 // the required number of samples were collected so set the filter cutoffs, but only if smoothing is active
502523 if (rxConfig ()-> rc_smoothing_mode ) {
503- rcSmoothingSetFilterCutoffs (& rcSmoothingData );
524+ rcSmoothingAutoRxRateCutoffs (& rcSmoothingData );
504525 rcSmoothingData .filterInitialized = true;
505526 }
506527 validRxFrameTimeMs = 0 ;
507528 }
508529 }
530+ // always update this as dynamically based on rc velocity
531+ rcSmoothingVelocityCutoffAdjustment (& rcSmoothingData );
509532
510533 }
511534 } else {
0 commit comments