Parcourir la source

Stop pattern on GRBL error/alarm instead of hanging

When GRBL returns an error (like error:2) or alarm, it will NOT send
'ok' afterwards. Previously the code just logged a warning and kept
waiting for 'ok' until timeout (120s).

Now GRBL errors/alarms immediately:
- Log the error with the failed command
- Set stop_requested = True
- Return False to stop pattern execution

This provides immediate feedback instead of hanging for 2 minutes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
tuanchris il y a 1 semaine
Parent
commit
fba7aee412
1 fichiers modifiés avec 14 ajouts et 19 suppressions
  1. 14 19
      modules/core/pattern_manager.py

+ 14 - 19
modules/core/pattern_manager.py

@@ -477,8 +477,6 @@ class MotionControlThread:
 
     def _move_polar_sync(self, theta: float, rho: float, speed: Optional[float] = None):
         """Synchronous version of move_polar for use in motion thread."""
-        import math
-
         # This is the original sync logic but running in dedicated thread
         if state.table_type == 'dune_weaver_mini':
             x_scaling_factor = 2
@@ -495,12 +493,7 @@ class MotionControlThread:
         x_total_steps = state.x_steps_per_mm * (100/x_scaling_factor)
         y_total_steps = state.y_steps_per_mm * (100/y_scaling_factor)
 
-        # Protect against division by zero
-        if state.gear_ratio == 0 or y_total_steps == 0:
-            logger.error(f"Invalid state for offset calculation: gear_ratio={state.gear_ratio}, y_total_steps={y_total_steps}")
-            offset = 0
-        else:
-            offset = x_increment * (x_total_steps * x_scaling_factor / (state.gear_ratio * y_total_steps * y_scaling_factor))
+        offset = x_increment * (x_total_steps * x_scaling_factor / (state.gear_ratio * y_total_steps * y_scaling_factor))
 
         if state.table_type == 'dune_weaver_mini' or state.y_steps_per_mm == 546:
             y_increment -= offset
@@ -513,14 +506,6 @@ class MotionControlThread:
         # Use provided speed or fall back to state.speed
         actual_speed = speed if speed is not None else state.speed
 
-        # Validate values before sending to GRBL
-        if not math.isfinite(new_x_abs) or not math.isfinite(new_y_abs) or not math.isfinite(actual_speed):
-            logger.error(f"Invalid coordinates detected: X={new_x_abs}, Y={new_y_abs}, F={actual_speed}")
-            logger.error(f"State: theta={theta}, rho={rho}, machine_x={state.machine_x}, machine_y={state.machine_y}")
-            logger.error(f"Steps: x_steps_per_mm={state.x_steps_per_mm}, y_steps_per_mm={state.y_steps_per_mm}")
-            state.stop_requested = True
-            return
-
         # Call sync version of send_grbl_coordinates in this thread
         self._send_grbl_coordinates_sync(round(new_x_abs, 3), round(new_y_abs, 3), actual_speed)
 
@@ -572,9 +557,19 @@ class MotionControlThread:
                         if response.lower() == "ok":
                             logger.debug("Motion thread: Command execution confirmed.")
                             return True
-                        # Log unexpected responses for debugging
-                        if "error" in response.lower() or "alarm" in response.lower():
-                            logger.warning(f"Motion thread: GRBL error/alarm: {response}")
+                        # Handle GRBL errors - these mean command failed, stop pattern
+                        if response.lower().startswith("error"):
+                            logger.error(f"Motion thread: GRBL error received: {response}")
+                            logger.error(f"Failed command: {gcode}")
+                            logger.error("Stopping pattern due to GRBL error")
+                            state.stop_requested = True
+                            return False
+                        # Handle GRBL alarms - machine needs attention
+                        if "alarm" in response.lower():
+                            logger.error(f"Motion thread: GRBL ALARM: {response}")
+                            logger.error("Machine alarm triggered - stopping pattern")
+                            state.stop_requested = True
+                            return False
                     # Small sleep to prevent CPU spin when readline() times out
                     time.sleep(0.01)