mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-25 09:15:49 +03:00
Merge branch 'master' into fix_tab_switch
This commit is contained in:
commit
a45cc1d8c7
45 changed files with 4438 additions and 561 deletions
|
@ -5,30 +5,31 @@
|
|||
const ConfigStorage = {
|
||||
// key can be one string, or array of strings
|
||||
get: function(key, callback) {
|
||||
let result = {};
|
||||
if (Array.isArray(key)) {
|
||||
let obj = {};
|
||||
key.forEach(function (element) {
|
||||
try {
|
||||
obj = {...obj, ...JSON.parse(window.localStorage.getItem(element))};
|
||||
result = {...result, ...JSON.parse(window.localStorage.getItem(element))};
|
||||
} catch (e) {
|
||||
// is okay
|
||||
}
|
||||
});
|
||||
callback(obj);
|
||||
callback?.(result);
|
||||
} else {
|
||||
const keyValue = window.localStorage.getItem(key);
|
||||
if (keyValue) {
|
||||
let obj = {};
|
||||
try {
|
||||
obj = JSON.parse(keyValue);
|
||||
result = JSON.parse(keyValue);
|
||||
} catch (e) {
|
||||
// It's fine if we fail that parse
|
||||
}
|
||||
callback(obj);
|
||||
callback?.(result);
|
||||
} else {
|
||||
callback({});
|
||||
callback?.(result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
// set takes an object like {'userLanguageSelect':'DEFAULT'}
|
||||
set: function(input) {
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -30,6 +30,9 @@ const CONFIGURATOR = {
|
|||
cliActive: false,
|
||||
cliValid: false,
|
||||
productName: 'Betaflight Configurator',
|
||||
cliEngineActive: false,
|
||||
cliEngineValid: false,
|
||||
gitChangesetId: 'unknown',
|
||||
version: '0.0.1',
|
||||
gitRevision: 'norevision',
|
||||
latestVersion: '0.0.1',
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
163
src/js/gui.js
163
src/js/gui.js
|
@ -19,6 +19,7 @@ const GuiControl = function () {
|
|||
this.operating_system = null;
|
||||
this.interval_array = [];
|
||||
this.timeout_array = [];
|
||||
this.buttonDisabledClass = "disabled";
|
||||
|
||||
this.defaultAllowedTabsWhenDisconnected = [
|
||||
'landing',
|
||||
|
@ -36,6 +37,7 @@ const GuiControl = function () {
|
|||
'power',
|
||||
'adjustments',
|
||||
'auxiliary',
|
||||
'presets',
|
||||
'cli',
|
||||
'configuration',
|
||||
'gps',
|
||||
|
@ -407,5 +409,166 @@ GuiControl.prototype.isOther = function () {
|
|||
return this.Mode === GUI_MODES.Other;
|
||||
};
|
||||
|
||||
|
||||
GuiControl.prototype.showYesNoDialog = function(yesNoDialogSettings) {
|
||||
// yesNoDialogSettings:
|
||||
// title, text, buttonYesText, buttonNoText, buttonYesCallback, buttonNoCallback
|
||||
const dialog = $(".dialogYesNo");
|
||||
const title = dialog.find(".dialogYesNoTitle");
|
||||
const content = dialog.find(".dialogYesNoContent");
|
||||
const buttonYes = dialog.find(".dialogYesNo-yesButton");
|
||||
const buttonNo = dialog.find(".dialogYesNo-noButton");
|
||||
|
||||
title.html(yesNoDialogSettings.title);
|
||||
content.html(yesNoDialogSettings.text);
|
||||
buttonYes.html(yesNoDialogSettings.buttonYesText);
|
||||
buttonNo.html(yesNoDialogSettings.buttonNoText);
|
||||
|
||||
buttonYes.off("click");
|
||||
buttonNo.off("click");
|
||||
|
||||
buttonYes.on("click", () => {
|
||||
dialog[0].close();
|
||||
yesNoDialogSettings.buttonYesCallback?.();
|
||||
});
|
||||
|
||||
buttonNo.on("click", () => {
|
||||
dialog[0].close();
|
||||
yesNoDialogSettings.buttonNoCallback?.();
|
||||
});
|
||||
|
||||
dialog[0].showModal();
|
||||
};
|
||||
|
||||
GuiControl.prototype.showWaitDialog = function(waitDialogSettings) {
|
||||
// waitDialogSettings:
|
||||
// title, buttonCancelCallback
|
||||
const dialog = $(".dialogWait")[0];
|
||||
const title = $(".dialogWaitTitle");
|
||||
const buttonCancel = $(".dialogWait-cancelButton");
|
||||
|
||||
title.html(waitDialogSettings.title);
|
||||
buttonCancel.toggle(!!waitDialogSettings.buttonCancelCallback);
|
||||
|
||||
buttonCancel.off("click");
|
||||
|
||||
buttonCancel.on("click", () => {
|
||||
dialog.close();
|
||||
waitDialogSettings.buttonCancelCallback?.();
|
||||
});
|
||||
|
||||
dialog.showModal();
|
||||
return dialog;
|
||||
};
|
||||
|
||||
GuiControl.prototype.showInformationDialog = function(informationDialogSettings) {
|
||||
// informationDialogSettings:
|
||||
// title, text, buttonConfirmText
|
||||
return new Promise(resolve => {
|
||||
const dialog = $(".dialogInformation");
|
||||
const title = dialog.find(".dialogInformationTitle");
|
||||
const content = dialog.find(".dialogInformationContent");
|
||||
const buttonConfirm = dialog.find(".dialogInformation-confirmButton");
|
||||
|
||||
title.html(informationDialogSettings.title);
|
||||
content.html(informationDialogSettings.text);
|
||||
buttonConfirm.html(informationDialogSettings.buttonConfirmText);
|
||||
|
||||
buttonConfirm.off("click");
|
||||
|
||||
buttonConfirm.on("click", () => {
|
||||
dialog[0].close();
|
||||
resolve();
|
||||
});
|
||||
|
||||
dialog[0].showModal();
|
||||
});
|
||||
};
|
||||
|
||||
GuiControl.prototype.saveToTextFileDialog = function(textToSave, suggestedFileName, extension) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const accepts = [{ description: extension.toUpperCase() + ' files', extensions: [extension] }];
|
||||
|
||||
chrome.fileSystem.chooseEntry(
|
||||
{
|
||||
type: 'saveFile',
|
||||
suggestedName: suggestedFileName,
|
||||
accepts: accepts,
|
||||
},
|
||||
entry => this._saveToTextFileDialogFileSelected(entry, textToSave, resolve, reject),
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
GuiControl.prototype._saveToTextFileDialogFileSelected = function(entry, textToSave, resolve, reject) {
|
||||
checkChromeRuntimeError();
|
||||
|
||||
if (!entry) {
|
||||
console.log('No file selected for saving');
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
entry.createWriter(writer => {
|
||||
writer.onerror = () => {
|
||||
reject();
|
||||
console.error('Failed to write file');
|
||||
};
|
||||
|
||||
writer.onwriteend = () => {
|
||||
if (textToSave.length > 0 && writer.length === 0) {
|
||||
writer.write(new Blob([textToSave], {type: 'text/plain'}));
|
||||
} else {
|
||||
resolve(true);
|
||||
console.log('File write complete');
|
||||
}
|
||||
};
|
||||
|
||||
writer.truncate(0);
|
||||
},
|
||||
() => {
|
||||
reject();
|
||||
console.error('Failed to get file writer');
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
GuiControl.prototype.readTextFileDialog = function(extension) {
|
||||
const accepts = [{ description: extension.toUpperCase() + ' files', extensions: [extension] }];
|
||||
|
||||
return new Promise(resolve => {
|
||||
chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function(entry) {
|
||||
checkChromeRuntimeError();
|
||||
|
||||
if (!entry) {
|
||||
console.log('No file selected for loading');
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
entry.file((file) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => resolve(reader.result);
|
||||
reader.onerror = () => {
|
||||
console.error(reader.error);
|
||||
reject();
|
||||
};
|
||||
reader.readAsText(file);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
GuiControl.prototype.escapeHtml = function(unsafe) {
|
||||
return unsafe
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
};
|
||||
|
||||
// initialize object into GUI variable
|
||||
window.GUI = new GuiControl();
|
||||
|
|
|
@ -404,6 +404,10 @@ function startProcess() {
|
|||
// Add a little timeout to let MSP comands finish
|
||||
GUI.timeout_add('wait_for_msp_finished', () => TABS.cli.initialize(content_ready, GUI.nwGui), timeout);
|
||||
break;
|
||||
case 'presets':
|
||||
TABS.presets.initialize(content_ready, GUI.nwGui);
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log(`Tab not found: ${tab}`);
|
||||
}
|
||||
|
|
|
@ -1178,6 +1178,8 @@ MspHelper.prototype.process_data = function(dataHandler) {
|
|||
FC.ADVANCED_TUNING.feedforward_averaging = data.readU8();
|
||||
FC.ADVANCED_TUNING.feedforward_smooth_factor = data.readU8();
|
||||
FC.ADVANCED_TUNING.feedforward_boost = data.readU8();
|
||||
FC.ADVANCED_TUNING.feedforward_max_rate_limit = data.readU8();
|
||||
FC.ADVANCED_TUNING.feedforward_jitter_factor = data.readU8();
|
||||
FC.ADVANCED_TUNING.vbat_sag_compensation = data.readU8();
|
||||
FC.ADVANCED_TUNING.thrustLinearization = data.readU8();
|
||||
}
|
||||
|
@ -1501,7 +1503,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 +1568,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');
|
||||
|
@ -2151,6 +2152,8 @@ MspHelper.prototype.crunch = function(code) {
|
|||
buffer.push8(FC.ADVANCED_TUNING.feedforward_averaging)
|
||||
.push8(FC.ADVANCED_TUNING.feedforward_smooth_factor)
|
||||
.push8(FC.ADVANCED_TUNING.feedforward_boost)
|
||||
.push8(FC.ADVANCED_TUNING.feedforward_max_rate_limit)
|
||||
.push8(FC.ADVANCED_TUNING.feedforward_jitter_factor)
|
||||
.push8(FC.ADVANCED_TUNING.vbat_sag_compensation)
|
||||
.push8(FC.ADVANCED_TUNING.thrustLinearization);
|
||||
}
|
||||
|
@ -2311,19 +2314,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:
|
||||
|
|
|
@ -583,13 +583,17 @@ function onClosed(result) {
|
|||
CONFIGURATOR.connectionValid = false;
|
||||
CONFIGURATOR.cliValid = false;
|
||||
CONFIGURATOR.cliActive = false;
|
||||
CONFIGURATOR.cliEngineValid = false;
|
||||
CONFIGURATOR.cliEngineActive = false;
|
||||
}
|
||||
|
||||
function read_serial(info) {
|
||||
if (!CONFIGURATOR.cliActive) {
|
||||
MSP.read(info);
|
||||
} else if (CONFIGURATOR.cliActive) {
|
||||
if (CONFIGURATOR.cliActive) {
|
||||
TABS.cli.read(info);
|
||||
} else if (CONFIGURATOR.cliEngineActive) {
|
||||
TABS.presets.read(info);
|
||||
} else {
|
||||
MSP.read(info);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -694,7 +698,8 @@ function update_live_status() {
|
|||
display: 'inline-block'
|
||||
});
|
||||
|
||||
if (GUI.active_tab != 'cli') {
|
||||
if (GUI.active_tab !== 'cli' && GUI.active_tab !== 'presets') {
|
||||
MSP.send_message(MSPCodes.MSP_BOXNAMES, false, false);
|
||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_32)) {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS_EX, false, false);
|
||||
} else {
|
||||
|
|
|
@ -18,6 +18,8 @@ options.initialize = function (callback) {
|
|||
TABS.options.initCordovaForceComputerUI();
|
||||
TABS.options.initDarkTheme();
|
||||
|
||||
TABS.options.initShowWarnings();
|
||||
|
||||
GUI.content_ready(callback);
|
||||
});
|
||||
};
|
||||
|
@ -28,6 +30,19 @@ options.cleanup = function (callback) {
|
|||
}
|
||||
};
|
||||
|
||||
options.initShowWarnings = function () {
|
||||
ConfigStorage.get('showPresetsWarningBackup', function (result) {
|
||||
if (result.showPresetsWarningBackup) {
|
||||
$('div.presetsWarningBackup input').prop('checked', true);
|
||||
}
|
||||
|
||||
$('div.presetsWarningBackup input').change(function () {
|
||||
const checked = $(this).is(':checked');
|
||||
ConfigStorage.set({'showPresetsWarningBackup': checked});
|
||||
}).change();
|
||||
});
|
||||
};
|
||||
|
||||
options.initPermanentExpertMode = function () {
|
||||
ConfigStorage.get('permanentExpertMode', function (result) {
|
||||
if (result.permanentExpertMode) {
|
||||
|
|
|
@ -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");
|
||||
|
@ -509,6 +519,8 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
$('select[id="feedforwardAveraging"]').val(FC.ADVANCED_TUNING.feedforward_averaging);
|
||||
$('input[name="feedforwardSmoothFactor"]').val(FC.ADVANCED_TUNING.feedforward_smooth_factor);
|
||||
$('input[name="feedforwardBoost"]').val(FC.ADVANCED_TUNING.feedforward_boost);
|
||||
$('input[name="feedforwardMaxRateLimit"]').val(FC.ADVANCED_TUNING.feedforward_max_rate_limit);
|
||||
$('input[name="feedforwardJitterFactor"]').val(FC.ADVANCED_TUNING.feedforward_jitter_factor);
|
||||
|
||||
// Vbat Sag Compensation
|
||||
const vbatSagCompensationCheck = $('input[id="vbatSagCompensation"]');
|
||||
|
@ -534,6 +546,8 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
} else {
|
||||
$('.vbatSagCompensation').hide();
|
||||
$('.thrustLinearization').hide();
|
||||
$('.feedforwardMaxRateLimit').hide();
|
||||
$('.feedforwardJitterFactor').hide();
|
||||
|
||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_40)) {
|
||||
$('.pid_tuning .ROLL input[name="f"]').val(FC.ADVANCED_TUNING.feedforwardRoll > 0 ? FC.ADVANCED_TUNING.feedforwardRoll : PID_DEFAULT[4]);
|
||||
|
@ -680,6 +694,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 +705,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 +716,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 +1092,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 +1251,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 +1261,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 +1292,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());
|
||||
|
@ -1069,10 +1349,11 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
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 +1769,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 +2184,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 +2194,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 +2218,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 +2244,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 +2476,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 +2488,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 +2504,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 +3053,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)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue