|
|
@@ -6,8 +6,11 @@ import serial.tools.list_ports
|
|
|
import websocket
|
|
|
import asyncio
|
|
|
|
|
|
+from modules.core import pattern_manager
|
|
|
from modules.core.state import state
|
|
|
from modules.led.led_controller import effect_loading, effect_idle, effect_connected, LEDController
|
|
|
+from modules.connection.reed_switch import ReedSwitchMonitor
|
|
|
+
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
IGNORE_PORTS = ['/dev/cu.debug-console', '/dev/cu.Bluetooth-Incoming-Port']
|
|
|
@@ -378,7 +381,7 @@ def get_machine_steps(timeout=10):
|
|
|
|
|
|
# Process results and determine table type
|
|
|
if settings_complete:
|
|
|
- if y_steps_per_mm == 180 and x_steps_per_mm == 256:
|
|
|
+ if y_steps_per_mm == 180:
|
|
|
state.table_type = 'dune_weaver_mini'
|
|
|
elif y_steps_per_mm >= 320:
|
|
|
state.table_type = 'dune_weaver_pro'
|
|
|
@@ -397,12 +400,12 @@ def get_machine_steps(timeout=10):
|
|
|
logger.error(f"Failed to get all machine parameters after {timeout}s. Missing: {', '.join(missing)}")
|
|
|
return False
|
|
|
|
|
|
-def home(timeout=15):
|
|
|
+def home(timeout=90):
|
|
|
"""
|
|
|
Perform homing by checking device configuration and sending the appropriate commands.
|
|
|
-
|
|
|
+
|
|
|
Args:
|
|
|
- timeout: Maximum time in seconds to wait for homing to complete (default: 15)
|
|
|
+ timeout: Maximum time in seconds to wait for homing to complete (default: 60)
|
|
|
"""
|
|
|
import threading
|
|
|
|
|
|
@@ -428,7 +431,7 @@ def home(timeout=15):
|
|
|
loop = asyncio.new_event_loop()
|
|
|
asyncio.set_event_loop(loop)
|
|
|
try:
|
|
|
- if state.gear_ratio == 6.25:
|
|
|
+ if state.table_type == 'dune_weaver_mini':
|
|
|
result = loop.run_until_complete(send_grbl_coordinates(0, - 30, homing_speed, home=True))
|
|
|
if result == False:
|
|
|
logger.error("Homing failed - send_grbl_coordinates returned False")
|
|
|
@@ -449,12 +452,83 @@ def home(timeout=15):
|
|
|
logger.info("Waiting for device to reach idle state after homing...")
|
|
|
idle_reached = check_idle()
|
|
|
|
|
|
- if idle_reached:
|
|
|
- state.current_theta = state.current_rho = 0
|
|
|
- homing_success = True
|
|
|
- logger.info("Homing completed and device is idle")
|
|
|
- else:
|
|
|
+ if not idle_reached:
|
|
|
logger.error("Device did not reach idle state after homing")
|
|
|
+ homing_complete.set()
|
|
|
+ return
|
|
|
+ else:
|
|
|
+ state.current_theta = state.current_rho = 0
|
|
|
+
|
|
|
+ # Perform angular homing if enabled (Raspberry Pi only)
|
|
|
+ if state.angular_homing_enabled:
|
|
|
+ logger.info("Starting angular homing sequence")
|
|
|
+ try:
|
|
|
+ # Initialize reed switch monitor
|
|
|
+ reed_switch = ReedSwitchMonitor(gpio_pin=18)
|
|
|
+
|
|
|
+ try:
|
|
|
+ # Reset theta first
|
|
|
+ logger.info("Resetting theta before angular homing")
|
|
|
+ asyncio.run(pattern_manager.reset_theta())
|
|
|
+
|
|
|
+ # Move radial arm to perimeter (theta=0, rho=1.0)
|
|
|
+ logger.info("Moving radial arm to perimeter (theta=0, rho=1.0)")
|
|
|
+ asyncio.run(pattern_manager.move_polar(0, 1.0, homing_speed))
|
|
|
+
|
|
|
+ idle_reached = check_idle()
|
|
|
+
|
|
|
+ if not idle_reached:
|
|
|
+ logger.error("Device did not reach idle state after moving to perimeter")
|
|
|
+ homing_complete.set()
|
|
|
+ return
|
|
|
+
|
|
|
+ # Wait 1 second for stabilization
|
|
|
+ logger.info("Waiting for stabilization...")
|
|
|
+ time.sleep(1)
|
|
|
+
|
|
|
+ # Perform angular rotation until reed switch is triggered
|
|
|
+ logger.info("Rotating around perimeter to find home position")
|
|
|
+ increment = 0.1 # Small angular increment in radians
|
|
|
+ current_theta = 0
|
|
|
+ max_theta = 6.28 # One full rotation (2*pi)
|
|
|
+ reed_switch_triggered = False
|
|
|
+
|
|
|
+ while current_theta < max_theta:
|
|
|
+ # Move to next position
|
|
|
+ current_theta += increment
|
|
|
+ asyncio.run(pattern_manager.move_polar(current_theta, 1.0, homing_speed))
|
|
|
+
|
|
|
+ # Small delay to allow reed switch to settle after movement
|
|
|
+ time.sleep(0.5)
|
|
|
+
|
|
|
+ # Check reed switch AFTER movement completes
|
|
|
+ if reed_switch.is_triggered():
|
|
|
+ logger.info(f"Reed switch triggered at theta={current_theta}")
|
|
|
+ reed_switch_triggered = True
|
|
|
+ break
|
|
|
+
|
|
|
+ if not reed_switch_triggered:
|
|
|
+ logger.warning("Completed full rotation without reed switch trigger")
|
|
|
+
|
|
|
+ # 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
|
|
|
+ logger.info(f"Angular homing completed - theta set to {state.angular_homing_offset_degrees}° ({offset_radians:.3f} radians)")
|
|
|
+
|
|
|
+ finally:
|
|
|
+ reed_switch.cleanup()
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"Error during angular homing: {e}")
|
|
|
+ # Continue with normal homing completion even if angular homing fails
|
|
|
+
|
|
|
+ homing_success = True
|
|
|
+ logger.info("Homing completed and device is idle")
|
|
|
|
|
|
homing_complete.set()
|
|
|
except Exception as e:
|