mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-21 15:25:22 +03:00
draw throttle position in tuning tab
This commit is contained in:
parent
d7e65b86e1
commit
b5f65495a8
1 changed files with 87 additions and 38 deletions
|
@ -1302,48 +1302,85 @@ TABS.pid_tuning.initialize = function (callback) {
|
||||||
$('input.feature').on('input change', updateRates);
|
$('input.feature').on('input change', updateRates);
|
||||||
$('.pid_tuning').on('input change', updateRates).trigger('input');
|
$('.pid_tuning').on('input change', updateRates).trigger('input');
|
||||||
|
|
||||||
$('.throttle input').on('input change', function () {
|
function redrawThrottleCurve(forced) {
|
||||||
setTimeout(function () { // let global validation trigger and adjust the values first
|
if (!forced && !TABS.pid_tuning.checkThrottle()) {
|
||||||
var throttleMidE = $('.throttle input[name="mid"]'),
|
return;
|
||||||
throttleExpoE = $('.throttle input[name="expo"]'),
|
}
|
||||||
mid = parseFloat(throttleMidE.val()),
|
|
||||||
expo = parseFloat(throttleExpoE.val()),
|
|
||||||
throttleCurve = $('.throttle .throttle_curve canvas').get(0),
|
|
||||||
context = throttleCurve.getContext("2d");
|
|
||||||
|
|
||||||
// local validation to deal with input event
|
/*
|
||||||
if (mid >= parseFloat(throttleMidE.prop('min')) &&
|
Quadratic curve formula taken from:
|
||||||
mid <= parseFloat(throttleMidE.prop('max')) &&
|
https://stackoverflow.com/a/9195706/176210
|
||||||
expo >= parseFloat(throttleExpoE.prop('min')) &&
|
*/
|
||||||
expo <= parseFloat(throttleExpoE.prop('max'))) {
|
|
||||||
// continue
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var canvasHeight = throttleCurve.height;
|
function getQBezierValue(t, p1, p2, p3) {
|
||||||
var canvasWidth = throttleCurve.width;
|
var iT = 1 - t;
|
||||||
|
return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;
|
||||||
|
}
|
||||||
|
|
||||||
// math magic by englishman
|
function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {
|
||||||
var midx = canvasWidth * mid,
|
return {
|
||||||
midxl = midx * 0.5,
|
x: getQBezierValue(position, startX, cpX, endX),
|
||||||
midxr = (((canvasWidth - midx) * 0.5) + midx),
|
y: getQBezierValue(position, startY, cpY, endY),
|
||||||
midy = canvasHeight - (midx * (canvasHeight / canvasWidth)),
|
};
|
||||||
midyl = canvasHeight - ((canvasHeight - midy) * 0.5 *(expo + 1)),
|
}
|
||||||
midyr = (midy / 2) * (expo + 1);
|
|
||||||
|
|
||||||
// draw
|
/* --- */
|
||||||
context.clearRect(0, 0, canvasWidth, canvasHeight);
|
|
||||||
context.beginPath();
|
// let global validation trigger and adjust the values first
|
||||||
context.moveTo(0, canvasHeight);
|
var throttleMidE = $('.throttle input[name="mid"]'),
|
||||||
context.quadraticCurveTo(midxl, midyl, midx, midy);
|
throttleExpoE = $('.throttle input[name="expo"]'),
|
||||||
context.moveTo(midx, midy);
|
mid = parseFloat(throttleMidE.val()),
|
||||||
context.quadraticCurveTo(midxr, midyr, canvasWidth, 0);
|
expo = parseFloat(throttleExpoE.val()),
|
||||||
context.lineWidth = 2;
|
throttleCurve = $('.throttle .throttle_curve canvas').get(0),
|
||||||
context.strokeStyle = '#ffbb00';
|
context = throttleCurve.getContext("2d");
|
||||||
context.stroke();
|
|
||||||
}, 0);
|
// local validation to deal with input event
|
||||||
}).trigger('input');
|
if (mid >= parseFloat(throttleMidE.prop('min')) &&
|
||||||
|
mid <= parseFloat(throttleMidE.prop('max')) &&
|
||||||
|
expo >= parseFloat(throttleExpoE.prop('min')) &&
|
||||||
|
expo <= parseFloat(throttleExpoE.prop('max'))) {
|
||||||
|
// continue
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var canvasHeight = throttleCurve.height;
|
||||||
|
var canvasWidth = throttleCurve.width;
|
||||||
|
|
||||||
|
// math magic by englishman
|
||||||
|
var midx = canvasWidth * mid,
|
||||||
|
midxl = midx * 0.5,
|
||||||
|
midxr = (((canvasWidth - midx) * 0.5) + midx),
|
||||||
|
midy = canvasHeight - (midx * (canvasHeight / canvasWidth)),
|
||||||
|
midyl = canvasHeight - ((canvasHeight - midy) * 0.5 *(expo + 1)),
|
||||||
|
midyr = (midy / 2) * (expo + 1);
|
||||||
|
|
||||||
|
let thrPercent = (RC.channels[3] - 1000) / 1000,
|
||||||
|
thrpos = thrPercent <= mid
|
||||||
|
? getQuadraticCurvePoint(0, canvasHeight, midxl, midyl, midx, midy, thrPercent * (1.0 / mid))
|
||||||
|
: getQuadraticCurvePoint(midx, midy, midxr, midyr, canvasWidth, 0, (thrPercent - mid) * (1.0 / (1.0 - mid)));
|
||||||
|
|
||||||
|
// draw
|
||||||
|
context.clearRect(0, 0, canvasWidth, canvasHeight);
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(0, canvasHeight);
|
||||||
|
context.quadraticCurveTo(midxl, midyl, midx, midy);
|
||||||
|
context.moveTo(midx, midy);
|
||||||
|
context.quadraticCurveTo(midxr, midyr, canvasWidth, 0);
|
||||||
|
context.lineWidth = 2;
|
||||||
|
context.strokeStyle = '#ffbb00';
|
||||||
|
context.stroke();
|
||||||
|
context.beginPath();
|
||||||
|
context.arc(thrpos.x, thrpos.y, 4, 0, 2 * Math.PI);
|
||||||
|
context.fillStyle = context.strokeStyle;
|
||||||
|
context.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.throttle input')
|
||||||
|
.on('input change', () => setTimeout(() => redrawThrottleCurve(true), 0))
|
||||||
|
.trigger('input');
|
||||||
|
|
||||||
|
TABS.pid_tuning.throttleDrawInterval = setInterval(redrawThrottleCurve, 100);
|
||||||
|
|
||||||
$('a.refresh').click(function () {
|
$('a.refresh').click(function () {
|
||||||
self.refresh(function () {
|
self.refresh(function () {
|
||||||
|
@ -1736,6 +1773,7 @@ TABS.pid_tuning.cleanup = function (callback) {
|
||||||
|
|
||||||
|
|
||||||
self.keepRendering = false;
|
self.keepRendering = false;
|
||||||
|
clearInterval(TABS.pid_tuning.throttleDrawInterval);
|
||||||
|
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
};
|
};
|
||||||
|
@ -1833,6 +1871,17 @@ TABS.pid_tuning.checkRC = function() {
|
||||||
return rateCurveUpdateRequired;
|
return rateCurveUpdateRequired;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TABS.pid_tuning.checkThrottle = function() {
|
||||||
|
// Function monitors for change in the received rc throttle data and returns true if a change is detected.
|
||||||
|
if (!this.oldThrottle) {
|
||||||
|
this.oldThrottle = RC.channels[3];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var updateRequired = this.oldThrottle != RC.channels[3];
|
||||||
|
this.oldThrottle = RC.channels[3];
|
||||||
|
return updateRequired;
|
||||||
|
};
|
||||||
|
|
||||||
TABS.pid_tuning.updatePidControllerParameters = function () {
|
TABS.pid_tuning.updatePidControllerParameters = function () {
|
||||||
if (semver.gte(CONFIG.apiVersion, "1.20.0") && semver.lt(CONFIG.apiVersion, "1.31.0") && $('.tab-pid_tuning select[name="controller"]').val() === '0') {
|
if (semver.gte(CONFIG.apiVersion, "1.20.0") && semver.lt(CONFIG.apiVersion, "1.31.0") && $('.tab-pid_tuning select[name="controller"]').val() === '0') {
|
||||||
$('.pid_tuning .YAW_JUMP_PREVENTION').show();
|
$('.pid_tuning .YAW_JUMP_PREVENTION').show();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue