mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-23 16:25:22 +03:00
Moved scaling factor for rates calculation into 'RateCurve'.
This commit is contained in:
parent
a22baa227c
commit
bc58101ab7
2 changed files with 70 additions and 55 deletions
|
@ -7,11 +7,11 @@ var maxRc = 2000;
|
||||||
var RateCurve = function (useLegacyCurve) {
|
var RateCurve = function (useLegacyCurve) {
|
||||||
this.useLegacyCurve = useLegacyCurve;
|
this.useLegacyCurve = useLegacyCurve;
|
||||||
|
|
||||||
function constrain(value, min, max) {
|
this.constrain = function (value, min, max) {
|
||||||
return Math.max(min, Math.min(value, max));
|
return Math.max(min, Math.min(value, max));
|
||||||
}
|
}
|
||||||
|
|
||||||
function rcCommand(rcData, rcRate, rcExpo) {
|
this.rcCommand = function (rcData, rcRate, rcExpo) {
|
||||||
var tmp = Math.min(Math.abs(rcData - midRc), 500) / 100;
|
var tmp = Math.min(Math.abs(rcData - midRc), 500) / 100;
|
||||||
|
|
||||||
var result = ((2500 + rcExpo * (tmp * tmp - 25)) * tmp * rcRate / 2500).toFixed(0);
|
var result = ((2500 + rcExpo * (tmp * tmp - 25)) * tmp * rcRate / 2500).toFixed(0);
|
||||||
|
@ -22,23 +22,6 @@ var RateCurve = function (useLegacyCurve) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rcCommandRawToDegreesPerSecond = function (rcData, rate, rcRate, rcExpo, superExpoActive) {
|
|
||||||
var inputValue = rcCommand(rcData, rcRate, rcExpo);
|
|
||||||
|
|
||||||
var angleRate;
|
|
||||||
if (superExpoActive) {
|
|
||||||
var rcFactor = Math.abs(inputValue) / (500 * rcRate / 100);
|
|
||||||
rcFactor = 1 / constrain(1 - rcFactor * rate / 100, 0.01, 1);
|
|
||||||
|
|
||||||
angleRate = rcFactor * 27 * inputValue / 16;
|
|
||||||
} else {
|
|
||||||
angleRate = (rate + 27) * inputValue / 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
angleRate = constrain(angleRate, -8190, 8190); // Rate limit protection
|
|
||||||
return angleRate >> 2; // the shift by 2 is to counterbalance the divide by 4 that occurs on the gyro to calculate the error
|
|
||||||
};
|
|
||||||
|
|
||||||
this.drawRateCurve = function (rate, rcRate, rcExpo, superExpoActive, maxAngularVel, context, width, height) {
|
this.drawRateCurve = function (rate, rcRate, rcExpo, superExpoActive, maxAngularVel, context, width, height) {
|
||||||
var canvasHeightScale = height / (2 * maxAngularVel);
|
var canvasHeightScale = height / (2 * maxAngularVel);
|
||||||
|
|
||||||
|
@ -62,10 +45,6 @@ var RateCurve = function (useLegacyCurve) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.drawLegacyRateCurve = function (rate, rcRate, rcExpo, context, width, height) {
|
this.drawLegacyRateCurve = function (rate, rcRate, rcExpo, context, width, height) {
|
||||||
rate = rate / 100;
|
|
||||||
rcRate = rcRate / 100;
|
|
||||||
rcExpo = rcExpo / 100;
|
|
||||||
|
|
||||||
// math magic by englishman
|
// math magic by englishman
|
||||||
var rateY = height * rcRate;
|
var rateY = height * rcRate;
|
||||||
rateY = rateY + (1 / (1 - ((rateY / height) * rate)))
|
rateY = rateY + (1 / (1 - ((rateY / height) * rate)))
|
||||||
|
@ -78,10 +57,34 @@ var RateCurve = function (useLegacyCurve) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RateCurve.prototype.rcCommandRawToDegreesPerSecond = function (rcData, rate, rcRate, rcExpo, superExpoActive) {
|
||||||
|
var angleRate;
|
||||||
|
if (rate !== undefined && rcRate !== undefined && rcExpo !== undefined) {
|
||||||
|
rate = rate * 100;
|
||||||
|
rcRate = rcRate * 100;
|
||||||
|
rcExpo = rcExpo * 100;
|
||||||
|
|
||||||
|
var inputValue = this.rcCommand(rcData, rcRate, rcExpo);
|
||||||
|
|
||||||
|
if (superExpoActive) {
|
||||||
|
var rcFactor = Math.abs(inputValue) / (500 * rcRate / 100);
|
||||||
|
rcFactor = 1 / this.constrain(1 - rcFactor * rate / 100, 0.01, 1);
|
||||||
|
|
||||||
|
angleRate = rcFactor * 27 * inputValue / 16;
|
||||||
|
} else {
|
||||||
|
angleRate = (rate + 27) * inputValue / 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
angleRate = this.constrain(angleRate, -8190, 8190); // Rate limit protection
|
||||||
|
angleRate = angleRate >> 2; // the shift by 2 is to counterbalance the divide by 4 that occurs on the gyro to calculate the error
|
||||||
|
}
|
||||||
|
|
||||||
|
return angleRate;
|
||||||
|
};
|
||||||
|
|
||||||
RateCurve.prototype.getMaxAngularVel = function (rate, rcRate, rcExpo, superExpoActive) {
|
RateCurve.prototype.getMaxAngularVel = function (rate, rcRate, rcExpo, superExpoActive) {
|
||||||
var maxAngularVel;
|
var maxAngularVel;
|
||||||
if (rate !== undefined && rcRate !== undefined && rcExpo !== undefined
|
if (!this.useLegacyCurve) {
|
||||||
&& !this.useLegacyCurve) {
|
|
||||||
maxAngularVel = this.rcCommandRawToDegreesPerSecond(maxRc, rate, rcRate, rcExpo, superExpoActive);
|
maxAngularVel = this.rcCommandRawToDegreesPerSecond(maxRc, rate, rcRate, rcExpo, superExpoActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -421,13 +421,13 @@ TABS.pid_tuning.initialize = function (callback) {
|
||||||
|
|
||||||
// Local cache of current rates
|
// Local cache of current rates
|
||||||
self.currentRates = {
|
self.currentRates = {
|
||||||
roll_rate: RC_tuning.roll_rate * 100,
|
roll_rate: RC_tuning.roll_rate,
|
||||||
pitch_rate: RC_tuning.pitch_rate * 100,
|
pitch_rate: RC_tuning.pitch_rate,
|
||||||
yaw_rate: RC_tuning.yaw_rate * 100,
|
yaw_rate: RC_tuning.yaw_rate,
|
||||||
rc_rate: RC_tuning.RC_RATE * 100,
|
rc_rate: RC_tuning.RC_RATE,
|
||||||
rc_rate_yaw: SPECIAL_PARAMETERS.RC_RATE_YAW * 100,
|
rc_rate_yaw: SPECIAL_PARAMETERS.RC_RATE_YAW,
|
||||||
rc_expo: RC_tuning.RC_EXPO * 100,
|
rc_expo: RC_tuning.RC_EXPO,
|
||||||
rc_yaw_expo: RC_tuning.RC_YAW_EXPO * 100,
|
rc_yaw_expo: RC_tuning.RC_YAW_EXPO,
|
||||||
superexpo: bit_check(BF_CONFIG.features, SUPEREXPO_FEATURE_BIT)
|
superexpo: bit_check(BF_CONFIG.features, SUPEREXPO_FEATURE_BIT)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -436,8 +436,8 @@ TABS.pid_tuning.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (semver.lt(CONFIG.apiVersion, "1.7.0")) {
|
if (semver.lt(CONFIG.apiVersion, "1.7.0")) {
|
||||||
self.currentRates.roll_rate = RC_tuning.roll_pitch_rate * 100;
|
self.currentRates.roll_rate = RC_tuning.roll_pitch_rate;
|
||||||
self.currentRates.pitch_rate = RC_tuning.roll_pitch_rate * 100;
|
self.currentRates.pitch_rate = RC_tuning.roll_pitch_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePidDisplay();
|
updatePidDisplay();
|
||||||
|
@ -524,49 +524,61 @@ TABS.pid_tuning.initialize = function (callback) {
|
||||||
var maxAngularVelPitchElement = $('.rc_curve .maxAngularVelPitch');
|
var maxAngularVelPitchElement = $('.rc_curve .maxAngularVelPitch');
|
||||||
var maxAngularVelYawElement = $('.rc_curve .maxAngularVelYaw');
|
var maxAngularVelYawElement = $('.rc_curve .maxAngularVelYaw');
|
||||||
|
|
||||||
|
var updateNeeded = true;
|
||||||
|
|
||||||
function updateRates(event) {
|
function updateRates(event) {
|
||||||
setTimeout(function () { // let global validation trigger and adjust the values first
|
setTimeout(function () { // let global validation trigger and adjust the values first
|
||||||
var targetElement = $(event.target),
|
var targetElement = $(event.target),
|
||||||
targetValue = checkInput(targetElement);
|
targetValue = checkInput(targetElement);
|
||||||
|
|
||||||
if (self.currentRates.hasOwnProperty(targetElement.attr('name')) && targetValue) {
|
if (self.currentRates.hasOwnProperty(targetElement.attr('name')) && targetValue) {
|
||||||
self.currentRates[targetElement.attr('name')] = targetValue * 100;
|
self.currentRates[targetElement.attr('name')] = targetValue;
|
||||||
|
|
||||||
|
updateNeeded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetElement.attr('name') === 'rc_rate' && CONFIG.flightControllerIdentifier !== "BTFL" || semver.lt(CONFIG.flightControllerVersion, "2.8.1")) {
|
if (targetElement.attr('name') === 'rc_rate' && CONFIG.flightControllerIdentifier !== "BTFL" || semver.lt(CONFIG.flightControllerVersion, "2.8.1")) {
|
||||||
self.currentRates.rc_rate_yaw = targetValue * 100;
|
self.currentRates.rc_rate_yaw = targetValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetElement.attr('name') === 'roll_pitch_rate' && semver.lt(CONFIG.apiVersion, "1.7.0")) {
|
if (targetElement.attr('name') === 'roll_pitch_rate' && semver.lt(CONFIG.apiVersion, "1.7.0")) {
|
||||||
self.currentRates.roll_rate = targetValue * 100;
|
self.currentRates.roll_rate = targetValue;
|
||||||
self.currentRates.pitch_rate = targetValue * 100;
|
self.currentRates.pitch_rate = targetValue;
|
||||||
|
|
||||||
|
updateNeeded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetElement.attr('name') === 'show_superexpo_rates') {
|
if (targetElement.attr('name') === 'show_superexpo_rates') {
|
||||||
self.currentRates.superexpo = targetElement.is(':checked');
|
self.currentRates.superexpo = targetElement.is(':checked');
|
||||||
|
|
||||||
|
updateNeeded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var curveHeight = rcCurveElement.height;
|
if (updateNeeded) {
|
||||||
var curveWidth = rcCurveElement.width;
|
var curveHeight = rcCurveElement.height;
|
||||||
|
var curveWidth = rcCurveElement.width;
|
||||||
|
|
||||||
var maxAngularVel = Math.max(
|
var maxAngularVel = Math.max(
|
||||||
printMaxAngularVel(self.currentRates.roll_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVelRollElement),
|
printMaxAngularVel(self.currentRates.roll_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVelRollElement),
|
||||||
printMaxAngularVel(self.currentRates.pitch_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVelPitchElement),
|
printMaxAngularVel(self.currentRates.pitch_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVelPitchElement),
|
||||||
printMaxAngularVel(self.currentRates.yaw_rate, self.currentRates.rc_rate_yaw, self.currentRates.rc_yaw_expo, self.currentRates.superexpo, maxAngularVelYawElement));
|
printMaxAngularVel(self.currentRates.yaw_rate, self.currentRates.rc_rate_yaw, self.currentRates.rc_yaw_expo, self.currentRates.superexpo, maxAngularVelYawElement));
|
||||||
|
|
||||||
curveContext.clearRect(0, 0, curveWidth, curveHeight);
|
curveContext.clearRect(0, 0, curveWidth, curveHeight);
|
||||||
|
|
||||||
if (!useLegacyCurve) {
|
if (!useLegacyCurve) {
|
||||||
drawAxes(curveContext, curveWidth, curveHeight, (curveHeight / 2) / maxAngularVel * 360);
|
drawAxes(curveContext, curveWidth, curveHeight, (curveHeight / 2) / maxAngularVel * 360);
|
||||||
|
}
|
||||||
|
|
||||||
|
curveContext.lineWidth = 4;
|
||||||
|
|
||||||
|
drawCurve(self.currentRates.roll_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVel, '#ff0000', 0, curveContext);
|
||||||
|
|
||||||
|
drawCurve(self.currentRates.pitch_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVel, '#00ff00', -4, curveContext);
|
||||||
|
|
||||||
|
drawCurve(self.currentRates.yaw_rate, self.currentRates.rc_rate_yaw, self.currentRates.rc_yaw_expo, self.currentRates.superexpo, maxAngularVel, '#0000ff', 4, curveContext);
|
||||||
|
|
||||||
|
updateNeeded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
curveContext.lineWidth = 4;
|
|
||||||
|
|
||||||
drawCurve(self.currentRates.roll_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVel, '#ff0000', 0, curveContext);
|
|
||||||
|
|
||||||
drawCurve(self.currentRates.pitch_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVel, '#00ff00', -4, curveContext);
|
|
||||||
|
|
||||||
drawCurve(self.currentRates.yaw_rate, self.currentRates.rc_rate_yaw, self.currentRates.rc_yaw_expo, self.currentRates.superexpo, maxAngularVel, '#0000ff', 4, curveContext);
|
|
||||||
}, 0);
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue