Idle animations. Closes #14
This commit is contained in:
+34
-14
@@ -52,21 +52,39 @@ function getSteps() {
|
||||
|
||||
let motionQueue = [];
|
||||
let isMoving = false;
|
||||
let currentIsIdleMove = false;
|
||||
let currentResolve = null;
|
||||
let queueCheckInterval = null;
|
||||
let currentMotionMode = 'direct';
|
||||
let hasHesitated = false;
|
||||
|
||||
function stopCurrentMove() {
|
||||
motionQueue = [];
|
||||
isMoving = false;
|
||||
if (queueCheckInterval) {
|
||||
clearInterval(queueCheckInterval);
|
||||
queueCheckInterval = null;
|
||||
}
|
||||
if (currentResolve) {
|
||||
currentResolve(false); // resolve false because aborted
|
||||
currentResolve = null;
|
||||
}
|
||||
}
|
||||
|
||||
async function executeQueue() {
|
||||
if (motionQueue.length === 0) {
|
||||
isMoving = false;
|
||||
if (queueCheckInterval) clearInterval(queueCheckInterval);
|
||||
if (queueCheckInterval) {
|
||||
clearInterval(queueCheckInterval);
|
||||
queueCheckInterval = null;
|
||||
}
|
||||
|
||||
// Restore speed if it was altered
|
||||
await MotionEffects.onSequenceEnd(currentMotionMode);
|
||||
|
||||
if (currentResolve) currentResolve(true);
|
||||
currentResolve = null;
|
||||
document.dispatchEvent(new CustomEvent('wiji:motion-end', { detail: { isIdleMove: currentIsIdleMove } }));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -83,11 +101,8 @@ async function executeQueue() {
|
||||
await BLE.write(cmd);
|
||||
} catch (e) {
|
||||
UI.log(`BLE error: ${e.message}`, 'error');
|
||||
motionQueue = []; // clear queue on error
|
||||
isMoving = false;
|
||||
if (queueCheckInterval) clearInterval(queueCheckInterval);
|
||||
if (currentResolve) currentResolve(false);
|
||||
currentResolve = null;
|
||||
stopCurrentMove();
|
||||
document.dispatchEvent(new CustomEvent('wiji:motion-end', { detail: { isIdleMove: currentIsIdleMove } }));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,12 +117,9 @@ async function executeQueue() {
|
||||
|
||||
// Check for timeout stall
|
||||
if (Date.now() - waypointStartTime > CONFIG.WAYPOINT_TIMEOUT_MS) {
|
||||
clearInterval(queueCheckInterval);
|
||||
motionQueue = [];
|
||||
isMoving = false;
|
||||
stopCurrentMove();
|
||||
forceUnhome('Motion timeout! Arms may be stuck. Rehoming required.');
|
||||
if (currentResolve) currentResolve(false);
|
||||
currentResolve = null;
|
||||
document.dispatchEvent(new CustomEvent('wiji:motion-end', { detail: { isIdleMove: currentIsIdleMove } }));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -222,12 +234,18 @@ function buildSegments(startX, startY, endX, endY, mode) {
|
||||
* Dynamically slices the path into segments to prevent out-of-bounds arcs.
|
||||
* @returns {Promise<boolean>} Resolves to true if successful, false if aborted/error.
|
||||
*/
|
||||
async function goto(targetX, targetY, mode = 'direct') {
|
||||
async function goto(targetX, targetY, mode = 'direct', isIdleMove = false) {
|
||||
if (isMoving) {
|
||||
UI.log('Arm is currently moving! Wait for it to finish.', 'warn');
|
||||
return false;
|
||||
// If the currently executing move is an idle move, and this is a user move, we can interrupt it.
|
||||
if (currentIsIdleMove && !isIdleMove) {
|
||||
stopCurrentMove(); // Abort the idle move
|
||||
} else {
|
||||
UI.log('Arm is currently moving! Wait for it to finish.', 'warn');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
currentIsIdleMove = isIdleMove;
|
||||
mode = MotionEffects.resolveMode(mode);
|
||||
|
||||
currentMotionMode = mode;
|
||||
@@ -283,6 +301,8 @@ async function goto(targetX, targetY, mode = 'direct') {
|
||||
|
||||
await MotionEffects.onSequenceStart(mode);
|
||||
|
||||
document.dispatchEvent(new CustomEvent('wiji:motion-start', { detail: { isIdleMove: currentIsIdleMove } }));
|
||||
|
||||
return new Promise((resolve) => {
|
||||
currentResolve = resolve;
|
||||
executeQueue();
|
||||
|
||||
Reference in New Issue
Block a user