1
0
Fork 0
mirror of https://github.com/betaflight/betaflight-configurator.git synced 2025-07-24 00:35:26 +03:00

Add FW Filter Slider Support-ALL credit to haslinhuis!

This commit is contained in:
UAV Tech 2021-02-28 22:28:48 -05:00
parent e84666eb7c
commit b4afe7231c
3 changed files with 246 additions and 144 deletions

View file

@ -10,10 +10,13 @@ const TuningSliders = {
sliderDMinRatio: 1, sliderDMinRatio: 1,
sliderFFGain: 1, sliderFFGain: 1,
pidSlidersUnavailable: false, pidSlidersUnavailable: false,
GyroSliderUnavailable: false,
DTermSliderUnavailable: false,
FilterReset: false,
sliderGyroFilter: 0, sliderGyroFilter: 1,
sliderGyroFilterMultiplier: 1, sliderGyroFilterMultiplier: 1,
sliderDTermFilter: 0, sliderDTermFilter: 1,
sliderDTermFilterMultiplier: 1, sliderDTermFilterMultiplier: 1,
dMinFeatureEnabled: true, dMinFeatureEnabled: true,
@ -93,7 +96,7 @@ TuningSliders.downscaleSliderValue = function(value) {
}; };
TuningSliders.initPidSlidersPosition = function() { TuningSliders.initPidSlidersPosition = function() {
if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
// used to estimate PID slider positions based on PIDF values, and set respective slider position // 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 // provides only an estimation due to limitation of feature without firmware support, to be improved in later versions
this.sliderMasterMultiplier = Math.round(FC.PIDS[2][1] / this.PID_DEFAULT[11] * 10) / 10; this.sliderMasterMultiplier = Math.round(FC.PIDS[2][1] / this.PID_DEFAULT[11] * 10) / 10;
@ -133,10 +136,11 @@ TuningSliders.initPidSlidersPosition = function() {
}; };
TuningSliders.initGyroFilterSliderPosition = function() { TuningSliders.initGyroFilterSliderPosition = function() {
if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
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.sliderGyroFilterMultiplier = Math.floor((FC.FILTER_CONFIG.gyro_lowpass_dyn_min_hz + FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz + FC.FILTER_CONFIG.gyro_lowpass2_hz) /
(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz + this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz + this.FILTER_DEFAULT.gyro_lowpass2_hz) * 100) / 100; (this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz + this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz + this.FILTER_DEFAULT.gyro_lowpass2_hz) * 100) / 100;
} else { } else {
this.sliderGyroFilter = FC.TUNING_SLIDERS.slider_gyro_filter;
this.sliderGyroFilterMultiplier = FC.TUNING_SLIDERS.slider_gyro_filter_multiplier / 100; this.sliderGyroFilterMultiplier = FC.TUNING_SLIDERS.slider_gyro_filter_multiplier / 100;
} }
@ -145,10 +149,11 @@ TuningSliders.initGyroFilterSliderPosition = function() {
}; };
TuningSliders.initDTermFilterSliderPosition = function() { TuningSliders.initDTermFilterSliderPosition = function() {
if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
this.sliderDTermFilterMultiplier = Math.floor((FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz + FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz + FC.FILTER_CONFIG.dterm_lowpass2_hz) / this.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; (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 { } else {
this.sliderDTermFilter = FC.TUNING_SLIDERS.slider_dterm_filter;
this.sliderDTermFilterMultiplier = FC.TUNING_SLIDERS.slider_dterm_filter_multiplier / 100; this.sliderDTermFilterMultiplier = FC.TUNING_SLIDERS.slider_dterm_filter_multiplier / 100;
} }
@ -167,7 +172,7 @@ TuningSliders.resetPidSliders = function() {
this.sliderFFGain = 1; this.sliderFFGain = 1;
} }
if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
$('#sliderMasterMultiplier').val(this.downscaleSliderValue(this.sliderMasterMultiplier)); $('#sliderMasterMultiplier').val(this.downscaleSliderValue(this.sliderMasterMultiplier));
$('#sliderPDRatio').val(this.downscaleSliderValue(this.sliderPDRatio)); $('#sliderPDRatio').val(this.downscaleSliderValue(this.sliderPDRatio));
$('#sliderPDGain').val(this.downscaleSliderValue(this.sliderPDGain)); $('#sliderPDGain').val(this.downscaleSliderValue(this.sliderPDGain));
@ -177,37 +182,74 @@ TuningSliders.resetPidSliders = function() {
} }
this.calculateNewPids(); this.calculateNewPids();
this.updatePidSlidersDisplay();
}; };
TuningSliders.resetGyroFilterSlider = function() { TuningSliders.resetGyroFilterSlider = function() {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
if (!this.cachedGyroSliderValues) { if (!this.cachedGyroSliderValues) {
this.sliderGyroFilterMultiplier = 1; this.sliderGyroFilterMultiplier = 1;
} }
this.sliderGyroFilter = 1;
if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { FC.TUNING_SLIDERS.slider_gyro_filter = 1;
$('#sliderGyroFilterMultiplier').val(this.downscaleSliderValue(this.sliderGyroFilterMultiplier));
} else {
this.initGyroFilterSliderPosition(); this.initGyroFilterSliderPosition();
} else {
this.sliderGyroFilterMultiplier = 1;
$('#sliderGyroFilterMultiplier').val(this.downscaleSliderValue(this.sliderGyroFilterMultiplier));
} }
this.FilterReset = true;
this.calculateNewGyroFilters(); this.calculateNewGyroFilters();
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
this.updateFilterSlidersDisplay(); this.updateFilterSlidersDisplay();
}
}; };
TuningSliders.resetDTermFilterSlider = function() { TuningSliders.resetDTermFilterSlider = function() {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
if (!this.cachedDTermSliderValues) { if (!this.cachedDTermSliderValues) {
this.sliderDTermFilterMultiplier = 1; this.sliderDTermFilterMultiplier = 1;
} }
this.sliderDtermFilter = 1;
if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { FC.TUNING_SLIDERS.slider_dterm_filter = 1;
$('#sliderDTermFilterMultiplier').val(this.downscaleSliderValue(this.sliderDTermFilterMultiplier));
} else {
this.initDTermFilterSliderPosition(); this.initDTermFilterSliderPosition();
} else {
this.sliderDTermFilterMultiplier = 1;
$('#sliderDTermFilterMultiplier').val(this.downscaleSliderValue(this.sliderDTermFilterMultiplier));
}
this.FilterReset = true;
this.calculateNewDTermFilters();
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
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="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;
} }
this.calculateNewDTermFilters(); if (parseInt($('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val()) !==
this.updateFilterSlidersDisplay(); 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="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;
}
}; };
TuningSliders.updatePidSlidersDisplay = function() { TuningSliders.updatePidSlidersDisplay = function() {
@ -229,7 +271,7 @@ TuningSliders.updatePidSlidersDisplay = function() {
}); });
}); });
if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
this.calculateNewPids(); this.calculateNewPids();
} }
@ -272,48 +314,68 @@ TuningSliders.updateFilterSlidersDisplay = function() {
const WARNING_FILTER_HIGH_GAIN = 1.4; const WARNING_FILTER_HIGH_GAIN = 1.4;
const WARNING_FILTER_LOW_GAIN = 0.7; const WARNING_FILTER_LOW_GAIN = 0.7;
this.sliderGyroFilter = false; this.GyroSliderUnavailable = false;
this.sliderDTermFilter = false; this.DTermSliderUnavailable = false;
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
if (FC.TUNING_SLIDERS.slider_gyro_filter === 0) {
this.GyroSliderUnavailable = true;
}
if (FC.TUNING_SLIDERS.slider_dterm_filter === 0) {
this.DTermSliderUnavailable = true;
}
if (parseInt($('.pid_filter input[name="gyroLowpassDynMinFrequency"]').val()) !== if (parseInt($('.pid_filter input[name="gyroLowpassDynMinFrequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz * this.sliderGyroFilterMultiplier) || Math.round(this.FILTER_DEFAULT.gyro_lowpass_dyn_min_hz * this.sliderGyroFilterMultiplier) ||
parseInt($('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').val()) !== parseInt($('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz * this.sliderGyroFilterMultiplier) || 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 select[name="gyroLowpassDynType"]').val()) !== this.FILTER_DEFAULT.gyro_lowpass_type ||
parseInt($('.pid_filter input[name="gyroLowpass2Frequency"]').val()) !== parseInt($('.pid_filter input[name="gyroLowpass2Frequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.gyro_lowpass2_hz * this.sliderGyroFilterMultiplier) || Math.floor(this.FILTER_DEFAULT.gyro_lowpass2_hz * this.sliderGyroFilterMultiplier) ||
parseInt($('.pid_filter select[name="gyroLowpass2Type"]').val()) !== this.FILTER_DEFAULT.gyro_lowpass2_type) { parseInt($('.pid_filter select[name="gyroLowpass2Type"]').val()) !== this.FILTER_DEFAULT.gyro_lowpass2_type) {
this.GyroSliderUnavailable = true;
$('.tuningFilterSliders .sliderLabels tr:nth-child(2)').hide(); this.sliderGyroFilter = 0;
this.sliderGyroFilter = true;
} else { } else {
$('.tuningFilterSliders .sliderLabels tr:nth-child(2)').show();
this.cachedGyroSliderValues = true; this.cachedGyroSliderValues = true;
this.sliderGyroFilter = 1;
} }
if (parseInt($('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val()) !== if (parseInt($('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz * this.sliderDTermFilterMultiplier) || Math.floor(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz * this.sliderDTermFilterMultiplier) ||
parseInt($('.pid_filter input[name="dtermLowpassDynMaxFrequency"]').val()) !== Math.abs(parseInt($('.pid_filter input[name="dtermLowpassDynMaxFrequency"]').val()) - this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz * this.sliderDTermFilterMultiplier) > 1 ||
Math.floor(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 select[name="dtermLowpassDynType"]').val()) !== this.FILTER_DEFAULT.dterm_lowpass_type ||
parseInt($('.pid_filter input[name="dtermLowpass2Frequency"]').val()) !== parseInt($('.pid_filter input[name="dtermLowpass2Frequency"]').val()) !==
Math.floor(this.FILTER_DEFAULT.dterm_lowpass2_hz * this.sliderDTermFilterMultiplier) || Math.floor(this.FILTER_DEFAULT.dterm_lowpass2_hz * this.sliderDTermFilterMultiplier) ||
parseInt($('.pid_filter select[name="dtermLowpass2Type"]').val()) !== this.FILTER_DEFAULT.dterm_lowpass2_type) { parseInt($('.pid_filter select[name="dtermLowpass2Type"]').val()) !== this.FILTER_DEFAULT.dterm_lowpass2_type) {
this.DTermSliderUnavailable = true;
$('.tuningFilterSliders .sliderLabels tr:last-child').hide(); this.sliderDTermFilter = 0;
this.sliderDTermFilter = true;
} else { } else {
$('.tuningFilterSliders .sliderLabels tr:last-child').show();
this.cachedDTermSliderValues = true; this.cachedDTermSliderValues = true;
this.sliderDTermFilter = 1;
}
} else {
this.legacyUpdateFilterSlidersDisplay();
} }
$('.tuningFilterSliders').toggle(!(this.sliderGyroFilter && this.sliderDTermFilter));
$('.subtab-filter .slidersDisabled').toggle(this.sliderGyroFilter || this.sliderDTermFilter); if (this.GyroSliderUnavailable) {
$('.subtab-filter .nonExpertModeSlidersNote').toggle((!this.sliderGyroFilter || !this.sliderDTermFilter) && !this.expertMode); $('.tuningFilterSliders .sliderLabels tr:nth-child(2)').hide();
} else {
$('.tuningFilterSliders .sliderLabels tr:nth-child(2)').show();
}
if (this.DTermSliderUnavailable) {
$('.tuningFilterSliders .sliderLabels tr:last-child').hide();
} else {
$('.tuningFilterSliders .sliderLabels tr:last-child').show();
}
$('.tuningFilterSliders').toggle(!(this.GyroSliderUnavailable && this.DTermSliderUnavailable));
$('.subtab-filter .slidersDisabled').toggle(this.GyroSliderUnavailable || this.DTermSliderUnavailable);
$('.subtab-filter .nonExpertModeSlidersNote').toggle((!this.GyroSliderUnavailable || !this.DTermSliderUnavailable) && !this.expertMode);
$('.subtab-filter .slidersWarning').toggle(((this.sliderGyroFilterMultiplier >= WARNING_FILTER_HIGH_GAIN || $('.subtab-filter .slidersWarning').toggle(((this.sliderGyroFilterMultiplier >= WARNING_FILTER_HIGH_GAIN ||
this.sliderGyroFilterMultiplier <= WARNING_FILTER_LOW_GAIN) && !this.sliderGyroFilter) || this.sliderGyroFilterMultiplier <= WARNING_FILTER_LOW_GAIN) && !this.GyroSliderUnavailable) ||
((this.sliderDTermFilterMultiplier >= WARNING_FILTER_HIGH_GAIN || ((this.sliderDTermFilterMultiplier >= WARNING_FILTER_HIGH_GAIN ||
this.sliderDTermFilterMultiplier <= WARNING_FILTER_LOW_GAIN) && !this.sliderDTermFilter)); this.sliderDTermFilterMultiplier <= WARNING_FILTER_LOW_GAIN) && !this.DTermSliderUnavailable));
}; };
TuningSliders.updateFormPids = function() { TuningSliders.updateFormPids = function() {
@ -325,9 +387,25 @@ TuningSliders.updateFormPids = function() {
} }
}); });
}); });
$('.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);
$('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);
}; };
TuningSliders.legacyCalculateNewPids = function() { TuningSliders.legacyCalculatePids = function() {
const MAX_PID_GAIN = 200; const MAX_PID_GAIN = 200;
const MAX_DMIN_GAIN = 100; const MAX_DMIN_GAIN = 100;
const MAX_FF_GAIN = 2000; const MAX_FF_GAIN = 2000;
@ -380,68 +458,40 @@ TuningSliders.legacyCalculateNewPids = function() {
FC.ADVANCED_TUNING.dMinYaw = Math.min(Math.round(FC.ADVANCED_TUNING.dMinYaw * this.sliderMasterMultiplier), MAX_DMIN_GAIN); FC.ADVANCED_TUNING.dMinYaw = Math.min(Math.round(FC.ADVANCED_TUNING.dMinYaw * this.sliderMasterMultiplier), MAX_DMIN_GAIN);
} }
$('.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);
this.updateFormPids(); this.updateFormPids();
TABS.pid_tuning.updatePIDColors();
}; };
TuningSliders.calculateNewPids = function() { TuningSliders.calculateNewPids = function() {
// this is the main calculation for PID sliders, inputs are in form of slider position values // 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 // values get set both into forms and their respective variables
if (semver.lte(FC.CONFIG.apiVersion, API_VERSION_1_43)) { if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
this.legacyCalculateNewPids(); this.legacyCalculatePids();
} }
$('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);
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
FC.TUNING_SLIDERS.slider_pids_mode = parseInt($('#sliderPidsModeSelect').val()); FC.TUNING_SLIDERS.slider_pids_mode = parseInt($('#sliderPidsModeSelect').val());
FC.TUNING_SLIDERS.slider_master_multiplier = TuningSliders.sliderMasterMultiplier * 100; //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_roll_pitch_ratio = TuningSliders.sliderRollPitchRatio * 100; FC.TUNING_SLIDERS.slider_master_multiplier = Math.round(this.sliderMasterMultiplier * 20) * 5;
FC.TUNING_SLIDERS.slider_i_gain = TuningSliders.sliderIGain * 100; FC.TUNING_SLIDERS.slider_roll_pitch_ratio = Math.round(this.sliderRollPitchRatio * 20) * 5;
FC.TUNING_SLIDERS.slider_pd_ratio = TuningSliders.sliderPDRatio * 100; FC.TUNING_SLIDERS.slider_i_gain = Math.round(this.sliderIGain * 20) * 5;
FC.TUNING_SLIDERS.slider_pd_gain = TuningSliders.sliderPDGain * 100; FC.TUNING_SLIDERS.slider_pd_ratio = Math.round(this.sliderPDRatio * 20) * 5;
FC.TUNING_SLIDERS.slider_dmin_ratio = TuningSliders.sliderDMinRatio * 100; FC.TUNING_SLIDERS.slider_pd_gain = Math.round(this.sliderPDGain * 20) * 5;
FC.TUNING_SLIDERS.slider_ff_gain = TuningSliders.sliderFFGain * 100; FC.TUNING_SLIDERS.slider_dmin_ratio = Math.round(this.sliderDMinRatio * 20) * 5;
FC.TUNING_SLIDERS.slider_ff_gain = Math.round(this.sliderFFGain * 20) * 5;
FC.TUNING_SLIDERS.slider_dterm_filter = TuningSliders.sliderDTermFilter ? 1 : 0; MSP.promise(MSPCodes.MSP_SET_TUNING_SLIDERS, mspHelper.crunch(MSPCodes.MSP_SET_TUNING_SLIDERS))
FC.TUNING_SLIDERS.slider_dterm_filter_multiplier = TuningSliders.sliderDTermFilterMultiplier * 100; .then(() => MSP.promise(MSPCodes.MSP_PID))
.then(() => MSP.promise(MSPCodes.MSP_PID_ADVANCED))
FC.TUNING_SLIDERS.slider_gyro_filter = TuningSliders.sliderGyroFilter ? 1 : 0; .then(() => {
FC.TUNING_SLIDERS.slider_gyro_filter_multiplier = TuningSliders.sliderGyroFilterMultiplier * 100; this.updateFormPids();
Promise.resolve(true)
.then(() => { return MSP.promise(MSPCodes.MSP_SET_TUNING_SLIDERS, mspHelper.crunch(MSPCodes.MSP_SET_TUNING_SLIDERS)); })
.then(() => { return MSP.send_message(MSPCodes.MSP_PID); })
.then(() => { return MSP.send_message(MSPCodes.MSP_PID_ADVANCED); });
}
const delayInMilliseconds = 250; //0.25 seconds
setTimeout(function() {
$('.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.updateFormPids();
TABS.pid_tuning.updatePIDColors(); TABS.pid_tuning.updatePIDColors();
});
}, delayInMilliseconds); }
}; };
TuningSliders.calculateNewGyroFilters = function() { TuningSliders.calculateLegacyGyroFilters = function() {
// calculate, set and display new values in forms based on slider position // 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_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_dyn_max_hz = Math.floor(this.FILTER_DEFAULT.gyro_lowpass_dyn_max_hz * this.sliderGyroFilterMultiplier);
@ -449,26 +499,71 @@ TuningSliders.calculateNewGyroFilters = function() {
FC.FILTER_CONFIG.gyro_lowpass_type = this.FILTER_DEFAULT.gyro_lowpass_type; FC.FILTER_CONFIG.gyro_lowpass_type = this.FILTER_DEFAULT.gyro_lowpass_type;
FC.FILTER_CONFIG.gyro_lowpass2_type = this.FILTER_DEFAULT.gyro_lowpass2_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); this.updateLowpassValues();
$('.pid_filter input[name="gyroLowpassDynMaxFrequency"]').val(FC.FILTER_CONFIG.gyro_lowpass_dyn_max_hz); };
$('.pid_filter input[name="gyroLowpass2Frequency"]').val(FC.FILTER_CONFIG.gyro_lowpass2_hz);
$('.pid_filter select[name="gyroLowpassDynType').val(FC.FILTER_CONFIG.gyro_lowpass_type); TuningSliders.calculateLegacyDTermFilters = function() {
$('.pid_filter select[name="gyroLowpass2Type').val(FC.FILTER_CONFIG.gyro_lowpass2_type); // calculate, set and display new values in forms based on slider position
$('output[name="sliderGyroFilterMultiplier-number"]').val(this.sliderGyroFilterMultiplier); FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz = Math.round(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz * this.sliderDTermFilterMultiplier);
FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz = Math.round(this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz * this.sliderDTermFilterMultiplier);
FC.FILTER_CONFIG.dterm_lowpass2_hz = Math.round(this.FILTER_DEFAULT.dterm_lowpass2_hz * this.sliderDTermFilterMultiplier);
FC.FILTER_CONFIG.dterm_lowpass_type = this.FILTER_DEFAULT.dterm_lowpass_type;
FC.FILTER_CONFIG.dterm_lowpass2_type = this.FILTER_DEFAULT.dterm_lowpass2_type;
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)) {
FC.TUNING_SLIDERS.slider_gyro_filter = this.sliderGyroFilter;
//rounds slider values to nearies multiple of 5 and passes to the FW. Avoid dividing calc by (* x 100)/5 = 20
FC.TUNING_SLIDERS.slider_gyro_filter_multiplier = Math.round(this.sliderGyroFilterMultiplier * 20) * 5;
this.writeFilterSliders();
} else {
this.calculateLegacyGyroFilters();
}
}; };
TuningSliders.calculateNewDTermFilters = function() { TuningSliders.calculateNewDTermFilters = function() {
// calculate, set and display new values in forms based on slider position // this is the main calculation for Gyro Filter slider, inputs are in form of slider position values
FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz = Math.floor(this.FILTER_DEFAULT.dterm_lowpass_dyn_min_hz * this.sliderDTermFilterMultiplier); // values get set both into forms and their respective variables
FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz = Math.floor(this.FILTER_DEFAULT.dterm_lowpass_dyn_max_hz * this.sliderDTermFilterMultiplier); if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
FC.FILTER_CONFIG.dterm_lowpass2_hz = Math.floor(this.FILTER_DEFAULT.dterm_lowpass2_hz * this.sliderDTermFilterMultiplier); FC.TUNING_SLIDERS.slider_dterm_filter = this.sliderDTermFilter;
FC.FILTER_CONFIG.dterm_lowpass_type = this.FILTER_DEFAULT.dterm_lowpass_type; //rounds slider values to nearies multiple of 5 and passes to the FW. Avoid divide by ROUND[(* x 100)/5 = 20]
FC.FILTER_CONFIG.dterm_lowpass2_type = this.FILTER_DEFAULT.dterm_lowpass2_type; FC.TUNING_SLIDERS.slider_dterm_filter_multiplier = Math.round(this.sliderDTermFilterMultiplier * 20) * 5;
this.writeFilterSliders();
} else {
this.calculateLegacyDTermFilters();
}
};
TuningSliders.writeFilterSliders = function () {
MSP.promise(MSPCodes.MSP_SET_TUNING_SLIDERS, mspHelper.crunch(MSPCodes.MSP_SET_TUNING_SLIDERS))
.then(() => MSP.promise(MSPCodes.MSP_EEPROM_WRITE))
.then(() => MSP.promise(MSPCodes.MSP_FILTER_CONFIG))
.then(() => {
TuningSliders.updateLowpassValues();
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="gyroLowpass2Frequency"]').val(FC.FILTER_CONFIG.gyro_lowpass2_hz);
$('.pid_filter select[name="gyroLowpassDynType]"').val(FC.FILTER_CONFIG.gyro_lowpass_type);
$('.pid_filter select[name="gyroLowpass2Type"]').val(FC.FILTER_CONFIG.gyro_lowpass2_type);
$('output[name="sliderGyroFilterMultiplier-number"]').val(this.sliderGyroFilterMultiplier);
$('.pid_filter input[name="dtermLowpassDynMinFrequency"]').val(FC.FILTER_CONFIG.dterm_lowpass_dyn_min_hz); $('.pid_filter input[name="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="dtermLowpassDynMaxFrequency"]').val(FC.FILTER_CONFIG.dterm_lowpass_dyn_max_hz);
$('.pid_filter input[name="dtermLowpass2Frequency"]').val(FC.FILTER_CONFIG.dterm_lowpass2_hz); $('.pid_filter input[name="dtermLowpass2Frequency"]').val(FC.FILTER_CONFIG.dterm_lowpass2_hz);
$('.pid_filter select[name="dtermLowpassDynType').val(FC.FILTER_CONFIG.dterm_lowpass_type); $('.pid_filter select[name="dtermLowpassDynType"]').val(FC.FILTER_CONFIG.dterm_lowpass_type);
$('.pid_filter select[name="dtermLowpass2Type').val(FC.FILTER_CONFIG.dterm_lowpass2_type); $('.pid_filter select[name="dtermLowpass2Type"]').val(FC.FILTER_CONFIG.dterm_lowpass2_type);
$('output[name="sliderDTermFilterMultiplier-number"]').val(this.sliderDTermFilterMultiplier); $('output[name="sliderDTermFilterMultiplier-number"]').val(this.sliderDTermFilterMultiplier);
}; };

