Skip to content

Commit aa07f4c

Browse files
Merge pull request #11215 from sensei-hacker/fix-issue-9912-autotrim-iterm
Fix #9912: Add I-term stability check to servo autotrim
2 parents ba406b6 + 4ae6da9 commit aa07f4c

4 files changed

Lines changed: 27 additions & 1 deletion

File tree

docs/Settings.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6052,6 +6052,16 @@ When feature SERIALRX is enabled, this allows connection to several receivers wh
60526052

60536053
---
60546054

6055+
### servo_autotrim_iterm_rate_limit
6056+
6057+
Maximum I-term rate of change (units/sec) for autotrim to be applied. Prevents trim updates during maneuver transitions when I-term is changing rapidly. Only applies when using `feature FW_AUTOTRIM`.
6058+
6059+
| Default | Min | Max |
6060+
| --- | --- | --- |
6061+
| 2 | 0 | 50 |
6062+
6063+
---
6064+
60556065
### servo_autotrim_rotation_limit
60566066

60576067
Servo midpoints are only updated when total aircraft rotation is less than this threshold [deg/s]. Only applies when using `feature FW_AUTOTRIM`.

src/main/fc/settings.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,6 +1361,11 @@ groups:
13611361
default_value: 15
13621362
min: 1
13631363
max: 60
1364+
- name: servo_autotrim_iterm_rate_limit
1365+
description: "Maximum I-term rate of change (units/sec) for autotrim to be applied. Prevents trim updates during maneuver transitions when I-term is changing rapidly. Only applies when using `feature FW_AUTOTRIM`."
1366+
default_value: 2
1367+
min: 0
1368+
max: 50
13641369

13651370
- name: PG_CONTROL_PROFILES
13661371
type: controlConfig_t

src/main/flight/servos.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,13 +614,21 @@ void processContinuousServoAutotrim(const float dT)
614614
static timeMs_t lastUpdateTimeMs;
615615
static servoAutotrimState_e trimState = AUTOTRIM_IDLE;
616616
static uint32_t servoMiddleUpdateCount;
617+
static float prevAxisIterm[2] = {0}; // Track previous I-term for rate-of-change calculation
617618

618619
const float rotRateMagnitudeFiltered = pt1FilterApply4(&rotRateFilter, fast_fsqrtf(vectorNormSquared(&imuMeasuredRotationBF)), SERVO_AUTOTRIM_FILTER_CUTOFF, dT);
619620
const float targetRateMagnitudeFiltered = pt1FilterApply4(&targetRateFilter, getTotalRateTarget(), SERVO_AUTOTRIM_FILTER_CUTOFF, dT);
620621

621622
if (ARMING_FLAG(ARMED)) {
622623
trimState = AUTOTRIM_COLLECTING;
623624
if ((millis() - lastUpdateTimeMs) > 500) {
625+
static float itermRateOfChange[2];
626+
for (int axis = FD_ROLL; axis <= FD_PITCH; axis++) {
627+
const float currentIterm = getAxisIterm(axis);
628+
itermRateOfChange[axis] = fabsf(currentIterm - prevAxisIterm[axis]) / 0.5f;
629+
prevAxisIterm[axis] = currentIterm;
630+
}
631+
624632
const bool planeIsFlyingStraight = rotRateMagnitudeFiltered <= DEGREES_TO_RADIANS(servoConfig()->servo_autotrim_rotation_limit);
625633
const bool noRotationCommanded = targetRateMagnitudeFiltered <= servoConfig()->servo_autotrim_rotation_limit;
626634
const bool sticksAreCentered = !areSticksDeflected();
@@ -638,7 +646,9 @@ void processContinuousServoAutotrim(const float dT)
638646
for (int axis = FD_ROLL; axis <= FD_PITCH; axis++) {
639647
// For each stabilized axis, add 5 units of I-term to all associated servo midpoints
640648
const float axisIterm = getAxisIterm(axis);
641-
if (fabsf(axisIterm) > SERVO_AUTOTRIM_UPDATE_SIZE) {
649+
const bool itermIsStable = itermRateOfChange[axis] < servoConfig()->servo_autotrim_iterm_rate_limit;
650+
651+
if (fabsf(axisIterm) > SERVO_AUTOTRIM_UPDATE_SIZE && itermIsStable) {
642652
const int8_t ItermUpdate = axisIterm > 0.0f ? SERVO_AUTOTRIM_UPDATE_SIZE : -SERVO_AUTOTRIM_UPDATE_SIZE;
643653
for (int i = 0; i < servoRuleCount; i++) {
644654
#ifdef USE_PROGRAMMING_FRAMEWORK

src/main/flight/servos.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ typedef struct servoConfig_s {
171171
uint8_t tri_unarmed_servo; // send tail servo correction pulses even when unarmed
172172
uint8_t servo_autotrim_rotation_limit; // Max rotation for servo midpoints to be updated
173173
uint8_t servo_autotrim_iterm_threshold; // How much of the Iterm is carried over to the servo midpoints on each update
174+
uint8_t servo_autotrim_iterm_rate_limit; // Max I-term rate of change (units/sec) to apply autotrim
174175
} servoConfig_t;
175176

176177
PG_DECLARE(servoConfig_t, servoConfig);

0 commit comments

Comments
 (0)