Переглянути джерело

Segmented manual moves for kinematics

Scott Lahteine 7 роки тому
джерело
коміт
38110e220d
1 змінених файлів з 101 додано та 22 видалено
  1. 101
    22
      Marlin/ultralcd.cpp

+ 101
- 22
Marlin/ultralcd.cpp Переглянути файл

460
     #define manual_move_e_index 0
460
     #define manual_move_e_index 0
461
   #endif
461
   #endif
462
 
462
 
463
+  #if IS_KINEMATIC
464
+    bool processing_manual_move = false;
465
+    float manual_move_offset = 0.0;
466
+  #else
467
+    constexpr bool processing_manual_move = false;
468
+  #endif
469
+
463
   #if PIN_EXISTS(SD_DETECT)
470
   #if PIN_EXISTS(SD_DETECT)
464
     uint8_t lcd_sd_status;
471
     uint8_t lcd_sd_status;
465
   #endif
472
   #endif
2732
 
2739
 
2733
   #endif // DELTA_CALIBRATION_MENU
2740
   #endif // DELTA_CALIBRATION_MENU
2734
 
2741
 
2742
+  #if IS_KINEMATIC
2743
+    extern float feedrate_mm_s;
2744
+    extern float destination[XYZE];
2745
+    void set_destination_to_current();
2746
+    void prepare_move_to_destination();
2747
+  #endif
2748
+
2735
   /**
2749
   /**
2736
    * If the most recent manual move hasn't been fed to the planner yet,
2750
    * If the most recent manual move hasn't been fed to the planner yet,
2737
    * and the planner can accept one, send immediately
2751
    * and the planner can accept one, send immediately
2738
    */
2752
    */
2739
   inline void manage_manual_move() {
2753
   inline void manage_manual_move() {
2754
+
2755
+    if (processing_manual_move) return;
2756
+
2740
     if (manual_move_axis != (int8_t)NO_AXIS && ELAPSED(millis(), manual_move_start_time) && !planner.is_full()) {
2757
     if (manual_move_axis != (int8_t)NO_AXIS && ELAPSED(millis(), manual_move_start_time) && !planner.is_full()) {
2741
-      planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_e_index);
2742
-      manual_move_axis = (int8_t)NO_AXIS;
2758
+
2759
+      #if IS_KINEMATIC
2760
+
2761
+        const float old_feedrate = feedrate_mm_s;
2762
+        feedrate_mm_s = MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]);
2763
+
2764
+        #if EXTRUDERS > 1
2765
+          const int8_t old_extruder = active_extruder;
2766
+          active_extruder = manual_move_e_index;
2767
+        #endif
2768
+
2769
+        // Set movement on a single axis
2770
+        set_destination_to_current();
2771
+        destination[manual_move_axis] += manual_move_offset;
2772
+
2773
+        // Reset for the next move
2774
+        manual_move_offset = 0.0;
2775
+        manual_move_axis = (int8_t)NO_AXIS;
2776
+
2777
+        // DELTA and SCARA machines use segmented moves, which could fill the planner during the call to
2778
+        // move_to_destination. This will cause idle() to be called, which can then call this function while the
2779
+        // previous invocation is being blocked. Modifications to manual_move_offset shouldn't be made while
2780
+        // processing_manual_move is true or the planner will get out of sync.
2781
+        processing_manual_move = true;
2782
+        prepare_move_to_destination(); // will call set_current_to_destination
2783
+        processing_manual_move = false;
2784
+
2785
+        feedrate_mm_s = old_feedrate;
2786
+        #if EXTRUDERS > 1
2787
+          active_extruder = old_extruder;
2788
+        #endif
2789
+
2790
+      #else
2791
+
2792
+        planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_e_index);
2793
+        manual_move_axis = (int8_t)NO_AXIS;
2794
+
2795
+      #endif
2743
     }
2796
     }
2744
   }
2797
   }
2745
 
2798
 
