1
0
Fork 0
mirror of https://github.com/betaflight/betaflight-configurator.git synced 2025-07-25 09:15:49 +03:00

rfc filter sliders

Fix manual input

improve gyro and dterm

Fix expo

Fix enabling gyro dyn lpf 1 to use slider value instead of default

Fix enabling dterm dyn lpf 1 to use slider value instead of default

Change labels to static

Refactor left panel

right panel

Add switches

latest fixes

save filter type on lp1

Remove need to save if changing switches

Change lowpass html

Change slider on/off behavior

Fix enable/disable filter mode selectors

Reworked to work with legacy and firmware sliders

Change gyro warning limit to 1.4 as in 10.7 (limon)
This commit is contained in:
Mark Haslinghuis 2021-10-21 02:09:28 +02:00
parent 41747c65b6
commit d57ce5ffd1
No known key found for this signature in database
GPG key ID: 198B0F616296A584
7 changed files with 1015 additions and 532 deletions

View file

@ -37,6 +37,9 @@ const TuningSliders = {
cachedGyroSliderValues: false,
cachedDTermSliderValues: false,
sliderGyroFilterDisabled: false,
sliderDTermFilterDisabled: false,
expertMode: false,
};
@ -72,7 +75,25 @@ TuningSliders.initialize = function() {
this.cachedDTermSliderValues = false;
this.updatePidSlidersDisplay();
this.updateFilterSlidersDisplay();
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
// if sliders are enabled on initialization tuning has not yet updated values according to sliders.
if (!FC.TUNING_SLIDERS.slider_gyro_filter) {
this.updateFilterSlidersDisplay();
}
if (!FC.TUNING_SLIDERS.slider_dterm_filter) {
this.updateFilterSlidersDisplay();
}
this.updateFilterSlidersWarning();
$('.subtab-filter .slidersDisabled').hide();
} else {
this.updateFilterSlidersDisplay();
$('select[id="sliderGyroFilterModeSelect"]').hide();
$('select[id="sliderDTermFilterModeSelect"]').hide();
}
};
TuningSliders.updateExpertModeSlidersDisplay = function() {
@ -109,6 +130,8 @@ TuningSliders.updateExpertModeSlidersDisplay = function() {
$('#sliderPitchPIGain').prop('disabled', !this.expertMode);
$('#sliderMasterMultiplier').prop('disabled', !this.expertMode);
$('.sliderGyroFilter').prop('disabled', gyro && !this.expertMode);
$('.sliderDTermFilter').prop('disabled', dterm && !this.expertMode);
$('#sliderGyroFilterMultiplier').prop('disabled', gyro && !this.expertMode);
$('#sliderDTermFilterMultiplier').prop('disabled', dterm && !this.expertMode);
@ -118,9 +141,6 @@ TuningSliders.updateExpertModeSlidersDisplay = function() {
$('.advancedSlider').toggleClass('disabledSliders', !this.expertMode);
$('.sliderGyroFilter').toggleClass('disabledSliders', gyro && !this.expertMode);
$('.sliderDtermFilter').toggleClass('disabledSliders', dterm && !this.expertMode);
$('.advancedSliderDmaxGain').toggle(dMaxGain || this.expertMode);
$('.advancedSliderIGain').toggle(iGain || this.expertMode);
$('.advancedSliderRollPitchRatio').toggle(rpRatio || this.expertMode);
@ -227,8 +247,11 @@ TuningSliders.initGyroFilterSliderPosition = function() {
this.sliderGyroFilter = FC.TUNING_SLIDERS.slider_gyro_filter;
this.sliderGyroFilterMultiplier = FC.TUNING_SLIDERS.slider_gyro_filter_multiplier / 100;
} else {
this.sliderGyroFilterMultiplier = Math.floor((FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz + FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz + FC.FILTER_CONFIG.gyro_lowpass2_hz) /
(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz + this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz + this.FILTER_DEFAULT.gyro_lowpass2_hz) * 100) / 100;
this.sliderGyroFilterMultiplier =
Math.floor(
(FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz + FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz + FC.FILTER_CONFIG.gyro_lowpass_hz + FC.FILTER_CONFIG.gyro_lowpass2_hz) /
(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz + this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz + this.FILTER_DEFAULT.gyro_lowpass_hz +
this.FILTER_DEFAULT.gyro_lowpass2_hz) * 100) / 100;
}
$('#sliderGyroFilterMultiplier').val(this.sliderGyroFilterMultiplier);
@ -236,16 +259,19 @@ TuningSliders.initGyroFilterSliderPosition = function() {
};
TuningSliders.initDTermFilterSliderPosition = function() {
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
this.sliderDTermFilterMultiplier = Math.floor((FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz + FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz + FC.FILTER_CONFIG.dterm_lowpass2_hz) /
(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz + this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz + this.FILTER_DEFAULT.dterm_lowpass2_hz) * 100) / 100;
} else {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
this.sliderDTermFilter = FC.TUNING_SLIDERS.slider_dterm_filter;
this.sliderDTermFilterMultiplier = FC.TUNING_SLIDERS.slider_dterm_filter_multiplier / 100;
} else {
this.sliderDTermFilterMultiplier =
Math.floor(
(FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz + FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz + FC.FILTER_CONFIG.dterm_lowpass_hz + FC.FILTER_CONFIG.dterm_lowpass2_hz) /
(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz + this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz + this.FILTER_DEFAULT.dterm_lowpass_hz +
this.FILTER_DEFAULT.dterm_lowpass2_hz) * 100) / 100;
}
$('output[name="sliderDTermFilterMultiplier-number"]').val(this.sliderDTermFilterMultiplier);
$('#sliderDTermFilterMultiplier').val(this.sliderDTermFilterMultiplier);
$('output[name="sliderDTermFilterMultiplier-number"]').val(this.sliderDTermFilterMultiplier);
};
TuningSliders.resetPidSliders = function() {
@ -282,43 +308,17 @@ TuningSliders.resetPidSliders = function() {
};
TuningSliders.resetGyroFilterSlider = function() {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
if (!this.cachedGyroSliderValues) {
this.sliderGyroFilterMultiplier = 1;
}
this.sliderGyroFilter = 1;
FC.TUNING_SLIDERS.slider_gyro_filter = 1;
this.initGyroFilterSliderPosition();
} else {
this.sliderGyroFilterMultiplier = 1;
$('#sliderGyroFilterMultiplier').val(this.sliderGyroFilterMultiplier);
}
this.FilterReset = true;
this.sliderGyroFilterMultiplier = 1;
$('#sliderGyroFilterMultiplier').val(this.sliderGyroFilterMultiplier);
this.calculateNewGyroFilters();
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
this.updateFilterSlidersDisplay();
}
this.updateFilterSlidersDisplay();
};
TuningSliders.resetDTermFilterSlider = function() {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
if (!this.cachedDTermSliderValues) {
this.sliderDTermFilterMultiplier = 1;
}
this.sliderDtermFilter = 1;
FC.TUNING_SLIDERS.slider_dterm_filter = 1;
this.initDTermFilterSliderPosition();
} else {
this.sliderDTermFilterMultiplier = 1;
$('#sliderDTermFilterMultiplier').val(this.sliderDTermFilterMultiplier);
}
this.FilterReset = true;
this.sliderDTermFilterMultiplier = 1;
$('#sliderDTermFilterMultiplier').val(this.sliderDTermFilterMultiplier);
this.calculateNewDTermFilters();
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
this.updateFilterSlidersDisplay();
}
this.updateFilterSlidersDisplay();
};
TuningSliders.legacyUpdateFilterSlidersDisplay = function() {
@ -327,6 +327,8 @@ TuningSliders.legacyUpdateFilterSlidersDisplay = function() {
parseInt($('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz * this.sliderGyroFilterMultiplier) ||
parseInt($('.pid_filter select[name="gyroLowpassDynType"]').val()) !== this.FILTER_DEFAULT.gyro_lowpass_type ||
parseInt($('.pid_filter input[name="gyroLowpassFrequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.gyro_lowpass_hz * this.sliderGyroFilterMultiplier) ||
parseInt($('.pid_filter input[name="gyroLowpass2Frequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.gyro_lowpass2_hz * this.sliderGyroFilterMultiplier) ||
parseInt($('.pid_filter select[name="gyroLowpass2Type"]').val()) !== this.FILTER_DEFAULT.gyro_lowpass2_type) {
@ -340,6 +342,8 @@ TuningSliders.legacyUpdateFilterSlidersDisplay = function() {
parseInt($('.pid_filter input[name="dtermLowpassDynMaxFrequency"]').val()) !==
Math.round(this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz * this.sliderDTermFilterMultiplier) ||
parseInt($('.pid_filter select[name="dtermLowpassDynType"]').val()) !== this.FILTER_DEFAULT.dterm_lowpass_type ||
parseInt($('.pid_filter input[name="dtermLowpassFrequency"]').val()) !==
Math.round(this.FILTER_DEFAULT.dterm_lowpass_hz * this.sliderDTermFilterMultiplier) ||
parseInt($('.pid_filter input[name="dtermLowpass2Frequency"]').val()) !==
Math.round(this.FILTER_DEFAULT.dterm_lowpass2_hz * this.sliderDTermFilterMultiplier) ||
parseInt($('.pid_filter select[name="dtermLowpass2Type"]').val()) !== this.FILTER_DEFAULT.dterm_lowpass2_type) {
@ -347,6 +351,12 @@ TuningSliders.legacyUpdateFilterSlidersDisplay = function() {
} else {
this.cachedDTermSliderValues = true;
}
$('.tuningFilterSliders .sliderLabels tr:nth-child(2)').toggle(!this.GyroSliderUnavailable);
$('.tuningFilterSliders .sliderLabels tr:last-child').toggle(!this.DTermSliderUnavailable);
$('.tuningFilterSliders').toggle(!(this.GyroSliderUnavailable && this.DTermSliderUnavailable));
$('.subtab-filter .slidersDisabled').toggle(this.GyroSliderUnavailable || this.DTermSliderUnavailable);
};
TuningSliders.updateSlidersWarning = function(slidersUnavailable = false) {
@ -366,20 +376,20 @@ TuningSliders.updateSlidersWarning = function(slidersUnavailable = false) {
$('.subtab-pid .slidersWarning').toggle(enableWarning && !slidersUnavailable);
};
TuningSliders.updateFilterSlidersWarning = function(gyroSliderUnavailable = false, DTermSliderUnavailable = false) {
TuningSliders.updateFilterSlidersWarning = function() {
let WARNING_FILTER_GYRO_LOW_GAIN = 0.7;
let WARNING_FILTER_GYRO_HIGH_GAIN = 1.25;
let WARNING_FILTER_GYRO_HIGH_GAIN = 1.4;
let WARNING_FILTER_DTERM_LOW_GAIN = 0.7;
const WARNING_FILTER_DTERM_HIGH_GAIN = 1.25;
let WARNING_FILTER_DTERM_HIGH_GAIN = 1.4;
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
WARNING_FILTER_GYRO_LOW_GAIN = 0.45;
WARNING_FILTER_GYRO_HIGH_GAIN = 1.55;
WARNING_FILTER_DTERM_LOW_GAIN = 0.75;
WARNING_FILTER_DTERM_HIGH_GAIN = 1.25;
}
$('.subtab-filter .slidersWarning').toggle(((this.sliderGyroFilterMultiplier >= WARNING_FILTER_GYRO_HIGH_GAIN ||
this.sliderGyroFilterMultiplier <= WARNING_FILTER_GYRO_LOW_GAIN) && !gyroSliderUnavailable) ||
((this.sliderDTermFilterMultiplier >= WARNING_FILTER_DTERM_HIGH_GAIN ||
this.sliderDTermFilterMultiplier <= WARNING_FILTER_DTERM_LOW_GAIN) && !DTermSliderUnavailable));
$('.subtab-filter .slidersWarning').toggle((this.sliderGyroFilterMultiplier >= WARNING_FILTER_GYRO_HIGH_GAIN ||
this.sliderGyroFilterMultiplier <= WARNING_FILTER_GYRO_LOW_GAIN) ||
(this.sliderDTermFilterMultiplier >= WARNING_FILTER_DTERM_HIGH_GAIN || this.sliderDTermFilterMultiplier <= WARNING_FILTER_DTERM_LOW_GAIN));
};
TuningSliders.updatePidSlidersDisplay = function() {
@ -426,65 +436,116 @@ TuningSliders.updatePidSlidersDisplay = function() {
this.updateSlidersWarning(this.pidSlidersUnavailable);
};
TuningSliders.updateGyroFilterSliderDisplay = function() {
// check if enabled filters were changed manually by comparing current value and those based on slider position
const lp1DynMin = parseInt($('.pid_filter input[name="gyroLowpassDynMinFrequency"]').val());
const lp1DynMax = parseInt($('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').val());
const lp1Static = parseInt($('.pid_filter input[name="gyroLowpassFrequency"]').val());
const lp2Freq = parseInt($('.pid_filter input[name="gyroLowpass2Frequency"]').val());
const lp1DynamicMinChanged = (lp1DynMin > 0) && (lp1DynMin !== Math.floor(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz * this.sliderGyroFilterMultiplier));
const lp1DynamicMaxChanged = (lp1DynMax > 0) && (lp1DynMax !== Math.floor(this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz * this.sliderGyroFilterMultiplier));
const lp1Changed = (lp1Static > 0) && (lp1Static !== Math.floor(this.FILTER_DEFAULT.gyro_lowpass_hz * this.sliderGyroFilterMultiplier));
const lp2Changed = (lp2Freq > 0) && (lp2Freq !== Math.floor(this.FILTER_DEFAULT.gyro_lowpass2_hz * this.sliderGyroFilterMultiplier));
const hideSlider = (lp1DynMin && (lp1DynamicMinChanged || lp1DynamicMaxChanged)) || (lp1Static && lp1Changed) || (lp2Freq && lp2Changed) || this.sliderGyroFilterDisabled;
if (hideSlider) {
this.GyroSliderUnavailable = true;
this.sliderGyroFilter = 0;
} else {
this.GyroSliderUnavailable = false;
this.sliderGyroFilter = 1;
this.cachedGyroSliderValues = true;
}
// update Gyro mode and slider
$('select[id="sliderGyroFilterModeSelect"]').val(this.sliderGyroFilter);
$('.sliderGyroFilter').toggleClass('disabledSliders', !this.sliderGyroFilter || !(lp1Static || lp1DynMin || lp2Freq));
$('#sliderGyroFilterMultiplier').prop('disabled', !this.sliderGyroFilter);
};
TuningSliders.updateDTermFilterSliderDisplay = function() {
// check if enabled filters were changed manually by comparing current value and those based on slider position
const lp1DynMin = parseInt($('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val());
const lp1DynMax = parseInt($('.pid_filter input[name="dtermLowpassDynMaxFrequency"]').val());
const lp1Static = parseInt($('.pid_filter input[name="dtermLowpassFrequency"]').val());
const lp2Freq = parseInt($('.pid_filter input[name="dtermLowpass2Frequency"]').val());
const lp1DynamicMinChanged = (lp1DynMin > 0) && (lp1DynMin !== Math.floor(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz * this.sliderDTermFilterMultiplier));
const lp1DynamicMaxChanged = (lp1DynMax > 0) && (lp1DynMax !== Math.floor(this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz * this.sliderDTermFilterMultiplier));
const lp1Changed = (lp1Static > 0) && (lp1Static !== Math.floor(this.FILTER_DEFAULT.dterm_lowpass_hz * this.sliderDTermFilterMultiplier));
const lp2Changed = (lp2Freq > 0) && (lp2Freq !== Math.floor(this.FILTER_DEFAULT.dterm_lowpass2_hz * this.sliderDTermFilterMultiplier));
const hideSlider = (lp1DynMin && (lp1DynamicMinChanged || lp1DynamicMaxChanged)) || (lp1Static && lp1Changed) || (lp2Freq && lp2Changed) || this.sliderDTermFilterDisabled;
if (hideSlider) {
this.DTermSliderUnavailable = true;
this.sliderDTermFilter = 0;
} else {
this.DTermSliderUnavailable = false;
this.sliderDTermFilter = 1;
this.cachedDTermSliderValues = true;
}
// update DTerm mode and slider
$('select[id="sliderDTermFilterModeSelect"]').val(this.sliderDTermFilter);
$('.sliderDTermFilter').toggleClass('disabledSliders', !this.sliderDTermFilter || !(lp1Static || lp1DynMin || lp2Freq));
$('#sliderDTermFilterMultiplier').prop('disabled', !this.sliderDTermFilter);
};
TuningSliders.updateFilterSlidersDisplay = function() {
// check if filters changed manually by comparing current value and those based on slider position
this.GyroSliderUnavailable = false;
this.DTermSliderUnavailable = false;
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
this.GyroSliderUnavailable = !FC.TUNING_SLIDERS.slider_gyro_filter;
this.DTermSliderUnavailable = !FC.TUNING_SLIDERS.slider_dterm_filter;
if (parseInt($('.pid_filter input[name="gyroLowpassDynMinFrequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz * this.sliderGyroFilterMultiplier) ||
parseInt($('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz * this.sliderGyroFilterMultiplier) ||
parseInt($('.pid_filter select[name="gyroLowpassDynType"]').val()) !== this.FILTER_DEFAULT.gyro_lowpass_type ||
parseInt($('.pid_filter input[name="gyroLowpass2Frequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.gyro_lowpass2_hz * this.sliderGyroFilterMultiplier) ||
parseInt($('.pid_filter select[name="gyroLowpass2Type"]').val()) !== this.FILTER_DEFAULT.gyro_lowpass2_type) {
this.GyroSliderUnavailable = true;
this.sliderGyroFilter = 0;
} else {
this.cachedGyroSliderValues = true;
this.sliderGyroFilter = 1;
}
if (parseInt($('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz * this.sliderDTermFilterMultiplier) ||
Math.abs(parseInt($('.pid_filter input[name="dtermLowpassDynMaxFrequency"]').val()) - this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz * this.sliderDTermFilterMultiplier) > 1 ||
parseInt($('.pid_filter select[name="dtermLowpassDynType"]').val()) !== this.FILTER_DEFAULT.dterm_lowpass_type ||
parseInt($('.pid_filter input[name="dtermLowpass2Frequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.dterm_lowpass2_hz * this.sliderDTermFilterMultiplier) ||
parseInt($('.pid_filter select[name="dtermLowpass2Type"]').val()) !== this.FILTER_DEFAULT.dterm_lowpass2_type) {
this.DTermSliderUnavailable = true;
this.sliderDTermFilter = 0;
} else {
this.cachedDTermSliderValues = true;
this.sliderDTermFilter = 1;
}
this.updateGyroFilterSliderDisplay();
this.updateDTermFilterSliderDisplay();
} else {
this.legacyUpdateFilterSlidersDisplay();
}
if (this.GyroSliderUnavailable) {
$('.tuningFilterSliders .sliderLabels tr:nth-child(2)').hide();
} else {
$('.tuningFilterSliders .sliderLabels tr:nth-child(2)').show();
}
if (this.DTermSliderUnavailable) {
$('.tuningFilterSliders .sliderLabels tr:last-child').hide();
} else {
$('.tuningFilterSliders .sliderLabels tr:last-child').show();
}
$('.tuningFilterSliders').toggle(!(this.GyroSliderUnavailable && this.DTermSliderUnavailable));
$('.subtab-filter .slidersDisabled').toggle(this.GyroSliderUnavailable || this.DTermSliderUnavailable);
$('.subtab-filter .nonExpertModeSlidersNote').toggle((!this.GyroSliderUnavailable || !this.DTermSliderUnavailable) && !this.expertMode);
this.updateFilterSlidersWarning(this.GyroSliderUnavailable, this.DTermSliderUnavailable);
};
TuningSliders.gyroFilterSliderEnable = function() {
this.sliderGyroFilter = true;
this.sliderGyroFilterDisabled = false;
this.FilterReset = true;
FC.TUNING_SLIDERS.slider_gyro_filter = 1;
this.writeFilterSliders();
this.updateLowpassValues();
this.updateFilterSlidersDisplay();
};
TuningSliders.gyroFilterSliderDisable = function() {
this.sliderGyroFilter = false;
this.sliderGyroFilterDisabled = true;
this.FilterReset = true;
FC.TUNING_SLIDERS.slider_gyro_filter = 0;
this.writeFilterSliders();
};
TuningSliders.dtermFilterSliderEnable = function() {
this.sliderDTermFilter = true;
this.sliderDTermFilterDisabled = false;
this.FilterReset = true;
FC.TUNING_SLIDERS.slider_dterm_filter = 1;
this.writeFilterSliders();
this.updateLowpassValues();
this.updateFilterSlidersDisplay();
};
TuningSliders.dtermFilterSliderDisable = function() {
this.sliderDTermFilter = false;
this.sliderDTermFilterDisabled = true;
this.FilterReset = true;
FC.TUNING_SLIDERS.slider_dterm_filter = 0;
this.writeFilterSliders();
};
TuningSliders.updateFormPids = function(updateSlidersOnly = false) {
if (!updateSlidersOnly) {
FC.PID_NAMES.forEach(function (elementPid, indexPid) {
@ -611,6 +672,7 @@ TuningSliders.calculateLegacyGyroFilters = function() {
// calculate, set and display new values in forms based on slider position
FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz = Math.floor(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz * this.sliderGyroFilterMultiplier);
FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz = Math.floor(this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz * this.sliderGyroFilterMultiplier);
FC.FILTER_CONFIG.gyro_lowpass_hz = Math.floor(this.FILTER_DEFAULT.gyro_lowpass_hz * this.sliderGyroFilterMultiplier);
FC.FILTER_CONFIG.gyro_lowpass2_hz = Math.floor(this.FILTER_DEFAULT.gyro_lowpass2_hz * this.sliderGyroFilterMultiplier);
FC.FILTER_CONFIG.gyro_lowpass_type = this.FILTER_DEFAULT.gyro_lowpass_type;
FC.FILTER_CONFIG.gyro_lowpass2_type = this.FILTER_DEFAULT.gyro_lowpass2_type;
@ -623,6 +685,7 @@ TuningSliders.calculateLegacyDTermFilters = function() {
// calculate, set and display new values in forms based on slider position
FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz = Math.round(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz * this.sliderDTermFilterMultiplier);
FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz = Math.round(this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz * this.sliderDTermFilterMultiplier);
FC.FILTER_CONFIG.dterm_lowpass_hz = Math.round(this.FILTER_DEFAULT.dterm_lowpass_hz * this.sliderDTermFilterMultiplier);
FC.FILTER_CONFIG.dterm_lowpass2_hz = Math.round(this.FILTER_DEFAULT.dterm_lowpass2_hz * this.sliderDTermFilterMultiplier);
FC.FILTER_CONFIG.dterm_lowpass_type = this.FILTER_DEFAULT.dterm_lowpass_type;
FC.FILTER_CONFIG.dterm_lowpass2_type = this.FILTER_DEFAULT.dterm_lowpass2_type;
@ -635,7 +698,6 @@ TuningSliders.calculateNewGyroFilters = function() {
// this is the main calculation for Gyro Filter slider, inputs are in form of slider position values
// values get set both into forms and their respective variables
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
FC.TUNING_SLIDERS.slider_gyro_filter = this.sliderGyroFilter;
//rounds slider values to nearies multiple of 5 and passes to the FW. Avoid dividing calc by (* x 100)/5 = 20
FC.TUNING_SLIDERS.slider_gyro_filter_multiplier = Math.round(this.sliderGyroFilterMultiplier * 20) * 5;
this.writeFilterSliders();
@ -645,10 +707,9 @@ TuningSliders.calculateNewGyroFilters = function() {
};
TuningSliders.calculateNewDTermFilters = function() {
// this is the main calculation for Gyro Filter slider, inputs are in form of slider position values
// this is the main calculation for DTerm Filter slider, inputs are in form of slider position values
// values get set both into forms and their respective variables
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
FC.TUNING_SLIDERS.slider_dterm_filter = this.sliderDTermFilter;
//rounds slider values to nearies multiple of 5 and passes to the FW. Avoid divide by ROUND[(* x 100)/5 = 20]
FC.TUNING_SLIDERS.slider_dterm_filter_multiplier = Math.round(this.sliderDTermFilterMultiplier * 20) * 5;
this.writeFilterSliders();
@ -657,8 +718,20 @@ TuningSliders.calculateNewDTermFilters = function() {
}
};
// We need to write filter config to switch filters without having to save.
TuningSliders.updateFiltersInFirmware = function() {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
MSP.promise(MSPCodes.MSP_SET_FILTER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FILTER_CONFIG))
.then(() => MSPCodes.MSP_SET_TUNING_SLIDERS, mspHelper.crunch(MSPCodes.MSP_SET_TUNING_SLIDERS))
.then(() => MSP.promise(MSPCodes.MSP_FILTER_CONFIG))
.then(() => this.updateLowpassValues());
}
};
TuningSliders.writeFilterSliders = function () {
// send sliders to firmware
MSP.promise(MSPCodes.MSP_SET_TUNING_SLIDERS, mspHelper.crunch(MSPCodes.MSP_SET_TUNING_SLIDERS))
// pulls values from firmware
.then(() => MSP.promise(MSPCodes.MSP_FILTER_CONFIG))
.then(() => {
TuningSliders.updateLowpassValues();
@ -673,15 +746,19 @@ TuningSliders.writeFilterSliders = function () {
TuningSliders.updateLowpassValues = function() {
$('.pid_filter input[name="gyroLowpassDynMinFrequency"]').val(FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz);
$('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').val(FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz);
$('.pid_filter select[name="gyroLowpassDynType"]').val(FC.FILTER_CONFIG.gyro_lowpass_type);
$('.pid_filter input[name="gyroLowpassFrequency"]').val(FC.FILTER_CONFIG.gyro_lowpass_hz);
$('.pid_filter select[name="gyroLowpassType"]').val(FC.FILTER_CONFIG.gyro_lowpass_type);
$('.pid_filter input[name="gyroLowpass2Frequency"]').val(FC.FILTER_CONFIG.gyro_lowpass2_hz);
$('.pid_filter select[name="gyroLowpassDynType]"').val(FC.FILTER_CONFIG.gyro_lowpass_type);
$('.pid_filter select[name="gyroLowpass2Type"]').val(FC.FILTER_CONFIG.gyro_lowpass2_type);
$('output[name="sliderGyroFilterMultiplier-number"]').val(this.sliderGyroFilterMultiplier);
$('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val(FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz);
$('.pid_filter input[name="dtermLowpassDynMaxFrequency"]').val(FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz);
$('.pid_filter input[name="dtermLowpass2Frequency"]').val(FC.FILTER_CONFIG.dterm_lowpass2_hz);
$('.pid_filter select[name="dtermLowpassDynType"]').val(FC.FILTER_CONFIG.dterm_lowpass_type);
$('.pid_filter input[name="dtermLowpassFrequency"]').val(FC.FILTER_CONFIG.dterm_lowpass_hz);
$('.pid_filter select[name="dtermLowpassType"]').val(FC.FILTER_CONFIG.dterm_lowpass_type);
$('.pid_filter input[name="dtermLowpass2Frequency"]').val(FC.FILTER_CONFIG.dterm_lowpass2_hz);
$('.pid_filter select[name="dtermLowpass2Type"]').val(FC.FILTER_CONFIG.dterm_lowpass2_type);
$('output[name="sliderDTermFilterMultiplier-number"]').val(this.sliderDTermFilterMultiplier);
};

View file

@ -853,6 +853,7 @@ const FC = {
versionFilterDefaults.gyro_lowpass_hz = 250;
versionFilterDefaults.gyro_lowpass_dyn_min_hz = 250;
versionFilterDefaults.gyro_lowpass2_hz = 500;
versionFilterDefaults.dterm_lowpass_hz = 75;
versionFilterDefaults.dterm_lowpass_dyn_min_hz = 75;
versionFilterDefaults.dterm_lowpass_dyn_max_hz = 150;
}

View file

@ -1501,7 +1501,6 @@ MspHelper.prototype.process_data = function(dataHandler) {
FC.TUNING_SLIDERS.slider_dterm_filter_multiplier = data.readU8();
FC.TUNING_SLIDERS.slider_gyro_filter = data.readU8();
FC.TUNING_SLIDERS.slider_gyro_filter_multiplier = data.readU8();
break;
case MSPCodes.MSP_SET_VTXTABLE_POWERLEVEL:
@ -1567,7 +1566,7 @@ MspHelper.prototype.process_data = function(dataHandler) {
console.log('Name set');
break;
case MSPCodes.MSP_SET_FILTER_CONFIG:
console.log('Filter config set');
// removed as this fires a lot with firmware sliders console.log('Filter config set');
break;
case MSPCodes.MSP_SET_ADVANCED_CONFIG:
console.log('Advanced config parameters set');
@ -2311,19 +2310,20 @@ MspHelper.prototype.crunch = function(code) {
break;
case MSPCodes.MSP_SET_TUNING_SLIDERS:
buffer.push8(FC.TUNING_SLIDERS.slider_pids_mode)
.push8(FC.TUNING_SLIDERS.slider_master_multiplier)
.push8(FC.TUNING_SLIDERS.slider_roll_pitch_ratio)
.push8(FC.TUNING_SLIDERS.slider_i_gain)
.push8(FC.TUNING_SLIDERS.slider_d_gain)
.push8(FC.TUNING_SLIDERS.slider_pi_gain)
.push8(FC.TUNING_SLIDERS.slider_dmax_gain)
.push8(FC.TUNING_SLIDERS.slider_feedforward_gain)
.push8(FC.TUNING_SLIDERS.slider_pitch_pi_gain)
.push8(FC.TUNING_SLIDERS.slider_dterm_filter)
.push8(FC.TUNING_SLIDERS.slider_dterm_filter_multiplier)
.push8(FC.TUNING_SLIDERS.slider_gyro_filter)
.push8(FC.TUNING_SLIDERS.slider_gyro_filter_multiplier);
buffer
.push8(FC.TUNING_SLIDERS.slider_pids_mode)
.push8(FC.TUNING_SLIDERS.slider_master_multiplier)
.push8(FC.TUNING_SLIDERS.slider_roll_pitch_ratio)
.push8(FC.TUNING_SLIDERS.slider_i_gain)
.push8(FC.TUNING_SLIDERS.slider_d_gain)
.push8(FC.TUNING_SLIDERS.slider_pi_gain)
.push8(FC.TUNING_SLIDERS.slider_dmax_gain)
.push8(FC.TUNING_SLIDERS.slider_feedforward_gain)
.push8(FC.TUNING_SLIDERS.slider_pitch_pi_gain)
.push8(FC.TUNING_SLIDERS.slider_dterm_filter)
.push8(FC.TUNING_SLIDERS.slider_dterm_filter_multiplier)
.push8(FC.TUNING_SLIDERS.slider_gyro_filter)
.push8(FC.TUNING_SLIDERS.slider_gyro_filter_multiplier);
break;
default:

View file

@ -235,6 +235,7 @@ TABS.pid_tuning.initialize = function (callback) {
$('.pid_filter select[name="gyroLowpassType"]').val(FC.FILTER_CONFIG.gyro_lowpass_type);
$('.pid_filter select[name="gyroLowpass2Type"]').val(FC.FILTER_CONFIG.gyro_lowpass2_type);
$('.pid_filter input[name="dtermLowpass2Frequency"]').val(FC.FILTER_CONFIG.dterm_lowpass2_hz);
$('.pid_filter select[name="dtermLowpass2Type"]').val(FC.FILTER_CONFIG.dterm_lowpass2_type);
// We load it again because the limits are now bigger than in 1.16.0
$('.pid_filter input[name="gyroLowpassFrequency"]').attr("max","16000");
@ -343,16 +344,13 @@ TABS.pid_tuning.initialize = function (callback) {
$('select[id="throttleLimitType"]').val(FC.RC_TUNING.throttleLimitType);
$('.throttle_limit input[name="throttleLimitPercent"]').val(FC.RC_TUNING.throttleLimitPercent);
$('.pid_filter select[name="dtermLowpass2Type"]').val(FC.FILTER_CONFIG.dterm_lowpass2_type);
$('.pid_filter input[name="gyroLowpassDynMinFrequency"]').val(FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz);
$('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').val(FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz);
$('.pid_filter select[name="gyroLowpassDynType"]').val(FC.FILTER_CONFIG.gyro_lowpass_type);
$('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val(FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz);
$('.pid_filter input[name="dtermLowpassDynMaxFrequency"]').val(FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz);
$('.pid_filter select[name="dtermLowpassDynType"]').val(FC.FILTER_CONFIG.dterm_lowpass_type);
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
$('.pid_filter input[name="dtermLowpassDynExpo"]').val(FC.FILTER_CONFIG.dyn_lpf_curve_expo);
}
$('.pid_tuning input[name="dMinRoll"]').val(FC.ADVANCED_TUNING.dMinRoll);
$('.pid_tuning input[name="dMinPitch"]').val(FC.ADVANCED_TUNING.dMinPitch);
@ -366,8 +364,8 @@ TABS.pid_tuning.initialize = function (callback) {
} else {
$('.throttle_limit').hide();
$('.gyroLowpassDyn').hide();
$('.dtermLowpassDyn').hide();
$('.gyroLowpassDynLegacy').hide();
$('.dtermLowpassDynLegacy').hide();
$('.dtermLowpass2TypeGroup').hide();
$('.dminGroup').hide();
@ -444,7 +442,7 @@ TABS.pid_tuning.initialize = function (callback) {
dynamicNotchQ_e.val(FC.FILTER_CONFIG.dyn_notch_q);
dynamicNotchWidthPercent_e.val(FC.FILTER_CONFIG.dyn_notch_width_percent);
}
$('.rpmFilter span.suboption').toggle(checked);
}).prop('checked', FC.FILTER_CONFIG.gyro_rpm_notch_harmonics != 0).change();
} else {
@ -488,7 +486,19 @@ TABS.pid_tuning.initialize = function (callback) {
$('.rates_type').hide();
}
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
// hide legacy filter switches
$('.gyroLowpassLegacy').hide();
$('.gyroLowpassDynLegacy').hide();
$('.dtermLowpassLegacy').hide();
$('.dtermLowpassDynLegacy').hide();
$('.pid_filter input[name="dtermLowpassExpo"]').val(FC.FILTER_CONFIG.dyn_lpf_curve_expo);
} else {
// hide firmware filter switches
$('.gyroLowpass').hide();
$('.dtermLowpass').hide();
// Previous html attributes for legacy sliders
$('.pid_tuning .ROLL input[name="p"]').attr("max", "200");
$('.pid_tuning .ROLL input[name="i"]').attr("max", "200");
@ -680,6 +690,8 @@ TABS.pid_tuning.initialize = function (callback) {
$('.pid_filter input[name="gyroNotch1Frequency"]').val(checked ? hz : 0).attr('disabled', !checked)
.attr("min", checked ? 1 : 0).change();
$('.pid_filter input[name="gyroNotch1Cutoff"]').attr('disabled', !checked).change();
$('.gyroNotch1 span.suboption').toggle(checked);
});
$('input[id="gyroNotch2Enabled"]').change(function() {
@ -689,6 +701,8 @@ TABS.pid_tuning.initialize = function (callback) {
$('.pid_filter input[name="gyroNotch2Frequency"]').val(checked ? hz : 0).attr('disabled', !checked)
.attr("min", checked ? 1 : 0).change();
$('.pid_filter input[name="gyroNotch2Cutoff"]').attr('disabled', !checked).change();
$('.gyroNotch2 span.suboption').toggle(checked);
});
$('input[id="dtermNotchEnabled"]').change(function() {
@ -698,114 +712,354 @@ TABS.pid_tuning.initialize = function (callback) {
$('.pid_filter input[name="dTermNotchFrequency"]').val(checked ? hz : 0).attr('disabled', !checked)
.attr("min", checked ? 1 : 0).change();
$('.pid_filter input[name="dTermNotchCutoff"]').attr('disabled', !checked).change();
$('.dtermNotch span.suboption').toggle(checked);
});
$('input[id="gyroLowpassEnabled"]').change(function() {
const checked = $(this).is(':checked');
const disabledByDynamicLowpass = $('input[id="gyroLowpassDynEnabled"]').is(':checked');
// gyro filter selectors
const gyroLowpassDynMinFrequency = $('.pid_filter input[name="gyroLowpassDynMinFrequency"]');
const gyroLowpassDynMaxFrequency = $('.pid_filter input[name="gyroLowpassDynMaxFrequency"]');
const gyroLowpassFrequency = $('.pid_filter input[name="gyroLowpassFrequency"]');
const gyroLowpass2Frequency = $('.pid_filter input[name="gyroLowpass2Frequency"]');
const gyroLowpassType = $('.pid_filter select[name="gyroLowpassType"]');
const gyroLowpass2Type = $('.pid_filter select[name="gyroLowpass2Type"]');
const gyroLowpassDynType = $('.pid_filter select[name="gyroLowpassDynType"]');
const cutoff = FC.FILTER_CONFIG.gyro_lowpass_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass_hz : FILTER_DEFAULT.gyro_lowpass_hz;
const type = FC.FILTER_CONFIG.gyro_lowpass_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass_type : FILTER_DEFAULT.gyro_lowpass_type;
const gyroLowpassDynEnabled = $('.pid_filter input[id="gyroLowpassDynEnabled"]');
const gyroLowpassEnabled = $('.pid_filter input[id="gyroLowpassEnabled"]');
const gyroLowpass2Enabled = $('.pid_filter input[id="gyroLowpass2Enabled"]');
$('.pid_filter input[name="gyroLowpassFrequency"]').val((checked || disabledByDynamicLowpass) ? cutoff : 0).attr('disabled', !checked);
$('.pid_filter select[name="gyroLowpassType"]').val(type).attr('disabled', !checked);
const gyroLowpassOption = $('.gyroLowpass span.suboption');
const gyroLowpassOptionStatic = $('.gyroLowpass span.suboption.static');
const gyroLowpassOptionDynamic = $('.gyroLowpass span.suboption.dynamic');
const gyroLowpass2Option = $('.gyroLowpass2 span.suboption');
if (checked) {
$('input[id="gyroLowpassDynEnabled"]').prop('checked', false).change();
}
self.updateFilterWarning();
});
const gyroLowpassFilterMode = $('.pid_filter select[name="gyroLowpassFilterMode"]');
$('input[id="gyroLowpassDynEnabled"]').change(function() {
const checked = $(this).is(':checked');
let cutoff_min = FILTER_DEFAULT.gyro_lowpass_dyn_min_hz;
let type = FILTER_DEFAULT.gyro_lowpass_type;
if (FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz > 0 && FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz < FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz) {
cutoff_min = FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz;
type = FC.FILTER_CONFIG.gyro_lowpass_type;
}
// dterm filter selectors
const dtermLowpassDynMinFrequency = $('.pid_filter input[name="dtermLowpassDynMinFrequency"]');
const dtermLowpassDynMaxFrequency = $('.pid_filter input[name="dtermLowpassDynMaxFrequency"]');
const dtermLowpassFrequency = $('.pid_filter input[name="dtermLowpassFrequency"]');
const dtermLowpass2Frequency = $('.pid_filter input[name="dtermLowpass2Frequency"]');
const dtermLowpassType = $('.pid_filter select[name="dtermLowpassType"]');
const dtermLowpass2Type = $('.pid_filter select[name="dtermLowpass2Type"]');
const dtermLowpassDynType = $('.pid_filter select[name="dtermLowpassDynType"]');
$('.pid_filter input[name="gyroLowpassDynMinFrequency"]').val(checked ? cutoff_min : 0).attr('disabled', !checked);
$('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').attr('disabled', !checked);
$('.pid_filter select[name="gyroLowpassDynType"]').val(type).attr('disabled', !checked);
const dtermLowpassDynEnabled = $('.pid_filter input[id="dtermLowpassDynEnabled"]');
const dtermLowpassEnabled = $('input[id="dtermLowpassEnabled"]');
const dtermLowpass2Enabled = $('input[id="dtermLowpass2Enabled"]');
if (checked) {
$('input[id="gyroLowpassEnabled"]').prop('checked', false).change();
} else if (FC.FILTER_CONFIG.gyro_lowpass_hz > 0 && !$('input[id="gyroLowpassEnabled"]').is(':checked')) {
$('input[id="gyroLowpassEnabled"]').prop('checked', true).change();
}
self.updateFilterWarning();
});
const dtermLowpassOption = $('.dtermLowpass span.suboption');
const dtermLowpassOptionStatic = $('.dtermLowpass span.suboption.static');
const dtermLowpassOptionDynamic = $('.dtermLowpass span.suboption.dynamic');
const dtermLowpass2Option = $('.dtermLowpass2 span.suboption');
$('input[id="gyroLowpass2Enabled"]').change(function() {
const checked = $(this).is(':checked');
const cutoff = FC.FILTER_CONFIG.gyro_lowpass2_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass2_hz : FILTER_DEFAULT.gyro_lowpass2_hz;
const type = FC.FILTER_CONFIG.gyro_lowpass2_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass2_type : FILTER_DEFAULT.gyro_lowpass2_type;
const dtermLowpassFilterMode = $('.pid_filter select[name="dtermLowpassFilterMode"]');
$('.pid_filter input[name="gyroLowpass2Frequency"]').val(checked ? cutoff : 0).attr('disabled', !checked);
$('.pid_filter select[name="gyroLowpass2Type"]').val(type).attr('disabled', !checked);
});
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
$('input[id="dtermLowpassEnabled"]').change(function() {
const checked = $(this).is(':checked');
const disabledByDynamicLowpass = $('input[id="dtermLowpassDynEnabled"]').is(':checked');
// Legacy filter selectors for lowpass 1 and 2
gyroLowpassEnabled.change(function() {
const checked = $(this).is(':checked');
const disabledByDynamicLowpass = gyroLowpassDynEnabled.is(':checked');
const cutoff = FC.FILTER_CONFIG.dterm_lowpass_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass_hz : FILTER_DEFAULT.dterm_lowpass_hz;
const type = FC.FILTER_CONFIG.dterm_lowpass_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass_type : FILTER_DEFAULT.dterm_lowpass_type;
const cutoff = FC.FILTER_CONFIG.gyro_lowpass_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass_hz : FILTER_DEFAULT.gyro_lowpass_hz;
const type = FC.FILTER_CONFIG.gyro_lowpass_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass_type : FILTER_DEFAULT.gyro_lowpass_type;
$('.pid_filter input[name="dtermLowpassFrequency"]').val((checked || disabledByDynamicLowpass) ? cutoff : 0).attr('disabled', !checked);
$('.pid_filter select[name="dtermLowpassType"]').val(type).attr('disabled', !checked);
gyroLowpassFrequency.val((checked || disabledByDynamicLowpass) ? cutoff : 0).attr('disabled', !checked);
gyroLowpassType.each((i, el) => $(el).val(type).attr('disabled', !checked));
if (checked) {
$('input[id="dtermLowpassDynEnabled"]').prop('checked', false).change();
}
self.updateFilterWarning();
});
if (checked) {
gyroLowpassDynEnabled.prop('checked', false).change();
}
self.updateFilterWarning();
});
$('.dynLpfCurveExpo').toggle(semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44));
$('input[id="dtermLowpassDynEnabled"]').change(function() {
const checked = $(this).is(':checked');
let cutoff_min = FILTER_DEFAULT.dterm_lowpass_dyn_min_hz;
let type = FILTER_DEFAULT.dterm_lowpass_type;
if (FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz > 0 && FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz < FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz) {
cutoff_min = FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz;
type = FC.FILTER_CONFIG.dterm_lowpass_type;
}
gyroLowpassDynEnabled.change(function() {
const checked = $(this).is(':checked');
let cutoff_min = FILTER_DEFAULT.gyro_lowpass_dyn_min_hz;
let type = FILTER_DEFAULT.gyro_lowpass_type;
if (FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz > 0 && FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz < FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz) {
cutoff_min = FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz;
type = FC.FILTER_CONFIG.gyro_lowpass_type;
}
$('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val(checked ? cutoff_min : 0).attr('disabled', !checked);
$('.pid_filter input[name="dtermLowpassDynMaxFrequency"]').attr('disabled', !checked);
$('.pid_filter select[name="dtermLowpassDynType"]').val(type).attr('disabled', !checked);
gyroLowpassDynMinFrequency.val(checked ? cutoff_min : 0).attr('disabled', !checked);
gyroLowpassDynMaxFrequency.attr('disabled', !checked);
gyroLowpassDynType.each((i, el) => $(el).val(type).attr('disabled', !checked));
if (checked) {
$('input[id="dtermLowpassEnabled"]').prop('checked', false).change();
} else if (FC.FILTER_CONFIG.dterm_lowpass_hz > 0 && !$('input[id="dtermLowpassEnabled"]').is(':checked')) {
$('input[id="dtermLowpassEnabled"]').prop('checked', true).change();
$('.pid_filter input[id="dtermLowpassDynExpoEnabled"]').prop('checked', false).change();
}
self.updateFilterWarning();
});
if (checked) {
gyroLowpassEnabled.prop('checked', false).change();
} else if (FC.FILTER_CONFIG.gyro_lowpass_hz > 0 && !gyroLowpassEnabled.is(':checked')) {
gyroLowpassEnabled.prop('checked', true).change();
}
self.updateFilterWarning();
});
$('input[id="dtermLowpassDynExpoEnabled"]').change(function() {
const checked = $(this).is(':checked');
const curveExpo = FC.FILTER_CONFIG.dyn_lpf_curve_expo > 0 ? FC.FILTER_CONFIG.dyn_lpf_curve_expo : FILTER_DEFAULT.dyn_lpf_curve_expo;
gyroLowpass2Enabled.change(function() {
const checked = $(this).is(':checked');
const cutoff = FC.FILTER_CONFIG.gyro_lowpass2_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass2_hz : FILTER_DEFAULT.gyro_lowpass2_hz;
const type = FC.FILTER_CONFIG.gyro_lowpass2_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass2_type : FILTER_DEFAULT.gyro_lowpass2_type;
$('.pid_filter input[name="dtermLowpassDynExpo"]').val(checked ? curveExpo : 0).attr('disabled', !checked);
});
gyroLowpass2Frequency.val(checked ? cutoff : 0).attr('disabled', !checked);
gyroLowpass2Type.each((i, el) => $(el).val(type).attr('disabled', !checked));
});
$('input[id="dtermLowpass2Enabled"]').change(function() {
const checked = $(this).is(':checked');
const cutoff = FC.FILTER_CONFIG.dterm_lowpass2_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass2_hz : FILTER_DEFAULT.dterm_lowpass2_hz;
const type = FC.FILTER_CONFIG.dterm_lowpass2_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass2_type : FILTER_DEFAULT.dterm_lowpass2_type;
dtermLowpassEnabled.change(function() {
const checked = $(this).is(':checked');
const disabledByDynamicLowpass = dtermLowpassDynEnabled.is(':checked');
$('.pid_filter input[name="dtermLowpass2Frequency"]').val(checked ? cutoff : 0).attr('disabled', !checked);
$('.pid_filter select[name="dtermLowpass2Type"]').val(type).attr('disabled', !checked);
});
const cutoff = FC.FILTER_CONFIG.dterm_lowpass_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass_hz : FILTER_DEFAULT.dterm_lowpass_hz;
const type = FC.FILTER_CONFIG.dterm_lowpass_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass_type : FILTER_DEFAULT.dterm_lowpass_type;
dtermLowpassFrequency.val((checked || disabledByDynamicLowpass) ? cutoff : 0).attr('disabled', !checked);
dtermLowpassType.each((i, el) => $(el).val(type).attr('disabled', !checked));
if (checked) {
dtermLowpassDynEnabled.prop('checked', false).change();
}
self.updateFilterWarning();
});
dtermLowpassDynEnabled.change(function() {
const checked = $(this).is(':checked');
let cutoff_min = FILTER_DEFAULT.dterm_lowpass_dyn_min_hz;
let type = FILTER_DEFAULT.dterm_lowpass_type;
if (FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz > 0 && FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz < FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz) {
cutoff_min = FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz;
type = FC.FILTER_CONFIG.dterm_lowpass_type;
}
dtermLowpassDynMinFrequency.val(checked ? cutoff_min : 0).attr('disabled', !checked);
dtermLowpassDynMaxFrequency.attr('disabled', !checked);
dtermLowpassDynType.each((i, el) => $(el).val(type).attr('disabled', !checked));
if (checked) {
dtermLowpassEnabled.prop('checked', false).change();
} else if (FC.FILTER_CONFIG.dterm_lowpass_hz > 0 && !dtermLowpassEnabled.is(':checked')) {
dtermLowpassEnabled.prop('checked', true).change();
}
self.updateFilterWarning();
});
dtermLowpass2Enabled.change(function() {
const checked = $(this).is(':checked');
const cutoff = FC.FILTER_CONFIG.dterm_lowpass2_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass2_hz : FILTER_DEFAULT.dterm_lowpass2_hz;
const type = FC.FILTER_CONFIG.dterm_lowpass2_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass2_type : FILTER_DEFAULT.dterm_lowpass2_type;
dtermLowpass2Frequency.val(checked ? cutoff : 0).attr('disabled', !checked);
dtermLowpass2Type.each((i, el) => $(el).val(type).attr('disabled', !checked));
});
} else {
// firmware 4.3 filter selectors for lowpass 1 and 2
gyroLowpassEnabled.change(function() {
const checked = $(this).is(':checked');
let cutoffMin = FILTER_DEFAULT.gyro_lowpass_dyn_min_hz;
let cutoffMax = FILTER_DEFAULT.gyro_lowpass_dyn_max_hz;
if (FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz > 0 || FC.FILTER_CONFIG.gyro_lowpass_hz > 0) {
// lowpass1 is enabled, set the master switch on, show the label, mode selector and type fields
if (checked) {
gyroLowpassFilterMode.val(FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz > 0 ? 1 : 0).change();
} else {
// the user is disabling Lowpass 1 so set everything to zero
gyroLowpassDynMinFrequency.val(0);
gyroLowpassDynMaxFrequency.val(0);
gyroLowpassFrequency.val(0);
FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz = 0;
FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz = 0;
FC.FILTER_CONFIG.gyro_lowpass_hz = 0;
TuningSliders.updateFiltersInFirmware();
}
} else {
// lowpass 1 is disabled, set the master switch off, only show label
if (checked) {
// user is trying to enable the lowpass filter, but it was off (both cutoffs are zero)
// initialise in dynamic mode with values at sliders, or use defaults
gyroLowpassFilterMode.val(1).change();
cutoffMin = Math.floor(cutoffMin * TuningSliders.sliderGyroFilterMultiplier);
cutoffMax = Math.floor(cutoffMax * TuningSliders.sliderGyroFilterMultiplier);
gyroLowpassDynMinFrequency.val(cutoffMin);
gyroLowpassDynMaxFrequency.val(cutoffMax);
FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz = cutoffMin;
FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz = cutoffMax;
TuningSliders.updateFiltersInFirmware();
}
}
gyroLowpassOption.toggle(checked);
gyroLowpassOptionStatic.toggle(FC.FILTER_CONFIG.gyro_lowpass_hz !== 0);
gyroLowpassOptionDynamic.toggle(FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz !== 0);
});
gyroLowpassFilterMode.change(function() {
const dynMode = parseInt($(this).val());
let cutoff = FILTER_DEFAULT.gyro_lowpass_hz;
let cutoffMin = FILTER_DEFAULT.gyro_lowpass_dyn_min_hz;
let cutoffMax = FILTER_DEFAULT.gyro_lowpass_dyn_max_hz;
if (dynMode) {
// dynamic mode, set the static field min to zero
gyroLowpassFrequency.val(0);
FC.FILTER_CONFIG.gyro_lowpass_hz = 0;
// if dyn min is zero, set dyn min to sliders or default
if (!FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz) {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44) && TuningSliders.sliderGyroFilter) {
cutoffMin = Math.floor(cutoffMin * TuningSliders.sliderGyroFilterMultiplier);
cutoffMax = Math.floor(cutoffMax * TuningSliders.sliderGyroFilterMultiplier);
}
gyroLowpassDynMinFrequency.val(cutoffMin);
gyroLowpassDynMaxFrequency.val(cutoffMax);
FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz = cutoffMin;
FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz = cutoffMax;
}
gyroLowpassOptionStatic.hide();
gyroLowpassOptionDynamic.show();
TuningSliders.updateFiltersInFirmware();
} else {
// static, set the dynamic field min to zero
gyroLowpassDynMinFrequency.val(0);
gyroLowpassDynMaxFrequency.val(0);
FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz = 0;
FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz = 0;
// If static is zero, set the dynamic cutoff field according to sliders or default
if (!FC.FILTER_CONFIG.gyro_lowpass_hz) {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44) && TuningSliders.sliderGyroFilter) {
cutoff = Math.floor(FILTER_DEFAULT.gyro_lowpass_hz * TuningSliders.sliderGyroFilterMultiplier);
}
gyroLowpassFrequency.val(cutoff);
FC.FILTER_CONFIG.gyro_lowpass_hz = cutoff;
}
gyroLowpassOptionStatic.show();
gyroLowpassOptionDynamic.hide();
TuningSliders.updateFiltersInFirmware();
}
});
// switch gyro lpf2
gyroLowpass2Enabled.change(function() {
const checked = $(this).is(':checked');
let cutoff = FC.FILTER_CONFIG.gyro_lowpass2_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass2_hz : FILTER_DEFAULT.gyro_lowpass2_hz;
if (TuningSliders.sliderGyroFilter) {
cutoff = checked ? Math.floor(FILTER_DEFAULT.gyro_lowpass2_hz * TuningSliders.sliderGyroFilterMultiplier) : 0;
FC.FILTER_CONFIG.gyro_lowpass2_hz = cutoff;
TuningSliders.updateFiltersInFirmware();
}
gyroLowpass2Frequency.val(checked ? cutoff : 0).attr('disabled', !checked);
gyroLowpass2Option.toggle(checked);
self.updateFilterWarning();
});
dtermLowpassEnabled.change(function() {
const checked = $(this).is(':checked');
let cutoffMin = FILTER_DEFAULT.dterm_lowpass_dyn_min_hz;
let cutoffMax = FILTER_DEFAULT.dterm_lowpass_dyn_max_hz;
if (FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz > 0 || FC.FILTER_CONFIG.dterm_lowpass_hz > 0) {
// lowpass1 is enabled, set the master switch on, show the label, mode selector and type fields
if (checked) {
dtermLowpassFilterMode.val(FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz > 0 ? 1 : 0).change();
} else {
// the user is disabling Lowpass 1 so set everything to zero
dtermLowpassDynMinFrequency.val(0);
dtermLowpassDynMaxFrequency.val(0);
dtermLowpassFrequency.val(0);
FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz = 0;
FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz = 0;
FC.FILTER_CONFIG.dterm_lowpass_hz = 0;
TuningSliders.updateFiltersInFirmware();
}
} else {
// lowpass 1 is disabled, set the master switch off, only show label
if (checked) {
// user is trying to enable the lowpass filter, but it was off (both cutoffs are zero)
// initialise in dynamic mode with values at sliders, or use defaults
dtermLowpassFilterMode.val(1).change();
if (TuningSliders.sliderDTermFilter) {
cutoffMin = Math.floor(cutoffMin * TuningSliders.sliderDTermFilterMultiplier);
cutoffMax = Math.floor(cutoffMax * TuningSliders.sliderDTermFilterMultiplier);
}
dtermLowpassDynMinFrequency.val(cutoffMin);
dtermLowpassDynMaxFrequency.val(cutoffMax);
FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz = cutoffMin;
FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz = cutoffMax;
TuningSliders.updateFiltersInFirmware();
}
}
dtermLowpassOption.toggle(checked);
dtermLowpassOptionStatic.toggle(FC.FILTER_CONFIG.dterm_lowpass_hz !== 0);
dtermLowpassOptionDynamic.toggle(FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz !== 0);
});
dtermLowpassFilterMode.change(function() {
const dynMode = parseInt($(this).val());
let cutoff = FILTER_DEFAULT.dterm_lowpass_hz;
let cutoffMin = FILTER_DEFAULT.dterm_lowpass_dyn_min_hz;
let cutoffMax = FILTER_DEFAULT.dterm_lowpass_dyn_max_hz;
if (dynMode) {
// dynamic mode, set the static field min to zero
dtermLowpassFrequency.val(0);
FC.FILTER_CONFIG.dterm_lowpass_hz = 0;
// if dyn min is zero, set dyn min to sliders or default
if (!FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz) {
if (TuningSliders.sliderDTermFilter) {
cutoffMin = Math.floor(cutoffMin * TuningSliders.sliderDTermFilterMultiplier);
cutoffMax = Math.floor(cutoffMax * TuningSliders.sliderDTermFilterMultiplier);
}
dtermLowpassDynMinFrequency.val(cutoffMin);
dtermLowpassDynMaxFrequency.val(cutoffMax);
FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz = cutoffMin;
FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz = cutoffMax;
}
dtermLowpassOptionStatic.hide();
dtermLowpassOptionDynamic.show();
TuningSliders.updateFiltersInFirmware();
} else {
// static, set the dynamic field min to zero
dtermLowpassDynMinFrequency.val(0);
dtermLowpassDynMaxFrequency.val(0);
FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz = 0;
FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz = 0;
// If static is zero, set the dynamic cutoff field according to sliders or default
if (!FC.FILTER_CONFIG.dterm_lowpass_hz) {
if (TuningSliders.sliderDTermFilter) {
cutoff = Math.floor(FILTER_DEFAULT.dterm_lowpass_hz * TuningSliders.sliderDTermFilterMultiplier);
}
dtermLowpassFrequency.val(cutoff);
FC.FILTER_CONFIG.dterm_lowpass_hz = cutoff;
}
dtermLowpassOptionStatic.show();
dtermLowpassOptionDynamic.hide();
TuningSliders.updateFiltersInFirmware();
}
});
dtermLowpass2Enabled.change(function() {
const checked = $(this).is(':checked');
let cutoff = FC.FILTER_CONFIG.dterm_lowpass2_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass2_hz : FILTER_DEFAULT.dterm_lowpass2_hz;
if (TuningSliders.sliderDTermFilter) {
cutoff = checked ? Math.floor(FILTER_DEFAULT.dterm_lowpass2_hz * TuningSliders.sliderDTermFilterMultiplier) : 0;
FC.FILTER_CONFIG.dterm_lowpass2_hz = cutoff;
TuningSliders.updateFiltersInFirmware();
}
dtermLowpass2Frequency.val(checked ? cutoff : 0).attr('disabled', !checked);
dtermLowpass2Option.toggle(checked);
self.updateFilterWarning();
});
}
$('input[id="yawLowpassEnabled"]').change(function() {
const checked = $(this).is(':checked');
const cutoff = FC.FILTER_CONFIG.yaw_lowpass_hz > 0 ? FC.FILTER_CONFIG.yaw_lowpass_hz : FILTER_DEFAULT.yaw_lowpass_hz;
$('.pid_filter input[name="yawLowpassFrequency"]').val(checked ? cutoff : 0).attr('disabled', !checked);
$('.yawLowpass span.suboption').toggle(checked);
});
// The notch cutoff must be smaller than the notch frecuency
@ -834,17 +1088,37 @@ TABS.pid_tuning.initialize = function (callback) {
}).change();
// Initial state of the filters: enabled or disabled
$('input[id="gyroNotch1Enabled"]').prop('checked', FC.FILTER_CONFIG.gyro_notch_hz != 0).change();
$('input[id="gyroNotch2Enabled"]').prop('checked', FC.FILTER_CONFIG.gyro_notch2_hz != 0).change();
$('input[id="dtermNotchEnabled"]').prop('checked', FC.FILTER_CONFIG.dterm_notch_hz != 0).change();
$('input[id="gyroLowpassEnabled"]').prop('checked', FC.FILTER_CONFIG.gyro_lowpass_hz != 0).change();
$('input[id="gyroLowpassDynEnabled"]').prop('checked', FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz != 0 && FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz < FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz).change();
$('input[id="dtermLowpassDynExpoEnabled"]').prop('checked', FC.FILTER_CONFIG.dyn_lpf_curve_expo != 0).change();
$('input[id="gyroLowpass2Enabled"]').prop('checked', FC.FILTER_CONFIG.gyro_lowpass2_hz != 0).change();
$('input[id="dtermLowpassEnabled"]').prop('checked', FC.FILTER_CONFIG.dterm_lowpass_hz != 0).change();
$('input[id="dtermLowpassDynEnabled"]').prop('checked', FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz != 0 && FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz < FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz).change();
$('input[id="dtermLowpass2Enabled"]').prop('checked', FC.FILTER_CONFIG.dterm_lowpass2_hz != 0).change();
$('input[id="yawLowpassEnabled"]').prop('checked', FC.FILTER_CONFIG.yaw_lowpass_hz != 0).change();
$('input[id="gyroNotch1Enabled"]').prop('checked', FC.FILTER_CONFIG.gyro_notch_hz !== 0).change();
$('input[id="gyroNotch2Enabled"]').prop('checked', FC.FILTER_CONFIG.gyro_notch2_hz !== 0).change();
$('input[id="dtermNotchEnabled"]').prop('checked', FC.FILTER_CONFIG.dterm_notch_hz !== 0).change();
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
gyroLowpassEnabled.prop('checked', FC.FILTER_CONFIG.gyro_lowpass_hz !== 0 || FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz !== 0).change();
dtermLowpassEnabled.prop('checked', FC.FILTER_CONFIG.dterm_lowpass_hz !== 0 || FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz !== 0).change();
if (FC.FILTER_CONFIG.gyro_lowpass_hz > 0) {
gyroLowpassFilterMode.val(0).change();
} else if (FC.FILTER_CONFIG.gyroLowpassDynMinFrequency > 0) {
gyroLowpassFilterMode.val(1).change();
}
if (FC.FILTER_CONFIG.dterm_lowpass_hz > 0) {
dtermLowpassFilterMode.val(0).change();
} else if (FC.FILTER_CONFIG.dtermLowpassDynMinFrequency > 0) {
dtermLowpassFilterMode.val(1).change();
}
} else {
gyroLowpassEnabled.prop('checked', FC.FILTER_CONFIG.gyro_lowpass_hz !== 0).change();
gyroLowpassDynEnabled.prop('checked', FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz !== 0 &&
FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz < FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz).change();
dtermLowpassEnabled.prop('checked', FC.FILTER_CONFIG.dterm_lowpass_hz !== 0).change();
dtermLowpassDynEnabled.prop('checked', FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz !== 0 &&
FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz < FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz).change();
}
gyroLowpass2Enabled.prop('checked', FC.FILTER_CONFIG.gyro_lowpass2_hz !== 0).change();
dtermLowpass2Enabled.prop('checked', FC.FILTER_CONFIG.dterm_lowpass2_hz !== 0).change();
$('input[id="yawLowpassEnabled"]').prop('checked', FC.FILTER_CONFIG.yaw_lowpass_hz !== 0).change();
self.updatePIDColors();
}
@ -973,7 +1247,7 @@ TABS.pid_tuning.initialize = function (callback) {
}
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
FC.FILTER_CONFIG.dterm_lowpass_type = $('.pid_filter select[name="dtermLowpassType"]').val();
FC.FILTER_CONFIG.dterm_lowpass_type = parseInt($('.pid_filter select[name="dtermLowpassType"]').val());
FC.ADVANCED_TUNING.itermThrottleThreshold = parseInt($('.antigravity input[name="itermThrottleThreshold"]').val());
FC.ADVANCED_TUNING.itermAcceleratorGain = parseInt($('.antigravity input[name="itermAcceleratorGain"]').val() * 1000);
}
@ -983,6 +1257,7 @@ TABS.pid_tuning.initialize = function (callback) {
FC.FILTER_CONFIG.gyro_lowpass_type = parseInt($('.pid_filter select[name="gyroLowpassType"]').val());
FC.FILTER_CONFIG.gyro_lowpass2_type = parseInt($('.pid_filter select[name="gyroLowpass2Type"]').val());
FC.FILTER_CONFIG.dterm_lowpass2_hz = parseInt($('.pid_filter input[name="dtermLowpass2Frequency"]').val());
FC.FILTER_CONFIG.dterm_lowpass2_type = parseInt($('.pid_filter select[name="dtermLowpass2Type"]').val());
}
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_40)) {
@ -1013,17 +1288,18 @@ TABS.pid_tuning.initialize = function (callback) {
FC.RC_TUNING.throttleLimitType = $('select[id="throttleLimitType"]').val();
FC.RC_TUNING.throttleLimitPercent = parseInt($('.throttle_limit input[name="throttleLimitPercent"]').val());
FC.FILTER_CONFIG.dterm_lowpass2_type = $('.pid_filter select[name="dtermLowpass2Type"]').val();
FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz = parseInt($('.pid_filter input[name="gyroLowpassDynMinFrequency"]').val());
FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz = parseInt($('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').val());
FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz = parseInt($('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val());
FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz = parseInt($('.pid_filter input[name="dtermLowpassDynMaxFrequency"]').val());
if (FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz > 0 && FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz < FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz ) {
FC.FILTER_CONFIG.gyro_lowpass_type = $('.pid_filter select[name="gyroLowpassDynType"]').val();
}
if (FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz > 0 && FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz < FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz ) {
FC.FILTER_CONFIG.dterm_lowpass_type = $('.pid_filter select[name="dtermLowpassDynType"]').val();
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
if (FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz > 0 && FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz < FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz ) {
FC.FILTER_CONFIG.gyro_lowpass_type = $('.pid_filter select[name="gyroLowpassDynType"]').val();
}
if (FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz > 0 && FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz < FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz ) {
FC.FILTER_CONFIG.dterm_lowpass_type = $('.pid_filter select[name="dtermLowpassDynType"]').val();
}
}
FC.ADVANCED_TUNING.dMinRoll = parseInt($('.pid_tuning input[name="dMinRoll"]').val());
@ -1066,13 +1342,13 @@ TABS.pid_tuning.initialize = function (callback) {
FC.ADVANCED_TUNING.feedforward_averaging = $('select[id="feedforwardAveraging"]').val();
FC.ADVANCED_TUNING.feedforward_smooth_factor = parseInt($('input[name="feedforwardSmoothFactor"]').val());
FC.ADVANCED_TUNING.feedforward_boost = parseInt($('input[name="feedforwardBoost"]').val());
FC.FILTER_CONFIG.dyn_lpf_curve_expo = parseInt($('.pid_filter input[name="dtermLowpassDynExpo"]').val());
FC.ADVANCED_TUNING.vbat_sag_compensation = $('input[id="vbatSagCompensation"]').is(':checked') ? parseInt($('input[name="vbatSagValue"]').val()) : 0;
FC.ADVANCED_TUNING.thrustLinearization = $('input[id="thrustLinearization"]').is(':checked') ? parseInt($('input[name="thrustLinearValue"]').val()) : 0;
FC.FILTER_CONFIG.dyn_lpf_curve_expo = parseInt($('.pid_filter input[name="dtermLowpassExpo"]').val());
FC.FILTER_CONFIG.dyn_notch_count = parseInt($('.pid_filter input[name="dynamicNotchCount"]').val());
FC.TUNING_SLIDERS.slider_pids_mode = TuningSliders.sliderPidsMode;
//rounds slider values to nearies multiple of 5 and passes to the FW. Avoid dividing calc by (* x 100)/5 = 20
//round slider values to nearest multiple of 5 and passes to the FW. Avoid dividing calc by (* x 100)/5 = 20
FC.TUNING_SLIDERS.slider_master_multiplier = Math.round(TuningSliders.sliderMasterMultiplier * 20) * 5;
FC.TUNING_SLIDERS.slider_d_gain = Math.round(TuningSliders.sliderDGain * 20) * 5;
FC.TUNING_SLIDERS.slider_pi_gain = Math.round(TuningSliders.sliderPIGain * 20) * 5;
@ -1488,11 +1764,14 @@ TABS.pid_tuning.initialize = function (callback) {
}
populateFilterTypeSelector('gyroLowpassType', loadFilterTypeValues());
populateFilterTypeSelector('gyroLowpassDynType', loadFilterTypeValues());
populateFilterTypeSelector('gyroLowpass2Type', loadFilterTypeValues());
populateFilterTypeSelector('dtermLowpassType', loadFilterTypeValues());
populateFilterTypeSelector('dtermLowpass2Type', loadFilterTypeValues());
populateFilterTypeSelector('dtermLowpassDynType', loadFilterTypeValues());
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
populateFilterTypeSelector('gyroLowpassDynType', loadFilterTypeValues());
populateFilterTypeSelector('dtermLowpassDynType', loadFilterTypeValues());
}
pid_and_rc_to_form();
@ -1900,6 +2179,8 @@ TABS.pid_tuning.initialize = function (callback) {
const SLIDER_STEP_UPPER = semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44) ? 0.05 : 0.1;
const sliderPidsModeSelect = $('#sliderPidsModeSelect');
const sliderGyroFilterModeSelect = $('#sliderGyroFilterModeSelect');
const sliderDTermFilterModeSelect = $('#sliderDTermFilterModeSelect');
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
if (self.retainConfiguration) {
@ -1908,6 +2189,8 @@ TABS.pid_tuning.initialize = function (callback) {
self.saveInitialSettings();
}
sliderPidsModeSelect.val(FC.TUNING_SLIDERS.slider_pids_mode);
sliderGyroFilterModeSelect.val(FC.TUNING_SLIDERS.slider_gyro_filter);
sliderDTermFilterModeSelect.val(FC.TUNING_SLIDERS.slider_dterm_filter);
} else {
$('#dMinSwitch').change(function() {
TuningSliders.setDMinFeatureEnabled($(this).is(':checked'));
@ -1930,9 +2213,9 @@ TABS.pid_tuning.initialize = function (callback) {
// disable slides if Integrated Yaw is enabled or Slider PID mode is set to OFF
$('input[id="useIntegratedYaw"]').change(() => TuningSliders.updatePidSlidersDisplay());
// trigger Slider Display update when PID mode is changed
// trigger Slider Display update when PID / Filter mode is changed
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
$('select[id="sliderPidsModeSelect"]').on('change', function () {
sliderPidsModeSelect.on('change', function () {
const setMode = parseInt($(this).val());
TuningSliders.sliderPidsMode = setMode;
@ -1956,6 +2239,30 @@ TABS.pid_tuning.initialize = function (callback) {
}
}).trigger('change');
sliderGyroFilterModeSelect.change(function() {
const mode = parseInt($(this).find(':selected').val());
if (mode === 0) {
TuningSliders.gyroFilterSliderEnable();
} else {
TuningSliders.gyroFilterSliderDisable();
}
});
sliderDTermFilterModeSelect.change(function() {
const mode = parseInt($(this).find(':selected').val());
if (mode === 0) {
TuningSliders.dtermFilterSliderEnable();
} else {
TuningSliders.dtermFilterSliderDisable();
}
});
// initial gyro mode
sliderGyroFilterModeSelect.val(TuningSliders.sliderGyroFilter);
// initial dterm mode
sliderDTermFilterModeSelect.val(TuningSliders.sliderDTermFilter);
}
let allPidTuningSliders;
@ -2164,13 +2471,10 @@ TABS.pid_tuning.initialize = function (callback) {
TuningSliders.calculateNewDTermFilters();
}
});
// enable Filter sliders button
// enable Filter sliders button (legacy sliders)
$('a.buttonFilterTuningSliders').click(function() {
if (TuningSliders.GyroSliderUnavailable) {
//set Slider mode to ON when re-enabling Sliders
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
FC.TUNING_SLIDERS.slider_gyro_filter = 1;
}
// update switchery dynamically based on defaults
$('input[id="gyroLowpassDynEnabled"]').prop('checked', false).click();
$('input[id="gyroLowpassEnabled"]').prop('checked', true).click();
@ -2179,11 +2483,6 @@ TABS.pid_tuning.initialize = function (callback) {
self.analyticsChanges['GyroFilterTuningSlider'] = "On";
}
if (TuningSliders.DTermSliderUnavailable) {
//set Slider mode to ON when re-enabling Sliders
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
FC.TUNING_SLIDERS.slider_dterm_filter = 1;
}
// update switchery dynamically based on defaults
$('input[id="dtermLowpassDynEnabled"]').prop('checked', false).click();
$('input[id="dtermLowpassEnabled"]').prop('checked', true).click();
$('input[id="dtermLowpass2Enabled"]').prop('checked', false).click();
@ -2200,7 +2499,15 @@ TABS.pid_tuning.initialize = function (callback) {
}
});
// update on filter value or type changes
$('.pid_filter tr:not(.newFilter) input, .pid_filter tr:not(.newFilter) select').on('input', function() {
$('.pid_filter tr:not(.newFilter) input, .pid_filter tr:not(.newFilter) select').on('input', function(e) {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
// because legacy / firmware slider inputs for lowpass1 are duplicate the value isn't updated so set it here.
if (e.target.type === 'number') {
$(`.pid_filter input[name="${e.target.name}"]`).val(e.target.value);
} else if (e.target.type === 'select-one') {
$(`.pid_filter select[name="${e.target.name}"]`).val(e.target.value);
}
}
TuningSliders.updateFilterSlidersDisplay();
if (TuningSliders.GyroSliderUnavailable) {
self.analyticsChanges['GyroFilterTuningSlider'] = "Off";
@ -2741,10 +3048,12 @@ TABS.pid_tuning.updateRatesLabels = function() {
};
TABS.pid_tuning.updateFilterWarning = function() {
const gyroDynamicLowpassEnabled = $('input[id="gyroLowpassDynEnabled"]').is(':checked');
const gyroLowpass1Enabled = $('input[id="gyroLowpassEnabled"]').is(':checked');
const dtermDynamicLowpassEnabled = $('input[id="dtermLowpassDynEnabled"]').is(':checked');
const dtermLowpass1Enabled = $('input[id="dtermLowpassEnabled"]').is(':checked');
const gyroLowpassFilterMode = parseInt($('.pid_filter select[name="gyroLowpassFilterMode"]').val());
const gyroDynamicLowpassEnabled = gyroLowpassFilterMode === 1;
const gyroLowpass1Enabled = !gyroLowpassFilterMode;
const dtermLowpassFilterMode = parseInt($('.pid_filter select[name="dtermLowpassFilterMode"]').val());
const dtermDynamicLowpassEnabled = dtermLowpassFilterMode === 1;
const dtermLowpass1Enabled = !dtermLowpassFilterMode;
const warningE = $('#pid-tuning .filterWarning');
const warningDynamicNotchE = $('#pid-tuning .dynamicNotchWarning');
if (!(gyroDynamicLowpassEnabled || gyroLowpass1Enabled) || !(dtermDynamicLowpassEnabled || dtermLowpass1Enabled)) {