upgrade motion pathing

This commit is contained in:
osiu97
2026-07-08 18:23:49 +02:00
parent 57ea3f7b4a
commit 4048ad0fe6
+59 -24
View File
@@ -118,6 +118,35 @@ async function executeQueue() {
} }
} }
function buildSegments(startX, startY, endX, endY, mode) {
const dx = endX - startX;
const dy = endY - startY;
const distance = Math.sqrt(dx * dx + dy * dy);
let numSegments = Math.ceil(distance / CONFIG.SEGMENT_SIZE_MM);
if (numSegments === 0) numSegments = 1;
let segs = [];
for (let i = 1; i <= numSegments; i++) {
const fraction = i / numSegments;
const px = startX + dx * fraction;
const py = startY + dy * fraction;
const wsCheck = IK.checkWorkspace(px, py);
if (!wsCheck.ok) return null;
const res = IK.solve(px, py);
if (!res.reachable || IK.armsCrossed(res.theta1, res.theta2)) return null;
const s1 = IK.radToStepsAbsolute(res.theta1, 1);
const s2 = IK.radToStepsAbsolute(res.theta2, 2);
segs.push({ s1, s2, mode });
}
return segs;
}
/** /**
* Moves the arm to Cartesian targetX, targetY. * Moves the arm to Cartesian targetX, targetY.
* Dynamically slices the path into segments to prevent out-of-bounds arcs. * Dynamically slices the path into segments to prevent out-of-bounds arcs.
@@ -129,6 +158,13 @@ async function goto(targetX, targetY, mode = 'direct') {
return false; return false;
} }
// Quick check on final destination
const destCheck = IK.checkWorkspace(targetX, targetY);
if (!destCheck.ok) {
UI.log(`⛔ Destination blocked: ${destCheck.reason}`, 'error');
return false;
}
// Calculate current Cartesian position // Calculate current Cartesian position
const t1 = IK.stepsToRad(steps1); const t1 = IK.stepsToRad(steps1);
const t2 = IK.stepsToRad(steps2); const t2 = IK.stepsToRad(steps2);
@@ -139,38 +175,37 @@ async function goto(targetX, targetY, mode = 'direct') {
return false; return false;
} }
const dx = targetX - currentPos.endX; let segments = buildSegments(currentPos.endX, currentPos.endY, targetX, targetY, mode);
const dy = targetY - currentPos.endY;
const distance = Math.sqrt(dx * dx + dy * dy);
let numSegments = Math.ceil(distance / CONFIG.SEGMENT_SIZE_MM); if (!segments) {
if (numSegments === 0) numSegments = 1; // Attempt rerouting through safe overhead point
const SAFE_X = 0;
const SAFE_Y = 75;
motionQueue = []; // Prevent infinite loop if already at/near safe point
const distToSafe = Math.sqrt(Math.pow(currentPos.endX - SAFE_X, 2) + Math.pow(currentPos.endY - SAFE_Y, 2));
for (let i = 1; i <= numSegments; i++) { if (distToSafe < 5) {
const fraction = i / numSegments; UI.log(`⛔ Path completely blocked even via safe point`, 'error');
const px = currentPos.endX + dx * fraction; return false;
const py = currentPos.endY + dy * fraction;
const wsCheck = IK.checkWorkspace(px, py);
if (!wsCheck.ok) {
UI.log(`⛔ Waypoint blocked: ${wsCheck.reason}`, 'error');
return false; // abort full move
} }
const res = IK.solve(px, py); const leg1 = buildSegments(currentPos.endX, currentPos.endY, SAFE_X, SAFE_Y, mode);
if (!res.reachable || IK.armsCrossed(res.theta1, res.theta2)) { if (leg1) {
UI.log(`Waypoint geometrically unreachable.`, 'error'); const leg2 = buildSegments(SAFE_X, SAFE_Y, targetX, targetY, mode);
if (leg2) {
segments = leg1.concat(leg2);
UI.log(`Rerouting around exclusion zone via (0, 75)`, 'info');
}
}
if (!segments) {
UI.log(`⛔ Target unreachable (path blocked by mechanism)`, 'error');
return false; return false;
} }
const s1 = IK.radToStepsAbsolute(res.theta1, 1);
const s2 = IK.radToStepsAbsolute(res.theta2, 2);
motionQueue.push({ s1, s2, mode });
} }
motionQueue = segments;
return new Promise((resolve) => { return new Promise((resolve) => {
currentResolve = resolve; currentResolve = resolve;
executeQueue(); executeQueue();