From 92a0c915dbaf16a3e2c222d918923bf0097a27b7 Mon Sep 17 00:00:00 2001 From: Mark Haslinghuis Date: Sun, 19 Dec 2021 16:23:58 +0100 Subject: [PATCH] Simplified Tuning update --- src/css/tabs/pid_tuning.css | 5 - src/js/TuningSliders.js | 597 ++++++++++++++++++------------------ src/js/fc.js | 19 +- src/js/main.js | 18 +- src/js/msp/MSPCodes.js | 10 +- src/js/msp/MSPHelper.js | 173 +++++++++-- src/js/tabs/pid_tuning.js | 532 +++++++++++--------------------- 7 files changed, 653 insertions(+), 701 deletions(-) diff --git a/src/css/tabs/pid_tuning.css b/src/css/tabs/pid_tuning.css index 8af8ee55..dfddd01e 100644 --- a/src/css/tabs/pid_tuning.css +++ b/src/css/tabs/pid_tuning.css @@ -255,11 +255,6 @@ text-align: right; border: 1px solid var(--subtleAccent); border-radius: 3px; - background-color: #f9f9f9; -} - -.tab-pid_tuning .subtab-pid table input:disabled { - background-color: #dddddd; } .tab-pid_tuning .subtab-filter table input, diff --git a/src/js/TuningSliders.js b/src/js/TuningSliders.js index 34fad1dc..a1b21b33 100644 --- a/src/js/TuningSliders.js +++ b/src/js/TuningSliders.js @@ -20,7 +20,6 @@ const TuningSliders = { pidSlidersUnavailable: false, GyroSliderUnavailable: false, DTermSliderUnavailable: false, - FilterReset: false, sliderGyroFilter: 1, sliderGyroFilterMultiplier: 1, @@ -37,9 +36,6 @@ const TuningSliders = { cachedGyroSliderValues: false, cachedDTermSliderValues: false, - sliderGyroFilterDisabled: false, - sliderDTermFilterDisabled: false, - expertMode: false, }; @@ -59,30 +55,49 @@ TuningSliders.initialize = function() { this.FILTER_DEFAULT = FC.getFilterDefaults(); this.SLIDER_DEFAULT = FC.getSliderDefaults(); - if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - this.setDMinFeatureEnabled($('#dMinSwitch').is(':checked')); - } - this.setExpertMode(isExpertModeEnabled()); - this.initPidSlidersPosition(); - this.initGyroFilterSliderPosition(); - this.initDTermFilterSliderPosition(); - // after refresh cached values are not available this.cachedPidSliderValues = false; this.cachedGyroSliderValues = false; this.cachedDTermSliderValues = false; - this.updatePidSlidersDisplay(); - if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { + this.initPidSlidersPosition(); + this.initGyroFilterSliderPosition(); + this.initDTermFilterSliderPosition(); + + // If reading manual values while sliders are on we set the sliders off + this.validateTuningSliders(); + + this.updatePidSlidersDisplay(); this.updateGyroFilterSliderDisplay(); this.updateDTermFilterSliderDisplay(); + this.updateFilterSlidersWarning(); + $('.subtab-pid .slidersDisabled').hide(); $('.subtab-filter .slidersDisabled').hide(); } else { + $('#sliderGyroFilterMultiplier, #sliderDTermFilterMultiplier').attr("min", "0.5"); + $('#sliderGyroFilterMultiplier, #sliderDTermFilterMultiplier').attr("max", "1.5"); + this.setDMinFeatureEnabled($('#dMinSwitch').is(':checked')); + + this.initPidSlidersPosition(); + this.initGyroFilterSliderPosition(); + this.initDTermFilterSliderPosition(); + + if (this.dMinFeatureEnabled) { + FC.ADVANCED_TUNING.dMinRoll = FC.PIDS_ACTIVE[0][2]; + FC.ADVANCED_TUNING.dMinPitch = FC.PIDS_ACTIVE[1][2]; + FC.ADVANCED_TUNING.dMinYaw = FC.PIDS_ACTIVE[2][2]; + } else { + FC.PIDS[0][2] = FC.ADVANCED_TUNING.dMinRoll; + FC.PIDS[1][2] = FC.ADVANCED_TUNING.dMinPitch; + FC.PIDS[2][2] = FC.ADVANCED_TUNING.dMinYaw; + } + + this.updatePidSlidersDisplay(); this.updateFilterSlidersDisplay(); $('select[id="sliderGyroFilterModeSelect"]').hide(); @@ -133,7 +148,7 @@ TuningSliders.updateExpertModeSlidersDisplay = function() { $('.baseSliderPIGain').toggleClass('disabledSliders', piGain && !this.expertMode); $('.baseSliderFeedforwardGain').toggleClass('disabledSliders', ffGain && !this.expertMode); - $('.advancedSlider').toggleClass('disabledSliders', !this.expertMode); + $('.advancedSlider').toggleClass('disabledSliders', !this.sliderPidsMode || !this.expertMode); $('.advancedSliderDmaxGain').toggle(dMaxGain || this.expertMode); $('.advancedSliderIGain').toggle(iGain || this.expertMode); @@ -168,7 +183,7 @@ TuningSliders.setExpertMode = function(expertModeEnabled) { TuningSliders.scaleSliderValue = function(value) { if (value > 1) { - return Math.round(((value - 1) * 2 + 1) * 100) / 100; + return Math.round(((value - 1) * 2 + 1) * 10) / 10; } else { return value; } @@ -215,13 +230,15 @@ TuningSliders.initPidSlidersPosition = function() { } else { // used to estimate PID slider positions based on PIDF values, and set respective slider position // provides only an estimation due to limitation of feature without firmware support, to be improved in later versions - this.sliderMasterMultiplierLegacy = Math.round(FC.PIDS[2][1] / this.PID_DEFAULT[11] * 10) / 10; - this.sliderPDRatio = Math.round(FC.PIDS[0][2] / FC.PIDS[0][0] / this.defaultPDRatio * 10) / 10; + this.sliderMasterMultiplierLegacy = Math.round(FC.PIDS_ACTIVE[2][1] / this.PID_DEFAULT[11] * 10) / 10; + this.sliderPDRatio = Math.round(FC.PIDS_ACTIVE[0][2] / FC.PIDS_ACTIVE[0][0] / this.defaultPDRatio * 10) / 10; + if (this.dMinFeatureEnabled) { this.sliderPDGain = Math.round(FC.ADVANCED_TUNING.dMinRoll / this.sliderPDRatio / this.sliderMasterMultiplierLegacy / this.PID_DEFAULT[3] * 10) / 10; } else { - this.sliderPDGain = Math.round(FC.PIDS[0][0] / this.sliderMasterMultiplierLegacy / (this.PID_DEFAULT[2] * (1 / D_MIN_RATIO)) * 10) / 10; + this.sliderPDGain = Math.round(FC.PIDS_ACTIVE[0][0] / this.sliderMasterMultiplierLegacy / (this.PID_DEFAULT[2] * (1 / D_MIN_RATIO)) * 10) / 10; } + this.sliderFeedforwardGainLegacy = Math.round(FC.ADVANCED_TUNING.feedforwardRoll / this.sliderMasterMultiplierLegacy / this.PID_DEFAULT[4] * 10) / 10; $('output[name="sliderMasterMultiplierLegacy-number"]').val(this.sliderMasterMultiplierLegacy); @@ -240,15 +257,16 @@ TuningSliders.initGyroFilterSliderPosition = function() { if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { this.sliderGyroFilter = FC.TUNING_SLIDERS.slider_gyro_filter; this.sliderGyroFilterMultiplier = FC.TUNING_SLIDERS.slider_gyro_filter_multiplier / 100; + $('#sliderGyroFilterMultiplier').val(this.sliderGyroFilterMultiplier); } 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_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 + + Math.round( + (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; + $('#sliderGyroFilterMultiplier').val(this.downscaleSliderValue(this.sliderGyroFilterMultiplier)); } - $('#sliderGyroFilterMultiplier').val(this.sliderGyroFilterMultiplier); $('output[name="sliderGyroFilterMultiplier-number"]').val(this.sliderGyroFilterMultiplier); }; @@ -256,101 +274,37 @@ TuningSliders.initDTermFilterSliderPosition = function() { 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; + $('#sliderDTermFilterMultiplier').val(this.sliderDTermFilterMultiplier); } 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 + + Math.round( + (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; + $('#sliderDTermFilterMultiplier').val(this.downscaleSliderValue(this.sliderDTermFilterMultiplier)); } - $('#sliderDTermFilterMultiplier').val(this.sliderDTermFilterMultiplier); $('output[name="sliderDTermFilterMultiplier-number"]').val(this.sliderDTermFilterMultiplier); }; -TuningSliders.resetPidSliders = function() { - if (!this.cachedPidSliderValues) { - if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - this.sliderDGain = this.SLIDER_DEFAULT.slider_d_gain / 100; - this.sliderPIGain = this.SLIDER_DEFAULT.slider_pi_gain / 100; - this.sliderFeedforwardGain = this.SLIDER_DEFAULT.slider_feedforward_gain / 100; - this.sliderDMaxGain = this.SLIDER_DEFAULT.slider_dmax_gain / 100; - this.sliderIGain = this.SLIDER_DEFAULT.slider_i_gain / 100; - this.sliderRollPitchRatio = this.SLIDER_DEFAULT.slider_roll_pitch_ratio / 100; - this.sliderPitchPIGain = this.SLIDER_DEFAULT.slider_pitch_pi_gain / 100; - this.sliderMasterMultiplier = this.SLIDER_DEFAULT.slider_master_multiplier / 100; - } else { - this.sliderMasterMultiplierLegacy = 1; - this.sliderPDRatio = 1; - this.sliderPDGain = 1; - this.sliderFeedforwardGainLegacy = 1; - } - } - - if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - this.calculateNewPids(); - this.updateFormPids(); - this.initPidSlidersPosition(); - this.updatePidSlidersDisplay(); - } else { - $('#sliderMasterMultiplierLegacy').val(this.downscaleSliderValue(this.sliderMasterMultiplierLegacy)); - $('#sliderPDRatio').val(this.downscaleSliderValue(this.sliderPDRatio)); - $('#sliderPDGain').val(this.downscaleSliderValue(this.sliderPDGain)); - $('#sliderFeedforwardGainLegacy').val(this.downscaleSliderValue(this.sliderFeedforwardGainLegacy)); - this.calculateNewPids(); - } -}; - -TuningSliders.resetGyroFilterSlider = function() { - this.sliderGyroFilterMultiplier = 1; - $('#sliderGyroFilterMultiplier').val(this.sliderGyroFilterMultiplier); +TuningSliders.gyroFilterSliderEnable = function() { + this.sliderGyroFilter = 1; this.calculateNewGyroFilters(); - this.updateFilterSlidersDisplay(); }; -TuningSliders.resetDTermFilterSlider = function() { - this.sliderDTermFilterMultiplier = 1; - $('#sliderDTermFilterMultiplier').val(this.sliderDTermFilterMultiplier); +TuningSliders.dtermFilterSliderEnable = function() { + this.sliderDTermFilter = 1; this.calculateNewDTermFilters(); - this.updateFilterSlidersDisplay(); }; -TuningSliders.legacyUpdateFilterSlidersDisplay = function() { - 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="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) { - this.GyroSliderUnavailable = true; - } else { - this.cachedGyroSliderValues = true; - } +TuningSliders.gyroFilterSliderDisable = function() { + FC.TUNING_SLIDERS.slider_gyro_filter = 0; + this.updateGyroFilterSliderDisplay(); +}; - if (parseInt($('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val()) !== - Math.round(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz * this.sliderDTermFilterMultiplier) || - 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) { - this.DTermSliderUnavailable = true; - } 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.dtermFilterSliderDisable = function() { + FC.TUNING_SLIDERS.slider_dterm_filter = 0; + this.updateDTermFilterSliderDisplay(); }; TuningSliders.updateSlidersWarning = function(slidersUnavailable = false) { @@ -389,65 +343,63 @@ TuningSliders.updateFilterSlidersWarning = function() { TuningSliders.updatePidSlidersDisplay = function() { // check if pid values changed manually by comparing the current values with those calculated by the sliders, // if all of them are equal the values haven't been changed manually - this.pidSlidersUnavailable = false; - - let rows = 3; if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - rows = this.sliderPidsMode === 1 ? 2 : 3; + $('#pid_main .ROLL .pid_data input, #pid_main .PITCH .pid_data input').each((_, el) => $(el).prop('disabled', this.sliderPidsMode > 0)); + $('#pid_main .YAW .pid_data input').each((_, el) => $(el).prop('disabled', this.sliderPidsMode === 2)); + + $('.baseSlider').toggleClass('disabledSliders', !this.sliderPidsMode); + $('.advancedSlider').toggleClass('disabledSliders', !this.sliderPidsMode || !this.expertMode); + + $('#sliderDGain').prop('disabled', !this.sliderPidsMode); + $('#sliderPIGain').prop('disabled', !this.sliderPidsMode); + $('#sliderFeedforwardGain').prop('disabled', !this.sliderPidsMode); + $('#sliderDMaxGain').prop('disabled', !this.sliderPidsMode); + $('#sliderIGain').prop('disabled', !this.sliderPidsMode); + $('#sliderRollPitchRatio').prop('disabled', !this.sliderPidsMode); + $('#sliderPitchPIGain').prop('disabled', !this.sliderPidsMode); + $('#sliderMasterMultiplier').prop('disabled', !this.sliderPidsMode); + + $('#sliderPidsModeSelect').val(this.sliderPidsMode); } else { + this.pidSlidersUnavailable = false; this.calculateNewPids(true); - } - FC.PID_NAMES.forEach(function (elementPid, indexPid) { - const pidElements = $(`.pid_tuning .${elementPid} input`); - pidElements.each(function (indexInput) { - if (indexPid < rows && indexInput < rows) { - if (parseInt($(this).val()) !== FC.PIDS[indexPid][indexInput]) { - TuningSliders.pidSlidersUnavailable = true; + FC.PID_NAMES.forEach(function (elementPid, indexPid) { + const pidElements = $(`.pid_tuning .${elementPid} input`); + + pidElements.each(function (indexInput) { + if (indexPid < 3 && indexInput < 3) { + if (parseInt($(this).val()) !== FC.PIDS[indexPid][indexInput]) { + TuningSliders.pidSlidersUnavailable = true; + } } - } + }); }); - }); - if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) { if ($('input[id="useIntegratedYaw"]').is(':checked')) { this.pidSlidersUnavailable = true; } - } - if (!this.pidSlidersUnavailable) { - this.cachedPidSliderValues = true; - } - - if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - if (this.sliderPidsMode === 0) { - this.pidSlidersUnavailable = true; + if (!this.pidSlidersUnavailable) { + this.cachedPidSliderValues = true; } - } - $('.tuningPIDSliders').toggle(!this.pidSlidersUnavailable); - $('.subtab-pid .slidersDisabled').toggle(this.pidSlidersUnavailable); - $('.subtab-pid .nonExpertModeSlidersNote').toggle(!this.pidSlidersUnavailable && !this.expertMode); + $('.tuningPIDSliders').toggle(!this.pidSlidersUnavailable); + $('.subtab-pid .slidersDisabled').toggle(this.pidSlidersUnavailable); + $('.subtab-pid .nonExpertModeSlidersNote').toggle(!this.pidSlidersUnavailable && !this.expertMode); + } 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 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 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; - const lpxDisabled = !lp1DynMin && !lp1Static && !lp2Freq; - - if (hideSlider) { + if (FC.TUNING_SLIDERS.slider_gyro_filter === 0) { this.GyroSliderUnavailable = true; this.sliderGyroFilter = 0; } else { @@ -456,28 +408,27 @@ TuningSliders.updateGyroFilterSliderDisplay = function() { this.cachedGyroSliderValues = true; } + gyroLowpassDynMinFrequency.val(FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz).prop('disabled', this.sliderGyroFilter); + gyroLowpassDynMaxFrequency.val(FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz).prop('disabled', this.sliderGyroFilter); + gyroLowpassFrequency.val(FC.FILTER_CONFIG.gyro_lowpass_hz).prop('disabled', this.sliderGyroFilter); + gyroLowpass2Frequency.val(FC.FILTER_CONFIG.gyro_lowpass2_hz).prop('disabled', this.sliderGyroFilter); + + $('output[name="sliderGyroFilterMultiplier-number"]').val(this.sliderGyroFilterMultiplier); + // update Gyro mode and slider $('select[id="sliderGyroFilterModeSelect"]').val(this.sliderGyroFilter); - $('.sliderGyroFilter').toggleClass('disabledSliders', !this.sliderGyroFilter || lpxDisabled); - $('input[id="sliderGyroFilterMultiplier"]').prop('disabled', !this.sliderGyroFilter || lpxDisabled); + $('.sliderGyroFilter').toggleClass('disabledSliders', this.GyroSliderUnavailable); + $('input[id="sliderGyroFilterMultiplier"]').prop('disabled', this.GyroSliderUnavailable); }; 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 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 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; - const lpxDisabled = !lp1DynMin && !lp1Static && !lp2Freq; - - if (hideSlider) { + if (FC.TUNING_SLIDERS.slider_dterm_filter === 0) { this.DTermSliderUnavailable = true; this.sliderDTermFilter = 0; } else { @@ -486,16 +437,21 @@ TuningSliders.updateDTermFilterSliderDisplay = function() { this.cachedDTermSliderValues = true; } + dtermLowpassDynMinFrequency.val(FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz).prop('disabled', this.sliderDTermFilter); + dtermLowpassDynMaxFrequency.val(FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz).prop('disabled', this.sliderDTermFilter); + dtermLowpassFrequency.val(FC.FILTER_CONFIG.dterm_lowpass_hz).prop('disabled', this.sliderDTermFilter); + dtermLowpass2Frequency.val(FC.FILTER_CONFIG.dterm_lowpass2_hz).prop('disabled', this.sliderDTermFilter); + + $('output[name="sliderDTermFilterMultiplier-number"]').val(this.sliderDTermFilterMultiplier); + // update DTerm mode and slider $('select[id="sliderDTermFilterModeSelect"]').val(this.sliderDTermFilter); - $('.sliderDTermFilter').toggleClass('disabledSliders', !this.sliderDTermFilter || lpxDisabled); - $('input[id="sliderDTermFilterMultiplier"]').prop('disabled', !this.sliderDTermFilter || lpxDisabled); + $('.sliderDTermFilter').toggleClass('disabledSliders', this.DTermSliderUnavailable); + $('input[id="sliderDTermFilterMultiplier"]').prop('disabled', this.DTermSliderUnavailable); }; 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.updateGyroFilterSliderDisplay(); @@ -508,43 +464,8 @@ TuningSliders.updateFilterSlidersDisplay = function() { 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) { const pidElements = $(`.pid_tuning .${elementPid} input`); @@ -578,8 +499,118 @@ TuningSliders.updateFormPids = function(updateSlidersOnly = false) { $('output[name="sliderPDGain-number"]').val(this.sliderPDGain); $('output[name="sliderFeedforwardGainLegacy-number"]').val(this.sliderFeedforwardGainLegacy); } + + this.updateSlidersWarning(); }; +TuningSliders.calculateNewPids = function(updateSlidersOnly = false) { + // this is the main calculation for PID sliders, 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_pids_mode = this.sliderPidsMode; + //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_d_gain = Math.round(this.sliderDGain * 20) * 5; + FC.TUNING_SLIDERS.slider_pi_gain = Math.round(this.sliderPIGain * 20) * 5; + FC.TUNING_SLIDERS.slider_feedforward_gain = Math.round(this.sliderFeedforwardGain * 20) * 5; + FC.TUNING_SLIDERS.slider_dmax_gain = Math.round(this.sliderDMaxGain * 20) * 5; + FC.TUNING_SLIDERS.slider_i_gain = Math.round(this.sliderIGain * 20) * 5; + FC.TUNING_SLIDERS.slider_roll_pitch_ratio = Math.round(this.sliderRollPitchRatio * 20) * 5; + FC.TUNING_SLIDERS.slider_pitch_pi_gain = Math.round(this.sliderPitchPIGain * 20) * 5; + FC.TUNING_SLIDERS.slider_master_multiplier = Math.round(this.sliderMasterMultiplier * 20) * 5; + + this.readSimplifiedPids(); + } else { + this.legacyCalculatePids(updateSlidersOnly); + } +}; + + +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)) { + this.readSimplifiedGyroFilters(); + } else { + this.calculateLegacyGyroFilters(); + } +}; + +TuningSliders.calculateNewDTermFilters = function() { + // 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)) { + this.readSimplifiedDTermFilters(); + } else { + this.calculateLegacyDTermFilters(); + } +}; + +TuningSliders.readSimplifiedPids = function(updateSlidersOnly = false) { + FC.TUNING_SLIDERS.slider_pids_mode = this.sliderPidsMode; + FC.TUNING_SLIDERS.slider_master_multiplier = Math.round(this.sliderMasterMultiplier * 100); + FC.TUNING_SLIDERS.slider_roll_pitch_ratio = Math.round(this.sliderRollPitchRatio * 100); + FC.TUNING_SLIDERS.slider_i_gain = Math.round(this.sliderIGain * 100); + FC.TUNING_SLIDERS.slider_d_gain = Math.round(this.sliderDGain * 100); + FC.TUNING_SLIDERS.slider_pi_gain = Math.round(this.sliderPIGain * 100); + FC.TUNING_SLIDERS.slider_dmax_gain = Math.round(this.sliderDMaxGain * 100); + FC.TUNING_SLIDERS.slider_feedforward_gain = Math.round(this.sliderFeedforwardGain * 100); + FC.TUNING_SLIDERS.slider_pitch_pi_gain = Math.round(this.sliderPitchPIGain * 100); + + MSP.promise(MSPCodes.MSP_CALCULATE_SIMPLIFIED_PID, mspHelper.crunch(MSPCodes.MSP_CALCULATE_SIMPLIFIED_PID)) + .then(() => this.updateFormPids(updateSlidersOnly)); +}; + +TuningSliders.readSimplifiedGyroFilters = function() { + FC.TUNING_SLIDERS.slider_gyro_filter = this.sliderGyroFilter; + FC.TUNING_SLIDERS.slider_gyro_filter_multiplier = this.sliderGyroFilterMultiplier * 100; + + FC.FILTER_CONFIG.gyro_lowpass_hz = parseInt($('.pid_filter input[name="gyroLowpassFrequency"]').val()); + FC.FILTER_CONFIG.gyro_lowpass2_hz = parseInt($('.pid_filter input[name="gyroLowpass2Frequency"]').val()); + FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz = parseInt($('.pid_filter input[name="gyroLowpassDynMinFrequency"]').val()); + + MSP.promise(MSPCodes.MSP_CALCULATE_SIMPLIFIED_GYRO, mspHelper.crunch(MSPCodes.MSP_CALCULATE_SIMPLIFIED_GYRO)) + .then(() => this.updateGyroFilterSliderDisplay()); +}; + +TuningSliders.readSimplifiedDTermFilters = function() { + FC.TUNING_SLIDERS.slider_dterm_filter = this.sliderDTermFilter; + FC.TUNING_SLIDERS.slider_dterm_filter_multiplier = this.sliderDTermFilterMultiplier * 100; + + FC.FILTER_CONFIG.dterm_lowpass_hz = parseInt($('.pid_filter input[name="dtermLowpassFrequency"]').val()); + FC.FILTER_CONFIG.dterm_lowpass2_hz = parseInt($('.pid_filter input[name="dtermLowpass2Frequency"]').val()); + FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz = parseInt($('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val()); + + MSP.promise(MSPCodes.MSP_CALCULATE_SIMPLIFIED_DTERM, mspHelper.crunch(MSPCodes.MSP_CALCULATE_SIMPLIFIED_DTERM)) + .then(() => this.updateDTermFilterSliderDisplay()); +}; + +TuningSliders.validateTuningSliders = function() { + MSP.promise(MSPCodes.MSP_VALIDATE_SIMPLIFIED_TUNING) + .then(() => { + this.sliderPidsMode = FC.TUNING_SLIDERS.slider_pids_valid > 0 ? FC.TUNING_SLIDERS.slider_pids_mode : 0; + this.sliderGyroFilter = FC.TUNING_SLIDERS.slider_gyro_valid; + this.sliderDTermFilter = FC.TUNING_SLIDERS.slider_dterm_valid; + + FC.TUNING_SLIDERS.slider_pids_mode = FC.TUNING_SLIDERS.slider_pids_valid ? FC.TUNING_SLIDERS.slider_pids_mode : 0; + FC.TUNING_SLIDERS.slider_gyro_filter = FC.TUNING_SLIDERS.slider_gyro_valid ? FC.TUNING_SLIDERS.slider_gyro_filter : 0; + FC.TUNING_SLIDERS.slider_dterm_filter = FC.TUNING_SLIDERS.slider_dterm_valid ? FC.TUNING_SLIDERS.slider_dterm_filter : 0; + + $('#sliderPidsModeSelect').val(this.sliderPidsMode); + $('#sliderGyroFilterModeSelect').val(this.sliderGyroFilter); + $('#sliderDTermFilterModeSelect').val(this.sliderDTermFilter); + + this.updatePidSlidersDisplay(); + this.updateGyroFilterSliderDisplay(); + this.updateDTermFilterSliderDisplay(); + }); +}; + +/* +* +* LEGACY SLIDERS CODE +* +*/ + TuningSliders.legacyCalculatePids = function(updateSlidersOnly = false) { const MAX_PID_GAIN = 200; const MAX_DMIN_GAIN = 100; @@ -638,45 +669,21 @@ TuningSliders.legacyCalculatePids = function(updateSlidersOnly = false) { this.updateSlidersWarning(); }; -TuningSliders.calculateNewPids = function(updateSlidersOnly = false) { - // this is the main calculation for PID sliders, 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_pids_mode = this.sliderPidsMode; - //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_d_gain = Math.round(this.sliderDGain * 20) * 5; - FC.TUNING_SLIDERS.slider_pi_gain = Math.round(this.sliderPIGain * 20) * 5; - FC.TUNING_SLIDERS.slider_feedforward_gain = Math.round(this.sliderFeedforwardGain * 20) * 5; - FC.TUNING_SLIDERS.slider_dmax_gain = Math.round(this.sliderDMaxGain * 20) * 5; - FC.TUNING_SLIDERS.slider_i_gain = Math.round(this.sliderIGain * 20) * 5; - FC.TUNING_SLIDERS.slider_roll_pitch_ratio = Math.round(this.sliderRollPitchRatio * 20) * 5; - FC.TUNING_SLIDERS.slider_pitch_pi_gain = Math.round(this.sliderPitchPIGain * 20) * 5; - FC.TUNING_SLIDERS.slider_master_multiplier = Math.round(this.sliderMasterMultiplier * 20) * 5; - - MSP.promise(MSPCodes.MSP_SET_TUNING_SLIDERS, mspHelper.crunch(MSPCodes.MSP_SET_TUNING_SLIDERS)) - .then(() => MSP.promise(MSPCodes.MSP_PID)) - .then(() => MSP.promise(MSPCodes.MSP_PID_ADVANCED)) - .then(() => { - this.updateFormPids(updateSlidersOnly); - this.updateSlidersWarning(); - }); - } else { - this.legacyCalculatePids(updateSlidersOnly); - } -}; - 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_dyn_min_hz = Math.round(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz * this.sliderGyroFilterMultiplier); + FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz = Math.round(this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz * this.sliderGyroFilterMultiplier); + FC.FILTER_CONFIG.gyro_lowpass2_hz = Math.round(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; + $('.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 input[name="gyroLowpassFrequency"]').val(FC.FILTER_CONFIG.gyro_lowpass_hz); + $('.pid_filter input[name="gyroLowpass2Frequency"]').val(FC.FILTER_CONFIG.gyro_lowpass2_hz); + $('output[name="sliderGyroFilterMultiplier-number"]').val(this.sliderGyroFilterMultiplier); + this.updateFilterSlidersWarning(); - this.updateLowpassValues(); }; TuningSliders.calculateLegacyDTermFilters = function() { @@ -688,69 +695,79 @@ TuningSliders.calculateLegacyDTermFilters = function() { FC.FILTER_CONFIG.dterm_lowpass_type = this.FILTER_DEFAULT.dterm_lowpass_type; FC.FILTER_CONFIG.dterm_lowpass2_type = this.FILTER_DEFAULT.dterm_lowpass2_type; - this.updateFilterSlidersWarning(); - this.updateLowpassValues(); -}; - -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)) { - //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(); - } else { - this.calculateLegacyGyroFilters(); - } -}; - -TuningSliders.calculateNewDTermFilters = function() { - // 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)) { - //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(); - } else { - this.calculateLegacyDTermFilters(); - } -}; - -// 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(); - TuningSliders.updateFilterSlidersWarning(); - if (this.FilterReset) { - this.FilterReset = false; - this.updateFilterSlidersDisplay(); - } - }); -}; - -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 input[name="gyroLowpassFrequency"]').val(FC.FILTER_CONFIG.gyro_lowpass_hz); - $('.pid_filter input[name="gyroLowpass2Frequency"]').val(FC.FILTER_CONFIG.gyro_lowpass2_hz); - $('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="dtermLowpassFrequency"]').val(FC.FILTER_CONFIG.dterm_lowpass_hz); $('.pid_filter input[name="dtermLowpass2Frequency"]').val(FC.FILTER_CONFIG.dterm_lowpass2_hz); $('output[name="sliderDTermFilterMultiplier-number"]').val(this.sliderDTermFilterMultiplier); + + this.updateFilterSlidersWarning(); +}; + +TuningSliders.legacyUpdateFilterSlidersDisplay = function() { + this.GyroSliderUnavailable = false; + this.DTermSliderUnavailable = false; + + if (parseInt($('.pid_filter input[name="gyroLowpassDynMinFrequency"]').val()) !== + Math.round(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz * this.sliderGyroFilterMultiplier) || + parseInt($('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').val()) !== + Math.round(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.round(this.FILTER_DEFAULT.gyro_lowpass2_hz * this.sliderGyroFilterMultiplier) || + parseInt($('.pid_filter select[name="gyroLowpass2Type"]').val()) !== this.FILTER_DEFAULT.gyro_lowpass2_type) { + this.GyroSliderUnavailable = true; + } else { + this.cachedGyroSliderValues = true; + } + + if (parseInt($('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val()) !== + Math.round(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz * this.sliderDTermFilterMultiplier) || + 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) { + this.DTermSliderUnavailable = true; + } 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.resetPidSliders = function() { + if (!this.cachedPidSliderValues) { + this.sliderMasterMultiplierLegacy = 1; + this.sliderPDRatio = 1; + this.sliderPDGain = 1; + this.sliderFeedforwardGainLegacy = 1; + } + + $('#sliderMasterMultiplierLegacy').val(this.downscaleSliderValue(this.sliderMasterMultiplierLegacy)); + $('#sliderPDRatio').val(this.downscaleSliderValue(this.sliderPDRatio)); + $('#sliderPDGain').val(this.downscaleSliderValue(this.sliderPDGain)); + $('#sliderFeedforwardGainLegacy').val(this.downscaleSliderValue(this.sliderFeedforwardGainLegacy)); + this.calculateNewPids(); +}; + +TuningSliders.resetGyroFilterSlider = function() { + this.sliderGyroFilterMultiplier = 1; + $('#sliderGyroFilterMultiplier').val(this.sliderGyroFilterMultiplier); + this.calculateNewGyroFilters(); + this.updateFilterSlidersDisplay(); +}; + +TuningSliders.resetDTermFilterSlider = function() { + this.sliderDTermFilterMultiplier = 1; + $('#sliderDTermFilterMultiplier').val(this.sliderDTermFilterMultiplier); + this.calculateNewDTermFilters(); + this.updateFilterSlidersDisplay(); }; diff --git a/src/js/fc.js b/src/js/fc.js index 772eb317..e04dc325 100644 --- a/src/js/fc.js +++ b/src/js/fc.js @@ -674,6 +674,10 @@ const FC = { slider_i_gain: 0, slider_roll_pitch_ratio: 0, slider_pitch_pi_gain: 0, + + slider_pids_valid: 0, + slider_gyro_valid: 0, + slider_dterm_valid: 0, }; this.DEFAULT_TUNING_SLIDERS = { @@ -691,6 +695,10 @@ const FC = { slider_dterm_filter_multiplier: 100, slider_gyro_filter: 1, slider_gyro_filter_multiplier: 100, + + slider_pids_valid: 1, + slider_gyro_valid: 1, + slider_dterm_valid: 1, }; }, @@ -877,20 +885,13 @@ const FC = { versionPidDefaults = [ 45, 80, 40, 30, 120, 47, 84, 46, 34, 125, - 45, 90, 0, 0, 120, + 45, 80, 0, 0, 120, ]; } return versionPidDefaults; }, getSliderDefaults() { - const sliderDefaults = this.DEFAULT_TUNING_SLIDERS; - // change slider defaults here - if (semver.gte(this.CONFIG.apiVersion, API_VERSION_1_44)) { - sliderDefaults.slider_roll_pitch_ratio = 115; - sliderDefaults.slider_pitch_pi_gain = 105; - } - - return sliderDefaults; + return this.DEFAULT_TUNING_SLIDERS; }, }; diff --git a/src/js/main.js b/src/js/main.js index 64efd91b..70cf6b34 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -250,14 +250,6 @@ function startProcess() { const tab = tabClass.substring(4); const tabName = $(self).text(); - let timeout = 0; - - if (GUI.active_tab === 'pid_tuning') { - if (TABS.pid_tuning.retainConfiguration) { - TABS.pid_tuning.restoreInitialSettings(); - timeout = 500; - } - } if (tabRequiresConnection && !CONFIGURATOR.connectionValid) { GUI.log(i18n.getMessage('tabSwitchConnectionRequired')); @@ -401,15 +393,7 @@ function startProcess() { TABS.onboard_logging.initialize(content_ready); break; case 'cli': - // Add a little timeout to let MSP comands finish - if (timeout > 0) { - GUI.timeout_add('wait_for_msp_finished', () => { - MSP.disconnect_cleanup(); - TABS.cli.initialize(content_ready, GUI.nwGui); - }, timeout); - } else { - TABS.cli.initialize(content_ready, GUI.nwGui); - } + TABS.cli.initialize(content_ready, GUI.nwGui); break; case 'presets': TABS.presets.initialize(content_ready, GUI.nwGui); diff --git a/src/js/msp/MSPCodes.js b/src/js/msp/MSPCodes.js index 385475da..d116156d 100644 --- a/src/js/msp/MSPCodes.js +++ b/src/js/msp/MSPCodes.js @@ -117,8 +117,14 @@ const MSPCodes = { MSP_MOTOR_TELEMETRY: 139, - MSP_TUNING_SLIDERS: 140, - MSP_SET_TUNING_SLIDERS: 141, + MSP_SIMPLIFIED_TUNING: 140, + MSP_SET_SIMPLIFIED_TUNING: 141, + + MSP_CALCULATE_SIMPLIFIED_PID: 142, // calculate slider values in temp profile + MSP_CALCULATE_SIMPLIFIED_GYRO: 143, + MSP_CALCULATE_SIMPLIFIED_DTERM: 144, + + MSP_VALIDATE_SIMPLIFIED_TUNING: 145, // validate slider values in temp profile MSP_STATUS_EX: 150, diff --git a/src/js/msp/MSPHelper.js b/src/js/msp/MSPHelper.js index d8310968..4309c4ea 100644 --- a/src/js/msp/MSPHelper.js +++ b/src/js/msp/MSPHelper.js @@ -52,6 +52,82 @@ function MspHelper() { self.mspMultipleCache = []; } + +MspHelper.readPidSliderSettings = function(data) { + FC.TUNING_SLIDERS.slider_pids_mode = data.readU8(); + FC.TUNING_SLIDERS.slider_master_multiplier = data.readU8(); + FC.TUNING_SLIDERS.slider_roll_pitch_ratio = data.readU8(); + FC.TUNING_SLIDERS.slider_i_gain = data.readU8(); + FC.TUNING_SLIDERS.slider_d_gain = data.readU8(); + FC.TUNING_SLIDERS.slider_pi_gain = data.readU8(); + FC.TUNING_SLIDERS.slider_dmax_gain = data.readU8(); + FC.TUNING_SLIDERS.slider_feedforward_gain = data.readU8(); + FC.TUNING_SLIDERS.slider_pitch_pi_gain = data.readU8(); + data.readU32(); // reserved for future use + data.readU32(); // reserved for future use +}; + +MspHelper.writePidSliderSettings = function(buffer) { + 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) + .push32(0) // reserved for future use + .push32(0); // reserved for future use +}; + +MspHelper.readDtermFilterSliderSettings = function(data) { + FC.TUNING_SLIDERS.slider_dterm_filter = data.readU8(); + FC.TUNING_SLIDERS.slider_dterm_filter_multiplier = data.readU8(); + FC.FILTER_CONFIG.dterm_lowpass_hz = data.readU16(); + FC.FILTER_CONFIG.dterm_lowpass2_hz = data.readU16(); + FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz = data.readU16(); + FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz = data.readU16(); + data.readU32(); // reserved for future use + data.readU32(); // reserved for future use +}; + +MspHelper.writeDtermFilterSliderSettings = function(buffer) { + buffer + .push8(FC.TUNING_SLIDERS.slider_dterm_filter) + .push8(FC.TUNING_SLIDERS.slider_dterm_filter_multiplier) + .push16(FC.FILTER_CONFIG.dterm_lowpass_hz) + .push16(FC.FILTER_CONFIG.dterm_lowpass2_hz) + .push16(FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz) + .push16(FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz) + .push32(0) // reserved for future use + .push32(0); // reserved for future use +}; + +MspHelper.readGyroFilterSliderSettings = function(data) { + FC.TUNING_SLIDERS.slider_gyro_filter = data.readU8(); + FC.TUNING_SLIDERS.slider_gyro_filter_multiplier = data.readU8(); + FC.FILTER_CONFIG.gyro_lowpass_hz = data.readU16(); + FC.FILTER_CONFIG.gyro_lowpass2_hz = data.readU16(); + FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz = data.readU16(); + FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz = data.readU16(); + data.readU32(); // reserved for future use + data.readU32(); // reserved for future use +}; + +MspHelper.writeGyroFilterSliderSettings = function(buffer) { + buffer + .push8(FC.TUNING_SLIDERS.slider_gyro_filter) + .push8(FC.TUNING_SLIDERS.slider_gyro_filter_multiplier) + .push16(FC.FILTER_CONFIG.gyro_lowpass_hz) + .push16(FC.FILTER_CONFIG.gyro_lowpass2_hz) + .push16(FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz) + .push16(FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz) + .push32(0) // reserved for future use + .push32(0); // reserved for future use +}; + MspHelper.prototype.process_data = function(dataHandler) { const self = this; const data = dataHandler.dataView; // DataView (allowing us to view arrayBuffer as struct/union) @@ -1485,30 +1561,58 @@ MspHelper.prototype.process_data = function(dataHandler) { break; - case MSPCodes.MSP_SET_TUNING_SLIDERS: - // This is done in a loop whenever the sliders are moved. Avoid logging to optimise the performance. + case MSPCodes.MSP_SET_SIMPLIFIED_TUNING: + console.log('Tuning Sliders sent'); break; - case MSPCodes.MSP_TUNING_SLIDERS: - FC.TUNING_SLIDERS.slider_pids_mode = data.readU8(); - FC.TUNING_SLIDERS.slider_master_multiplier = data.readU8(); - FC.TUNING_SLIDERS.slider_roll_pitch_ratio = data.readU8(); - FC.TUNING_SLIDERS.slider_i_gain = data.readU8(); - FC.TUNING_SLIDERS.slider_d_gain = data.readU8(); - FC.TUNING_SLIDERS.slider_pi_gain = data.readU8(); - FC.TUNING_SLIDERS.slider_dmax_gain = data.readU8(); - FC.TUNING_SLIDERS.slider_feedforward_gain = data.readU8(); - FC.TUNING_SLIDERS.slider_pitch_pi_gain = data.readU8(); - FC.TUNING_SLIDERS.slider_dterm_filter = data.readU8(); - 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_SIMPLIFIED_TUNING: + MspHelper.readPidSliderSettings(data); + MspHelper.readDtermFilterSliderSettings(data); + MspHelper.readGyroFilterSliderSettings(data); + break; + case MSPCodes.MSP_CALCULATE_SIMPLIFIED_PID: + + if (FC.TUNING_SLIDERS.slider_pids_mode > 0) { + FC.PIDS[0][0] = data.readU8(); + FC.PIDS[0][1] = data.readU8(); + FC.PIDS[0][2] = data.readU8(); + FC.ADVANCED_TUNING.dMinRoll = data.readU8(); + FC.ADVANCED_TUNING.feedforwardRoll = data.readU16(); + + FC.PIDS[1][0] = data.readU8(); + FC.PIDS[1][1] = data.readU8(); + FC.PIDS[1][2] = data.readU8(); + FC.ADVANCED_TUNING.dMinPitch = data.readU8(); + FC.ADVANCED_TUNING.feedforwardPitch = data.readU16(); + } + + if (FC.TUNING_SLIDERS.slider_pids_mode > 1) { + FC.PIDS[2][0] = data.readU8(); + FC.PIDS[2][1] = data.readU8(); + FC.PIDS[2][2] = data.readU8(); + FC.ADVANCED_TUNING.dMinYaw = data.readU8(); + FC.ADVANCED_TUNING.feedforwardYaw = data.readU16(); + } + + break; + case MSPCodes.MSP_CALCULATE_SIMPLIFIED_GYRO: + MspHelper.readGyroFilterSliderSettings(data); + + break; + case MSPCodes.MSP_CALCULATE_SIMPLIFIED_DTERM: + MspHelper.readDtermFilterSliderSettings(data); + + break; + case MSPCodes.MSP_VALIDATE_SIMPLIFIED_TUNING: + FC.TUNING_SLIDERS.slider_pids_valid = data.readU8(); + FC.TUNING_SLIDERS.slider_gyro_valid = data.readU8(); + FC.TUNING_SLIDERS.slider_dterm_valid = data.readU8(); + + break; case MSPCodes.MSP_SET_VTXTABLE_POWERLEVEL: console.log("VTX powerlevel sent"); break; - case MSPCodes.MSP_SET_MODE_RANGE: console.log('Mode range saved'); break; @@ -2313,21 +2417,24 @@ MspHelper.prototype.crunch = function(code) { buffer.push8(1); 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); + case MSPCodes.MSP_SET_SIMPLIFIED_TUNING: + MspHelper.writePidSliderSettings(buffer); + MspHelper.writeDtermFilterSliderSettings(buffer); + MspHelper.writeGyroFilterSliderSettings(buffer); + + break; + case MSPCodes.MSP_CALCULATE_SIMPLIFIED_PID: + MspHelper.writePidSliderSettings(buffer); + + break; + + case MSPCodes.MSP_CALCULATE_SIMPLIFIED_GYRO: + MspHelper.writeGyroFilterSliderSettings(buffer); + + break; + case MSPCodes.MSP_CALCULATE_SIMPLIFIED_DTERM: + MspHelper.writeDtermFilterSliderSettings(buffer); + break; default: diff --git a/src/js/tabs/pid_tuning.js b/src/js/tabs/pid_tuning.js index cf15ec56..caef2ee8 100644 --- a/src/js/tabs/pid_tuning.js +++ b/src/js/tabs/pid_tuning.js @@ -22,8 +22,6 @@ TABS.pid_tuning = { activeSubtab: 'pid', analyticsChanges: {}, - retainConfiguration: false, - CONFIGURATOR_PIDS: [], CONFIGURATOR_ADVANCED_TUNING: {}, CONFIGURATOR_FILTER_CONFIG: {}, @@ -69,7 +67,7 @@ TABS.pid_tuning.initialize = function (callback) { }).then(function() { let promise; if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - promise = MSP.promise(MSPCodes.MSP_TUNING_SLIDERS); + promise = MSP.promise(MSPCodes.MSP_SIMPLIFIED_TUNING); } return promise; @@ -96,9 +94,9 @@ TABS.pid_tuning.initialize = function (callback) { const searchRow = $('.pid_tuning .' + elementPid + ' input'); // Assign each value - searchRow.each(function (indexInput) { + searchRow.each((indexInput, element) => { if (FC.PIDS[indexPid][indexInput] !== undefined) { - $(this).val(FC.PIDS[indexPid][indexInput]); + $(element).val(FC.PIDS_ACTIVE[indexPid][indexInput]); } }); }); @@ -597,9 +595,6 @@ TABS.pid_tuning.initialize = function (callback) { $('input[id="useIntegratedYaw"]').change(function() { const checked = $(this).is(':checked'); // 4.3 firmware has RP mode. - if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - $('#pid_main .pid_data input').prop('disabled', !checked); - } $('#pidTuningIntegratedYawCaution').toggle(checked); }).change(); @@ -690,6 +685,7 @@ TABS.pid_tuning.initialize = function (callback) { dMinSwitch.on('change', function() { const checked = $(this).is(':checked'); + if (checked) { if ($('.pid_tuning input[name="dMinRoll"]').val() == 0 && $('.pid_tuning input[name="dMinPitch"]').val() == 0 && $('.pid_tuning input[name="dMinYaw"]').val() == 0) { // when enabling dmin set its value based on 0.57x of actual dmax, dmin is limited to 100 @@ -721,8 +717,7 @@ TABS.pid_tuning.initialize = function (callback) { $('.pid_tuning input[name="dMinPitch"]').val(0); $('.pid_tuning input[name="dMinYaw"]').val(0); } - }); - dMinSwitch.trigger('change'); + }).trigger('change'); } } @@ -896,14 +891,13 @@ TABS.pid_tuning.initialize = function (callback) { } else { - // firmware 4.3 filter selectors for lowpass 1 and 2 + // firmware 4.3 filter selectors for lowpass 1 and 2; sliders are not yet initialized here 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 { @@ -911,10 +905,6 @@ TABS.pid_tuning.initialize = function (callback) { 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 @@ -922,84 +912,50 @@ TABS.pid_tuning.initialize = function (callback) { // 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); + gyroLowpassOptionStatic.toggle(checked && FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz === 0); + gyroLowpassOptionDynamic.toggle(checked && 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(); + const cutoff = FC.FILTER_CONFIG.gyro_lowpass_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass_hz : FILTER_DEFAULT.gyro_lowpass_hz; + const cutoffMin = FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz : FILTER_DEFAULT.gyro_lowpass_dyn_min_hz; + const cutoffMax = FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz : FILTER_DEFAULT.gyro_lowpass_dyn_max_hz; + + gyroLowpassFrequency.val(dynMode ? 0 : cutoff); + gyroLowpassDynMinFrequency.val(dynMode ? cutoffMin : 0); + gyroLowpassDynMaxFrequency.val(dynMode ? cutoffMax : 0); + + if (TuningSliders.sliderGyroFilter) { + self.calculateNewGyroFilters(); } + + gyroLowpassOptionStatic.toggle(!dynMode); + gyroLowpassOptionDynamic.toggle(!!dynMode); }); // 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(); - } + const cutoff = FC.FILTER_CONFIG.gyro_lowpass2_hz > 0 ? FC.FILTER_CONFIG.gyro_lowpass2_hz : FILTER_DEFAULT.gyro_lowpass2_hz; gyroLowpass2Frequency.val(checked ? cutoff : 0).attr('disabled', !checked); + + if (checked && TuningSliders.sliderGyroFilter) { + self.calculateNewGyroFilters(); + } + 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 @@ -1010,10 +966,6 @@ TABS.pid_tuning.initialize = function (callback) { 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 @@ -1021,77 +973,43 @@ TABS.pid_tuning.initialize = function (callback) { // 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); + dtermLowpassOptionStatic.toggle(checked && FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz === 0); + dtermLowpassOptionDynamic.toggle(checked && 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(); + const cutoff = FC.FILTER_CONFIG.dterm_lowpass_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass_hz : FILTER_DEFAULT.dterm_lowpass_hz; + const cutoffMin = FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz : FILTER_DEFAULT.dterm_lowpass_dyn_min_hz; + const cutoffMax = FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz : FILTER_DEFAULT.dterm_lowpass_dyn_max_hz; + + dtermLowpassFrequency.val(dynMode ? 0 : cutoff); + dtermLowpassDynMinFrequency.val(dynMode ? cutoffMin : 0); + dtermLowpassDynMaxFrequency.val(dynMode ? cutoffMax : 0); + + if (TuningSliders.sliderDTermFilter) { + self.calculateNewDTermFilters(); } + + dtermLowpassOptionStatic.toggle(!dynMode); + dtermLowpassOptionDynamic.toggle(!!dynMode); }); 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(); - } + const cutoff = FC.FILTER_CONFIG.dterm_lowpass2_hz > 0 ? FC.FILTER_CONFIG.dterm_lowpass2_hz : FILTER_DEFAULT.dterm_lowpass2_hz; dtermLowpass2Frequency.val(checked ? cutoff : 0).attr('disabled', !checked); + + if (checked && TuningSliders.sliderDTermFilter) { + self.calculateNewDTermFilters(); + } + dtermLowpass2Option.toggle(checked); self.updateFilterWarning(); }); @@ -1138,18 +1056,6 @@ TABS.pid_tuning.initialize = function (callback) { 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 && @@ -1406,9 +1312,9 @@ TABS.pid_tuning.initialize = function (callback) { FC.TUNING_SLIDERS.slider_roll_pitch_ratio = Math.round(TuningSliders.sliderRollPitchRatio * 20) * 5; FC.TUNING_SLIDERS.slider_pitch_pi_gain = Math.round(TuningSliders.sliderPitchPIGain * 20) * 5; - FC.TUNING_SLIDERS.slider_dterm_filter = TuningSliders.sliderDTermFilter ? 1 : 0; + FC.TUNING_SLIDERS.slider_dterm_filter = TuningSliders.sliderDTermFilter; FC.TUNING_SLIDERS.slider_dterm_filter_multiplier = Math.round(TuningSliders.sliderDTermFilterMultiplier * 20) * 5; - FC.TUNING_SLIDERS.slider_gyro_filter = TuningSliders.sliderGyroFilter ? 1 : 0; + FC.TUNING_SLIDERS.slider_gyro_filter = TuningSliders.sliderGyroFilter; FC.TUNING_SLIDERS.slider_gyro_filter_multiplier = Math.round(TuningSliders.sliderGyroFilterMultiplier * 20) * 5; } } @@ -1517,6 +1423,7 @@ TABS.pid_tuning.initialize = function (callback) { } function process_html() { + TABS.pid_tuning.isHtmlProcessing = true; FC.FEATURE_CONFIG.features.generateElements($('.tab-pid_tuning .features')); if (semver.lt(FC.CONFIG.apiVersion, "1.16.0") || semver.gte(FC.CONFIG.apiVersion, "1.20.0")) { @@ -1691,7 +1598,6 @@ TABS.pid_tuning.initialize = function (callback) { $('#resetPidProfile').on('click', function(){ self.updating = true; - self.retainConfiguration = true; MSP.promise(MSPCodes.MSP_SET_RESET_CURR_PID).then(function () { self.refresh(function () { @@ -2131,9 +2037,7 @@ TABS.pid_tuning.initialize = function (callback) { // exclude integratedYaw from setDirty for 4.3 as it uses RP mode. $('#pid-tuning').find('input').each(function (k, item) { - if ($(item).attr('class') !== "feature toggle" - && $(item).attr('class') !== "nonProfile" - && (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44) && $(item).attr('id'))) { + if ($(item).attr('class') !== "feature toggle" && $(item).attr('class') !== "nonProfile") { $(item).change(function () { self.setDirty(true); }); @@ -2225,41 +2129,13 @@ TABS.pid_tuning.initialize = function (callback) { const NON_EXPERT_SLIDER_MAX = semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44) ? 1.4 : 1.25; const NON_EXPERT_SLIDER_MIN = 0.7; - const SLIDER_STEP_LOWER = semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44) ? 0.05 : 0.1; + const SLIDER_STEP_LOWER = 0.05; 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) { - self.setDirty(true); - } else { - 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')); - // switch dmin and dmax values on dmin on/off if sliders available - if (!TuningSliders.pidSlidersUnavailable) { - if (TuningSliders.dMinFeatureEnabled) { - FC.ADVANCED_TUNING.dMinRoll = FC.PIDS[0][2]; - FC.ADVANCED_TUNING.dMinPitch = FC.PIDS[1][2]; - FC.ADVANCED_TUNING.dMinYaw = FC.PIDS[2][2]; - } else { - FC.PIDS[0][2] = FC.ADVANCED_TUNING.dMinRoll; - FC.PIDS[1][2] = FC.ADVANCED_TUNING.dMinPitch; - FC.PIDS[2][2] = FC.ADVANCED_TUNING.dMinYaw; - } - TuningSliders.calculateNewPids(); - } - }); - } - const useIntegratedYaw = $('input[id="useIntegratedYaw"]'); useIntegratedYaw.on('change', () => { @@ -2276,39 +2152,25 @@ TABS.pid_tuning.initialize = function (callback) { // trigger Slider Display update when PID / Filter mode is changed if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { + sliderPidsModeSelect.on('change', function () { const setMode = parseInt($(this).val()); TuningSliders.sliderPidsMode = setMode; - TuningSliders.calculateNewPids(); - TuningSliders.updateFormPids(); - TuningSliders.updatePidSlidersDisplay(); - const disableRP = !!setMode; - const disableY = setMode > 1; + TuningSliders.calculateNewPids(); + TuningSliders.updatePidSlidersDisplay(); // disable Integrated Yaw when going into RPY mode if (setMode === 2) { useIntegratedYaw.prop('checked', false).trigger('change'); } - - $('#pid_main .ROLL .pid_data input, #pid_main .PITCH .pid_data input').each(function() { - $(this).prop('disabled', disableRP); - }); - - $('#pid_main .YAW .pid_data input').each(function() { - $(this).prop('disabled', disableY); - }); - - if (setMode !== self.CONFIGURATOR_TUNING_SLIDERS.slider_pids_mode) { - self.setDirty(true); - } - - }).trigger('change'); + }); sliderGyroFilterModeSelect.change(function() { const mode = parseInt($(this).find(':selected').val()); - if (mode === 0) { + + if (mode === 1) { TuningSliders.gyroFilterSliderEnable(); } else { TuningSliders.gyroFilterSliderDisable(); @@ -2317,18 +2179,13 @@ TABS.pid_tuning.initialize = function (callback) { sliderDTermFilterModeSelect.change(function() { const mode = parseInt($(this).find(':selected').val()); - if (mode === 0) { + + if (mode !== 0) { TuningSliders.dtermFilterSliderEnable(); } else { TuningSliders.dtermFilterSliderDisable(); } }); - - // initial gyro mode - sliderGyroFilterModeSelect.val(TuningSliders.sliderGyroFilter); - - // initial dterm mode - sliderDTermFilterModeSelect.val(TuningSliders.sliderDTermFilter); } let allPidTuningSliders; @@ -2361,9 +2218,8 @@ TABS.pid_tuning.initialize = function (callback) { } } - const sliderValue = isInt(slider.val()) ? parseInt(slider.val()) : parseFloat(slider.val()); - if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { + const sliderValue = isInt(slider.val()) ? parseInt(slider.val()) : parseFloat(slider.val()); if (slider.is('#sliderDGain')) { TuningSliders.sliderDGain = sliderValue; } else if (slider.is('#sliderPIGain')) { @@ -2382,6 +2238,7 @@ TABS.pid_tuning.initialize = function (callback) { TuningSliders.sliderMasterMultiplier = sliderValue; } } else { + const sliderValue = TuningSliders.scaleSliderValue(slider.val()); if (slider.is('#sliderMasterMultiplierLegacy')) { TuningSliders.sliderMasterMultiplierLegacy = sliderValue; } else if (slider.is('#sliderPDRatio')) { @@ -2392,17 +2249,11 @@ TABS.pid_tuning.initialize = function (callback) { TuningSliders.sliderFeedforwardGainLegacy = sliderValue; } } - TuningSliders.calculateNewPids(); + + self.calculateNewPids(); self.analyticsChanges['PidTuningSliders'] = "On"; }); - if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - allPidTuningSliders.mouseup(function() { - // readjust dmin maximums - $('.pid_tuning .ROLL input[name="d"]').change(); - $('.pid_tuning .PITCH input[name="d"]').change(); - $('.pid_tuning .YAW input[name="d"]').change(); - }); - } + // reset to middle with double click allPidTuningSliders.dblclick(function() { const slider = $(this); @@ -2447,30 +2298,7 @@ TABS.pid_tuning.initialize = function (callback) { } } slider.val(value); - - TuningSliders.calculateNewPids(); - }); - - // enable PID sliders button - $('a.buttonPidTuningSliders').click(function() { - // set Slider PID mode to RP(Y) when re-enabling Sliders - if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - const firmwareMode = self.CONFIGURATOR_TUNING_SLIDERS.slider_pids_mode; - const workingMode = firmwareMode === 1 ? 1 : 2; - - if (firmwareMode !== workingMode) { - self.retainConfiguration = true; - } - sliderPidsModeSelect.val(workingMode).trigger('change'); - } - // if values were previously changed manually and then sliders are reactivated, reset pids to previous valid values if available, else default - TuningSliders.resetPidSliders(); - TuningSliders.updatePidSlidersDisplay(); - // disable integrated yaw when enabling sliders - if ($('input[id="useIntegratedYaw"]').is(':checked')) { - $('input[id="useIntegratedYaw"]').prop('checked', true).click(); - } - self.analyticsChanges['PidTuningSliders'] = "On"; + self.calculateNewPids(); }); // enable filter sliders inputs @@ -2478,13 +2306,6 @@ TABS.pid_tuning.initialize = function (callback) { allFilterTuningSliders.on('input mouseup', function() { const slider = $(this); - if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - if (slider.val() >= 1) { - slider.attr('step', SLIDER_STEP_LOWER); - } else { - slider.attr('step', SLIDER_STEP_UPPER); - } - } if (!TuningSliders.expertMode) { if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { const NON_EXPERT_SLIDER_MIN_GYRO = 0.5; @@ -2514,56 +2335,35 @@ TABS.pid_tuning.initialize = function (callback) { } } - const sliderValue = isInt(slider.val()) ? parseInt(slider.val()) : parseFloat(slider.val()); + let sliderValue = isInt(slider.val()) ? parseInt(slider.val()) : parseFloat(slider.val()); + if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) { + sliderValue = TuningSliders.scaleSliderValue(slider.val()); + } + if (slider.is('#sliderGyroFilterMultiplier')) { TuningSliders.sliderGyroFilterMultiplier = sliderValue; - TuningSliders.calculateNewGyroFilters(); + self.calculateNewGyroFilters(); self.analyticsChanges['GyroFilterTuningSlider'] = "On"; } else if (slider.is('#sliderDTermFilterMultiplier')) { TuningSliders.sliderDTermFilterMultiplier = sliderValue; - TuningSliders.calculateNewDTermFilters(); + self.calculateNewDTermFilters(); self.analyticsChanges['DTermFilterTuningSlider'] = "On"; } }); + // reset to middle with double click allFilterTuningSliders.dblclick(function() { const slider = $(this); slider.val(1); if (slider.is('#sliderGyroFilterMultiplier')) { TuningSliders.sliderGyroFilterMultiplier = 1; - TuningSliders.calculateNewGyroFilters(); + self.calculateNewGyroFilters(); } else if (slider.is('#sliderDTermFilterMultiplier')) { TuningSliders.sliderDTermFilterMultiplier = 1; - TuningSliders.calculateNewDTermFilters(); + self.calculateNewDTermFilters(); } }); - // enable Filter sliders button (legacy sliders) - $('a.buttonFilterTuningSliders').click(function() { - if (TuningSliders.GyroSliderUnavailable) { - // update switchery dynamically based on defaults - $('input[id="gyroLowpassDynEnabled"]').prop('checked', false).click(); - $('input[id="gyroLowpassEnabled"]').prop('checked', true).click(); - $('input[id="gyroLowpass2Enabled"]').prop('checked', false).click(); - TuningSliders.resetGyroFilterSlider(); - self.analyticsChanges['GyroFilterTuningSlider'] = "On"; - } - if (TuningSliders.DTermSliderUnavailable) { - $('input[id="dtermLowpassDynEnabled"]').prop('checked', false).click(); - $('input[id="dtermLowpassEnabled"]').prop('checked', true).click(); - $('input[id="dtermLowpass2Enabled"]').prop('checked', false).click(); - TuningSliders.resetDTermFilterSlider(); - self.analyticsChanges['DTermFilterTuningSlider'] = "On"; - } - }); - - // update on pid table inputs - $('#pid_main input').on('input', function() { - if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - TuningSliders.updatePidSlidersDisplay(); - self.analyticsChanges['PidTuningSliders'] = "Off"; - } - }); // update on filter value or type changes $('.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)) { @@ -2573,8 +2373,10 @@ TABS.pid_tuning.initialize = function (callback) { } else if (e.target.type === 'select-one') { $(`.pid_filter select[name="${e.target.name}"]`).val(e.target.value); } + } else { + TuningSliders.updateFilterSlidersDisplay(); } - TuningSliders.updateFilterSlidersDisplay(); + if (TuningSliders.GyroSliderUnavailable) { self.analyticsChanges['GyroFilterTuningSlider'] = "Off"; } @@ -2582,11 +2384,85 @@ TABS.pid_tuning.initialize = function (callback) { self.analyticsChanges['DTermFilterTuningSlider'] = "Off"; } }); + // update on filter switch changes - $('.pid_filter tr:not(.newFilter) .inputSwitch input').change(() => $('.pid_filter input').triggerHandler('input')); + $('.pid_filter tr:not(.newFilter) .inputSwitch input').change(() => { + $('.pid_filter input').triggerHandler('input'); + self.setDirty(true); + }); $('.tuningHelp').hide(); + + // LEGACY SLIDERS CODE + if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) { + $('#dMinSwitch').change(function() { + TuningSliders.setDMinFeatureEnabled($(this).is(':checked')); + // switch dmin and dmax values on dmin on/off if sliders available + if (!TuningSliders.pidSlidersUnavailable) { + if (TuningSliders.dMinFeatureEnabled) { + FC.ADVANCED_TUNING.dMinRoll = FC.PIDS[0][2]; + FC.ADVANCED_TUNING.dMinPitch = FC.PIDS[1][2]; + FC.ADVANCED_TUNING.dMinYaw = FC.PIDS[2][2]; + } else { + FC.PIDS[0][2] = FC.ADVANCED_TUNING.dMinRoll; + FC.PIDS[1][2] = FC.ADVANCED_TUNING.dMinPitch; + FC.PIDS[2][2] = FC.ADVANCED_TUNING.dMinYaw; + } + TuningSliders.calculateNewPids(); + } + }); + + allPidTuningSliders.mouseup(function() { + // readjust dmin maximums + $('.pid_tuning .ROLL input[name="d"]').change(); + $('.pid_tuning .PITCH input[name="d"]').change(); + $('.pid_tuning .YAW input[name="d"]').change(); + }); + + // enable PID sliders button (legacy) + $('a.buttonPidTuningSliders').click(function() { + // if values were previously changed manually and then sliders are reactivated, reset pids to previous valid values if available, else default + TuningSliders.resetPidSliders(); + TuningSliders.updatePidSlidersDisplay(); + + // disable integrated yaw when enabling sliders + if ($('input[id="useIntegratedYaw"]').is(':checked')) { + $('input[id="useIntegratedYaw"]').prop('checked', true).click(); + } + + self.analyticsChanges['PidTuningSliders'] = "On"; + }); + + // enable Filter sliders button (legacy sliders) + $('a.buttonFilterTuningSliders').click(function() { + if (TuningSliders.GyroSliderUnavailable) { + // update switchery dynamically based on defaults + $('input[id="gyroLowpassDynEnabled"]').prop('checked', false).click(); + $('input[id="gyroLowpassEnabled"]').prop('checked', true).click(); + $('input[id="gyroLowpass2Enabled"]').prop('checked', false).click(); + TuningSliders.resetGyroFilterSlider(); + + self.analyticsChanges['GyroFilterTuningSlider'] = "On"; + } + if (TuningSliders.DTermSliderUnavailable) { + $('input[id="dtermLowpassDynEnabled"]').prop('checked', false).click(); + $('input[id="dtermLowpassEnabled"]').prop('checked', true).click(); + $('input[id="dtermLowpass2Enabled"]').prop('checked', false).click(); + TuningSliders.resetDTermFilterSlider(); + + self.analyticsChanges['DTermFilterTuningSlider'] = "On"; + } + }); + + // update on pid table inputs + $('#pid_main input').on('input', function() { + TuningSliders.updatePidSlidersDisplay(); + self.analyticsChanges['PidTuningSliders'] = "Off"; + }); + } + } else { + // semver.lt API_VERSION_1_42 $('.tuningPIDSliders').hide(); $('.tuningFilterSliders').hide(); $('.slidersDisabled').hide(); @@ -2624,29 +2500,19 @@ TABS.pid_tuning.initialize = function (callback) { console.log(`Unsupported API version: ${FC.CONFIG.apiVersion}`); } return promise; - }).then(function () { - return MSP.promise(MSPCodes.MSP_SET_PID, mspHelper.crunch(MSPCodes.MSP_SET_PID)); - }).then(function () { - return MSP.promise(MSPCodes.MSP_SET_PID_ADVANCED, mspHelper.crunch(MSPCodes.MSP_SET_PID_ADVANCED)); - }).then(function () { + }) + .then(() => MSP.promise(MSPCodes.MSP_SET_PID, mspHelper.crunch(MSPCodes.MSP_SET_PID))) + .then(() => MSP.promise(MSPCodes.MSP_SET_PID_ADVANCED, mspHelper.crunch(MSPCodes.MSP_SET_PID_ADVANCED))) + .then(() => { self.updatePIDColors(); return MSP.promise(MSPCodes.MSP_SET_FILTER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FILTER_CONFIG)); - }).then(function () { - return MSP.promise(MSPCodes.MSP_SET_RC_TUNING, mspHelper.crunch(MSPCodes.MSP_SET_RC_TUNING)); - }).then(function () { - return MSP.promise(MSPCodes.MSP_SET_FEATURE_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FEATURE_CONFIG)); - }).then(function () { - let promise; - if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - promise = MSP.promise(MSPCodes.MSP_SET_TUNING_SLIDERS, mspHelper.crunch(MSPCodes.MSP_SET_TUNING_SLIDERS)); - } - - return promise; - }).then(function () { - return MSP.promise(MSPCodes.MSP_EEPROM_WRITE); - }).then(function () { + }) + .then(() => MSP.promise(MSPCodes.MSP_SET_RC_TUNING, mspHelper.crunch(MSPCodes.MSP_SET_RC_TUNING))) + .then(() => MSP.promise(MSPCodes.MSP_SET_FEATURE_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FEATURE_CONFIG))) + .then(() => semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44) ? MSP.promise(MSPCodes.MSP_SET_SIMPLIFIED_TUNING, mspHelper.crunch(MSPCodes.MSP_SET_SIMPLIFIED_TUNING)) : true) + .then(() => MSP.promise(MSPCodes.MSP_EEPROM_WRITE)) + .then(() => { self.updating = false; - self.retainConfiguration = false; self.setDirty(false); @@ -2676,6 +2542,7 @@ TABS.pid_tuning.initialize = function (callback) { self.analyticsChanges = {}; GUI.content_ready(callback); + TABS.pid_tuning.isHtmlProcessing = false; } }; @@ -2757,10 +2624,6 @@ TABS.pid_tuning.cleanup = function (callback) { TABS.pid_tuning.refresh = function (callback) { const self = this; - if (self.retainConfiguration && !self.updating) { - self.restoreInitialSettings(); - } - GUI.tab_switch_cleanup(function () { self.initialize(); @@ -2772,41 +2635,6 @@ TABS.pid_tuning.refresh = function (callback) { }); }; -TABS.pid_tuning.saveInitialSettings = function () { - if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - this.CONFIGURATOR_PIDS = [ ...FC.PIDS ]; - this.CONFIGURATOR_ADVANCED_TUNING = { ...FC.ADVANCED_TUNING }; - this.CONFIGURATOR_FILTER_CONFIG = { ...FC.FILTER_CONFIG }; - this.CONFIGURATOR_RC_TUNING = { ...FC.RC_TUNING }; - this.CONFIGURATOR_FEATURE_CONFIG = { ...FC.FEATURE_CONFIG }; - this.CONFIGURATOR_TUNING_SLIDERS = { ...FC.TUNING_SLIDERS}; - } -}; - -TABS.pid_tuning.restoreInitialSettings = function () { - if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { - FC.PIDS = [ ...this.CONFIGURATOR_PIDS ]; - FC.ADVANCED_TUNING = { ...this.CONFIGURATOR_ADVANCED_TUNING }; - FC.FILTER_CONFIG = { ...this.CONFIGURATOR_FILTER_CONFIG }; - FC.RC_TUNING = { ...this.CONFIGURATOR_RC_TUNING }; - FC.FEATURE_CONFIG = { ...this.CONFIGURATOR_FEATURE_CONFIG }; - FC.TUNING_SLIDERS = { ...this.CONFIGURATOR_TUNING_SLIDERS }; - - Promise.resolve(true) - .then(() => MSP.promise(MSPCodes.MSP_SET_PID, mspHelper.crunch(MSPCodes.MSP_SET_PID))) - .then(() => MSP.promise(MSPCodes.MSP_SET_PID_ADVANCED, mspHelper.crunch(MSPCodes.MSP_SET_PID_ADVANCED))) - .then(() => MSP.promise(MSPCodes.MSP_SET_FILTER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FILTER_CONFIG))) - .then(() => MSP.promise(MSPCodes.MSP_SET_RC_TUNING, mspHelper.crunch(MSPCodes.MSP_SET_RC_TUNING))) - .then(() => MSP.promise(MSPCodes.MSP_SET_FEATURE_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FEATURE_CONFIG))) - .then(() => MSP.promise(MSPCodes.MSP_SET_TUNING_SLIDERS, mspHelper.crunch(MSPCodes.MSP_SET_TUNING_SLIDERS))) - .then(() => { - TABS.pid_tuning.retainConfiguration = false; - - console.log('Configuration restored to initial values'); - }); - } -}; - TABS.pid_tuning.setProfile = function () { const self = this; @@ -2829,10 +2657,6 @@ TABS.pid_tuning.setDirty = function (isDirty) { if (semver.gte(FC.CONFIG.apiVersion, "1.20.0")) { $('.tab-pid_tuning select[name="rate_profile"]').prop('disabled', isDirty); } - - if (isDirty) { - self.retainConfiguration = true; - } }; TABS.pid_tuning.checkUpdateProfile = function (updateRateProfile) { @@ -3113,6 +2937,24 @@ TABS.pid_tuning.updateRatesLabels = function() { } }; +TABS.pid_tuning.calculateNewPids = function() { + if (!TABS.pid_tuning.isHtmlProcessing) { + TuningSliders.calculateNewPids(); + } +}; + +TABS.pid_tuning.calculateNewGyroFilters = function() { + if (!TABS.pid_tuning.isHtmlProcessing) { + TuningSliders.calculateNewGyroFilters(); + } +}; + +TABS.pid_tuning.calculateNewDTermFilters = function() { + if (!TABS.pid_tuning.isHtmlProcessing) { + TuningSliders.calculateNewDTermFilters(); + } +}; + TABS.pid_tuning.updateFilterWarning = function() { const gyroLowpassFilterMode = parseInt($('.pid_filter select[name="gyroLowpassFilterMode"]').val()); const gyroDynamicLowpassEnabled = gyroLowpassFilterMode === 1;