1
0
tuanchris 3 сар өмнө
parent
commit
25f5bc4233

+ 10 - 7
main.py

@@ -382,26 +382,29 @@ async def set_scheduled_pause(request: ScheduledPauseRequest):
 
 
 @app.get("/api/angular-homing")
 @app.get("/api/angular-homing")
 async def get_angular_homing():
 async def get_angular_homing():
-    """Get current angular homing setting."""
+    """Get current angular homing settings."""
     return {
     return {
-        "angular_homing_enabled": state.angular_homing_enabled
+        "angular_homing_enabled": state.angular_homing_enabled,
+        "angular_homing_offset_degrees": state.angular_homing_offset_degrees
     }
     }
 
 
 class AngularHomingRequest(BaseModel):
 class AngularHomingRequest(BaseModel):
     angular_homing_enabled: bool
     angular_homing_enabled: bool
+    angular_homing_offset_degrees: float = 0.0
 
 
 @app.post("/api/angular-homing")
 @app.post("/api/angular-homing")
 async def set_angular_homing(request: AngularHomingRequest):
 async def set_angular_homing(request: AngularHomingRequest):
-    """Update angular homing setting."""
+    """Update angular homing settings."""
     try:
     try:
         state.angular_homing_enabled = request.angular_homing_enabled
         state.angular_homing_enabled = request.angular_homing_enabled
+        state.angular_homing_offset_degrees = request.angular_homing_offset_degrees
         state.save()
         state.save()
 
 
-        logger.info(f"Angular homing {'enabled' if request.angular_homing_enabled else 'disabled'}")
-        return {"success": True, "message": "Angular homing setting updated"}
+        logger.info(f"Angular homing {'enabled' if request.angular_homing_enabled else 'disabled'}, offset: {request.angular_homing_offset_degrees}°")
+        return {"success": True, "message": "Angular homing settings updated"}
     except Exception as e:
     except Exception as e:
-        logger.error(f"Error updating angular homing setting: {str(e)}")
-        raise HTTPException(status_code=500, detail=f"Failed to update angular homing setting: {str(e)}")
+        logger.error(f"Error updating angular homing settings: {str(e)}")
+        raise HTTPException(status_code=500, detail=f"Failed to update angular homing settings: {str(e)}")
 
 
 @app.get("/list_serial_ports")
 @app.get("/list_serial_ports")
 async def list_ports():
 async def list_ports():

+ 8 - 3
modules/connection/connection_manager.py

@@ -510,10 +510,15 @@ def home(timeout=90):
                         if not reed_switch_triggered:
                         if not reed_switch_triggered:
                             logger.warning("Completed full rotation without reed switch trigger")
                             logger.warning("Completed full rotation without reed switch trigger")
 
 
-                        # Set theta to 0 at this position (home position)
-                        state.current_theta = 0
+                        # Set theta to the offset value (accounting for sensor placement)
+                        # If offset is 0, this is the true home position
+                        # If offset is non-zero, the sensor is physically placed at that angle
+                        # Convert degrees to radians for internal use
+                        import math
+                        offset_radians = math.radians(state.angular_homing_offset_degrees)
+                        state.current_theta = offset_radians
                         state.current_rho = 1
                         state.current_rho = 1
-                        logger.info("Angular homing completed - theta set to 0")
+                        logger.info(f"Angular homing completed - theta set to {state.angular_homing_offset_degrees}° ({offset_radians:.3f} radians)")
 
 
                     finally:
                     finally:
                         reed_switch.cleanup()
                         reed_switch.cleanup()

+ 5 - 0
modules/core/state.py

@@ -36,6 +36,9 @@ class AppState:
         self.homing = 0
         self.homing = 0
         # Angular homing with reed switch (Raspberry Pi only)
         # Angular homing with reed switch (Raspberry Pi only)
         self.angular_homing_enabled = False
         self.angular_homing_enabled = False
+        # Angular offset in degrees for reed switch sensor placement
+        # This allows correcting for the physical position of the reed switch
+        self.angular_homing_offset_degrees = 0.0
 
 
         self.STATE_FILE = "state.json"
         self.STATE_FILE = "state.json"
         self.mqtt_handler = None  # Will be set by the MQTT handler
         self.mqtt_handler = None  # Will be set by the MQTT handler
@@ -182,6 +185,7 @@ class AppState:
             "gear_ratio": self.gear_ratio,
             "gear_ratio": self.gear_ratio,
             "homing": self.homing,
             "homing": self.homing,
             "angular_homing_enabled": self.angular_homing_enabled,
             "angular_homing_enabled": self.angular_homing_enabled,
+            "angular_homing_offset_degrees": self.angular_homing_offset_degrees,
             "current_playlist": self._current_playlist,
             "current_playlist": self._current_playlist,
             "current_playlist_name": self._current_playlist_name,
             "current_playlist_name": self._current_playlist_name,
             "current_playlist_index": self.current_playlist_index,
             "current_playlist_index": self.current_playlist_index,
@@ -222,6 +226,7 @@ class AppState:
         self.gear_ratio = data.get('gear_ratio', 10)
         self.gear_ratio = data.get('gear_ratio', 10)
         self.homing = data.get('homing', 0)
         self.homing = data.get('homing', 0)
         self.angular_homing_enabled = data.get('angular_homing_enabled', False)
         self.angular_homing_enabled = data.get('angular_homing_enabled', False)
+        self.angular_homing_offset_degrees = data.get('angular_homing_offset_degrees', 0.0)
         self._current_playlist = data.get("current_playlist", None)
         self._current_playlist = data.get("current_playlist", None)
         self._current_playlist_name = data.get("current_playlist_name", None)
         self._current_playlist_name = data.get("current_playlist_name", None)
         self.current_playlist_index = data.get("current_playlist_index", None)
         self.current_playlist_index = data.get("current_playlist_index", None)

+ 16 - 6
static/js/settings.js

@@ -1373,30 +1373,37 @@ async function initializeAngularHomingConfig() {
 
 
     const angularHomingToggle = document.getElementById('angularHomingToggle');
     const angularHomingToggle = document.getElementById('angularHomingToggle');
     const angularHomingInfo = document.getElementById('angularHomingInfo');
     const angularHomingInfo = document.getElementById('angularHomingInfo');
+    const angularOffsetContainer = document.getElementById('angularOffsetContainer');
+    const angularOffsetInput = document.getElementById('angularOffsetInput');
     const saveHomingConfigButton = document.getElementById('saveHomingConfig');
     const saveHomingConfigButton = document.getElementById('saveHomingConfig');
 
 
     // Check if elements exist
     // Check if elements exist
-    if (!angularHomingToggle || !angularHomingInfo || !saveHomingConfigButton) {
+    if (!angularHomingToggle || !angularHomingInfo || !saveHomingConfigButton || !angularOffsetContainer || !angularOffsetInput) {
         logMessage('Angular Homing elements not found, skipping initialization', LOG_TYPE.WARNING);
         logMessage('Angular Homing elements not found, skipping initialization', LOG_TYPE.WARNING);
         return;
         return;
     }
     }
 
 
     logMessage('All Angular Homing elements found successfully', LOG_TYPE.INFO);
     logMessage('All Angular Homing elements found successfully', LOG_TYPE.INFO);
 
 
-    // Load current angular homing setting
+    // Load current angular homing settings
     try {
     try {
         const response = await fetch('/api/angular-homing');
         const response = await fetch('/api/angular-homing');
         const data = await response.json();
         const data = await response.json();
 
 
         angularHomingToggle.checked = data.angular_homing_enabled || false;
         angularHomingToggle.checked = data.angular_homing_enabled || false;
+        angularOffsetInput.value = data.angular_homing_offset_degrees || 0;
+
         if (data.angular_homing_enabled) {
         if (data.angular_homing_enabled) {
             angularHomingInfo.style.display = 'block';
             angularHomingInfo.style.display = 'block';
+            angularOffsetContainer.style.display = 'block';
         }
         }
     } catch (error) {
     } catch (error) {
         logMessage(`Error loading angular homing settings: ${error.message}`, LOG_TYPE.ERROR);
         logMessage(`Error loading angular homing settings: ${error.message}`, LOG_TYPE.ERROR);
-        // Initialize with default (disabled) if load fails
+        // Initialize with defaults if load fails
         angularHomingToggle.checked = false;
         angularHomingToggle.checked = false;
+        angularOffsetInput.value = 0;
         angularHomingInfo.style.display = 'none';
         angularHomingInfo.style.display = 'none';
+        angularOffsetContainer.style.display = 'none';
     }
     }
 
 
     // Function to save settings
     // Function to save settings
@@ -1411,13 +1418,14 @@ async function initializeAngularHomingConfig() {
                 method: 'POST',
                 method: 'POST',
                 headers: { 'Content-Type': 'application/json' },
                 headers: { 'Content-Type': 'application/json' },
                 body: JSON.stringify({
                 body: JSON.stringify({
-                    angular_homing_enabled: angularHomingToggle.checked
+                    angular_homing_enabled: angularHomingToggle.checked,
+                    angular_homing_offset_degrees: parseFloat(angularOffsetInput.value) || 0
                 })
                 })
             });
             });
 
 
             if (!response.ok) {
             if (!response.ok) {
                 const errorData = await response.json();
                 const errorData = await response.json();
-                throw new Error(errorData.detail || 'Failed to save angular homing setting');
+                throw new Error(errorData.detail || 'Failed to save angular homing settings');
             }
             }
 
 
             // Show success state temporarily
             // Show success state temporarily
