@@ -64,6 +64,8 @@ float rcCommandDelta[XYZ_AXIS_COUNT];
64
64
#endif
65
65
static float rawSetpoint [XYZ_AXIS_COUNT ];
66
66
static float setpointRate [3 ], rcDeflection [3 ], rcDeflectionAbs [3 ];
67
+ FAST_DATA_ZERO_INIT float lastRcDeflection [4 ], rcVelocity [4 ];
68
+ static float rcDeflectionSmoothed [3 ];
67
69
static bool reverseMotors = false;
68
70
static applyRatesFn * applyRates ;
69
71
static uint16_t currentRxRefreshRate ;
@@ -333,32 +335,55 @@ FAST_CODE_NOINLINE int calcAutoSmoothingCutoff(int avgRxFrameTimeUs, uint8_t aut
333
335
334
336
// Initialize or update the filters base on either the manually selected cutoff, or
335
337
// the auto-calculated cutoff frequency based on detected rx frame rate.
336
- FAST_CODE_NOINLINE void rcSmoothingSetFilterCutoffs (rcSmoothingFilter_t * smoothingData )
338
+ FAST_CODE_NOINLINE void rcSmoothingAutoRxRateCutoffs (rcSmoothingFilter_t * smoothingData )
337
339
{
338
- const float dT = targetPidLooptime * 1e-6f ;
339
- uint16_t oldCutoff = smoothingData -> setpointCutoffFrequency ;
340
-
341
340
if (smoothingData -> setpointCutoffSetting == 0 ) {
342
341
smoothingData -> setpointCutoffFrequency = MAX (RC_SMOOTHING_CUTOFF_MIN_HZ , calcAutoSmoothingCutoff (smoothingData -> averageFrameTimeUs , smoothingData -> autoSmoothnessFactorSetpoint ));
343
342
}
344
343
if (smoothingData -> throttleCutoffSetting == 0 ) {
345
344
smoothingData -> throttleCutoffFrequency = MAX (RC_SMOOTHING_CUTOFF_MIN_HZ , calcAutoSmoothingCutoff (smoothingData -> averageFrameTimeUs , smoothingData -> autoSmoothnessFactorThrottle ));
346
345
}
346
+ if (rcSmoothingData .ffCutoffSetting == 0 ) {
347
+ smoothingData -> feedforwardCutoffFrequency = MAX (RC_SMOOTHING_CUTOFF_MIN_HZ , calcAutoSmoothingCutoff (smoothingData -> averageFrameTimeUs , smoothingData -> autoSmoothnessFactorSetpoint ));
348
+ }
349
+ // todo add the rc velocity filter boost to ff
350
+ if (!smoothingData -> filterInitialized ) {
351
+ pidInitFeedforwardLpf (smoothingData -> feedforwardCutoffFrequency , smoothingData -> debugAxis );
352
+ } else {
353
+ pidUpdateFeedforwardLpf (smoothingData -> feedforwardCutoffFrequency );
354
+ }
355
+ }
347
356
357
+ FAST_CODE_NOINLINE void rcSmoothingVelocityCutoffAdjustment (rcSmoothingFilter_t * smoothingData ) {
358
+ const float dT = targetPidLooptime * 1e-6f ;
359
+ float filterVelocityBoost [4 ];
348
360
// initialize or update the Setpoint filter
349
- if (( smoothingData -> setpointCutoffFrequency != oldCutoff ) || !smoothingData -> filterInitialized ) {
361
+ if (!smoothingData -> filterInitialized ) {
350
362
for (int i = 0 ; i < PRIMARY_CHANNEL_COUNT ; i ++ ) {
363
+ // rcVelocity of 1 matches to moving your stick to the end of its travel in 1 second
364
+ if (i != 3 ) {
365
+ rcVelocity [i ] = ABS (rcDeflection [i ] - lastRcDeflection [i ]) / (smoothingData -> averageFrameTimeUs * 1e-6f );
366
+ lastRcDeflection [i ] = rcDeflection [i ];
367
+
368
+ } else {
369
+ float throttle = (rcCommand [i ] / 1000.0 );
370
+ rcVelocity [i ] = ABS (throttle - lastRcDeflection [i ]) / (smoothingData -> averageFrameTimeUs * 1e-6f );
371
+ lastRcDeflection [i ] = throttle ;
372
+ }
373
+ rcVelocity [i ] = pt1FilterApply (& smoothingData -> rcVelocityFilter [i ], rcVelocity [i ]);
374
+ filterVelocityBoost [i ] = MAX (5.0 , rcVelocity [i ] * rxConfig ()-> rcVelocityCutoffBoost / 100.0f );
375
+
351
376
if (i < THROTTLE ) { // Throttle handled by smoothing rcCommand
352
377
if (!smoothingData -> filterInitialized ) {
353
378
ptnFilterInit (& smoothingData -> filter [i ], rxConfig ()-> rc_smoothing_order , smoothingData -> setpointCutoffFrequency , dT );
354
379
} else {
355
- ptnFilterUpdate (& smoothingData -> filter [i ], smoothingData -> setpointCutoffFrequency , dT );
380
+ ptnFilterUpdate (& smoothingData -> filter [i ], smoothingData -> setpointCutoffFrequency * filterVelocityBoost [ i ] , dT );
356
381
}
357
382
} else {
358
383
if (!smoothingData -> filterInitialized ) {
359
384
ptnFilterInit (& smoothingData -> filter [i ], rxConfig ()-> rc_smoothing_order , smoothingData -> throttleCutoffFrequency , dT );
360
385
} else {
361
- ptnFilterUpdate (& smoothingData -> filter [i ], smoothingData -> throttleCutoffFrequency , dT );
386
+ ptnFilterUpdate (& smoothingData -> filter [i ], smoothingData -> throttleCutoffFrequency * filterVelocityBoost [ i ] , dT );
362
387
}
363
388
}
364
389
}
@@ -368,21 +393,10 @@ FAST_CODE_NOINLINE void rcSmoothingSetFilterCutoffs(rcSmoothingFilter_t *smoothi
368
393
if (!smoothingData -> filterInitialized ) {
369
394
ptnFilterInit (& smoothingData -> filterDeflection [i ], rxConfig ()-> rc_smoothing_order , smoothingData -> setpointCutoffFrequency , dT );
370
395
} else {
371
- ptnFilterUpdate (& smoothingData -> filterDeflection [i ], smoothingData -> setpointCutoffFrequency , dT );
396
+ ptnFilterUpdate (& smoothingData -> filterDeflection [i ], smoothingData -> setpointCutoffFrequency * filterVelocityBoost [ i ] , dT );
372
397
}
373
398
}
374
399
}
375
-
376
- // update or initialize the FF filter
377
- oldCutoff = smoothingData -> feedforwardCutoffFrequency ;
378
- if (rcSmoothingData .ffCutoffSetting == 0 ) {
379
- smoothingData -> feedforwardCutoffFrequency = MAX (RC_SMOOTHING_CUTOFF_MIN_HZ , calcAutoSmoothingCutoff (smoothingData -> averageFrameTimeUs , smoothingData -> autoSmoothnessFactorSetpoint ));
380
- }
381
- if (!smoothingData -> filterInitialized ) {
382
- pidInitFeedforwardLpf (smoothingData -> feedforwardCutoffFrequency , smoothingData -> debugAxis );
383
- } else if (smoothingData -> feedforwardCutoffFrequency != oldCutoff ) {
384
- pidUpdateFeedforwardLpf (smoothingData -> feedforwardCutoffFrequency );
385
- }
386
400
}
387
401
388
402
FAST_CODE_NOINLINE void rcSmoothingResetAccumulation (rcSmoothingFilter_t * smoothingData )
@@ -431,11 +445,13 @@ static FAST_CODE void processRcSmoothingFilter(void)
431
445
static FAST_DATA_ZERO_INIT timeMs_t validRxFrameTimeMs ;
432
446
static FAST_DATA_ZERO_INIT bool calculateCutoffs ;
433
447
448
+ const float dT = targetPidLooptime * 1e-6f ;
449
+
434
450
// first call initialization
435
451
if (!initialized ) {
436
452
initialized = true;
437
453
rcSmoothingData .filterInitialized = false;
438
- rcSmoothingData .averageFrameTimeUs = 0 ;
454
+ rcSmoothingData .averageFrameTimeUs = 2000 ;
439
455
rcSmoothingData .autoSmoothnessFactorSetpoint = rxConfig ()-> rc_smoothing_auto_factor_rpy ;
440
456
rcSmoothingData .autoSmoothnessFactorThrottle = rxConfig ()-> rc_smoothing_auto_factor_throttle ;
441
457
rcSmoothingData .debugAxis = rxConfig ()-> rc_smoothing_debug_axis ;
@@ -445,6 +461,10 @@ static FAST_CODE void processRcSmoothingFilter(void)
445
461
rcSmoothingResetAccumulation (& rcSmoothingData );
446
462
rcSmoothingData .setpointCutoffFrequency = rcSmoothingData .setpointCutoffSetting ;
447
463
rcSmoothingData .throttleCutoffFrequency = rcSmoothingData .throttleCutoffSetting ;
464
+ for (int i = 0 ; i < PRIMARY_CHANNEL_COUNT ; i ++ ) {
465
+ pt1FilterInit (& rcSmoothingData .rcVelocityFilter [i ], pt1FilterGain (rxConfig ()-> rcVelocityCutoff , dT ));
466
+ }
467
+
448
468
if (rcSmoothingData .ffCutoffSetting == 0 ) {
449
469
// calculate and use an initial derivative cutoff until the RC interval is known
450
470
const float cutoffFactor = 1.5f / (1.0f + (rcSmoothingData .autoSmoothnessFactorSetpoint / 10.0f ));
@@ -459,7 +479,8 @@ static FAST_CODE void processRcSmoothingFilter(void)
459
479
460
480
// if we don't need to calculate cutoffs dynamically then the filters can be initialized now
461
481
if (!calculateCutoffs ) {
462
- rcSmoothingSetFilterCutoffs (& rcSmoothingData );
482
+ rcSmoothingAutoRxRateCutoffs (& rcSmoothingData );
483
+ rcSmoothingVelocityCutoffAdjustment (& rcSmoothingData );
463
484
rcSmoothingData .filterInitialized = true;
464
485
}
465
486
}
@@ -505,12 +526,14 @@ static FAST_CODE void processRcSmoothingFilter(void)
505
526
if (rcSmoothingAccumulateSample (& rcSmoothingData , currentRxRefreshRate )) {
506
527
// the required number of samples were collected so set the filter cutoffs, but only if smoothing is active
507
528
if (rxConfig ()-> rc_smoothing_mode ) {
508
- rcSmoothingSetFilterCutoffs (& rcSmoothingData );
529
+ rcSmoothingAutoRxRateCutoffs (& rcSmoothingData );
509
530
rcSmoothingData .filterInitialized = true;
510
531
}
511
532
validRxFrameTimeMs = 0 ;
512
533
}
513
534
}
535
+ // always update this as dynamically based on rc velocity
536
+ rcSmoothingVelocityCutoffAdjustment (& rcSmoothingData );
514
537
515
538
}
516
539
} else {
0 commit comments