dlouapre HF Staff commited on
Commit
308f53f
·
1 Parent(s): 10e6ba6

Document timing limitation on Spaces, simplify fallback

Browse files
Files changed (2) hide show
  1. README.md +4 -3
  2. frontend/app.js +11 -17
README.md CHANGED
@@ -67,9 +67,10 @@ uv run python app.py
67
  ## Current Limitations
68
 
69
  - Sound and picture actions are not yet implemented in execution
70
- - **On HuggingFace Spaces**: Due to browser security policies (HTTPS HTTP localhost), the demo uses a WebSocket fallback instead of the REST API `/goto` endpoint.
71
- - Timing is approximated by repeatedly sending the target position over the specified duration
72
- - For smoother interpolated movements with proper minimum-jerk trajectories, run the demo locally
 
73
 
74
  ## Deployment to HuggingFace Spaces
75
 
 
67
  ## Current Limitations
68
 
69
  - Sound and picture actions are not yet implemented in execution
70
+ - **Movement timing on HuggingFace Spaces**: Due to browser security (HTTPS cannot fetch `http://localhost`), the Space version cannot use the robot's `/goto` endpoint which supports duration control.
71
+ - **On Spaces**: Robot moves to each target as fast as possible (instant), but script execution pauses for the specified duration before the next move
72
+ - **Locally**: Robot moves smoothly with proper duration and minimum-jerk interpolation
73
+ - **Recommendation**: For demos requiring accurate movement timing, run locally
74
 
75
  ## Deployment to HuggingFace Spaces
76
 
frontend/app.js CHANGED
@@ -405,30 +405,24 @@ async function executeIRAction(action) {
405
  await sleep(action.duration * 1000 + 100);
406
 
407
  } catch (fetchError) {
408
- // Fallback to WebSocket with client-side interpolation (for Spaces deployment)
409
- console.warn('Using WebSocket interpolation fallback for duration:', fetchError.message);
 
410
 
411
  if (!state.robotWs || state.robotWs.readyState !== WebSocket.OPEN) {
412
  throw new Error('Robot WebSocket not connected');
413
  }
414
 
415
- // Simulate duration by sending intermediate targets
416
- // Send updates at 10Hz (every 100ms) for smooth movement
417
- const updateInterval = 100; // ms
418
- const numSteps = Math.max(1, Math.floor((action.duration * 1000) / updateInterval));
419
 
420
- for (let step = 0; step <= numSteps; step++) {
421
- const wsMessage = {};
422
- if (head_pose) wsMessage.target_head_pose = head_pose;
423
- if (action.antennas) wsMessage.target_antennas = action.antennas;
424
- if (action.body_yaw !== null) wsMessage.target_body_yaw = action.body_yaw;
425
 
426
- state.robotWs.send(JSON.stringify(wsMessage));
427
-
428
- if (step < numSteps) {
429
- await sleep(updateInterval);
430
- }
431
- }
432
  }
433
  }
434
 
 
405
  await sleep(action.duration * 1000 + 100);
406
 
407
  } catch (fetchError) {
408
+ // Fallback to WebSocket (for Spaces deployment - HTTPS can't fetch localhost)
409
+ // Note: This won't respect durations - robot moves as fast as possible
410
+ console.warn('Using WebSocket fallback - durations not supported:', fetchError.message);
411
 
412
  if (!state.robotWs || state.robotWs.readyState !== WebSocket.OPEN) {
413
  throw new Error('Robot WebSocket not connected');
414
  }
415
 
416
+ const wsMessage = {};
417
+ if (head_pose) wsMessage.target_head_pose = head_pose;
418
+ if (action.antennas) wsMessage.target_antennas = action.antennas;
419
+ if (action.body_yaw !== null) wsMessage.target_body_yaw = action.body_yaw;
420
 
421
+ state.robotWs.send(JSON.stringify(wsMessage));
 
 
 
 
422
 
423
+ // Wait for specified duration to maintain script timing
424
+ // (robot moves fast, but at least script execution pauses correctly)
425
+ await sleep(action.duration * 1000);
 
 
 
426
  }
427
  }
428