1
0
Fork 0
mirror of https://github.com/betaflight/betaflight-configurator.git synced 2025-07-16 12:55:14 +03:00
betaflight-configurator/js/RateCurve.js
mikeller 1da5219bf2 Added new rc rate calculation to rates curve. Removed SUPER_EXPO feature for >= 3.0.
Added support for RC Expo Power setting.

fixed titlebar in pid tuning tab

request from @mikeller #252
fixed titlebar from pid tuning and accel
2016-09-05 11:02:33 +12:00

114 lines
3.8 KiB
JavaScript
Executable file

'use strict';
var minRc = 1000;
var midRc = 1500;
var maxRc = 2000;
var RateCurve = function (useLegacyCurve) {
this.useLegacyCurve = useLegacyCurve;
this.constrain = function (value, min, max) {
return Math.max(min, Math.min(value, max));
};
this.rcCommand = function (rcData, rcRate) {
var tmp = Math.min(Math.abs(rcData - midRc), 500);
rcRate = rcRate;
if (rcRate > 2) {
rcRate = rcRate + (rcRate - 2) * 14.54;
}
var result = tmp * rcRate;
if (rcData < midRc) {
result = -result;
}
return result;
};
this.drawRateCurve = function (rate, rcRate, rcExpo, superExpoActive, maxAngularVel, context, width, height) {
var canvasHeightScale = height / (2 * maxAngularVel);
var stepWidth = context.lineWidth;
context.save();
context.translate(width / 2, height / 2);
context.beginPath();
var rcData = minRc;
context.moveTo(-500, -canvasHeightScale * this.rcCommandRawToDegreesPerSecond(rcData, rate, rcRate, rcExpo, superExpoActive));
rcData = rcData + stepWidth;
while (rcData <= maxRc) {
context.lineTo(rcData - midRc, -canvasHeightScale * this.rcCommandRawToDegreesPerSecond(rcData, rate, rcRate, rcExpo, superExpoActive));
rcData = rcData + stepWidth;
}
context.stroke();
context.restore();
};
this.drawLegacyRateCurve = function (rate, rcRate, rcExpo, context, width, height) {
// math magic by englishman
var rateY = height * rcRate;
rateY = rateY + (1 / (1 - ((rateY / height) * rate)))
// draw
context.beginPath();
context.moveTo(0, height);
context.quadraticCurveTo(width * 11 / 20, height - ((rateY / 2) * (1 - rcExpo)), width, height - rateY);
context.stroke();
}
};
RateCurve.prototype.rcCommandRawToDegreesPerSecond = function (rcData, rate, rcRate, rcExpo, superExpoActive) {
var angleRate;
if (rate !== undefined && rcRate !== undefined && rcExpo !== undefined) {
var inputValue = this.rcCommand(rcData, rcRate);
var maxRc = 500 * rcRate;
if (rcExpo > 0) {
var absRc = Math.abs(inputValue) / maxRc;
inputValue = inputValue * ((rcExpo * absRc * absRc * absRc) + absRc * (1-rcExpo)); // absRc should be wrapped in function using expo power
}
var rcInput = inputValue / maxRc;
if (superExpoActive) {
var rcFactor = 1 / this.constrain(1 - Math.abs(rcInput) * rate, 0.01, 1);
angleRate = 200 * rcRate * rcInput; // 200 should be variable checked on version (older versions it's 205,9)
angleRate = angleRate * rcFactor;
} else {
angleRate = (((rate * 100) + 27) * inputValue / 16) / 4.1; // Only applies to old versions ?
}
angleRate = this.constrain(angleRate, -1998, 1998); // Rate limit protection
}
return angleRate;
};
RateCurve.prototype.getMaxAngularVel = function (rate, rcRate, rcExpo, superExpoActive) {
var maxAngularVel;
if (!this.useLegacyCurve) {
maxAngularVel = this.rcCommandRawToDegreesPerSecond(maxRc, rate, rcRate, rcExpo, superExpoActive);
}
return maxAngularVel;
};
RateCurve.prototype.draw = function (rate, rcRate, rcExpo, superExpoActive, maxAngularVel, context) {
if (rate !== undefined && rcRate !== undefined && rcExpo !== undefined) {
var height = context.canvas.height;
var width = context.canvas.width;
if (this.useLegacyCurve) {
this.drawLegacyRateCurve(rate, rcRate, rcExpo, context, width, height);
} else {
this.drawRateCurve(rate, rcRate, rcExpo, superExpoActive, maxAngularVel, context, width, height);
}
}
};