Przeglądaj źródła

add buttons to calibrate

tuanchris 5 miesięcy temu
rodzic
commit
f24ab61d21
2 zmienionych plików z 107 dodań i 2 usunięć
  1. 3 1
      modules/core/pattern_manager.py
  2. 104 1
      templates/table_control.html

+ 3 - 1
modules/core/pattern_manager.py

@@ -547,7 +547,9 @@ def get_status():
         "speed": state.speed,
         "pause_time_remaining": state.pause_time_remaining,
         "original_pause_time": getattr(state, 'original_pause_time', None),
-        "connection_status": state.conn.is_connected() if state.conn else False
+        "connection_status": state.conn.is_connected() if state.conn else False,
+        "current_theta": state.current_theta,
+        "current_rho": state.current_rho
     }
     
     # Add playlist information if available

+ 104 - 1
templates/table_control.html

@@ -192,7 +192,7 @@
         </li>
         <li class="flex items-start gap-3">
           <span class="font-semibold text-blue-600 dark:text-blue-400 min-w-[20px]">2.</span>
-          <span><strong>Manually</strong> move the radial arm to point 90° to the right of where you want the pattern bottom to be.</span>
+          <span><strong>Manually</strong> move the radial arm or <strong>use the rotation buttons below</strong> to point 90° to the right of where you want the pattern bottom to be.</span>
         </li>
         <li class="flex items-start gap-3">
           <span class="font-semibold text-blue-600 dark:text-blue-400 min-w-[20px]">3.</span>
@@ -210,6 +210,34 @@
         </p>
       </div>
       
+      <!-- Fine Adjustment Controls -->
+      <div class="border-t border-gray-200 dark:border-gray-600 pt-4 mb-4">
+        <p class="text-gray-700 dark:text-gray-300 text-sm mb-3 text-center">
+          <strong>Fine Adjustment:</strong> Use these buttons to rotate the ball precisely
+        </p>
+        <div class="flex justify-center gap-3">
+          <button
+            id="rotateCCW"
+            class="flex items-center gap-2 px-4 py-2 bg-gray-600 hover:bg-gray-700 text-white rounded-lg transition-colors"
+            title="Rotate Counter-Clockwise 10°"
+          >
+            <span class="material-icons text-lg">rotate_left</span>
+            <span class="text-sm">CCW 10°</span>
+          </button>
+          <button
+            id="rotateCW"
+            class="flex items-center gap-2 px-4 py-2 bg-gray-600 hover:bg-gray-700 text-white rounded-lg transition-colors"
+            title="Rotate Clockwise 10°"
+          >
+            <span class="text-sm">CW 10°</span>
+            <span class="material-icons text-lg">rotate_right</span>
+          </button>
+        </div>
+        <p class="text-gray-500 dark:text-gray-400 text-xs text-center mt-2">
+          Each click rotates 10 degrees for fine adjustment
+        </p>
+      </div>
+      
       <div class="flex justify-center">
         <button
           id="closeOrientationHelpModal"
@@ -231,6 +259,12 @@ document.addEventListener('DOMContentLoaded', function() {
   const helpButton = document.getElementById('orientationHelpButton');
   const modal = document.getElementById('orientationHelpModal');
   const closeButton = document.getElementById('closeOrientationHelpModal');
+  const rotateCWButton = document.getElementById('rotateCW');
+  const rotateCCWButton = document.getElementById('rotateCCW');
+  
+  // Track current position (theta, rho)
+  let currentTheta = 0;
+  let currentRho = 1; // Always at perimeter for rotation adjustments
   
   helpButton.addEventListener('click', () => {
     modal.classList.remove('hidden');
@@ -246,6 +280,75 @@ document.addEventListener('DOMContentLoaded', function() {
       modal.classList.add('hidden');
     }
   });
+  
+  // Rotation button handlers
+  async function rotateByDegrees(degrees) {
+    try {
+      // Convert degrees to radians
+      const radians = degrees * (Math.PI / 180);
+      
+      // Calculate new theta position
+      const newTheta = currentTheta + radians;
+      
+      // Send coordinate to move to new position (always at perimeter, rho = 1)
+      const response = await fetch('/send_coordinate', {
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json',
+        },
+        body: JSON.stringify({
+          theta: newTheta,
+          rho: 1
+        })
+      });
+      
+      if (response.ok) {
+        // Update tracked position
+        currentTheta = newTheta;
+        console.log(`Rotated ${degrees}°. New theta: ${(currentTheta * 180 / Math.PI).toFixed(1)}°`);
+      } else {
+        throw new Error('Failed to send coordinate');
+      }
+    } catch (error) {
+      console.error('Error rotating:', error);
+      alert('Failed to rotate. Please check connection.');
+    }
+  }
+  
+  // Clockwise rotation (positive angle)
+  rotateCWButton.addEventListener('click', async () => {
+    await rotateByDegrees(10);
+  });
+  
+  // Counter-clockwise rotation (negative angle)  
+  rotateCCWButton.addEventListener('click', async () => {
+    await rotateByDegrees(-10);
+  });
+  
+  // Try to get current position from WebSocket status
+  // This assumes you have a WebSocket connection for status updates
+  if (typeof ws !== 'undefined' && ws) {
+    const originalOnMessage = ws.onmessage;
+    ws.onmessage = function(event) {
+      try {
+        const data = JSON.parse(event.data);
+        if (data.type === 'status_update' && data.data) {
+          // Update current theta position if available in status
+          if (data.data.current_theta !== undefined) {
+            currentTheta = data.data.current_theta;
+          }
+          // Keep rho at 1 for rotation adjustments
+          currentRho = 1;
+        }
+      } catch (error) {
+        // Ignore parsing errors
+      }
+      // Call original handler if it exists
+      if (originalOnMessage) {
+        originalOnMessage.call(ws, event);
+      }
+    };
+  }
 });
 </script>
 {% endblock %}