Implement motion timeout. #21

This commit is contained in:
PROFERIS - Mi³osz Stocki
2026-07-09 13:39:40 +02:00
parent d536ec5ced
commit 79e0be007e
+23 -6
View File
@@ -6,13 +6,22 @@ import { MotionEffects } from './motion-effects.js';
const CONFIG = { const CONFIG = {
SEGMENT_SIZE_MM: 25, // Maximum distance between waypoints to prevent out-of-bounds joint-space arcs SEGMENT_SIZE_MM: 25, // Maximum distance between waypoints to prevent out-of-bounds joint-space arcs
BLEND_THRESHOLD_STEPS: 300 // Send next waypoint when within this many steps (prevents deceleration) BLEND_THRESHOLD_STEPS: 300, // Send next waypoint when within this many steps (prevents deceleration)
WAYPOINT_TIMEOUT_MS: 8000 // Max time to wait for a single waypoint to complete before declaring a stall
}; };
// Global state tracking // Global state tracking
let steps1 = 0; let steps1 = 0;
let steps2 = 0; let steps2 = 0;
function forceUnhome(reason) {
localStorage.setItem('wiji_homed', 'false');
UI.log(reason, 'warn');
document.dispatchEvent(new CustomEvent('wiji:unhomed'));
const warningEl = document.getElementById('home-warning');
if (warningEl) warningEl.style.display = 'block';
}
// Listen to BLE position updates // Listen to BLE position updates
document.addEventListener('ble:status', (e) => { document.addEventListener('ble:status', (e) => {
const msg = e.detail; const msg = e.detail;
@@ -25,11 +34,7 @@ document.addEventListener('ble:status', (e) => {
if (parts.length > 2) { if (parts.length > 2) {
const isHolding = parts[2] === '1'; const isHolding = parts[2] === '1';
if (!isHolding && localStorage.getItem('wiji_homed') === 'true') { if (!isHolding && localStorage.getItem('wiji_homed') === 'true') {
localStorage.setItem('wiji_homed', 'false'); forceUnhome('Steppers are not holding. Rehoming required.');
UI.log('Steppers are not holding. Rehoming required.', 'warn');
document.dispatchEvent(new CustomEvent('wiji:unhomed'));
const warningEl = document.getElementById('home-warning');
if (warningEl) warningEl.style.display = 'block';
} }
} }
} }
@@ -88,12 +93,24 @@ async function executeQueue() {
// Setup interval to monitor progress // Setup interval to monitor progress
if (queueCheckInterval) clearInterval(queueCheckInterval); if (queueCheckInterval) clearInterval(queueCheckInterval);
const waypointStartTime = Date.now();
queueCheckInterval = setInterval(async () => { queueCheckInterval = setInterval(async () => {
// Calculate distance to target in steps // Calculate distance to target in steps
const dist1 = Math.abs(target.s1 - steps1); const dist1 = Math.abs(target.s1 - steps1);
const dist2 = Math.abs(target.s2 - steps2); const dist2 = Math.abs(target.s2 - steps2);
const maxDist = Math.max(dist1, dist2); const maxDist = Math.max(dist1, dist2);
// Check for timeout stall
if (Date.now() - waypointStartTime > CONFIG.WAYPOINT_TIMEOUT_MS) {
clearInterval(queueCheckInterval);
motionQueue = [];
isMoving = false;
forceUnhome('Motion timeout! Arms may be stuck. Rehoming required.');
if (currentResolve) currentResolve(false);
currentResolve = null;
return;
}
if (motionQueue.length > 0) { if (motionQueue.length > 0) {
const nextTarget = motionQueue[0]; const nextTarget = motionQueue[0];
const queueAction = MotionEffects.getQueueAction(target.mode, nextTarget.mode, maxDist, CONFIG.BLEND_THRESHOLD_STEPS); const queueAction = MotionEffects.getQueueAction(target.mode, nextTarget.mode, maxDist, CONFIG.BLEND_THRESHOLD_STEPS);