diff --git a/locales/en/messages.json b/locales/en/messages.json index 68c32cac..1b255a91 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -61,7 +61,7 @@ }, "portOverrideText": { "message": "Port:" - }, + }, "autoConnect": { "message": "Auto-Connect" }, @@ -1642,7 +1642,7 @@ }, "pidTuningDMin": { "message": "D Min", - "description": "Table header of the D Min feature in the PIDs tab" + "description": "Table header of the D Min feature in the PIDs tab" }, "pidTuningDMinDisabledNote": { "message": "Note: D Min feature is disabled and its parameters are hidden. To use D Min please enable it in $t(pidTuningPidSettings.message)." @@ -2099,7 +2099,7 @@ "auxiliaryDisabled": { "message": "(DISABLED)", "descripton": "Text to add to the ARM mode (maybe others in the future) in the MODES TAB when it has been disabled for some external reason" - }, + }, "auxiliaryAddRange": { "message": "Add Range" }, @@ -2828,7 +2828,7 @@ }, "dataflashLogsSpace": { "message": "Free space for logs" - }, + }, "dataflashNote": { "message": "Flight logs can be recorded to your flight controller's onboard dataflash chip." }, @@ -2883,25 +2883,25 @@ "dataflashFileWriteFailed": { "message": "Failed to write to the file you selected, are the permissions on that folder okay?" }, - + "sdcardStatusNoCard": { "message": "No card inserted" - }, + }, "sdcardStatusReboot": { "message": "Fatal error
Reboot to retry" - }, + }, "sdcardStatusReady": { "message": "Card ready" - }, + }, "sdcardStatusStarting": { "message": "Card starting..." - }, + }, "sdcardStatusFileSystem": { "message": "Filesystem starting..." - }, + }, "sdcardStatusUnknown": { "message": "Unknown state $1" - }, + }, "firmwareFlasherReleaseSummaryHead": { "message": "Release info" @@ -3008,7 +3008,7 @@ }, "firmwareFlasherBaudRate": { "message": "Baud Rate" - }, + }, "firmwareFlasherShowDevelopmentReleases":{ "message": "Show unstable releases" }, @@ -3594,6 +3594,22 @@ "message": "Master Multiplier:", "description": "Master tuning slider label" }, + "pidTuningRollPitchRatioSlider": { + "message": "Roll Pitch Ratio:", + "description": "Roll pitch ratio slider label" + }, + "pidTuningRollPitchRatioSliderHelp": { + "message": "Roll Pitch Ratio", + "description": "This needs a meaningful help text" + }, + "pidTuningIGainSlider": { + "message": "I Gain:", + "description": "I gain slider label" + }, + "pidTuningIGainSliderHelp": { + "message": "I Gain", + "description": "This needs a meaningful help text" + }, "pidTuningPDRatioSlider": { "message": "PD Balance:", "description": "PD balance tuning slider label" @@ -3602,6 +3618,14 @@ "message": "P and D Gain:", "description": "P and D gain tuning slider label" }, + "pidTuningDMinRatioSlider": { + "message": "D Min Ratio:", + "description": "D Min ratio slider label" + }, + "pidTuningDMinRatioSliderHelp": { + "message": "D Min Ratio", + "description": "This needs a meaningful help text" + }, "pidTuningResponseSlider": { "message": "Stick Response Gain:", "description": "Response tuning slider label" @@ -3735,7 +3759,7 @@ }, "pidTuningDTermLowpassFiltersGroup": { "message": "D Term Lowpass Filters" - }, + }, "pidTuningDTermLowpassType": { "message": "D Term Lowpass 1 Filter Type" }, @@ -3762,7 +3786,7 @@ }, "pidTuningDTermNotchFiltersGroup": { "message": "D Term Notch Filters" - }, + }, "pidTuningDTermNotchFrequency": { "message": "D Term Notch Filter Center Frequency [Hz]" }, @@ -3771,7 +3795,7 @@ }, "pidTuningYawLospassFiltersGroup": { "message": "Yaw Lowpass Filters" - }, + }, "pidTuningYawLowpassFrequency": { "message": "Yaw Lowpass Cutoff Frequency [Hz]" }, @@ -4462,7 +4486,7 @@ "osdSetupUploadingFontEnd": { "message": "Uploaded all {{length}} characters to the OSD" }, - + "osdSetupSave": { "message": "Save" }, @@ -5618,7 +5642,7 @@ "vtxLoadClipboardOk": { "message": "VTX Config info loaded from clipboard", "description": "Message in the GUI log when the VTX Config file is pasted from clipboard" - }, + }, "vtxLoadClipboardKo": { "message": "Error while loading the VTX Config info from clipboard. Maybe the contents are not correct", "description": "Message in the GUI log when the VTX Config file is pasted from clipboard" diff --git a/src/css/tabs/pid_tuning.css b/src/css/tabs/pid_tuning.css index 6f389dd0..d734cafc 100644 --- a/src/css/tabs/pid_tuning.css +++ b/src/css/tabs/pid_tuning.css @@ -734,7 +734,7 @@ height: 15px; } -.tab-pid_tuning .nonExpertModeSliders.tuningSlider::-webkit-slider-runnable-track { +.tab-pid_tuning .nonExpertModeSliders .tuningSlider::-webkit-slider-runnable-track { background: linear-gradient(90deg, rgb(197, 197, 197) -50%, rgb(241, 241, 241) 50%, rgb(255, 84, 14) 150%); background-size: 55%; background-position: 44%; diff --git a/src/js/TuningSliders.js b/src/js/TuningSliders.js index 3cacc7ed..b1048864 100644 --- a/src/js/TuningSliders.js +++ b/src/js/TuningSliders.js @@ -1,19 +1,21 @@ 'use strict'; const TuningSliders = { - MasterSliderValue: 1, - PDRatioSliderValue: 1, - PDGainSliderValue: 1, - ResponseSliderValue: 1, + sliderPidsMode: 0, + sliderMasterMultiplier: 1, + sliderRollPitchRatio: 1, + sliderIGain: 1, + sliderPDRatio: 1, + sliderPDGain: 1, + sliderDMinRatio: 1, + sliderFFGain: 1, pidSlidersUnavailable: false, - gyroFilterSliderValue: 1, - dtermFilterSliderValue: 1, - filterGyroSliderUnavailable: false, - filterDTermSliderUnavailable: false, + sliderGyroFilter: 0, + sliderGyroFilterMultiplier: 1, + sliderDTermFilter: 0, + sliderDTermFilterMultiplier: 1, - dMinFeatureEnabled: true, - defaultPDRatio: 0, PID_DEFAULT: [], FILTER_DEFAULT: {}, @@ -30,7 +32,6 @@ TuningSliders.initialize = function() { this.PID_DEFAULT = FC.getPidDefaults(); this.FILTER_DEFAULT = FC.getFilterDefaults(); - this.setDMinFeatureEnabled($('#dMinSwitch').is(':checked')); this.setExpertMode($('input[name="expertModeCheckbox"]').is(':checked')); this.initPidSlidersPosition(); @@ -46,29 +47,18 @@ TuningSliders.initialize = function() { this.updateFilterSlidersDisplay(); }; -TuningSliders.setDMinFeatureEnabled = function(dMinFeatureEnabled) { - this.dMinFeatureEnabled = dMinFeatureEnabled; - if (this.dMinFeatureEnabled) { - this.defaultPDRatio = this.PID_DEFAULT[2] / this.PID_DEFAULT[0]; - } else { - this.defaultPDRatio = this.PID_DEFAULT[2] / (this.PID_DEFAULT[0] * (1 / D_MIN_RATIO)); - } -}; - TuningSliders.setExpertMode = function(expertMode) { this.expertMode = expertMode; - const allTuningSliderElements = $('#tuningMasterSlider, #tuningPDRatioSlider, #tuningPDGainSlider,\ - #tuningResponseSlider, #tuningGyroFilterSlider, #tuningDTermFilterSlider'); if (this.expertMode) { - allTuningSliderElements.removeClass('nonExpertModeSliders'); + $('#slidersPidsBox, #slidersFilterBox').removeClass('nonExpertModeSliders'); } else { - allTuningSliderElements.addClass('nonExpertModeSliders'); + $('#slidersPidsBox, #slidersFilterBox').addClass('nonExpertModeSliders'); } }; TuningSliders.scaleSliderValue = function(value) { if (value > 1) { - return Math.round(((value - 1) * 2 + 1) * 10) / 10; + return Math.round(((value - 1) * 2 + 1) * 100) / 100; } else { return value; } @@ -83,71 +73,115 @@ TuningSliders.downscaleSliderValue = function(value) { }; TuningSliders.initPidSlidersPosition = function() { - // 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.MasterSliderValue = Math.round(FC.PIDS[2][1] / this.PID_DEFAULT[11] * 10) / 10; - this.PDRatioSliderValue = Math.round(FC.PIDS[0][2] / FC.PIDS[0][0] / this.defaultPDRatio * 10) / 10; - if (this.dMinFeatureEnabled) { - this.PDGainSliderValue = Math.round(FC.ADVANCED_TUNING.dMinRoll / this.PDRatioSliderValue / this.MasterSliderValue / this.PID_DEFAULT[3] * 10) / 10; + if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { + // 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.sliderMasterMultiplier = Math.floor(FC.PIDS[2][1] / this.PID_DEFAULT[11] * 10) / 10; + this.sliderPDRatio = Math.floor(FC.PIDS[0][0] / FC.PIDS[0][2] / (this.PID_DEFAULT[0] / this.PID_DEFAULT[2]) * 10) / 10; + this.sliderPDGain = Math.floor(FC.ADVANCED_TUNING.dMinRoll / this.sliderMasterMultiplier / this.PID_DEFAULT[3] * 10) / 10; + this.sliderFFGain = Math.floor(FC.ADVANCED_TUNING.feedforwardRoll / this.sliderMasterMultiplier / this.PID_DEFAULT[4] * 10) / 10; } else { - this.PDGainSliderValue = Math.round(FC.PIDS[0][0] / this.MasterSliderValue / (this.PID_DEFAULT[2] * (1 / D_MIN_RATIO)) * 10) / 10; + this.sliderPidsMode = FC.TUNING_SLIDERS.slider_pids_mode; + this.sliderMasterMultiplier = FC.TUNING_SLIDERS.slider_master_multiplier / 100; + this.sliderRollPitchRatio = FC.TUNING_SLIDERS.slider_roll_pitch_ratio / 100; + this.sliderIGain = FC.TUNING_SLIDERS.slider_i_gain / 100; + this.sliderPDRatio = FC.TUNING_SLIDERS.slider_pd_ratio / 100; + this.sliderPDGain = FC.TUNING_SLIDERS.slider_pd_gain / 100; + this.sliderDMinRatio = FC.TUNING_SLIDERS.slider_dmin_ratio / 100; + this.sliderFFGain = FC.TUNING_SLIDERS.slider_ff_gain / 100; } - this.ResponseSliderValue = Math.round(FC.ADVANCED_TUNING.feedforwardRoll / this.MasterSliderValue / this.PID_DEFAULT[4] * 10) / 10; - $('output[name="tuningMasterSlider-number"]').val(this.MasterSliderValue); - $('output[name="tuningPDRatioSlider-number"]').val(this.PDRatioSliderValue); - $('output[name="tuningPDGainSlider-number"]').val(this.PDGainSliderValue); - $('output[name="tuningResponseSlider-number"]').val(this.ResponseSliderValue); + $('output[name="sliderMasterMultiplier-number"]').val(this.sliderMasterMultiplier); + $('output[name="sliderRollPitchRatio-number"]').val(this.sliderRollPitchRatio); + $('output[name="sliderIGain-number"]').val(this.sliderIGain); + $('output[name="sliderPDRatio-number"]').val(this.sliderPDRatio); + $('output[name="sliderPDGain-number"]').val(this.sliderPDGain); + $('output[name="sliderDMinRatio-number"]').val(this.sliderDMinRatio); + $('output[name="sliderFFGain-number"]').val(this.sliderFFGain); - $('#tuningMasterSlider').val(this.downscaleSliderValue(this.MasterSliderValue)); - $('#tuningPDRatioSlider').val(this.downscaleSliderValue(this.PDRatioSliderValue)); - $('#tuningPDGainSlider').val(this.downscaleSliderValue(this.PDGainSliderValue)); - $('#tuningResponseSlider').val(this.downscaleSliderValue(this.ResponseSliderValue)); + $('#sliderMasterMultiplier').val(this.downscaleSliderValue(this.sliderMasterMultiplier)); + $('#sliderRollPitchRatio').val(this.downscaleSliderValue(this.sliderRollPitchRatio)); + $('#sliderIGain').val(this.downscaleSliderValue(this.sliderIGain)); + $('#sliderPDRatio').val(this.downscaleSliderValue(this.sliderPDRatio)); + $('#sliderPDGain').val(this.downscaleSliderValue(this.sliderPDGain)); + $('#sliderDMinRatio').val(this.downscaleSliderValue(this.sliderDMinRatio)); + $('#sliderFFGain').val(this.downscaleSliderValue(this.sliderFFGain)); }; TuningSliders.initGyroFilterSliderPosition = function() { - this.gyroFilterSliderValue = 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; - $('output[name="tuningGyroFilterSlider-number"]').val(this.gyroFilterSliderValue); - $('#tuningGyroFilterSlider').val(this.downscaleSliderValue(this.gyroFilterSliderValue)); + if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { + 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; + } else { + this.sliderGyroFilterMultiplier = FC.TUNING_SLIDERS.slider_gyro_filter_multiplier / 100; + } + + $('output[name="sliderGyroFilterMultiplier-number"]').val(this.sliderGyroFilterMultiplier); + $('#sliderGyroFilterMultiplier').val(this.downscaleSliderValue(this.sliderGyroFilterMultiplier)); }; TuningSliders.initDTermFilterSliderPosition = function() { - this.dtermFilterSliderValue = 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; - $('output[name="tuningDTermFilterSlider-number"]').val(this.dtermFilterSliderValue); - $('#tuningDTermFilterSlider').val(this.downscaleSliderValue(this.dtermFilterSliderValue)); + if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { + 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 { + this.sliderDTermFilterMultiplier = FC.TUNING_SLIDERS.slider_dterm_filter_multiplier / 100; + } + + $('output[name="sliderDTermFilterMultiplier-number"]').val(this.sliderDTermFilterMultiplier); + $('#sliderDTermFilterMultiplier').val(this.downscaleSliderValue(this.sliderDTermFilterMultiplier)); }; TuningSliders.resetPidSliders = function() { if (!this.cachedPidSliderValues) { - $('#tuningMasterSlider').val(1); - $('#tuningPDRatioSlider').val(1); - $('#tuningPDGainSlider').val(1); - $('#tuningResponseSlider').val(1); - this.MasterSliderValue = 1; - this.PDRatioSliderValue = 1; - this.PDGainSliderValue = 1; - this.ResponseSliderValue = 1; + this.sliderMasterMultiplier = 1; + this.sliderRollPitchRatio = 1; + this.sliderIGain = 1; + this.sliderPDRatio = 1; + this.sliderPDGain = 1; + this.sliderDMinRatio = 1; + this.sliderFFGain = 1; } + + if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { + $('#sliderMasterMultiplier').val(this.downscaleSliderValue(this.sliderMasterMultiplier)); + $('#sliderPDRatio').val(this.downscaleSliderValue(this.sliderPDRatio)); + $('#sliderPDGain').val(this.downscaleSliderValue(this.sliderPDGain)); + $('#sliderFFGain').val(this.downscaleSliderValue(this.sliderFFGain)); + } else { + this.initPidSlidersPosition(); + } + this.calculateNewPids(); this.updatePidSlidersDisplay(); }; TuningSliders.resetGyroFilterSlider = function() { if (!this.cachedGyroSliderValues) { - $('#tuningGyroFilterSlider').val(1); - this.gyroFilterSliderValue = 1; + this.sliderGyroFilterMultiplier = 1; } + + if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { + $('#sliderGyroFilterMultiplier').val(this.downscaleSliderValue(this.sliderGyroFilterMultiplier)); + } else { + this.initGyroFilterSliderPosition(); + } + this.calculateNewGyroFilters(); this.updateFilterSlidersDisplay(); }; TuningSliders.resetDTermFilterSlider = function() { if (!this.cachedDTermSliderValues) { - $('#tuningDTermFilterSlider').val(1); - this.dtermFilterSliderValue = 1; + this.sliderDTermFilterMultiplier = 1; } + + if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { + $('#sliderDTermFilterMultiplier').val(this.downscaleSliderValue(this.sliderDTermFilterMultiplier)); + } else { + this.initDTermFilterSliderPosition(); + } + this.calculateNewDTermFilters(); this.updateFilterSlidersDisplay(); }; @@ -160,37 +194,37 @@ TuningSliders.updatePidSlidersDisplay = function() { const WARNING_DMAX_GAIN = 60; const WARNING_DMIN_GAIN = 40; - this.pidSlidersUnavailable = false; - let currentPIDs = []; - FC.PID_NAMES.forEach(function(elementPid, indexPid) { - let searchRow = $('.pid_tuning .' + elementPid + ' input'); - searchRow.each(function (indexInput) { - if (indexPid < 3 && indexInput < 5) { - currentPIDs.push($(this).val()); - } - }); - }); - this.calculateNewPids(); - FC.PID_NAMES.forEach(function(elementPid, indexPid) { - let searchRow = $('.pid_tuning .' + elementPid + ' input'); - searchRow.each(function (indexInput) { - if (indexPid < 3 && indexInput < 5) { - if (currentPIDs[indexPid * 5 + indexInput] != $(this).val()) { - TuningSliders.pidSlidersUnavailable = true; + if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { + this.pidSlidersUnavailable = false; + let currentPIDs = []; + FC.PID_NAMES.forEach(function(elementPid, indexPid) { + const pidElements = $(`.pid_tuning .${elementPid} input`); + pidElements.each(function (indexInput) { + if (indexPid < 3 && indexInput < 5) { + currentPIDs.push($(this).val()); } - $(this).val(currentPIDs[indexPid * 5 + indexInput]); - } + }); + }); + this.calculateNewPids(); + FC.PID_NAMES.forEach(function(elementPid, indexPid) { + const pidElements = $(`.pid_tuning .${elementPid} input`); + pidElements.each(function (indexInput) { + if (indexPid < 3 && indexInput < 5) { + if (currentPIDs[indexPid * 5 + indexInput] != $(this).val()) { + TuningSliders.pidSlidersUnavailable = true; + } + $(this).val(currentPIDs[indexPid * 5 + indexInput]); + } + }); }); - }); - if ($('input[id="useIntegratedYaw"]').is(':checked')) { - this.pidSlidersUnavailable = true; - } + if ($('input[id="useIntegratedYaw"]').is(':checked')) { + this.pidSlidersUnavailable = true; + } - if (this.pidSlidersUnavailable) { - TABS.pid_tuning.updatePIDColors(true); - } else { - this.cachedPidSliderValues = true; + if (!this.pidSlidersUnavailable) { + this.cachedPidSliderValues = true; + } } $('.tuningPIDSliders').toggle(!this.pidSlidersUnavailable); @@ -205,72 +239,78 @@ TuningSliders.updateFilterSlidersDisplay = function() { const WARNING_FILTER_HIGH_GAIN = 1.4; const WARNING_FILTER_LOW_GAIN = 0.7; - this.filterGyroSliderUnavailable = false; - this.filterDTermSliderUnavailable = false; + this.sliderGyroFilter = false; + this.sliderDTermFilter = false; - if (parseInt($('.pid_filter input[name="gyroLowpassDynMinFrequency"]').val(), 10) !== Math.round(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz * this.gyroFilterSliderValue) || - parseInt($('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').val(), 10) !== Math.round(this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz * this.gyroFilterSliderValue) || - parseInt($('.pid_filter select[name="gyroLowpassDynType"]').val(), 10) !== this.FILTER_DEFAULT.gyro_lowpass_type || - parseInt($('.pid_filter input[name="gyroLowpass2Frequency"]').val(), 10) !== Math.round(this.FILTER_DEFAULT.gyro_lowpass2_hz * this.gyroFilterSliderValue) || - parseInt($('.pid_filter select[name="gyroLowpass2Type"]').val(), 10) !== this.FILTER_DEFAULT.gyro_lowpass2_type) { + if ($('.pid_filter input[name="gyroLowpassDynMinFrequency"]').val() !== Math.floor(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz * this.sliderGyroFilterMultiplier) || + $('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').val() !== Math.floor(this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz * this.sliderGyroFilterMultiplier) || + $('.pid_filter select[name="gyroLowpassDynType"]').val() !== this.FILTER_DEFAULT.gyro_lowpass_type || + $('.pid_filter input[name="gyroLowpass2Frequency"]').val() !== Math.floor(this.FILTER_DEFAULT.gyro_lowpass2_hz * this.sliderGyroFilterMultiplier) || + $('.pid_filter select[name="gyroLowpass2Type"]').val() !== this.FILTER_DEFAULT.gyro_lowpass2_type) { - $('.tuningFilterSliders .sliderLabels tr:nth-child(2)').hide(); - this.filterGyroSliderUnavailable = true; + $('.tuningFilterSliders .sliderLabels tr:first-child').hide(); + this.sliderGyroFilter = true; } else { $('.tuningFilterSliders .sliderLabels tr:nth-child(2)').show() this.cachedGyroSliderValues = true; } - if (parseInt($('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val(), 10) !== Math.round(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz * this.dtermFilterSliderValue) || - parseInt($('.pid_filter input[name="dtermLowpassDynMaxFrequency"]').val(), 10) !== Math.round(this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz * this.dtermFilterSliderValue) || - parseInt($('.pid_filter select[name="dtermLowpassDynType"]').val(), 10) !== this.FILTER_DEFAULT.dterm_lowpass_type || - parseInt($('.pid_filter input[name="dtermLowpass2Frequency"]').val(), 10) !== Math.round(this.FILTER_DEFAULT.dterm_lowpass2_hz * this.dtermFilterSliderValue) || - parseInt($('.pid_filter select[name="dtermLowpass2Type"]').val(), 10) !== this.FILTER_DEFAULT.dterm_lowpass2_type) { + if ($('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val() !== Math.floor(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz * this.sliderDTermFilterMultiplier) || + $('.pid_filter input[name="dtermLowpassDynMaxFrequency"]').val() !== Math.floor(this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz * this.sliderDTermFilterMultiplier) || + $('.pid_filter select[name="dtermLowpassDynType"]').val() !== this.FILTER_DEFAULT.dterm_lowpass_type || + $('.pid_filter input[name="dtermLowpass2Frequency"]').val() !== Math.floor(this.FILTER_DEFAULT.dterm_lowpass2_hz * this.sliderDTermFilterMultiplier) || + $('.pid_filter select[name="dtermLowpass2Type"]').val() !== this.FILTER_DEFAULT.dterm_lowpass2_type) { $('.tuningFilterSliders .sliderLabels tr:last-child').hide(); - this.filterDTermSliderUnavailable = true; + this.sliderDTermFilter = true; } else { $('.tuningFilterSliders .sliderLabels tr:last-child').show(); this.cachedDTermSliderValues = true; } - $('.tuningFilterSliders').toggle(!(this.filterGyroSliderUnavailable && this.filterDTermSliderUnavailable)); - $('.subtab-filter .slidersDisabled').toggle(this.filterGyroSliderUnavailable || this.filterDTermSliderUnavailable); - $('.subtab-filter .nonExpertModeSlidersNote').toggle((!this.filterGyroSliderUnavailable || !this.filterDTermSliderUnavailable) && !this.expertMode); - $('.subtab-filter .slidersWarning').toggle(((this.gyroFilterSliderValue >= WARNING_FILTER_HIGH_GAIN || - this.gyroFilterSliderValue <= WARNING_FILTER_LOW_GAIN) && !this.filterGyroSliderUnavailable) || - ((this.dtermFilterSliderValue >= WARNING_FILTER_HIGH_GAIN || - this.dtermFilterSliderValue <= WARNING_FILTER_LOW_GAIN) && !this.filterDTermSliderUnavailable)); + $('.tuningFilterSliders').toggle(!(this.sliderGyroFilter && this.sliderDTermFilter)); + $('.subtab-filter .slidersDisabled').toggle(this.sliderGyroFilter || this.sliderDTermFilter); + $('.subtab-filter .nonExpertModeSlidersNote').toggle((!this.sliderGyroFilter || !this.sliderDTermFilter) && !this.expertMode); + $('.subtab-filter .slidersWarning').toggle(((this.sliderGyroFilterMultiplier >= WARNING_FILTER_HIGH_GAIN || + this.sliderGyroFilterMultiplier <= WARNING_FILTER_LOW_GAIN) && !this.sliderGyroFilter) || + ((this.sliderDTermFilterMultiplier >= WARNING_FILTER_HIGH_GAIN || + this.sliderDTermFilterMultiplier <= WARNING_FILTER_LOW_GAIN) && !this.sliderDTermFilter)); }; -TuningSliders.calculateNewPids = function() { - // 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 +TuningSliders.updateFormPids = function() { + FC.PID_NAMES.forEach(function(elementPid, indexPid) { + const pidElements = $(`.pid_tuning .${elementPid} input`); + pidElements.each(function (indexInput) { + if (indexPid < 3 && indexInput < 3) { + $(this).val(FC.PIDS[indexPid][indexInput]); + } + }); + }); +}; + +TuningSliders.legacyCalculateNewPids = function() { const MAX_PID_GAIN = 200; const MAX_DMIN_GAIN = 100; const MAX_FF_GAIN = 2000; + // only used for 4.1 where calculation is not done in firmware if (this.dMinFeatureEnabled) { //dmin - FC.ADVANCED_TUNING.dMinRoll = Math.round(this.PID_DEFAULT[3] * this.PDGainSliderValue * this.PDRatioSliderValue); - FC.ADVANCED_TUNING.dMinPitch = Math.round(this.PID_DEFAULT[8] * this.PDGainSliderValue * this.PDRatioSliderValue); + FC.ADVANCED_TUNING.dMinRoll = Math.floor(this.PID_DEFAULT[3] * this.sliderPDGain); + FC.ADVANCED_TUNING.dMinPitch = Math.floor(this.PID_DEFAULT[8] * this.sliderPDGain); // dmax - FC.PIDS[0][2] = Math.round(this.PID_DEFAULT[2] * this.PDGainSliderValue * this.PDRatioSliderValue); - FC.PIDS[1][2] = Math.round(this.PID_DEFAULT[7] * this.PDGainSliderValue * this.PDRatioSliderValue); + FC.PIDS[0][2] = Math.floor(this.PID_DEFAULT[2] * this.sliderPDGain); + FC.PIDS[1][2] = Math.floor(this.PID_DEFAULT[7] * this.sliderPDGain); } else { FC.ADVANCED_TUNING.dMinRoll = 0; FC.ADVANCED_TUNING.dMinPitch = 0; - FC.PIDS[0][2] = Math.round((this.PID_DEFAULT[2] * D_MIN_RATIO) * this.PDGainSliderValue * this.PDRatioSliderValue); - FC.PIDS[1][2] = Math.round((this.PID_DEFAULT[7] * D_MIN_RATIO) * this.PDGainSliderValue * this.PDRatioSliderValue); + FC.PIDS[0][2] = Math.floor(this.PID_DEFAULT[3] * this.sliderPDGain); + FC.PIDS[1][2] = Math.floor(this.PID_DEFAULT[8] * this.sliderPDGain); } - // p - FC.PIDS[0][0] = Math.round(this.PID_DEFAULT[0] * this.PDGainSliderValue); - FC.PIDS[1][0] = Math.round(this.PID_DEFAULT[5] * this.PDGainSliderValue); - FC.PIDS[2][0] = Math.round(this.PID_DEFAULT[10] * this.PDGainSliderValue); - // ff - FC.ADVANCED_TUNING.feedforwardRoll = Math.round(this.PID_DEFAULT[4] * this.ResponseSliderValue); - FC.ADVANCED_TUNING.feedforwardPitch = Math.round(this.PID_DEFAULT[9] * this.ResponseSliderValue); - FC.ADVANCED_TUNING.feedforwardYaw = Math.round(this.PID_DEFAULT[14] * this.ResponseSliderValue); + + FC.PIDS[0][0] = Math.floor(FC.PIDS[0][2] * this.PID_DEFAULT[0] / this.PID_DEFAULT[2] * this.sliderPDRatio); + FC.PIDS[1][0] = Math.floor(FC.PIDS[1][2] * this.PID_DEFAULT[5] / this.PID_DEFAULT[7] * this.sliderPDRatio); + FC.PIDS[2][0] = Math.floor(this.PID_DEFAULT[10] * this.sliderPDGain); // master slider part // these are not calculated anywhere other than master slider multiplier therefore set at default before every calculation @@ -284,32 +324,65 @@ TuningSliders.calculateNewPids = function() { //master slider multiplication, max value 200 for main PID values for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { - FC.PIDS[j][i] = Math.min(Math.round(FC.PIDS[j][i] * this.MasterSliderValue), MAX_PID_GAIN); + FC.PIDS[j][i] = Math.min(Math.floor(FC.PIDS[j][i] * this.sliderMasterMultiplier), MAX_PID_GAIN); } } - FC.ADVANCED_TUNING.feedforwardRoll = Math.min(Math.round(FC.ADVANCED_TUNING.feedforwardRoll * this.MasterSliderValue), MAX_FF_GAIN); - FC.ADVANCED_TUNING.feedforwardPitch = Math.min(Math.round(FC.ADVANCED_TUNING.feedforwardPitch * this.MasterSliderValue), MAX_FF_GAIN); - FC.ADVANCED_TUNING.feedforwardYaw = Math.min(Math.round(FC.ADVANCED_TUNING.feedforwardYaw * this.MasterSliderValue), MAX_FF_GAIN); + // ff + FC.ADVANCED_TUNING.feedforwardRoll = Math.min(Math.floor(this.PID_DEFAULT[4] * this.sliderFFGain * this.sliderMasterMultiplier), MAX_FF_GAIN); + FC.ADVANCED_TUNING.feedforwardPitch = Math.min(Math.floor(this.PID_DEFAULT[9] * this.sliderFFGain * this.sliderMasterMultiplier), MAX_FF_GAIN); + FC.ADVANCED_TUNING.feedforwardYaw = Math.min(Math.floor(this.PID_DEFAULT[14] * this.sliderFFGain * this.sliderMasterMultiplier), MAX_FF_GAIN); if (this.dMinFeatureEnabled) { - FC.ADVANCED_TUNING.dMinRoll = Math.min(Math.round(FC.ADVANCED_TUNING.dMinRoll * this.MasterSliderValue), MAX_DMIN_GAIN); - FC.ADVANCED_TUNING.dMinPitch = Math.min(Math.round(FC.ADVANCED_TUNING.dMinPitch * this.MasterSliderValue), MAX_DMIN_GAIN); - FC.ADVANCED_TUNING.dMinYaw = Math.min(Math.round(FC.ADVANCED_TUNING.dMinYaw * this.MasterSliderValue), MAX_DMIN_GAIN); + FC.ADVANCED_TUNING.dMinRoll = Math.min(Math.floor(FC.ADVANCED_TUNING.dMinRoll * this.sliderMasterMultiplier), MAX_DMIN_GAIN); + FC.ADVANCED_TUNING.dMinPitch = Math.min(Math.floor(FC.ADVANCED_TUNING.dMinPitch * this.sliderMasterMultiplier), MAX_DMIN_GAIN); + FC.ADVANCED_TUNING.dMinYaw = Math.min(Math.floor(FC.ADVANCED_TUNING.dMinYaw * this.sliderMasterMultiplier), MAX_DMIN_GAIN); } - $('output[name="tuningMasterSlider-number"]').val(this.MasterSliderValue); - $('output[name="tuningPDRatioSlider-number"]').val(this.PDRatioSliderValue); - $('output[name="tuningPDGainSlider-number"]').val(this.PDGainSliderValue); - $('output[name="tuningResponseSlider-number"]').val(this.ResponseSliderValue); + this.updateFormPids(); + + $('.pid_tuning input[name="dMinRoll"]').val(FC.ADVANCED_TUNING.dMinRoll); + $('.pid_tuning input[name="dMinPitch"]').val(FC.ADVANCED_TUNING.dMinPitch); + $('.pid_tuning input[name="dMinYaw"]').val(FC.ADVANCED_TUNING.dMinYaw); + $('.pid_tuning .ROLL input[name="f"]').val(FC.ADVANCED_TUNING.feedforwardRoll); + $('.pid_tuning .PITCH input[name="f"]').val(FC.ADVANCED_TUNING.feedforwardPitch); + $('.pid_tuning .YAW input[name="f"]').val(FC.ADVANCED_TUNING.feedforwardYaw); +}; + +TuningSliders.calculateNewPids = function() { + // 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.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { + this.legacyCalculateNewPids(); + } + + $('output[name="sliderMasterMultiplier-number"]').val(this.sliderMasterMultiplier); + $('output[name="sliderRollPitchRatio-number"]').val(this.sliderRollPitchRatio); + $('output[name="sliderIGain-number"]').val(this.sliderIGain); + $('output[name="sliderPDRatio-number"]').val(this.sliderPDRatio); + $('output[name="sliderPDGain-number"]').val(this.sliderPDGain); + $('output[name="sliderDMinRatio-number"]').val(this.sliderDMinRatio); + $('output[name="sliderFFGain-number"]').val(this.sliderFFGain); + + FC.TUNING_SLIDERS.slider_pids_mode = parseInt($('#sliderPidsModeSelect').val()); + FC.TUNING_SLIDERS.slider_master_multiplier = TuningSliders.sliderMasterMultiplier * 100; + FC.TUNING_SLIDERS.slider_roll_pitch_ratio = TuningSliders.sliderRollPitchRatio * 100; + FC.TUNING_SLIDERS.slider_i_gain = TuningSliders.sliderIGain * 100; + FC.TUNING_SLIDERS.slider_pd_ratio = TuningSliders.sliderPDRatio * 100; + FC.TUNING_SLIDERS.slider_pd_gain = TuningSliders.sliderPDGain * 100; + FC.TUNING_SLIDERS.slider_dmin_ratio = TuningSliders.sliderDMinRatio * 100; + FC.TUNING_SLIDERS.slider_ff_gain = TuningSliders.sliderFFGain * 100; + + FC.TUNING_SLIDERS.slider_dterm_filter = TuningSliders.sliderDTermFilter ? 1 : 0; + FC.TUNING_SLIDERS.slider_dterm_filter_multiplier = TuningSliders.sliderDTermFilterMultiplier * 100; + + FC.TUNING_SLIDERS.slider_gyro_filter = TuningSliders.sliderGyroFilter ? 1 : 0; + FC.TUNING_SLIDERS.slider_gyro_filter_multiplier = TuningSliders.sliderGyroFilterMultiplier * 100; + + MSP.promise(MSPCodes.MSP_SET_TUNING_SLIDERS, mspHelper.crunch(MSPCodes.MSP_SET_TUNING_SLIDERS)); + MSP.send_message(MSPCodes.MSP_PID); + MSP.send_message(MSPCodes.MSP_PID_ADVANCED); + + this.updateFormPids(); - // updates values in forms - FC.PID_NAMES.forEach(function(elementPid, indexPid) { - let searchRow = $('.pid_tuning .' + elementPid + ' input'); - searchRow.each(function (indexInput) { - if (indexPid < 3 && indexInput < 3) { - $(this).val(FC.PIDS[indexPid][indexInput]); - } - }); - }); $('.pid_tuning input[name="dMinRoll"]').val(FC.ADVANCED_TUNING.dMinRoll); $('.pid_tuning input[name="dMinPitch"]').val(FC.ADVANCED_TUNING.dMinPitch); $('.pid_tuning input[name="dMinYaw"]').val(FC.ADVANCED_TUNING.dMinYaw); @@ -322,9 +395,9 @@ TuningSliders.calculateNewPids = function() { TuningSliders.calculateNewGyroFilters = function() { // calculate, set and display new values in forms based on slider position - FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz = Math.round(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz * this.gyroFilterSliderValue); - FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz = Math.round(this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz * this.gyroFilterSliderValue); - FC.FILTER_CONFIG.gyro_lowpass2_hz = Math.round(this.FILTER_DEFAULT.gyro_lowpass2_hz * this.gyroFilterSliderValue); + 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_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; @@ -333,14 +406,14 @@ TuningSliders.calculateNewGyroFilters = function() { $('.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="tuningGyroFilterSlider-number"]').val(this.gyroFilterSliderValue); + $('output[name="sliderGyroFilterMultiplier-number"]').val(this.sliderGyroFilterMultiplier); }; TuningSliders.calculateNewDTermFilters = 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.dtermFilterSliderValue); - FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz = Math.round(this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz * this.dtermFilterSliderValue); - FC.FILTER_CONFIG.dterm_lowpass2_hz = Math.round(this.FILTER_DEFAULT.dterm_lowpass2_hz * this.dtermFilterSliderValue); + FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz = Math.floor(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz * this.sliderDTermFilterMultiplier); + FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz = Math.floor(this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz * this.sliderDTermFilterMultiplier); + FC.FILTER_CONFIG.dterm_lowpass2_hz = Math.floor(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; @@ -349,5 +422,5 @@ TuningSliders.calculateNewDTermFilters = function() { $('.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 select[name="dtermLowpass2Type').val(FC.FILTER_CONFIG.dterm_lowpass2_type); - $('output[name="tuningDTermFilterSlider-number"]').val(this.dtermFilterSliderValue); + $('output[name="sliderDTermFilterMultiplier-number"]').val(this.sliderDTermFilterMultiplier); }; diff --git a/src/js/fc.js b/src/js/fc.js index d55452f2..ec37fe36 100644 --- a/src/js/fc.js +++ b/src/js/fc.js @@ -148,6 +148,7 @@ const FC = { SERVO_DATA: null, SERVO_RULES: null, TRANSPONDER: null, + TUNING_SLIDERS: null, VOLTAGE_METERS: null, VOLTAGE_METER_CONFIGS: null, VTXTABLE_BAND: null, @@ -648,6 +649,21 @@ const FC = { ]; this.VTX_DEVICE_STATUS = null; + + this.TUNING_SLIDERS = { + slider_pids_mode: 0, + slider_master_multiplier: 0, + slider_roll_pitch_ratio: 0, + slider_i_gain: 0, + slider_pd_ratio: 0, + slider_pd_gain: 0, + slider_dmin_ratio: 0, + slider_ff_gain: 0, + slider_dterm_filter: 0, + slider_dterm_filter_multiplier: 0, + slider_gyro_filter: 0, + slider_gyro_filter_multiplier: 0, + }; }, getSerialRxTypes: () => { diff --git a/src/js/main.js b/src/js/main.js index ab064dbd..c44ec69f 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -502,6 +502,8 @@ function startProcess() { if (FC.FEATURE_CONFIG && FC.FEATURE_CONFIG.features !== 0) { updateTabList(FC.FEATURE_CONFIG.features); } + + TuningSliders.setExpertMode(checked); }).change(); }); diff --git a/src/js/msp/MSPCodes.js b/src/js/msp/MSPCodes.js index 9d36bbd1..385475da 100644 --- a/src/js/msp/MSPCodes.js +++ b/src/js/msp/MSPCodes.js @@ -117,6 +117,9 @@ const MSPCodes = { MSP_MOTOR_TELEMETRY: 139, + MSP_TUNING_SLIDERS: 140, + MSP_SET_TUNING_SLIDERS: 141, + MSP_STATUS_EX: 150, MSP_UID: 160, diff --git a/src/js/msp/MSPHelper.js b/src/js/msp/MSPHelper.js index 6dd2a844..a12c9a92 100644 --- a/src/js/msp/MSPHelper.js +++ b/src/js/msp/MSPHelper.js @@ -1475,6 +1475,26 @@ MspHelper.prototype.process_data = function(dataHandler) { break; + case MSPCodes.MSP_SET_TUNING_SLIDERS: + console.log("Tuning Sliders data 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_pd_ratio = data.readU8(); + FC.TUNING_SLIDERS.slider_pd_gain = data.readU8(); + FC.TUNING_SLIDERS.slider_dmin_ratio = data.readU8(); + FC.TUNING_SLIDERS.slider_ff_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_SET_VTXTABLE_POWERLEVEL: console.log("VTX powerlevel sent"); break; @@ -2274,6 +2294,22 @@ 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_pd_ratio) + .push8(FC.TUNING_SLIDERS.slider_pd_gain) + .push8(FC.TUNING_SLIDERS.slider_dmin_ratio) + .push8(FC.TUNING_SLIDERS.slider_ff_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: return false; } diff --git a/src/js/tabs/pid_tuning.js b/src/js/tabs/pid_tuning.js index e3a53436..40a516b6 100644 --- a/src/js/tabs/pid_tuning.js +++ b/src/js/tabs/pid_tuning.js @@ -46,7 +46,7 @@ TABS.pid_tuning.initialize = function (callback) { return MSP.promise(MSPCodes.MSP_PID); }).then(function() { if (semver.gte(FC.CONFIG.apiVersion, "1.16.0")) { - return MSP.promise(MSPCodes.MSP_PID_ADVANCED); + return MSP.promise(MSPCodes.MSP_PID_ADVANCED); } }).then(function() { return MSP.promise(MSPCodes.MSP_RC_TUNING); @@ -56,6 +56,13 @@ TABS.pid_tuning.initialize = function (callback) { return MSP.promise(MSPCodes.MSP_RC_DEADBAND); }).then(function() { return MSP.promise(MSPCodes.MSP_MOTOR_CONFIG); + }).then(function() { + let promise; + if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { + promise = MSP.promise(MSPCodes.MSP_TUNING_SLIDERS); + } + + return promise; }).then(function() { MSP.send_message(MSPCodes.MSP_MIXER_CONFIG, false, false, load_html); }); @@ -973,6 +980,23 @@ TABS.pid_tuning.initialize = function (callback) { 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; } + + if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { + FC.TUNING_SLIDERS.slider_pids_mode = parseInt($('#sliderPidsModeSelect').val()); + FC.TUNING_SLIDERS.slider_master_multiplier = TuningSliders.sliderMasterMultiplier * 100; + FC.TUNING_SLIDERS.slider_roll_pitch_ratio = TuningSliders.sliderRollPitchRatio * 100; + FC.TUNING_SLIDERS.slider_i_gain = TuningSliders.sliderIGain * 100; + FC.TUNING_SLIDERS.slider_pd_ratio = TuningSliders.sliderPDRatio * 100; + FC.TUNING_SLIDERS.slider_pd_gain = TuningSliders.sliderPDGain * 100; + FC.TUNING_SLIDERS.slider_dmin_ratio = TuningSliders.sliderDMinRatio * 100; + FC.TUNING_SLIDERS.slider_ff_gain = TuningSliders.sliderFFGain * 100; + + FC.TUNING_SLIDERS.slider_dterm_filter = TuningSliders.sliderDTermFilter ? 1 : 0; + FC.TUNING_SLIDERS.slider_dterm_filter_multiplier = TuningSliders.sliderDTermFilterMultiplier * 100; + + FC.TUNING_SLIDERS.slider_gyro_filter = TuningSliders.sliderGyroFilter ? 1 : 0; + FC.TUNING_SLIDERS.slider_gyro_filter_multiplier = TuningSliders.sliderGyroFilterMultiplier * 100; + } } function showAllPids() { @@ -1774,41 +1798,23 @@ TABS.pid_tuning.initialize = function (callback) { const NON_EXPERT_SLIDER_MAX = 1.25; const NON_EXPERT_SLIDER_MIN = 0.7; - $('input[name="expertModeCheckbox"]').change(function() { - if (TuningSliders.expertMode !== $(this).is(':checked')) { - TuningSliders.setExpertMode($(this).is(':checked')); - TuningSliders.updatePidSlidersDisplay(); - TuningSliders.updateFilterSlidersDisplay(); - } - }); + const SLIDER_STEP_LOWER = semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_43) ? 0.005 : 0.05; + const SLIDER_STEP_UPPER = semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_43) ? 0.01 : 0.1; + + $('#sliderPidsModeSelect').val(FC.TUNING_SLIDERS.slider_pids_mode); - $('#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(); - } - }); // integrated yaw doesn't work with sliders therefore sliders are disabled $('input[id="useIntegratedYaw"]').change(() => TuningSliders.updatePidSlidersDisplay()); - // pid sliders inputs - $('#tuningMasterSlider, #tuningPDRatioSlider, #tuningPDGainSlider, #tuningResponseSlider').on('input', function() { + const allPidTuningSliders = $('#sliderMasterMultiplier, #sliderRollPitchRatio, #sliderIGain, #sliderPDRatio, #sliderPDGain, #sliderDMinRatio, #sliderFFGain'); + + allPidTuningSliders.on('input', function() { const slider = $(this); // adjust step for more smoothness above 1x if (slider.val() >= 1) { - slider.attr('step', 0.05); + slider.attr('step', SLIDER_STEP_LOWER); } else { - slider.attr('step', 0.1); + slider.attr('step', SLIDER_STEP_UPPER); } if (!TuningSliders.expertMode) { if (slider.val() > NON_EXPERT_SLIDER_MAX) { @@ -1818,28 +1824,25 @@ TABS.pid_tuning.initialize = function (callback) { } } const scaledValue = TuningSliders.scaleSliderValue(slider.val()); - if (slider.is('#tuningMasterSlider')) { - TuningSliders.MasterSliderValue = scaledValue; - } else if (slider.is('#tuningPDRatioSlider')) { - TuningSliders.PDRatioSliderValue = scaledValue; - } else if (slider.is('#tuningPDGainSlider')) { - TuningSliders.PDGainSliderValue = scaledValue; - } else if (slider.is('#tuningResponseSlider')) { - TuningSliders.ResponseSliderValue = scaledValue; + if (slider.is('#sliderMasterMultiplier')) { + TuningSliders.sliderMasterMultiplier = scaledValue; + } else if (slider.is('#sliderRollPitchRatio')) { + TuningSliders.sliderRollPitchRatio = scaledValue; + } else if (slider.is('#sliderIGain')) { + TuningSliders.sliderIGain = scaledValue; + } else if (slider.is('#sliderPDRatio')) { + TuningSliders.sliderPDRatio = scaledValue; + } else if (slider.is('#sliderPDGain')) { + TuningSliders.sliderPDGain = scaledValue; + } else if (slider.is('#sliderDMinRatio')) { + TuningSliders.sliderDMinRatio = scaledValue; + } else if (slider.is('#sliderFFGain')) { + TuningSliders.sliderFFGain = scaledValue; } TuningSliders.calculateNewPids(); self.analyticsChanges['PidTuningSliders'] = "On"; }); - $('#tuningMasterSlider, #tuningPDRatioSlider, #tuningPDGainSlider, #tuningResponseSlider').mousedown(function() { - // adjust step for more smoothness above 1x on mousedown - const slider = $(this); - if (slider.val() >= 1) { - slider.attr('step', 0.05); - } else { - slider.attr('step', 0.1); - } - }); - $('#tuningMasterSlider, #tuningPDRatioSlider, #tuningPDGainSlider, #tuningResponseSlider').mouseup(function() { + allPidTuningSliders.mouseup(function() { // readjust dmin maximums $('.pid_tuning .ROLL input[name="d"]').change(); $('.pid_tuning .PITCH input[name="d"]').change(); @@ -1847,17 +1850,23 @@ TABS.pid_tuning.initialize = function (callback) { TuningSliders.updatePidSlidersDisplay(); }); // reset to middle with double click - $('#tuningMasterSlider, #tuningPDRatioSlider, #tuningPDGainSlider, #tuningResponseSlider').dblclick(function() { + allPidTuningSliders.dblclick(function() { const slider = $(this); slider.val(1); - if (slider.is('#tuningMasterSlider')) { - TuningSliders.MasterSliderValue = 1; - } else if (slider.is('#tuningPDRatioSlider')) { - TuningSliders.PDRatioSliderValue = 1; - } else if (slider.is('#tuningPDGainSlider')) { - TuningSliders.PDGainSliderValue = 1; - } else if (slider.is('#tuningResponseSlider')) { - TuningSliders.ResponseSliderValue = 1; + if (slider.is('#sliderMasterMultiplier')) { + TuningSliders.sliderMasterMultiplier = 1; + } else if (slider.is('#sliderRollPitchRatio')) { + TuningSliders.sliderRollPitchRatio = 1; + } else if (slider.is('#sliderIGain')) { + TuningSliders.sliderIGain = 1; + } else if (slider.is('#sliderPDRatio')) { + TuningSliders.sliderPDRatio = 1; + } else if (slider.is('#sliderPDGain')) { + TuningSliders.sliderPDGain = 1; + } else if (slider.is('#sliderDMinRatio')) { + TuningSliders.sliderDMinRatio = 1; + } else if (slider.is('#sliderFFGain')) { + TuningSliders.sliderFFGain = 1; } TuningSliders.calculateNewPids(); TuningSliders.updatePidSlidersDisplay(); @@ -1874,8 +1883,15 @@ TABS.pid_tuning.initialize = function (callback) { }); // filter slider inputs - $('#tuningGyroFilterSlider, #tuningDTermFilterSlider').on('input', function() { + const allFilterTuningSliders = $('#sliderGyroFilterMultiplier, #sliderDTermFilterMultiplier'); + allFilterTuningSliders.on('input', function() { const slider = $(this); + // adjust step for more smoothness above 1x + if (slider.val() >= 1) { + slider.attr('step', SLIDER_STEP_LOWER); + } else { + slider.attr('step', SLIDER_STEP_UPPER); + } if (!TuningSliders.expertMode) { if (slider.val() > NON_EXPERT_SLIDER_MAX) { slider.val(NON_EXPERT_SLIDER_MAX); @@ -1884,35 +1900,35 @@ TABS.pid_tuning.initialize = function (callback) { } } const scaledValue = TuningSliders.scaleSliderValue(slider.val()); - if (slider.is('#tuningGyroFilterSlider')) { - TuningSliders.gyroFilterSliderValue = scaledValue; + if (slider.is('#sliderGyroFilterMultiplier')) { + TuningSliders.sliderGyroFilterMultiplier = scaledValue; TuningSliders.calculateNewGyroFilters(); self.analyticsChanges['GyroFilterTuningSlider'] = "On"; - } else if (slider.is('#tuningDTermFilterSlider')) { - TuningSliders.dtermFilterSliderValue = scaledValue; + } else if (slider.is('#sliderDTermFilterMultiplier')) { + TuningSliders.sliderDTermFilterMultiplier = scaledValue; TuningSliders.calculateNewDTermFilters(); self.analyticsChanges['DTermFilterTuningSlider'] = "On"; } }); - $('#tuningGyroFilterSlider, #tuningDTermFilterSlider').mouseup(function() { + allFilterTuningSliders.mouseup(function() { TuningSliders.updateFilterSlidersDisplay(); }); // reset to middle with double click - $('#tuningGyroFilterSlider, #tuningDTermFilterSlider').dblclick(function() { + allFilterTuningSliders.dblclick(function() { const slider = $(this); slider.val(1); - if (slider.is('#tuningGyroFilterSlider')) { - TuningSliders.gyroFilterSliderValue = 1; + if (slider.is('#sliderGyroFilterMultiplier')) { + TuningSliders.sliderGyroFilterMultiplier = 1; TuningSliders.calculateNewGyroFilters(); - } else if (slider.is('#tuningDTermFilterSlider')) { - TuningSliders.dtermFilterSliderValue = 1; + } else if (slider.is('#sliderDTermFilterMultiplier')) { + TuningSliders.sliderDTermFilterMultiplier = 1; TuningSliders.calculateNewDTermFilters(); } TuningSliders.updateFilterSlidersDisplay(); }); // enable PID sliders button $('a.buttonFilterTuningSliders').click(function() { - if (TuningSliders.filterGyroSliderUnavailable) { + if (TuningSliders.sliderGyroFilter) { // update switchery dynamically based on defaults $('input[id="gyroLowpassDynEnabled"]').prop('checked', false).click(); $('input[id="gyroLowpassEnabled"]').prop('checked', true).click(); @@ -1920,7 +1936,7 @@ TABS.pid_tuning.initialize = function (callback) { TuningSliders.resetGyroFilterSlider(); self.analyticsChanges['GyroFilterTuningSlider'] = "On"; } - if (TuningSliders.filterDTermSliderUnavailable) { + if (TuningSliders.sliderDTermFilter) { $('input[id="dtermLowpassDynEnabled"]').prop('checked', false).click(); $('input[id="dtermLowpassEnabled"]').prop('checked', true).click(); $('input[id="dtermLowpass2Enabled"]').prop('checked', false).click(); @@ -1937,10 +1953,10 @@ 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() { TuningSliders.updateFilterSlidersDisplay(); - if (TuningSliders.filterGyroSliderUnavailable) { + if (TuningSliders.sliderGyroFilter) { self.analyticsChanges['GyroFilterTuningSlider'] = "Off"; } - if (TuningSliders.filterDTermSliderUnavailable) { + if (TuningSliders.sliderDTermFilter) { self.analyticsChanges['DTermFilterTuningSlider'] = "Off"; } }); @@ -1997,6 +2013,13 @@ TABS.pid_tuning.initialize = function (callback) { 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_43)) { + 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 () { diff --git a/src/tabs/pid_tuning.html b/src/tabs/pid_tuning.html index 77df8f7c..0cd978b8 100644 --- a/src/tabs/pid_tuning.html +++ b/src/tabs/pid_tuning.html @@ -169,10 +169,16 @@ -
+
- + @@ -193,10 +199,10 @@ + + + + + + + + + + + + + + + + + +
+ + - + - +
@@ -209,13 +215,41 @@
- + - + - + + +
+
+ + + + + + +
+
+ + + + +
@@ -231,10 +265,10 @@
- + - +
@@ -247,13 +281,27 @@
- + - + - + + +
+
+ + + + +
@@ -1016,7 +1064,7 @@ -
+
@@ -1040,10 +1088,10 @@
- + - +
@@ -1059,10 +1107,10 @@
- + - +