From 08bef5db3ef6c3886ec19bf79a945e799a0ad477 Mon Sep 17 00:00:00 2001 From: ChrisRosser <41840611+ChrisRosser@users.noreply.github.com> Date: Sat, 6 Apr 2024 18:09:15 +0100 Subject: [PATCH] first atttempt --- src/js/fc.js | 2 ++ src/js/tabs/pid_tuning.js | 52 ++++++++++++++++++++++++++++++--------- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/js/fc.js b/src/js/fc.js index 21c34a97c81..e573923c48c 100644 --- a/src/js/fc.js +++ b/src/js/fc.js @@ -250,6 +250,8 @@ const FC = { rcYawRate: 0, rcPitchRate: 0, RC_PITCH_EXPO: 0, + throttleLimitType: 0, + throttleLimitPercent: 100, roll_rate_limit: 1998, pitch_rate_limit: 1998, yaw_rate_limit: 1998, diff --git a/src/js/tabs/pid_tuning.js b/src/js/tabs/pid_tuning.js index f709b180881..ae1185ee323 100644 --- a/src/js/tabs/pid_tuning.js +++ b/src/js/tabs/pid_tuning.js @@ -1719,22 +1719,30 @@ pid_tuning.initialize = function (callback) { Maths from: https://stackoverflow.com/questions/40918569/quadratic-bezier-curve-calculate-x-for-any-given-y */ function getPosfromYBezier(y, startY, cpY, endY){ - // y = (p0+p2-2p1)x^2 + 2(p1 - p2)x + p2 - // 0 = (p0+p2-2p1)x^2 + 2(p1 - p2)x + (p2 - y) - // x = ( -2(p1 - p2) + sqrt( (2(p1 - p2))^2 - 4 * (p0+p2-2p1) * (p2 - y) ) ) / ( 2 * (p0+p2-2p1)) - const a = startY+endY-2*cpY - const b = 2*(cpY - endY) - const c = endY - y - return (-b + Math.sqrt(Math.pow(b, 2) - 4 * a * c)) / (2 * a) + // y = (1-t)^2 * p0 + 2 * (1-t)*t*p1 + t^2 * p2 + // y = (p2+p0-2p1)x^2 + 2(p1 - p0)x + p0 + // 0 = (p2+p0-2p1)x^2 + 2(p1 - p0)x + (p0 - y) + const a = startY+endY-2*cpY + const b = 2*(cpY - startY) + const c = startY - y + return a==0? -c/b : (-b + Math.sqrt(Math.pow(b, 2) - 4 * a * c)) / (2 * a) } /* --- */ - + const THROTTLE_LIMIT_TYPES = { + OFF: 0, + SCALE: 1, + CLIP: 2, + }; // let global validation trigger and adjust the values first const throttleMidE = $('.throttle input[name="mid"]'); const throttleExpoE = $('.throttle input[name="expo"]'); + const throttleLimitPercentE = $('.throttle_limit input[name="throttleLimitPercent"]'); + const throttleLimitTypeE = $('.throttle_limit select[id="throttleLimitType"]'); const mid = parseFloat(throttleMidE.val()); const expo = parseFloat(throttleExpoE.val()); + const throttleLimitPercent = parseInt(throttleLimitPercentE.val()) / 100; + const throttleLimitType = parseInt(throttleLimitTypeE.val()); const throttleCurve = $('.throttle .throttle_curve canvas').get(0); const context = throttleCurve.getContext("2d"); @@ -1755,12 +1763,13 @@ pid_tuning.initialize = function (callback) { const canvasWidth = throttleCurve.width; // math magic by englishman + const curvescale = throttleLimitType === THROTTLE_LIMIT_TYPES.SCALE ? throttleLimitPercent : 1; const midx = canvasWidth * mid; const midxl = midx * 0.5; const midxr = (((canvasWidth - midx) * 0.5) + midx); - const midy = canvasHeight - (midx * (canvasHeight / canvasWidth)); - const midyl = canvasHeight - ((canvasHeight - midy) * 0.5 *(expo + 1)); - const midyr = (midy / 2) * (expo + 1); + const midy = (canvasHeight - (midx * (canvasHeight / canvasWidth))) * curvescale; + const midyl = (canvasHeight - ((canvasHeight - midy) * 0.5 *(expo + 1))) * curvescale; + const midyr = ((midy / 2) * (expo + 1)) * curvescale; let thrPercent = (FC.RC.channels[3] - 1000) / 1000, thrpos = thrPercent <= mid @@ -1771,6 +1780,27 @@ pid_tuning.initialize = function (callback) { context.clearRect(0, 0, canvasWidth, canvasHeight); context.beginPath(); context.moveTo(0, canvasHeight); + if (throttleLimitType === THROTTLE_LIMIT_TYPES.CLIP){ + const clippos = throttleLimitPercent <= midy + ? getPosfromYBezier(throttleLimitPercent,canvasHeight,midyl, midy) + : getPosfromYBezier(throttleLimitPercent,midy, midyl, 0); + if (throttleLimitPercent <= midyl){ + //first half + lowerctrl = getQuadraticCurvePoint(0, canvasHeight, midxl, midyl, midx, midy, clippos/2); + curveclip = getQuadraticCurvePoint(0, canvasHeight, midxl, midyl, midx, midy, clippos); + context.quadraticCurveTo(lowerctrl.x, lowerctrl.y, curveclip.x, curveclip.y); + context.moveTo(curveclip.x, curveclip.y); + context.lineTo(canvasWidth, curveclip.y); + } else { + context.quadraticCurveTo(midxl, midyl, midx, midy); + context.moveTo(midx, midy); + lowerctrl = getQuadraticCurvePoint(midx, midy, midxr, midyr, canvasWidth, 0, clippos/2); + curveclip = getQuadraticCurvePoint(midx, midy, midxr, midyr, canvasWidth, 0, clippos); + context.quadraticCurveTo(lowerctrl.x, lowerctrl.y, curveclip.x, curveclip.y); + context.moveTo(curveclip.x, curveclip.y); + context.lineTo(canvasWidth, curveclip.y); + } + } context.quadraticCurveTo(midxl, midyl, midx, midy); context.moveTo(midx, midy); context.quadraticCurveTo(midxr, midyr, canvasWidth, 0);