Skip to content

Commit

Permalink
First attempt low throttle airmode oscillation fix
Browse files Browse the repository at this point in the history
raise dc offset immediately

Add airmode noise fix

no filter when inactive and slightly more throttle

hpf throttle to avoid large moves increasing throttle persistently

fix ws

fix ununsed variable and default to off

include airmode throttle offset in loggingThrottle
  • Loading branch information
joelucid authored and mikeller committed Feb 18, 2019
1 parent 966971c commit e16ef1d
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/main/cli/settings.c
Expand Up @@ -1012,6 +1012,9 @@ const clivalue_t valueTable[] = {
#ifdef USE_THRUST_LINEARIZATION
{ "thrust_linear", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 100 }, PG_PID_PROFILE, offsetof(pidProfile_t, thrustLinearization) },
#endif
#ifdef USE_AIRMODE_LPF
{ "transient_throttle_limit", VAR_UINT8 | MASTER_VALUE, .config.minmax = { 0, 30 }, PG_PID_PROFILE, offsetof(pidProfile_t, transient_throttle_limit) },
#endif

// PG_TELEMETRY_CONFIG
#ifdef USE_TELEMETRY
Expand Down
13 changes: 13 additions & 0 deletions src/main/flight/mixer.c
Expand Up @@ -926,7 +926,13 @@ FAST_CODE_NOINLINE void mixTable(timeUs_t currentTimeUs, uint8_t vbatPidCompensa
}
#endif

#ifdef USE_AIRMODE_LPF
const float unadjustedThrottle = throttle;
throttle += pidGetAirmodeThrottleOffset();
float airmodeThrottleChange = 0;
#endif
loggingThrottle = throttle;

motorMixRange = motorMixMax - motorMixMin;
if (motorMixRange > 1.0f) {
for (int i = 0; i < motorCount; i++) {
Expand All @@ -939,9 +945,16 @@ FAST_CODE_NOINLINE void mixTable(timeUs_t currentTimeUs, uint8_t vbatPidCompensa
} else {
if (airmodeEnabled || throttle > 0.5f) { // Only automatically adjust throttle when airmode enabled. Airmode logic is always active on high throttle
throttle = constrainf(throttle, -motorMixMin, 1.0f - motorMixMax);
#ifdef USE_AIRMODE_LPF
airmodeThrottleChange = constrainf(unadjustedThrottle, -motorMixMin, 1.0f - motorMixMax) - unadjustedThrottle;
#endif
}
}

#ifdef USE_AIRMODE_LPF
pidUpdateAirmodeLpf(airmodeThrottleChange);
#endif

if (featureIsEnabled(FEATURE_MOTOR_STOP)
&& ARMING_FLAG(ARMED)
&& !featureIsEnabled(FEATURE_3D)
Expand Down
44 changes: 44 additions & 0 deletions src/main/flight/pid.c
Expand Up @@ -117,6 +117,10 @@ PG_RESET_TEMPLATE(pidConfig_t, pidConfig,
#define ACRO_TRAINER_SETPOINT_LIMIT 1000.0f // Limit the correcting setpoint
#endif // USE_ACRO_TRAINER

#ifdef USE_AIRMODE_LPF
static FAST_RAM_ZERO_INIT float airmodeThrottleOffsetLimit;
#endif

#define ANTI_GRAVITY_THROTTLE_FILTER_CUTOFF 15 // The anti gravity throttle highpass filter cutoff

#define CRASH_RECOVERY_DETECTION_DELAY_US 1000000 // 1 second delay before crash recovery detection is active after entering a self-level mode
Expand Down Expand Up @@ -196,6 +200,7 @@ void resetPidProfile(pidProfile_t *pidProfile)
.d_min_advance = 20,
.motor_output_limit = 100,
.auto_profile_cell_count = AUTO_PROFILE_CELL_COUNT_STAY,
.transient_throttle_limit = 0,
);
#ifdef USE_DYN_LPF
pidProfile->dterm_lowpass_hz = 150;
Expand Down Expand Up @@ -287,6 +292,11 @@ static FAST_RAM_ZERO_INIT uint8_t rcSmoothingDebugAxis;
static FAST_RAM_ZERO_INIT uint8_t rcSmoothingFilterType;
#endif // USE_RC_SMOOTHING_FILTER

#ifdef USE_AIRMODE_LPF
static FAST_RAM_ZERO_INIT pt1Filter_t airmodeThrottleLpf1;
static FAST_RAM_ZERO_INIT pt1Filter_t airmodeThrottleLpf2;
#endif

static FAST_RAM_ZERO_INIT pt1Filter_t antiGravityThrottleLpf;

void pidInitFilters(const pidProfile_t *pidProfile)
Expand Down Expand Up @@ -415,6 +425,12 @@ void pidInitFilters(const pidProfile_t *pidProfile)
pt1FilterInit(&dMinLowpass[axis], pt1FilterGain(D_MIN_LOWPASS_HZ, dT));
}
#endif
#if defined(USE_AIRMODE_LPF)
if (pidProfile->transient_throttle_limit) {
pt1FilterInit(&airmodeThrottleLpf1, pt1FilterGain(7.0f, dT));
pt1FilterInit(&airmodeThrottleLpf2, pt1FilterGain(20.0f, dT));
}
#endif

pt1FilterInit(&antiGravityThrottleLpf, pt1FilterGain(ANTI_GRAVITY_THROTTLE_FILTER_CUTOFF, dT));
}
Expand Down Expand Up @@ -674,6 +690,9 @@ void pidInitConfig(const pidProfile_t *pidProfile)
dMinSetpointGain = pidProfile->d_min_gain * D_MIN_SETPOINT_GAIN_FACTOR * pidProfile->d_min_advance * pidFrequency / (100 * D_MIN_LOWPASS_HZ);
// lowpass included inversely in gain since stronger lowpass decreases peak effect
#endif
#if defined(USE_AIRMODE_LPF)
airmodeThrottleOffsetLimit = pidProfile->transient_throttle_limit / 100.0f;
#endif
}

void pidInit(const pidProfile_t *pidProfile)
Expand Down Expand Up @@ -1117,6 +1136,31 @@ STATIC_UNIT_TESTED void applyItermRelax(const int axis, const float iterm,
}
#endif

#ifdef USE_AIRMODE_LPF
void pidUpdateAirmodeLpf(float currentOffset)
{
if (airmodeThrottleOffsetLimit == 0.0f) {
return;
}

float offsetHpf = currentOffset * 2.5f;
offsetHpf = offsetHpf - pt1FilterApply(&airmodeThrottleLpf2, offsetHpf);

// During high frequency oscillation 2 * currentOffset averages to the offset required to avoid mirroring of the waveform
pt1FilterApply(&airmodeThrottleLpf1, offsetHpf);
// Bring offset up immediately so the filter only applies to the decline
if (currentOffset * airmodeThrottleLpf1.state >= 0 && fabsf(currentOffset) > airmodeThrottleLpf1.state) {
airmodeThrottleLpf1.state = currentOffset;
}
airmodeThrottleLpf1.state = constrainf(airmodeThrottleLpf1.state, -airmodeThrottleOffsetLimit, airmodeThrottleOffsetLimit);
}

float pidGetAirmodeThrottleOffset()
{
return airmodeThrottleLpf1.state;
}
#endif

#ifdef USE_LAUNCH_CONTROL
#define LAUNCH_CONTROL_MAX_RATE 100.0f
#define LAUNCH_CONTROL_MIN_RATE 5.0f
Expand Down
5 changes: 5 additions & 0 deletions src/main/flight/pid.h
Expand Up @@ -165,6 +165,7 @@ typedef struct pidProfile_s {
uint8_t d_min_advance; // Percentage multiplier for setpoint input to boost algorithm
uint8_t motor_output_limit; // Upper limit of the motor output (percent)
int8_t auto_profile_cell_count; // Cell count for this profile to be used with if auto PID profile switching is used
uint8_t transient_throttle_limit; // Maximum DC component of throttle change to mix into throttle to prevent airmode mirroring noise
} pidProfile_t;

PG_DECLARE_ARRAY(pidProfile_t, PID_PROFILE_COUNT, pidProfiles);
Expand Down Expand Up @@ -220,6 +221,10 @@ bool pidAntiGravityEnabled(void);
float pidApplyThrustLinearization(float motorValue);
float pidCompensateThrustLinearization(float throttle);
#endif
#ifdef USE_AIRMODE_LPF
void pidUpdateAirmodeLpf(float currentOffset);
float pidGetAirmodeThrottleOffset();
#endif

#ifdef UNIT_TEST
#include "sensors/acceleration.h"
Expand Down
1 change: 1 addition & 0 deletions src/main/target/common_pre.h
Expand Up @@ -258,6 +258,7 @@
#endif // FLASH_SIZE > 128

#if (FLASH_SIZE > 256)
#define USE_AIRMODE_LPF
#define USE_DASHBOARD
#define USE_GPS
#define USE_GPS_NMEA
Expand Down

0 comments on commit e16ef1d

Please sign in to comment.