@@ -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 ;
@@ -328,32 +330,55 @@ FAST_CODE_NOINLINE int calcAutoSmoothingCutoff(int avgRxFrameTimeUs, uint8_t aut
328
330
329
331
// Initialize or update the filters base on either the manually selected cutoff, or
330
332
// 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 )
332
334
{
333
- const float dT = targetPidLooptime * 1e-6f ;
334
- uint16_t oldCutoff = smoothingData -> setpointCutoffFrequency ;
335
-
336
335
if (smoothingData -> setpointCutoffSetting == 0 ) {
337
336
smoothingData -> setpointCutoffFrequency = MAX (RC_SMOOTHING_CUTOFF_MIN_HZ , calcAutoSmoothingCutoff (smoothingData -> averageFrameTimeUs , smoothingData -> autoSmoothnessFactorSetpoint ));
338
337
}
339
338
if (smoothingData -> throttleCutoffSetting == 0 ) {
340
339
smoothingData -> throttleCutoffFrequency = MAX (RC_SMOOTHING_CUTOFF_MIN_HZ , calcAutoSmoothingCutoff (smoothingData -> averageFrameTimeUs , smoothingData -> autoSmoothnessFactorThrottle ));
341
340
}
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
+ }
342
351
352
+ FAST_CODE_NOINLINE void rcSmoothingVelocityCutoffAdjustment (rcSmoothingFilter_t * smoothingData ) {
353
+ const float dT = targetPidLooptime * 1e-6f ;
354
+ float filterVelocityBoost [4 ];
343
355
// initialize or update the Setpoint filter
344
- if (( smoothingData -> setpointCutoffFrequency != oldCutoff ) || !smoothingData -> filterInitialized ) {
356
+ if (!smoothingData -> filterInitialized ) {
345
357
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
+
346
371
if (i < THROTTLE ) { // Throttle handled by smoothing rcCommand
347
372
if (!smoothingData -> filterInitialized ) {
348
373
ptnFilterInit (& smoothingData -> filter [i ], rxConfig ()-> rc_smoothing_order , smoothingData -> setpointCutoffFrequency , dT );
349
374
} else {
350
- ptnFilterUpdate (& smoothingData -> filter [i ], smoothingData -> setpointCutoffFrequency , dT );
375
+ ptnFilterUpdate (& smoothingData -> filter [i ], smoothingData -> setpointCutoffFrequency * filterVelocityBoost [ i ] , dT );
351
376
}
352
377
} else {
353
378
if (!smoothingData -> filterInitialized ) {
354
379
ptnFilterInit (& smoothingData -> filter [i ], rxConfig ()-> rc_smoothing_order , smoothingData -> throttleCutoffFrequency , dT );
355
380
} else {
356
- ptnFilterUpdate (& smoothingData -> filter [i ], smoothingData -> throttleCutoffFrequency , dT );
381
+ ptnFilterUpdate (& smoothingData -> filter [i ], smoothingData -> throttleCutoffFrequency * filterVelocityBoost [ i ] , dT );
357
382
}
358
383
}
359
384
}
@@ -363,21 +388,10 @@ FAST_CODE_NOINLINE void rcSmoothingSetFilterCutoffs(rcSmoothingFilter_t *smoothi
363
388
if (!smoothingData -> filterInitialized ) {
364
389
ptnFilterInit (& smoothingData -> filterDeflection [i ], rxConfig ()-> rc_smoothing_order , smoothingData -> setpointCutoffFrequency , dT );
365
390
} else {
366
- ptnFilterUpdate (& smoothingData -> filterDeflection [i ], smoothingData -> setpointCutoffFrequency , dT );
391
+ ptnFilterUpdate (& smoothingData -> filterDeflection [i ], smoothingData -> setpointCutoffFrequency * filterVelocityBoost [ i ] , dT );
367
392
}
368
393
}
369
394
}
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
- }
381
395
}
382
396
383
397
FAST_CODE_NOINLINE void rcSmoothingResetAccumulation (rcSmoothingFilter_t * smoothingData )
@@ -426,11 +440,13 @@ static FAST_CODE void processRcSmoothingFilter(void)
426
440
static FAST_DATA_ZERO_INIT timeMs_t validRxFrameTimeMs ;
427
441
static FAST_DATA_ZERO_INIT bool calculateCutoffs ;
428
442
443
+ const float dT = targetPidLooptime * 1e-6f ;
444
+
429
445
// first call initialization
430
446
if (!initialized ) {
431
447
initialized = true;
432
448
rcSmoothingData .filterInitialized = false;
433
- rcSmoothingData .averageFrameTimeUs = 0 ;
449
+ rcSmoothingData .averageFrameTimeUs = 2000 ;
434
450
rcSmoothingData .autoSmoothnessFactorSetpoint = rxConfig ()-> rc_smoothing_auto_factor_rpy ;
435
451
rcSmoothingData .autoSmoothnessFactorThrottle = rxConfig ()-> rc_smoothing_auto_factor_throttle ;
436
452
rcSmoothingData .debugAxis = rxConfig ()-> rc_smoothing_debug_axis ;
@@ -440,6 +456,10 @@ static FAST_CODE void processRcSmoothingFilter(void)
440
456
rcSmoothingResetAccumulation (& rcSmoothingData );
441
457
rcSmoothingData .setpointCutoffFrequency = rcSmoothingData .setpointCutoffSetting ;
442
458
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
+
443
463
if (rcSmoothingData .ffCutoffSetting == 0 ) {
444
464
// calculate and use an initial derivative cutoff until the RC interval is known
445
465
const float cutoffFactor = 1.5f / (1.0f + (rcSmoothingData .autoSmoothnessFactorSetpoint / 10.0f ));
@@ -454,7 +474,8 @@ static FAST_CODE void processRcSmoothingFilter(void)
454
474
455
475
// if we don't need to calculate cutoffs dynamically then the filters can be initialized now
456
476
if (!calculateCutoffs ) {
457
- rcSmoothingSetFilterCutoffs (& rcSmoothingData );
477
+ rcSmoothingAutoRxRateCutoffs (& rcSmoothingData );
478
+ rcSmoothingVelocityCutoffAdjustment (& rcSmoothingData );
458
479
rcSmoothingData .filterInitialized = true;
459
480
}
460
481
}
@@ -500,12 +521,14 @@ static FAST_CODE void processRcSmoothingFilter(void)
500
521
if (rcSmoothingAccumulateSample (& rcSmoothingData , currentRxRefreshRate )) {
501
522
// the required number of samples were collected so set the filter cutoffs, but only if smoothing is active
502
523
if (rxConfig ()-> rc_smoothing_mode ) {
503
- rcSmoothingSetFilterCutoffs (& rcSmoothingData );
524
+ rcSmoothingAutoRxRateCutoffs (& rcSmoothingData );
504
525
rcSmoothingData .filterInitialized = true;
505
526
}
506
527
validRxFrameTimeMs = 0 ;
507
528
}
508
529
}
530
+ // always update this as dynamically based on rc velocity
531
+ rcSmoothingVelocityCutoffAdjustment (& rcSmoothingData );
509
532
510
533
}
511
534
} else {
0 commit comments