@@ -1442,7 +1450,9 @@ async function initializeAngularHomingConfig() {
     // Event listeners
     // Event listeners
     angularHomingToggle.addEventListener('change', () => {
     angularHomingToggle.addEventListener('change', () => {
         logMessage(`Angular homing toggle changed: ${angularHomingToggle.checked}`, LOG_TYPE.INFO);
         logMessage(`Angular homing toggle changed: ${angularHomingToggle.checked}`, LOG_TYPE.INFO);
-        angularHomingInfo.style.display = angularHomingToggle.checked ? 'block' : 'none';
+        const isEnabled = angularHomingToggle.checked;
+        angularHomingInfo.style.display = isEnabled ? 'block' : 'none';
+        angularOffsetContainer.style.display = isEnabled ? 'block' : 'none';
         logMessage(`Info display set to: ${angularHomingInfo.style.display}`, LOG_TYPE.INFO);
         logMessage(`Info display set to: ${angularHomingInfo.style.display}`, LOG_TYPE.INFO);
     });
     });
 
 

+ 22 - 1
templates/settings.html

@@ -331,6 +331,27 @@ input:checked + .slider:before {
         </label>
         </label>
       </div>
       </div>
 
 
+      <!-- Angular Offset Input (shown when angular homing is enabled) -->
+      <div id="angularOffsetContainer" class="space-y-2" style="display: none;">
+        <label for="angularOffsetInput" class="text-sm font-medium text-slate-700 flex items-center gap-2">
+          <span class="material-icons text-slate-600 text-base">straighten</span>
+          Sensor Offset (degrees)
+        </label>
+        <input
+          type="number"
+          id="angularOffsetInput"
+          min="0"
+          max="360"
+          step="0.1"
+          value="0"
+          class="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-sky-500 focus:border-sky-500 text-sm"
+          placeholder="0.0"
+        />
+        <p class="text-xs text-slate-500">
+          Set the angle (in degrees) where your reed switch is physically mounted. 0° = East, increases clockwise (90° = South, 180° = West, 270° = North).
+        </p>
+      </div>
+
       <div id="angularHomingInfo" class="text-xs text-slate-600 bg-blue-50 border border-blue-200 rounded-lg p-3" style="display: none;">
       <div id="angularHomingInfo" class="text-xs text-slate-600 bg-blue-50 border border-blue-200 rounded-lg p-3" style="display: none;">
         <div class="flex items-start gap-2">
         <div class="flex items-start gap-2">
           <span class="material-icons text-blue-600 text-base">info</span>
           <span class="material-icons text-blue-600 text-base">info</span>
@@ -339,7 +360,7 @@ input:checked + .slider:before {
             <ul class="mt-1 space-y-1 text-blue-700">
             <ul class="mt-1 space-y-1 text-blue-700">
               <li>• After radial homing, the arm moves to the perimeter (y20)</li>
               <li>• After radial homing, the arm moves to the perimeter (y20)</li>
               <li>• The table rotates around the perimeter until the reed switch on GPIO 18 is triggered</li>
               <li>• The table rotates around the perimeter until the reed switch on GPIO 18 is triggered</li>
-              <li>• This position is set as the angular home (theta = 0)</li>
+              <li>• This position is set as the angular home based on your sensor offset</li>
               <li>• Only works on Raspberry Pi with a reed switch connected to GPIO 18</li>
               <li>• Only works on Raspberry Pi with a reed switch connected to GPIO 18</li>
               <li>• Reed switch should connect GPIO 18 to ground when triggered</li>
               <li>• Reed switch should connect GPIO 18 to ground when triggered</li>
             </ul>
             </ul>