2771
   void _lcd_move_xyz(const char* name, AxisEnum axis) {
2824
   void _lcd_move_xyz(const char* name, AxisEnum axis) {
2772
     if (lcd_clicked) { return lcd_goto_previous_menu(); }
2825
     if (lcd_clicked) { return lcd_goto_previous_menu(); }
2773
     ENCODER_DIRECTION_NORMAL();
2826
     ENCODER_DIRECTION_NORMAL();
2774
-    if (encoderPosition) {
2827
+    if (encoderPosition && !processing_manual_move) {
2775
       refresh_cmd_timeout();
2828
       refresh_cmd_timeout();
2776
 
2829
 
2830
+      // Start with no limits to movement
2777
       float min = current_position[axis] - 1000,
2831
       float min = current_position[axis] - 1000,
2778
             max = current_position[axis] + 1000;
2832
             max = current_position[axis] + 1000;
2779
 
2833
 
2789
         }
2843
         }
2790
       #endif
2844
       #endif
2791
 
2845
 
2792
-      // Get the new position
2793
-      current_position[axis] += float((int32_t)encoderPosition) * move_menu_scale;
2794
-
2795
       // Delta limits XY based on the current offset from center
2846
       // Delta limits XY based on the current offset from center
2796
       // This assumes the center is 0,0
2847
       // This assumes the center is 0,0
2797
       #if ENABLED(DELTA)
2848
       #if ENABLED(DELTA)
2798
         if (axis != Z_AXIS) {
2849
         if (axis != Z_AXIS) {
2799
-          max = SQRT(sq((float)(DELTA_PRINTABLE_RADIUS)) - sq(current_position[Y_AXIS - axis]));
2850
+          max = SQRT(sq((float)(DELTA_PRINTABLE_RADIUS)) - sq(current_position[Y_AXIS - axis])); // (Y_AXIS - axis) == the other axis
2800
           min = -max;
2851
           min = -max;
2801
         }
2852
         }
2802
       #endif
2853
       #endif
2803
 
2854
 
2804
-      // Limit only when trying to move towards the limit
2805
-      if ((int32_t)encoderPosition < 0) NOLESS(current_position[axis], min);
2806
-      if ((int32_t)encoderPosition > 0) NOMORE(current_position[axis], max);
2855
+      // Get the new position
2856
+      const float diff = float((int32_t)encoderPosition) * move_menu_scale;
2857
+      #if IS_KINEMATIC
2858
+        manual_move_offset += diff;
2859
+        // Limit only when trying to move towards the limit
2860
+        if ((int32_t)encoderPosition < 0) NOLESS(manual_move_offset, min - current_position[axis]);
2861
+        if ((int32_t)encoderPosition > 0) NOMORE(manual_move_offset, max - current_position[axis]);
2862
+      #else
2863
+        current_position[axis] += diff;
2864
+        // Limit only when trying to move towards the limit
2865
+        if ((int32_t)encoderPosition < 0) NOLESS(current_position[axis], min);
2866
+        if ((int32_t)encoderPosition > 0) NOMORE(current_position[axis], max);
2867
+      #endif
2868
+
2869
+      encoderPosition = 0;
2807
 
2870
 
2808
       manual_move_to_current(axis);
2871
       manual_move_to_current(axis);
2809
 
2872
 
2810
-      encoderPosition = 0;
2811
       lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
2873
       lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
2812
     }
2874
     }
2813
-    if (lcdDrawUpdate)
2814
-      lcd_implementation_drawedit(name, move_menu_scale >= 0.1 ? ftostr41sign(current_position[axis]) : ftostr43sign(current_position[axis]));
2875
+    if (lcdDrawUpdate) {
2876
+      const float pos = current_position[axis]
2877
+        #if IS_KINEMATIC
2878
+          + manual_move_offset
2879
+        #endif
2880
+      ;
2881
+      lcd_implementation_drawedit(name, move_menu_scale >= 0.1 ? ftostr41sign(pos) : ftostr43sign(pos));
2882
+    }
2815
   }
2883
   }
2816
   void lcd_move_x() { _lcd_move_xyz(PSTR(MSG_MOVE_X), X_AXIS); }
2884
   void lcd_move_x() { _lcd_move_xyz(PSTR(MSG_MOVE_X), X_AXIS); }
2817
   void lcd_move_y() { _lcd_move_xyz(PSTR(MSG_MOVE_Y), Y_AXIS); }
2885
   void lcd_move_y() { _lcd_move_xyz(PSTR(MSG_MOVE_Y), Y_AXIS); }
2824
     if (lcd_clicked) { return lcd_goto_previous_menu(); }
2892
     if (lcd_clicked) { return lcd_goto_previous_menu(); }
2825
     ENCODER_DIRECTION_NORMAL();
2893
     ENCODER_DIRECTION_NORMAL();
2826
     if (encoderPosition) {
2894
     if (encoderPosition) {
2827
-      current_position[E_AXIS] += float((int32_t)encoderPosition) * move_menu_scale;
2828
-      encoderPosition = 0;
2829
-      manual_move_to_current(E_AXIS
2830
-        #if E_MANUAL > 1
2831
-          , eindex
2895
+      if (!processing_manual_move) {
2896
+        const float diff = float((int32_t)encoderPosition) * move_menu_scale;
2897
+        #if IS_KINEMATIC
2898
+          manual_move_offset += diff;
2899
+        #else
2900
+          current_position[E_AXIS] += diff;
2832
         #endif
2901
         #endif
2833
-      );
2834
-      lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
2902
+        manual_move_to_current(E_AXIS
2903
+          #if E_MANUAL > 1
2904
+            , eindex
2905
+          #endif
2906
+        );
2907
+        lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
2908
+      }
2909
+      encoderPosition = 0;
2835
     }
2910
     }
2836
-    if (lcdDrawUpdate) {
2911
+    if (lcdDrawUpdate && !processing_manual_move) {
2837
       PGM_P pos_label;
2912
       PGM_P pos_label;
2838
       #if E_MANUAL == 1
2913
       #if E_MANUAL == 1
2839
         pos_label = PSTR(MSG_MOVE_E);
2914
         pos_label = PSTR(MSG_MOVE_E);
2852
           #endif // E_MANUAL > 2
2927
           #endif // E_MANUAL > 2
2853
         }
2928
         }
2854
       #endif // E_MANUAL > 1
2929
       #endif // E_MANUAL > 1
2855
-      lcd_implementation_drawedit(pos_label, ftostr41sign(current_position[E_AXIS]));
2930
+      lcd_implementation_drawedit(pos_label, ftostr41sign(current_position[E_AXIS]
2931
+        #if IS_KINEMATIC
2932
+          + manual_move_offset
2933
+        #endif
2934
+      ));
2856
     }
2935
     }
2857
   }
2936
   }
2858
 
2937
 

Завантаження…
Відмінити
Зберегти