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

Fix model preview

Refactor currentRates
This commit is contained in:
Mark Haslinghuis 2022-03-01 12:53:23 +01:00
parent d9089dc212
commit 94037827e8
4 changed files with 141 additions and 163 deletions

View file

@ -3,7 +3,6 @@
const minRc = 1000;
const midRc = 1500;
const maxRc = 2000;
const RateCurve = function (useLegacyCurve) {
this.useLegacyCurve = useLegacyCurve;
this.maxAngularVel = null;
@ -150,6 +149,81 @@ const RateCurve = function (useLegacyCurve) {
return angularVel;
};
this.getCurrentRates = function () {
const currentRates = {
roll_rate: FC.RC_TUNING.roll_rate,
pitch_rate: FC.RC_TUNING.pitch_rate,
yaw_rate: FC.RC_TUNING.yaw_rate,
rc_rate: FC.RC_TUNING.RC_RATE,
rc_rate_yaw: FC.RC_TUNING.rcYawRate,
rc_expo: FC.RC_TUNING.RC_EXPO,
rc_yaw_expo: FC.RC_TUNING.RC_YAW_EXPO,
rc_rate_pitch: FC.RC_TUNING.rcPitchRate,
rc_pitch_expo: FC.RC_TUNING.RC_PITCH_EXPO,
superexpo: FC.FEATURE_CONFIG.features.isEnabled('SUPEREXPO_RATES'),
deadband: FC.RC_DEADBAND_CONFIG.deadband,
yawDeadband: FC.RC_DEADBAND_CONFIG.yaw_deadband,
roll_rate_limit: FC.RC_TUNING.roll_rate_limit,
pitch_rate_limit: FC.RC_TUNING.pitch_rate_limit,
yaw_rate_limit: FC.RC_TUNING.yaw_rate_limit,
};
if (semver.lt(FC.CONFIG.apiVersion, "1.7.0")) {
currentRates.roll_rate = FC.RC_TUNING.roll_pitch_rate;
currentRates.pitch_rate = FC.RC_TUNING.roll_pitch_rate;
}
if (semver.lt(FC.CONFIG.apiVersion, "1.16.0")) {
currentRates.rc_rate_yaw = currentRates.rc_rate;
}
if (semver.gte(FC.CONFIG.apiVersion, "1.20.0")) {
currentRates.superexpo = true;
}
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_37)) {
currentRates.rc_rate_pitch = currentRates.rc_rate;
currentRates.rc_expo_pitch = currentRates.rc_expo;
}
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_43)) {
switch (FC.RC_TUNING.rates_type) {
case FC.RATES_TYPE.RACEFLIGHT:
currentRates.roll_rate *= 100;
currentRates.pitch_rate *= 100;
currentRates.yaw_rate *= 100;
currentRates.rc_rate *= 1000;
currentRates.rc_rate_yaw *= 1000;
currentRates.rc_rate_pitch *= 1000;
currentRates.rc_expo *= 100;
currentRates.rc_yaw_expo *= 100;
currentRates.rc_pitch_expo *= 100;
break;
case FC.RATES_TYPE.ACTUAL:
currentRates.roll_rate *= 1000;
currentRates.pitch_rate *= 1000;
currentRates.yaw_rate *= 1000;
currentRates.rc_rate *= 1000;
currentRates.rc_rate_yaw *= 1000;
currentRates.rc_rate_pitch *= 1000;
break;
case FC.RATES_TYPE.QUICKRATES:
currentRates.roll_rate *= 1000;
currentRates.pitch_rate *= 1000;
currentRates.yaw_rate *= 1000;
break;
default: // add future rates types here
break;
}
}
return currentRates;
};
};
RateCurve.prototype.rcCommandRawToDegreesPerSecond = function (rcData, rate, rcRate, rcExpo, superExpoActive, deadband, limit) {
@ -165,23 +239,23 @@ RateCurve.prototype.rcCommandRawToDegreesPerSecond = function (rcData, rate, rcR
const rcCommandfAbs = Math.abs(rcCommandf);
switch(TABS.pid_tuning.currentRatesType) {
case TABS.pid_tuning.RATES_TYPE.RACEFLIGHT:
switch (FC.RC_TUNING.rates_type) {
case FC.RATES_TYPE.RACEFLIGHT:
angleRate=this.getRaceflightRates(rcCommandf, rate, rcRate, rcExpo);
break;
case TABS.pid_tuning.RATES_TYPE.KISS:
case FC.RATES_TYPE.KISS:
angleRate=this.getKISSRates(rcCommandf, rcCommandfAbs, rate, rcRate, rcExpo);
break;
case TABS.pid_tuning.RATES_TYPE.ACTUAL:
case FC.RATES_TYPE.ACTUAL:
angleRate=this.getActualRates(rcCommandf, rcCommandfAbs, rate, rcRate, rcExpo);
break;
case TABS.pid_tuning.RATES_TYPE.QUICKRATES:
case FC.RATES_TYPE.QUICKRATES:
angleRate=this.getQuickRates(rcCommandf, rcCommandfAbs, rate, rcRate, rcExpo);
break;
@ -208,8 +282,8 @@ RateCurve.prototype.getMaxAngularVel = function (rate, rcRate, rcExpo, superExpo
RateCurve.prototype.setMaxAngularVel = function (value) {
this.maxAngularVel = Math.ceil(value/200) * 200;
return this.maxAngularVel;
return this.maxAngularVel;
};
RateCurve.prototype.draw = function (rate, rcRate, rcExpo, superExpoActive, deadband, limit, maxAngularVel, context) {

View file

@ -893,4 +893,12 @@ const FC = {
getSliderDefaults() {
return this.DEFAULT_TUNING_SLIDERS;
},
RATES_TYPE: {
BETAFLIGHT: 0,
RACEFLIGHT: 1,
KISS: 2,
ACTUAL: 3,
QUICKRATES: 4,
},
};

View file

@ -11,13 +11,6 @@ TABS.pid_tuning = {
currentRateProfile: null,
currentRatesType: null,
previousRatesType: null,
RATES_TYPE: {
BETAFLIGHT: 0,
RACEFLIGHT: 1,
KISS: 2,
ACTUAL: 3,
QUICKRATES: 4,
},
SETPOINT_WEIGHT_RANGE_LOW: 2.55,
SETPOINT_WEIGHT_RANGE_HIGH: 20,
SETPOINT_WEIGHT_RANGE_LEGACY: 2.54,
@ -1117,8 +1110,8 @@ TABS.pid_tuning.initialize = function (callback) {
FC.RC_TUNING.RC_PITCH_EXPO = parseFloat(rc_pitch_expo_e.val());
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_43)) {
switch(self.currentRatesType) {
case self.RATES_TYPE.RACEFLIGHT:
switch (self.currentRatesType) {
case FC.RATES_TYPE.RACEFLIGHT:
FC.RC_TUNING.pitch_rate = parseFloat(pitch_rate_e.val()) / 100;
FC.RC_TUNING.roll_rate = parseFloat(roll_rate_e.val()) / 100;
FC.RC_TUNING.yaw_rate = parseFloat(yaw_rate_e.val()) / 100;
@ -1131,7 +1124,7 @@ TABS.pid_tuning.initialize = function (callback) {
break;
case self.RATES_TYPE.ACTUAL:
case FC.RATES_TYPE.ACTUAL:
FC.RC_TUNING.pitch_rate = parseFloat(pitch_rate_e.val()) / 1000;
FC.RC_TUNING.roll_rate = parseFloat(roll_rate_e.val()) / 1000;
FC.RC_TUNING.yaw_rate = parseFloat(yaw_rate_e.val()) / 1000;
@ -1141,7 +1134,7 @@ TABS.pid_tuning.initialize = function (callback) {
break;
case self.RATES_TYPE.QUICKRATES:
case FC.RATES_TYPE.QUICKRATES:
FC.RC_TUNING.pitch_rate = parseFloat(pitch_rate_e.val()) / 1000;
FC.RC_TUNING.roll_rate = parseFloat(roll_rate_e.val()) / 1000;
FC.RC_TUNING.yaw_rate = parseFloat(yaw_rate_e.val()) / 1000;
@ -1411,6 +1404,11 @@ TABS.pid_tuning.initialize = function (callback) {
self.rateCurve = new RateCurve(useLegacyCurve);
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
$('.pid_tuning input[name="sensitivity"]').hide();
$('.pid_tuning .levelSensitivityHeader').empty();
}
function printMaxAngularVel(rate, rcRate, rcExpo, useSuperExpo, deadband, limit, maxAngularVelElement) {
const maxAngularVel = self.rateCurve.getMaxAngularVel(rate, rcRate, rcExpo, useSuperExpo, deadband, limit).toFixed(0);
maxAngularVelElement.text(maxAngularVel);
@ -1441,86 +1439,7 @@ TABS.pid_tuning.initialize = function (callback) {
// translate to user-selected language
i18n.localizePage();
// Local cache of current rates
self.currentRates = {
roll_rate: FC.RC_TUNING.roll_rate,
pitch_rate: FC.RC_TUNING.pitch_rate,
yaw_rate: FC.RC_TUNING.yaw_rate,
rc_rate: FC.RC_TUNING.RC_RATE,
rc_rate_yaw: FC.RC_TUNING.rcYawRate,
rc_expo: FC.RC_TUNING.RC_EXPO,
rc_yaw_expo: FC.RC_TUNING.RC_YAW_EXPO,
rc_rate_pitch: FC.RC_TUNING.rcPitchRate,
rc_pitch_expo: FC.RC_TUNING.RC_PITCH_EXPO,
superexpo: FC.FEATURE_CONFIG.features.isEnabled('SUPEREXPO_RATES'),
deadband: FC.RC_DEADBAND_CONFIG.deadband,
yawDeadband: FC.RC_DEADBAND_CONFIG.yaw_deadband,
roll_rate_limit: FC.RC_TUNING.roll_rate_limit,
pitch_rate_limit: FC.RC_TUNING.pitch_rate_limit,
yaw_rate_limit: FC.RC_TUNING.yaw_rate_limit,
};
if (semver.lt(FC.CONFIG.apiVersion, "1.7.0")) {
self.currentRates.roll_rate = FC.RC_TUNING.roll_pitch_rate;
self.currentRates.pitch_rate = FC.RC_TUNING.roll_pitch_rate;
}
if (semver.lt(FC.CONFIG.apiVersion, "1.16.0")) {
self.currentRates.rc_rate_yaw = self.currentRates.rc_rate;
}
if (semver.gte(FC.CONFIG.apiVersion, "1.20.0")) {
self.currentRates.superexpo = true;
}
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
$('.pid_tuning input[name="sensitivity"]').hide();
$('.pid_tuning .levelSensitivityHeader').empty();
}
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_37)) {
self.currentRates.rc_rate_pitch = self.currentRates.rc_rate;
self.currentRates.rc_expo_pitch = self.currentRates.rc_expo;
}
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_43)) {
switch(FC.RC_TUNING.rates_type) {
case self.RATES_TYPE.RACEFLIGHT:
self.currentRates.roll_rate *= 100;
self.currentRates.pitch_rate *= 100;
self.currentRates.yaw_rate *= 100;
self.currentRates.rc_rate *= 1000;
self.currentRates.rc_rate_yaw *= 1000;
self.currentRates.rc_rate_pitch *= 1000;
self.currentRates.rc_expo *= 100;
self.currentRates.rc_yaw_expo *= 100;
self.currentRates.rc_pitch_expo *= 100;
break;
case self.RATES_TYPE.ACTUAL:
self.currentRates.roll_rate *= 1000;
self.currentRates.pitch_rate *= 1000;
self.currentRates.yaw_rate *= 1000;
self.currentRates.rc_rate *= 1000;
self.currentRates.rc_rate_yaw *= 1000;
self.currentRates.rc_rate_pitch *= 1000;
break;
case self.RATES_TYPE.QUICKRATES:
self.currentRates.roll_rate *= 1000;
self.currentRates.pitch_rate *= 1000;
self.currentRates.yaw_rate *= 1000;
break;
// add future rates types here
default: // BetaFlight
break;
}
}
self.currentRates = self.rateCurve.getCurrentRates();
$('.tab-pid_tuning .tab-container .pid').on('click', () => activateSubtab('pid'));
@ -1639,6 +1558,7 @@ TABS.pid_tuning.initialize = function (callback) {
$('.tab-pid_tuning select[name="rate_profile"]').prop('disabled', 'false');
FC.CONFIG.rateProfile = self.currentRateProfile;
self.currentRates = self.rateCurve.getCurrentRates();
GUI.log(i18n.getMessage('pidTuningLoadedRateProfile', [self.currentRateProfile + 1]));
});
@ -3048,6 +2968,10 @@ TABS.pid_tuning.changeRatesType = function(rateTypeID) {
self.changeRatesSystem(false);
self.previousRatesType = self.currentRatesType;
dialogRatesType.close();
FC.RC_TUNING.rates_type = self.currentRatesType;
self.currentRates = self.rateCurve.getCurrentRates();
});
}
@ -3091,8 +3015,8 @@ TABS.pid_tuning.changeRatesSystem = function(sameType) {
rc_yaw_expo_e.val(FC.RC_TUNING.RC_YAW_EXPO.toFixed(2));
}
switch(self.currentRatesType) {
case self.RATES_TYPE.RACEFLIGHT:
switch (self.currentRatesType) {
case FC.RATES_TYPE.RACEFLIGHT:
rcRateLabel.text(i18n.getMessage("pidTuningRcRateRaceflight"));
rateLabel.text(i18n.getMessage("pidTuningRateRaceflight"));
rcExpoLabel.text(i18n.getMessage("pidTuningRcExpoRaceflight"));
@ -3123,7 +3047,7 @@ TABS.pid_tuning.changeRatesSystem = function(sameType) {
break;
case self.RATES_TYPE.KISS:
case FC.RATES_TYPE.KISS:
rcRateLabel.text(i18n.getMessage("pidTuningRcRate"));
rateLabel.text(i18n.getMessage("pidTuningRcRateRaceflight"));
rcExpoLabel.text(i18n.getMessage("pidTuningRcExpoKISS"));
@ -3132,7 +3056,7 @@ TABS.pid_tuning.changeRatesSystem = function(sameType) {
break;
case self.RATES_TYPE.ACTUAL:
case FC.RATES_TYPE.ACTUAL:
rcRateLabel.text(i18n.getMessage("pidTuningRcRateActual"));
rateLabel.text(i18n.getMessage("pidTuningRateQuickRates"));
rcExpoLabel.text(i18n.getMessage("pidTuningRcExpoRaceflight"));
@ -3162,7 +3086,7 @@ TABS.pid_tuning.changeRatesSystem = function(sameType) {
break;
case self.RATES_TYPE.QUICKRATES:
case FC.RATES_TYPE.QUICKRATES:
rcRateLabel.text(i18n.getMessage("pidTuningRcRate"));
rateLabel.text(i18n.getMessage("pidTuningRateQuickRates"));
rcExpoLabel.text(i18n.getMessage("pidTuningRcExpoRaceflight"));
@ -3213,23 +3137,23 @@ TABS.pid_tuning.changeRatesTypeLogo = function() {
const ratesLogoElement = $('.rates_type img[id="ratesLogo"]');
switch(self.currentRatesType) {
case self.RATES_TYPE.RACEFLIGHT:
switch (self.currentRatesType) {
case FC.RATES_TYPE.RACEFLIGHT:
ratesLogoElement.attr("src", "./images/rate_logos/raceflight.svg");
break;
case self.RATES_TYPE.KISS:
case FC.RATES_TYPE.KISS:
ratesLogoElement.attr("src", "./images/rate_logos/kiss.svg");
break;
case self.RATES_TYPE.ACTUAL:
case FC.RATES_TYPE.ACTUAL:
ratesLogoElement.attr("src", "./images/rate_logos/actual.svg");
break;
case self.RATES_TYPE.QUICKRATES:
case FC.RATES_TYPE.QUICKRATES:
ratesLogoElement.attr("src", "./images/rate_logos/quickrates.svg");
break;

View file

@ -2,18 +2,14 @@
TABS.receiver = {
rateChartHeight: 117,
useSuperExpo: false,
deadband: 0,
yawDeadband: 0,
analyticsChanges: {},
needReboot: false,
ratesMultiplier: 1,
};
TABS.receiver.initialize = function (callback) {
const tab = this;
if (GUI.active_tab != 'receiver') {
if (GUI.active_tab !== 'receiver') {
GUI.active_tab = 'receiver';
}
@ -77,13 +73,6 @@ TABS.receiver.initialize = function (callback) {
$('.deadband input[name="yaw_deadband"]').val(FC.RC_DEADBAND_CONFIG.yaw_deadband);
$('.deadband input[name="deadband"]').val(FC.RC_DEADBAND_CONFIG.deadband);
$('.deadband input[name="3ddeadbandthrottle"]').val(FC.RC_DEADBAND_CONFIG.deadband3d_throttle);
$('.deadband input[name="deadband"]').change(function () {
tab.deadband = parseInt($(this).val());
}).change();
$('.deadband input[name="yaw_deadband"]').change(function () {
tab.yawDeadband = parseInt($(this).val());
}).change();
}
if (semver.lt(FC.CONFIG.apiVersion, "1.15.0")) {
@ -132,7 +121,7 @@ TABS.receiver.initialize = function (callback) {
<li class="meter">\
<div class="meter-bar">\
<div class="label"></div>\
<div class="fill${FC.RC.active_channels == 0 ? 'disabled' : ''}">\
<div class="fill${FC.RC.active_channels === 0 ? 'disabled' : ''}">\
<div class="label"></div>\
</div>\
</div>\
@ -202,7 +191,7 @@ TABS.receiver.initialize = function (callback) {
strBuffer = val.split('');
const duplicityBuffer = [];
if (val.length != 8) {
if (val.length !== 8) {
$(this).val(lastValid);
return false;
}
@ -522,7 +511,7 @@ TABS.receiver.initialize = function (callback) {
}, function(createdWindow) {
// Give the window a callback it can use to send the channels (otherwise it can't see those objects)
createdWindow.contentWindow.setRawRx = function(channels) {
if (CONFIGURATOR.connectionValid && GUI.active_tab != 'cli') {
if (CONFIGURATOR.connectionValid && GUI.active_tab !== 'cli') {
mspHelper.setRawRx(channels);
return true;
} else {
@ -826,32 +815,18 @@ TABS.receiver.initModelPreview = function () {
this.keepRendering = true;
this.model = new Model($('.model_preview'), $('.model_preview canvas'));
this.useSuperExpo = false;
if (semver.gte(FC.CONFIG.apiVersion, "1.20.0") || (semver.gte(FC.CONFIG.apiVersion, "1.16.0") && FC.FEATURE_CONFIG.features.isEnabled('SUPEREXPO_RATES'))) {
this.useSuperExpo = true;
}
let useOldRateCurve = false;
if (FC.CONFIG.flightControllerIdentifier == 'CLFL' && semver.lt(FC.CONFIG.apiVersion, '2.0.0')) {
if (FC.CONFIG.flightControllerIdentifier === 'CLFL' && semver.lt(FC.CONFIG.apiVersion, '2.0.0')) {
useOldRateCurve = true;
}
if (FC.CONFIG.flightControllerIdentifier == 'BTFL' && semver.lt(FC.CONFIG.flightControllerVersion, '2.8.0')) {
if (FC.CONFIG.flightControllerIdentifier === 'BTFL' && semver.lt(FC.CONFIG.flightControllerVersion, '2.8.0')) {
useOldRateCurve = true;
}
this.rateCurve = new RateCurve(useOldRateCurve);
this.currentRates = this.rateCurve.getCurrentRates();
const ratesMultiplierList = [
{name: "Betaflight", value: 1},
{name: "Raceflight", value: 100},
{name: "KISS", value: 1},
{name: "Actual", value: 1000},
{name: "QuickRates", value: 1000},
];
this.ratesMultiplier = ratesMultiplierList[FC.RC_TUNING.rates_type].value;
$(window).on('resize', $.proxy(this.model.resize, this.model));
$(window).on('resize', $.bind(this.model.resize, this.model));
};
TABS.receiver.renderModel = function () {
@ -864,39 +839,36 @@ TABS.receiver.renderModel = function () {
const roll = delta * this.rateCurve.rcCommandRawToDegreesPerSecond(
FC.RC.channels[0],
FC.RC_TUNING.roll_rate * this.ratesMultiplier,
FC.RC_TUNING.RC_RATE * this.ratesMultiplier,
FC.RC_TUNING.RC_EXPO * this.ratesMultiplier,
this.useSuperExpo,
this.deadband,
FC.RC_TUNING.roll_rate_limit,
this.currentRates.roll_rate,
this.currentRates.rc_rate,
this.currentRates.rc_expo,
this.currentRates.superexpo,
this.currentRates.deadband,
this.currentRates.roll_rate_limit,
);
const pitch = delta * this.rateCurve.rcCommandRawToDegreesPerSecond(
FC.RC.channels[1],
FC.RC_TUNING.pitch_rate * this.ratesMultiplier,
FC.RC_TUNING.rcPitchRate * this.ratesMultiplier,
FC.RC_TUNING.RC_PITCH_EXPO * this.ratesMultiplier,
this.useSuperExpo,
this.deadband,
FC.RC_TUNING.pitch_rate_limit,
this.currentRates.pitch_rate,
this.currentRates.rc_rate_pitch,
this.currentRates.rc_pitch_expo,
this.currentRates.superexpo,
this.currentRates.deadband,
this.currentRates.pitch_rate_limit,
);
const yaw = delta * this.rateCurve.rcCommandRawToDegreesPerSecond(
FC.RC.channels[2],
FC.RC_TUNING.yaw_rate * this.ratesMultiplier,
FC.RC_TUNING.rcYawRate * this.ratesMultiplier,
FC.RC_TUNING.RC_YAW_EXPO * this.ratesMultiplier,
this.useSuperExpo,
this.yawDeadband,
FC.RC_TUNING.yaw_rate_limit,
this.currentRates.yaw_rate,
this.currentRates.rc_rate_yaw,
this.currentRates.rc_yaw_expo,
this.currentRates.superexpo,
this.currentRates.yawDeadband,
this.currentRates.yaw_rate_limit,
);
this.model.rotateBy(-degToRad(pitch), -degToRad(yaw), -degToRad(roll));
}
};
TABS.receiver.cleanup = function (callback) {
$(window).off('resize', this.resize);
if (this.model) {