View file

@ -995,19 +995,20 @@ TABS.pid_tuning.initialize = function (callback) {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) { if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
FC.TUNING_SLIDERS.slider_pids_mode = parseInt($('#sliderPidsModeSelect').val()); FC.TUNING_SLIDERS.slider_pids_mode = parseInt($('#sliderPidsModeSelect').val());
FC.TUNING_SLIDERS.slider_master_multiplier = TuningSliders.sliderMasterMultiplier * 100; //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_roll_pitch_ratio = TuningSliders.sliderRollPitchRatio * 100; FC.TUNING_SLIDERS.slider_master_multiplier = Math.round(TuningSliders.sliderMasterMultiplier * 20) * 5;
FC.TUNING_SLIDERS.slider_i_gain = TuningSliders.sliderIGain * 100; FC.TUNING_SLIDERS.slider_roll_pitch_ratio = Math.round(TuningSliders.sliderRollPitchRatio * 20) * 5;
FC.TUNING_SLIDERS.slider_pd_ratio = TuningSliders.sliderPDRatio * 100; FC.TUNING_SLIDERS.slider_i_gain = Math.round(TuningSliders.sliderIGain * 20) * 5;
FC.TUNING_SLIDERS.slider_pd_gain = TuningSliders.sliderPDGain * 100; FC.TUNING_SLIDERS.slider_pd_ratio = Math.round(TuningSliders.sliderPDRatio * 20) * 5;
FC.TUNING_SLIDERS.slider_dmin_ratio = TuningSliders.sliderDMinRatio * 100; FC.TUNING_SLIDERS.slider_pd_gain = Math.round(TuningSliders.sliderPDGain * 20) * 5;
FC.TUNING_SLIDERS.slider_ff_gain = TuningSliders.sliderFFGain * 100; FC.TUNING_SLIDERS.slider_dmin_ratio = Math.round(TuningSliders.sliderDMinRatio * 20) * 5;
FC.TUNING_SLIDERS.slider_ff_gain = Math.round(TuningSliders.sliderFFGain * 20) * 5;
FC.TUNING_SLIDERS.slider_dterm_filter = TuningSliders.sliderDTermFilter ? 1 : 0; FC.TUNING_SLIDERS.slider_dterm_filter = TuningSliders.sliderDTermFilter ? 1 : 0;
FC.TUNING_SLIDERS.slider_dterm_filter_multiplier = TuningSliders.sliderDTermFilterMultiplier * 100; 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 ? 1 : 0;
FC.TUNING_SLIDERS.slider_gyro_filter_multiplier = TuningSliders.sliderGyroFilterMultiplier * 100; FC.TUNING_SLIDERS.slider_gyro_filter_multiplier = Math.round(TuningSliders.sliderGyroFilterMultiplier * 20) * 5;
} }
} }
@ -1928,6 +1929,7 @@ TABS.pid_tuning.initialize = function (callback) {
} }
// if values were previously changed manually and then sliders are reactivated, reset pids to previous valid values if available, else default // if values were previously changed manually and then sliders are reactivated, reset pids to previous valid values if available, else default
TuningSliders.resetPidSliders(); TuningSliders.resetPidSliders();
TuningSliders.updatePidSlidersDisplay();
// disable integrated yaw when enabling sliders // disable integrated yaw when enabling sliders
if ($('input[id="useIntegratedYaw"]').is(':checked')) { if ($('input[id="useIntegratedYaw"]').is(':checked')) {
$('input[id="useIntegratedYaw"]').prop('checked', true).click(); $('input[id="useIntegratedYaw"]').prop('checked', true).click();
@ -1945,7 +1947,7 @@ TABS.pid_tuning.initialize = function (callback) {
} else { } else {
slider.attr('step', SLIDER_STEP_UPPER); slider.attr('step', SLIDER_STEP_UPPER);
} }
if (!TuningSliders.expertMode) { if (!TuningSliders.expertMode && semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
if (slider.val() > NON_EXPERT_SLIDER_MAX) { if (slider.val() > NON_EXPERT_SLIDER_MAX) {
slider.val(NON_EXPERT_SLIDER_MAX); slider.val(NON_EXPERT_SLIDER_MAX);
} else if (slider.val() < NON_EXPERT_SLIDER_MIN) { } else if (slider.val() < NON_EXPERT_SLIDER_MIN) {
@ -1963,9 +1965,6 @@ TABS.pid_tuning.initialize = function (callback) {
self.analyticsChanges['DTermFilterTuningSlider'] = "On"; self.analyticsChanges['DTermFilterTuningSlider'] = "On";
} }
}); });
allFilterTuningSliders.mouseup(function() {
TuningSliders.updateFilterSlidersDisplay();
});
// reset to middle with double click // reset to middle with double click
allFilterTuningSliders.dblclick(function() { allFilterTuningSliders.dblclick(function() {
const slider = $(this); const slider = $(this);
@ -1977,11 +1976,14 @@ TABS.pid_tuning.initialize = function (callback) {
TuningSliders.sliderDTermFilterMultiplier = 1; TuningSliders.sliderDTermFilterMultiplier = 1;
TuningSliders.calculateNewDTermFilters(); TuningSliders.calculateNewDTermFilters();
} }
TuningSliders.updateFilterSlidersDisplay();
}); });
// enable Filter sliders button // enable Filter sliders button
$('a.buttonFilterTuningSliders').click(function() { $('a.buttonFilterTuningSliders').click(function() {
if (TuningSliders.sliderGyroFilter) { if (TuningSliders.GyroSliderUnavailable) {
//set Slider mode to ON when re-enabling Sliders
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
FC.TUNING_SLIDERS.slider_gyro_filter = 1;
}
// update switchery dynamically based on defaults // update switchery dynamically based on defaults
$('input[id="gyroLowpassDynEnabled"]').prop('checked', false).click(); $('input[id="gyroLowpassDynEnabled"]').prop('checked', false).click();
$('input[id="gyroLowpassEnabled"]').prop('checked', true).click(); $('input[id="gyroLowpassEnabled"]').prop('checked', true).click();
@ -1989,7 +1991,12 @@ TABS.pid_tuning.initialize = function (callback) {
TuningSliders.resetGyroFilterSlider(); TuningSliders.resetGyroFilterSlider();
self.analyticsChanges['GyroFilterTuningSlider'] = "On"; self.analyticsChanges['GyroFilterTuningSlider'] = "On";
} }
if (TuningSliders.sliderDTermFilter) { if (TuningSliders.DTermSliderUnavailable) {
//set Slider mode to ON when re-enabling Sliders
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
FC.TUNING_SLIDERS.slider_dterm_filter = 1;
}
// update switchery dynamically based on defaults
$('input[id="dtermLowpassDynEnabled"]').prop('checked', false).click(); $('input[id="dtermLowpassDynEnabled"]').prop('checked', false).click();
$('input[id="dtermLowpassEnabled"]').prop('checked', true).click(); $('input[id="dtermLowpassEnabled"]').prop('checked', true).click();
$('input[id="dtermLowpass2Enabled"]').prop('checked', false).click(); $('input[id="dtermLowpass2Enabled"]').prop('checked', false).click();
@ -2006,10 +2013,10 @@ TABS.pid_tuning.initialize = function (callback) {
// update on filter value or type changes // update on filter value or type changes
$('.pid_filter tr:not(.newFilter) input, .pid_filter tr:not(.newFilter) select').on('input', function() { $('.pid_filter tr:not(.newFilter) input, .pid_filter tr:not(.newFilter) select').on('input', function() {
TuningSliders.updateFilterSlidersDisplay(); TuningSliders.updateFilterSlidersDisplay();
if (TuningSliders.sliderGyroFilter) { if (TuningSliders.GyroSliderUnavailable) {
self.analyticsChanges['GyroFilterTuningSlider'] = "Off"; self.analyticsChanges['GyroFilterTuningSlider'] = "Off";
} }
if (TuningSliders.sliderDTermFilter) { if (TuningSliders.DTermSliderUnavailable) {
self.analyticsChanges['DTermFilterTuningSlider'] = "Off"; self.analyticsChanges['DTermFilterTuningSlider'] = "Off";
} }
}); });

View file

@ -197,7 +197,7 @@
<output type="number" name="sliderMasterMultiplier-number"></output> <output type="number" name="sliderMasterMultiplier-number"></output>
</td> </td>
<td colspan="3"> <td colspan="3">
<input type="range" min="0.5" max="1.5" step="0.05" class="tuningSlider" id="sliderMasterMultiplier" /> <input type="range" min="0.5" max="1.5" step="0.025" class="tuningSlider" id="sliderMasterMultiplier" />
</td> </td>
<td> <td>
<div class="helpicon cf_tip" i18n_title="pidTuningMasterSliderHelp"></div> <div class="helpicon cf_tip" i18n_title="pidTuningMasterSliderHelp"></div>
@ -211,7 +211,7 @@
<output type="number" name="sliderPDRatio-number"></output> <output type="number" name="sliderPDRatio-number"></output>
</td> </td>
<td colspan="3"> <td colspan="3">
<input type="range" min="0.5" max="1.5" step="0.05" class="tuningSlider" id="sliderPDRatio" /> <input type="range" min="0.5" max="1.5" step="0.025" class="tuningSlider" id="sliderPDRatio" />
</td> </td>
<td> <td>
<div class="helpicon cf_tip" i18n_title="pidTuningPDRatioSliderHelp"></div> <div class="helpicon cf_tip" i18n_title="pidTuningPDRatioSliderHelp"></div>
@ -225,7 +225,7 @@
<output type="number" name="sliderPDGain-number"></output> <output type="number" name="sliderPDGain-number"></output>
</td> </td>
<td colspan="3"> <td colspan="3">
<input type="range" min="0.5" max="1.5" step="0.05" class="tuningSlider" id="sliderPDGain" /> <input type="range" min="0.5" max="1.5" step="0.025" class="tuningSlider" id="sliderPDGain" />
</td> </td>
<td> <td>
<div class="helpicon cf_tip" i18n_title="pidTuningPDGainSliderHelp"></div> <div class="helpicon cf_tip" i18n_title="pidTuningPDGainSliderHelp"></div>
@ -239,7 +239,7 @@
<output type="number" name="sliderFFGain-number"></output> <output type="number" name="sliderFFGain-number"></output>
</td> </td>
<td colspan="3"> <td colspan="3">
<input type="range" min="0.5" max="1.5" step="0.05" class="tuningSlider" id="sliderFFGain" /> <input type="range" min="0.5" max="1.5" step="0.025" class="tuningSlider" id="sliderFFGain" />
</td> </td>
<td> <td>
<div class="helpicon cf_tip" i18n_title="pidTuningResponseSliderHelp"></div> <div class="helpicon cf_tip" i18n_title="pidTuningResponseSliderHelp"></div>
@ -253,7 +253,7 @@
<output type="number" name="sliderIGain-number"></output> <output type="number" name="sliderIGain-number"></output>
</td> </td>
<td colspan="3"> <td colspan="3">
<input type="range" min="0.5" max="1.5" step="0.05" class="tuningSlider" id="sliderIGain" /> <input type="range" min="0.5" max="1.5" step="0.025" class="tuningSlider" id="sliderIGain" />
</td> </td>
<td> <td>
<div class="helpicon cf_tip" i18n_title="pidTuningIGainSliderHelp"></div> <div class="helpicon cf_tip" i18n_title="pidTuningIGainSliderHelp"></div>
@ -266,7 +266,7 @@
<output type="number" name="sliderDMinRatio-number"></output> <output type="number" name="sliderDMinRatio-number"></output>
</td> </td>
<td colspan="3"> <td colspan="3">
<input type="range" min="0.5" max="1.5" step="0.05" class="tuningSlider" id="sliderDMinRatio" /> <input type="range" min="0.5" max="1.5" step="0.025" class="tuningSlider" id="sliderDMinRatio" />
</td> </td>
<td> <td>
<div class="helpicon cf_tip" i18n_title="pidTuningDMinRatioSliderHelp"></div> <div class="helpicon cf_tip" i18n_title="pidTuningDMinRatioSliderHelp"></div>
@ -280,7 +280,7 @@
<output type="number" name="sliderRollPitchRatio-number"></output> <output type="number" name="sliderRollPitchRatio-number"></output>
</td> </td>
<td colspan="3"> <td colspan="3">
<input type="range" min="0.5" max="1.5" step="0.05" class="tuningSlider" id="sliderRollPitchRatio" /> <input type="range" min="0.5" max="1.5" step="0.025" class="tuningSlider" id="sliderRollPitchRatio" />
</td> </td>
<td> <td>
<div class="helpicon cf_tip" i18n_title="pidTuningRollPitchRatioSliderHelp"></div> <div class="helpicon cf_tip" i18n_title="pidTuningRollPitchRatioSliderHelp"></div>
@ -1070,7 +1070,7 @@
<output type="number" name="sliderGyroFilterMultiplier-number"></output> <output type="number" name="sliderGyroFilterMultiplier-number"></output>
</td> </td>
<td colspan="3"> <td colspan="3">
<input type="range" min="0.5" max="1.5" step="0.05" class="tuningSlider" id="sliderGyroFilterMultiplier" /> <input type="range" min="0.5" max="1.5" step="0.025" class="tuningSlider" id="sliderGyroFilterMultiplier" />
</td> </td>
<td> <td>
<div class="helpicon cf_tip" i18n_title="pidTuningGyroFilterSliderHelp"></div> <div class="helpicon cf_tip" i18n_title="pidTuningGyroFilterSliderHelp"></div>
@ -1089,7 +1089,7 @@
<output type="number" name="sliderDTermFilterMultiplier-number"></output> <output type="number" name="sliderDTermFilterMultiplier-number"></output>
</td> </td>
<td colspan="3"> <td colspan="3">
<input type="range" min="0.5" max="1.5" step="0.05" class="tuningSlider" id="sliderDTermFilterMultiplier" /> <input type="range" min="0.5" max="1.5" step="0.025" class="tuningSlider" id="sliderDTermFilterMultiplier" />
</td> </td>
<td> <td>
<div class="helpicon cf_tip" i18n_title="pidTuningDTermFilterSliderHelp"></div> <div class="helpicon cf_tip" i18n_title="pidTuningDTermFilterSliderHelp"></div>