Explorar el Código

Merge pull request #6099 from thinkyhead/rc_cleanup_ubl_1

Patch till UBL is integrated with planner-based leveling
Scott Lahteine hace 8 años
padre
commit
4433b63d7a
Se han modificado 37 ficheros con 553 adiciones y 593 borrados
  1. 1
    1
      Marlin/Conditionals_post.h
  2. 1
    0
      Marlin/Configuration.h
  3. 40
    122
      Marlin/G26_Mesh_Validation_Tool.cpp
  4. 0
    1
      Marlin/Marlin.h
  5. 36
    28
      Marlin/Marlin_main.cpp
  6. 87
    73
      Marlin/UBL.h
  7. 39
    31
      Marlin/UBL_Bed_Leveling.cpp
  8. 110
    157
      Marlin/UBL_G29.cpp
  9. 134
    91
      Marlin/UBL_line_to_destination.cpp
  10. 45
    39
      Marlin/configuration_store.cpp
  11. 1
    0
      Marlin/example_configurations/Cartesio/Configuration.h
  12. 1
    0
      Marlin/example_configurations/Felix/Configuration.h
  13. 1
    0
      Marlin/example_configurations/Felix/DUAL/Configuration.h
  14. 1
    0
      Marlin/example_configurations/Hephestos/Configuration.h
  15. 1
    0
      Marlin/example_configurations/Hephestos_2/Configuration.h
  16. 1
    0
      Marlin/example_configurations/K8200/Configuration.h
  17. 1
    0
      Marlin/example_configurations/K8400/Configuration.h
  18. 1
    0
      Marlin/example_configurations/K8400/Dual-head/Configuration.h
  19. 1
    0
      Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
  20. 1
    0
      Marlin/example_configurations/RigidBot/Configuration.h
  21. 1
    0
      Marlin/example_configurations/SCARA/Configuration.h
  22. 1
    0
      Marlin/example_configurations/TAZ4/Configuration.h
  23. 1
    0
      Marlin/example_configurations/WITBOX/Configuration.h
  24. 1
    0
      Marlin/example_configurations/adafruit/ST7565/Configuration.h
  25. 1
    0
      Marlin/example_configurations/delta/flsun_kossel_mini/Configuration.h
  26. 1
    0
      Marlin/example_configurations/delta/generic/Configuration.h
  27. 1
    0
      Marlin/example_configurations/delta/kossel_mini/Configuration.h
  28. 1
    0
      Marlin/example_configurations/delta/kossel_pro/Configuration.h
  29. 1
    0
      Marlin/example_configurations/delta/kossel_xl/Configuration.h
  30. 1
    0
      Marlin/example_configurations/makibox/Configuration.h
  31. 1
    0
      Marlin/example_configurations/tvrrug/Round2/Configuration.h
  32. 2
    2
      Marlin/mesh_bed_leveling.h
  33. 3
    3
      Marlin/planner.cpp
  34. 4
    4
      Marlin/planner.h
  35. 18
    29
      Marlin/stepper.cpp
  36. 1
    1
      Marlin/ultralcd.cpp
  37. 11
    11
      Marlin/vector_3.cpp

+ 1
- 1
Marlin/Conditionals_post.h Ver fichero

669
   #define ABL_GRID   (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR))
669
   #define ABL_GRID   (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR))
670
   #define HAS_ABL    (ABL_PLANAR || ABL_GRID || ENABLED(AUTO_BED_LEVELING_UBL))
670
   #define HAS_ABL    (ABL_PLANAR || ABL_GRID || ENABLED(AUTO_BED_LEVELING_UBL))
671
 
671
 
672
-  #define PLANNER_LEVELING      ((HAS_ABL && DISABLED(AUTO_BED_LEVELING_UBL)) || ENABLED(MESH_BED_LEVELING))
672
+  #define PLANNER_LEVELING      (HAS_ABL || ENABLED(MESH_BED_LEVELING))
673
   #define HAS_PROBING_PROCEDURE (HAS_ABL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST))
673
   #define HAS_PROBING_PROCEDURE (HAS_ABL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST))
674
 
674
 
675
   #if HAS_PROBING_PROCEDURE
675
   #if HAS_PROBING_PROCEDURE

+ 1
- 0
Marlin/Configuration.h Ver fichero

862
   #define UBL_PROBE_PT_2_Y 20
862
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_3_X 180
863
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_Y 20
864
   #define UBL_PROBE_PT_3_Y 20
865
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
865
 
866
 
866
 #elif ENABLED(MESH_BED_LEVELING)
867
 #elif ENABLED(MESH_BED_LEVELING)
867
 
868
 

+ 40
- 122
Marlin/G26_Mesh_Validation_Tool.cpp Ver fichero

24
  * Marlin Firmware -- G26 - Mesh Validation Tool
24
  * Marlin Firmware -- G26 - Mesh Validation Tool
25
  */
25
  */
26
 
26
 
27
-#define EXTRUSION_MULTIPLIER 1.0    // This is too much clutter for the main Configuration.h file  But
28
-#define RETRACTION_MULTIPLIER 1.0   // some user have expressed an interest in being able to customize
29
-#define NOZZLE 0.3                  // these numbers for thier printer so they don't need to type all
30
-#define FILAMENT 1.75               // the options every time they do a Mesh Validation Print.
31
-#define LAYER_HEIGHT 0.2
32
-#define PRIME_LENGTH 10.0           // So, we put these number in an easy to find and change place.
33
-#define BED_TEMP 60.0
34
-#define HOTEND_TEMP 205.0
35
-#define OOZE_AMOUNT 0.3
36
-
37
-#include "Marlin.h"
38
-#include "Configuration.h"
39
-#include "planner.h"
40
-#include "stepper.h"
41
-#include "temperature.h"
42
-#include "UBL.h"
43
-#include "ultralcd.h"
44
-
45
-#if ENABLED(AUTO_BED_LEVELING_UBL)
27
+#include "MarlinConfig.h"
28
+
29
+#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_MESH_EDIT_ENABLED)
30
+
31
+  #include "Marlin.h"
32
+  #include "Configuration.h"
33
+  #include "planner.h"
34
+  #include "stepper.h"
35
+  #include "temperature.h"
36
+  #include "UBL.h"
37
+  #include "ultralcd.h"
38
+
39
+  #define EXTRUSION_MULTIPLIER 1.0    // This is too much clutter for the main Configuration.h file  But
40
+  #define RETRACTION_MULTIPLIER 1.0   // some user have expressed an interest in being able to customize
41
+  #define NOZZLE 0.3                  // these numbers for thier printer so they don't need to type all
42
+  #define FILAMENT 1.75               // the options every time they do a Mesh Validation Print.
43
+  #define LAYER_HEIGHT 0.2
44
+  #define PRIME_LENGTH 10.0           // So, we put these number in an easy to find and change place.
45
+  #define BED_TEMP 60.0
46
+  #define HOTEND_TEMP 205.0
47
+  #define OOZE_AMOUNT 0.3
46
 
48
 
47
   #define SIZE_OF_INTERSECTION_CIRCLES 5
49
   #define SIZE_OF_INTERSECTION_CIRCLES 5
48
   #define SIZE_OF_CROSS_HAIRS 3 // cross hairs inside the circle.  This number should be
50
   #define SIZE_OF_CROSS_HAIRS 3 // cross hairs inside the circle.  This number should be
50
 
52
 
51
   /**
53
   /**
52
    *   Roxy's G26 Mesh Validation Tool
54
    *   Roxy's G26 Mesh Validation Tool
53
-   *  
55
+   *
54
    *   G26 Is a Mesh Validation Tool intended to provide support for the Marlin Unified Bed Leveling System.
56
    *   G26 Is a Mesh Validation Tool intended to provide support for the Marlin Unified Bed Leveling System.
55
    *   In order to fully utilize and benefit from the Marlin Unified Bed Leveling System an accurate Mesh must
57
    *   In order to fully utilize and benefit from the Marlin Unified Bed Leveling System an accurate Mesh must
56
    *   be defined.  G29 is designed to allow the user to quickly validate the correctness of her Mesh.  It will
58
    *   be defined.  G29 is designed to allow the user to quickly validate the correctness of her Mesh.  It will
57
    *   first heat the bed and nozzle. It will then print lines and circles along the Mesh Cell boundaries and
59
    *   first heat the bed and nozzle. It will then print lines and circles along the Mesh Cell boundaries and
58
    *   the intersections of those lines (respectively).
60
    *   the intersections of those lines (respectively).
59
-   *  
61
+   *
60
    *   This action allows the user to immediately see where the Mesh is properly defined and where it needs to
62
    *   This action allows the user to immediately see where the Mesh is properly defined and where it needs to
61
    *   be edited.  The command will generate the Mesh lines closest to the nozzle's starting position.  Alternatively
63
    *   be edited.  The command will generate the Mesh lines closest to the nozzle's starting position.  Alternatively
62
    *   the user can specify the X and Y position of interest with command parameters.  This allows the user to
64
    *   the user can specify the X and Y position of interest with command parameters.  This allows the user to
63
    *   focus on a particular area of the Mesh where attention is needed.
65
    *   focus on a particular area of the Mesh where attention is needed.
64
-   *  
66
+   *
65
    *   B #  Bed   Set the Bed Temperature.  If not specified, a default of 60 C. will be assumed.
67
    *   B #  Bed   Set the Bed Temperature.  If not specified, a default of 60 C. will be assumed.
66
-   *  
68
+   *
67
    *   C    Current   When searching for Mesh Intersection points to draw, use the current nozzle location
69
    *   C    Current   When searching for Mesh Intersection points to draw, use the current nozzle location
68
    *        as the base for any distance comparison.
70
    *        as the base for any distance comparison.
69
-   *  
71
+   *
70
    *   D    Disable   Disable the Unified Bed Leveling System.  In the normal case the user is invoking this
72
    *   D    Disable   Disable the Unified Bed Leveling System.  In the normal case the user is invoking this
71
    *        command to see how well a Mesh as been adjusted to match a print surface.  In order to do
73
    *        command to see how well a Mesh as been adjusted to match a print surface.  In order to do
72
    *        this the Unified Bed Leveling System is turned on by the G26 command.  The D parameter
74
    *        this the Unified Bed Leveling System is turned on by the G26 command.  The D parameter
73
    *        alters the command's normal behaviour and disables the Unified Bed Leveling System even if
75
    *        alters the command's normal behaviour and disables the Unified Bed Leveling System even if
74
    *        it is on.
76
    *        it is on.
75
-   *  
77
+   *
76
    *   H #  Hotend    Set the Nozzle Temperature.  If not specified, a default of 205 C. will be assumed.
78
    *   H #  Hotend    Set the Nozzle Temperature.  If not specified, a default of 205 C. will be assumed.
77
-   *  
79
+   *
78
    *   F #  Filament  Used to specify the diameter of the filament being used.  If not specified
80
    *   F #  Filament  Used to specify the diameter of the filament being used.  If not specified
79
    *        1.75mm filament is assumed.  If you are not getting acceptable results by using the
81
    *        1.75mm filament is assumed.  If you are not getting acceptable results by using the
80
    *        'correct' numbers, you can scale this number up or down a little bit to change the amount
82
    *        'correct' numbers, you can scale this number up or down a little bit to change the amount
81
    *        of filament that is being extruded during the printing of the various lines on the bed.
83
    *        of filament that is being extruded during the printing of the various lines on the bed.
82
-   *  
84
+   *
83
    *   K    Keep-On   Keep the heaters turned on at the end of the command.
85
    *   K    Keep-On   Keep the heaters turned on at the end of the command.
84
-   *  
86
+   *
85
    *   L #  Layer   Layer height.  (Height of nozzle above bed)  If not specified .20mm will be used.
87
    *   L #  Layer   Layer height.  (Height of nozzle above bed)  If not specified .20mm will be used.
86
-   *  
88
+   *
87
    *   Q #  Multiplier  Retraction Multiplier.  Normally not needed.  Retraction defaults to 1.0mm and
89
    *   Q #  Multiplier  Retraction Multiplier.  Normally not needed.  Retraction defaults to 1.0mm and
88
    *        un-retraction is at 1.2mm   These numbers will be scaled by the specified amount
90
    *        un-retraction is at 1.2mm   These numbers will be scaled by the specified amount
89
-   *  
91
+   *
90
    *   N #  Nozzle    Used to control the size of nozzle diameter.  If not specified, a .4mm nozzle is assumed.
92
    *   N #  Nozzle    Used to control the size of nozzle diameter.  If not specified, a .4mm nozzle is assumed.
91
-   *  
93
+   *
92
    *   O #  Ooooze    How much your nozzle will Ooooze filament while getting in position to print.  This
94
    *   O #  Ooooze    How much your nozzle will Ooooze filament while getting in position to print.  This
93
    *        is over kill, but using this parameter will let you get the very first 'cicle' perfect
95
    *        is over kill, but using this parameter will let you get the very first 'cicle' perfect
94
    *        so you have a trophy to peel off of the bed and hang up to show how perfectly you have your
96
    *        so you have a trophy to peel off of the bed and hang up to show how perfectly you have your
95
    *        Mesh calibrated.  If not specified, a filament length of .3mm is assumed.
97
    *        Mesh calibrated.  If not specified, a filament length of .3mm is assumed.
96
-   *  
98
+   *
97
    *   P #  Prime   Prime the nozzle with specified length of filament.  If this parameter is not
99
    *   P #  Prime   Prime the nozzle with specified length of filament.  If this parameter is not
98
    *        given, no prime action will take place.  If the parameter specifies an amount, that much
100
    *        given, no prime action will take place.  If the parameter specifies an amount, that much
99
    *        will be purged before continuing.  If no amount is specified the command will start
101
    *        will be purged before continuing.  If no amount is specified the command will start
100
    *        purging filament until the user provides an LCD Click and then it will continue with
102
    *        purging filament until the user provides an LCD Click and then it will continue with
101
    *        printing the Mesh.  You can carefully remove the spent filament with a needle nose
103
    *        printing the Mesh.  You can carefully remove the spent filament with a needle nose
102
    *        pliers while holding the LCD Click wheel in a depressed state.
104
    *        pliers while holding the LCD Click wheel in a depressed state.
103
-   *  
105
+   *
104
    *   R #  Random    Randomize the order that the circles are drawn on the bed.  The search for the closest
106
    *   R #  Random    Randomize the order that the circles are drawn on the bed.  The search for the closest
105
    *        undrawn cicle is still done.  But the distance to the location for each circle has a
107
    *        undrawn cicle is still done.  But the distance to the location for each circle has a
106
    *        random number of the size specified added to it.  Specifying R50 will give an interesting
108
    *        random number of the size specified added to it.  Specifying R50 will give an interesting
107
    *        deviation from the normal behaviour on a 10 x 10 Mesh.
109
    *        deviation from the normal behaviour on a 10 x 10 Mesh.
108
-   *  
110
+   *
109
    *   X #  X coordinate  Specify the starting location of the drawing activity.
111
    *   X #  X coordinate  Specify the starting location of the drawing activity.
110
-   *  
112
+   *
111
    *   Y #  Y coordinate  Specify the starting location of the drawing activity.
113
    *   Y #  Y coordinate  Specify the starting location of the drawing activity.
112
    */
114
    */
113
 
115
 
156
 
158
 
157
   float valid_trig_angle(float);
159
   float valid_trig_angle(float);
158
   mesh_index_pair find_closest_circle_to_print(float, float);
160
   mesh_index_pair find_closest_circle_to_print(float, float);
159
-  void debug_current_and_destination(char *title);
160
   void ubl_line_to_destination(const float&, const float&, const float&, const float&, const float&, uint8_t);
161
   void ubl_line_to_destination(const float&, const float&, const float&, const float&, const float&, uint8_t);
161
   //uint16_t x_splits = 0xFFFF, uint16_t y_splits = 0xFFFF);  /* needed for the old mesh_buffer_line() routine */
162
   //uint16_t x_splits = 0xFFFF, uint16_t y_splits = 0xFFFF);  /* needed for the old mesh_buffer_line() routine */
162
 
163
 
172
 
173
 
173
   int8_t prime_flag = 0;
174
   int8_t prime_flag = 0;
174
 
175
 
175
-  bool keep_heaters_on = false;
176
-
177
-  bool g26_debug_flag = false;
178
-
179
-  /**
180
-   * These support functions allow the use of large bit arrays of flags that take very
181
-   * little RAM. Currently they are limited to being 16x16 in size. Changing the declaration
182
-   * to unsigned long will allow us to go to 32x32 if higher resolution Mesh's are needed
183
-   * in the future.
184
-   */
185
-  void bit_clear(uint16_t bits[16], uint8_t x, uint8_t y) { CBI(bits[y], x); }
186
-  void bit_set(uint16_t bits[16], uint8_t x, uint8_t y) { SBI(bits[y], x); }
187
-  bool is_bit_set(uint16_t bits[16], uint8_t x, uint8_t y) { return TEST(bits[y], x); }
176
+  bool keep_heaters_on = false,
177
+       g26_debug_flag = false;
188
 
178
 
189
   /**
179
   /**
190
    * G26: Mesh Validation Pattern generation.
180
    * G26: Mesh Validation Pattern generation.
544
     }
534
     }
545
   }
535
   }
546
 
536
 
547
-  void debug_current_and_destination(char *title) {
548
-    float dx, dy, de, xy_dist, fpmm;
549
-
550
-    // if the title message starts with a '!' it is so important, we are going to
551
-    // ignore the status of the g26_debug_flag
552
-    if (*title != '!' && !g26_debug_flag) return;
553
-
554
-    dx = current_position[X_AXIS] - destination[X_AXIS];
555
-    dy = current_position[Y_AXIS] - destination[Y_AXIS];
556
-    de = destination[E_AXIS] - current_position[E_AXIS];
557
-    if (de == 0.0) return;
558
-
559
-    xy_dist = HYPOT(dx, dy);
560
-    if (xy_dist == 0.0) {
561
-      return;
562
-      //SERIAL_ECHOPGM("   FPMM=");
563
-      //fpmm = de;
564
-      //SERIAL_PROTOCOL_F(fpmm, 6);
565
-    }
566
-    else {
567
-      SERIAL_ECHOPGM("   fpmm=");
568
-      fpmm = de / xy_dist;
569
-      SERIAL_ECHO_F(fpmm, 6);
570
-    }
571
-
572
-    SERIAL_ECHOPGM("    current=( ");
573
-    SERIAL_ECHO_F(current_position[X_AXIS], 6);
574
-    SERIAL_ECHOPGM(", ");
575
-    SERIAL_ECHO_F(current_position[Y_AXIS], 6);
576
-    SERIAL_ECHOPGM(", ");
577
-    SERIAL_ECHO_F(current_position[Z_AXIS], 6);
578
-    SERIAL_ECHOPGM(", ");
579
-    SERIAL_ECHO_F(current_position[E_AXIS], 6);
580
-    SERIAL_ECHOPGM(" )   destination=( ");
581
-    if (current_position[X_AXIS] == destination[X_AXIS])
582
-      SERIAL_ECHOPGM("-------------");
583
-    else
584
-      SERIAL_ECHO_F(destination[X_AXIS], 6);
585
-
586
-    SERIAL_ECHOPGM(", ");
587
-
588
-    if (current_position[Y_AXIS] == destination[Y_AXIS])
589
-      SERIAL_ECHOPGM("-------------");
590
-    else
591
-      SERIAL_ECHO_F(destination[Y_AXIS], 6);
592
-
593
-    SERIAL_ECHOPGM(", ");
594
-
595
-    if (current_position[Z_AXIS] == destination[Z_AXIS])
596
-      SERIAL_ECHOPGM("-------------");
597
-    else
598
-      SERIAL_ECHO_F(destination[Z_AXIS], 6);
599
-
600
-    SERIAL_ECHOPGM(", ");
601
-
602
-    if (current_position[E_AXIS] == destination[E_AXIS])
603
-      SERIAL_ECHOPGM("-------------");
604
-    else
605
-      SERIAL_ECHO_F(destination[E_AXIS], 6);
606
-
607
-    SERIAL_ECHOPGM(" )   ");
608
-    SERIAL_ECHO(title);
609
-    SERIAL_EOL;
610
-
611
-    SET_INPUT_PULLUP(66); // Roxy's Left Switch is on pin 66.  Right Switch is on pin 65
612
-
613
-    //if (been_to_2_6) {
614
-    //while ((digitalRead(66) & 0x01) != 0)
615
-    //  idle();
616
-    //}
617
-  }
618
-
619
   void move_to(const float &x, const float &y, const float &z, const float &e_delta) {
537
   void move_to(const float &x, const float &y, const float &z, const float &e_delta) {
620
     float feed_value;
538
     float feed_value;
621
     static float last_z = -999.99;
539
     static float last_z = -999.99;
1002
     return UBL_OK;
920
     return UBL_OK;
1003
   }
921
   }
1004
 
922
 
1005
-#endif // AUTO_BED_LEVELING_UBL
923
+#endif // AUTO_BED_LEVELING_UBL && UBL_MESH_EDIT_ENABLED

+ 0
- 1
Marlin/Marlin.h Ver fichero

40
 #include "fastio.h"
40
 #include "fastio.h"
41
 #include "utility.h"
41
 #include "utility.h"
42
 
42
 
43
-
44
 #ifdef USBCON
43
 #ifdef USBCON
45
   #include "HardwareSerial.h"
44
   #include "HardwareSerial.h"
46
   #if ENABLED(BLUETOOTH)
45
   #if ENABLED(BLUETOOTH)

+ 36
- 28
Marlin/Marlin_main.cpp Ver fichero

233
 #include "duration_t.h"
233
 #include "duration_t.h"
234
 #include "types.h"
234
 #include "types.h"
235
 
235
 
236
-#if ENABLED(AUTO_BED_LEVELING_UBL)
237
-  #include "UBL.h"
238
-#endif
239
-
240
 #if HAS_ABL
236
 #if HAS_ABL
241
   #include "vector_3.h"
237
   #include "vector_3.h"
242
   #if ENABLED(AUTO_BED_LEVELING_LINEAR)
238
   #if ENABLED(AUTO_BED_LEVELING_LINEAR)
301
 #endif
297
 #endif
302
 
298
 
303
 #if ENABLED(AUTO_BED_LEVELING_UBL)
299
 #if ENABLED(AUTO_BED_LEVELING_UBL)
300
+  #include "UBL.h"
304
   unified_bed_leveling ubl;
301
   unified_bed_leveling ubl;
302
+#define UBL_MESH_VALID !(   z_values[0][0] == z_values[0][1] && z_values[0][1] == z_values[0][2] \
303
+                         && z_values[1][0] == z_values[1][1] && z_values[1][1] == z_values[1][2] \
304
+                         && z_values[2][0] == z_values[2][1] && z_values[2][1] == z_values[2][2] \
305
+                         && z_values[0][0] == 0 && z_values[1][0] == 0 && z_values[2][0] == 0    \
306
+                         || isnan(z_values[0][0]))
305
 #endif
307
 #endif
306
 
308
 
307
 bool Running = true;
309
 bool Running = true;
2009
       safe_delay(375);
2011
       safe_delay(375);
2010
     }
2012
     }
2011
 
2013
 
2012
-    FORCE_INLINE void set_bltouch_deployed(const bool &deploy) {
2014
+    void set_bltouch_deployed(const bool deploy) {
2013
       bltouch_command(deploy ? BLTOUCH_DEPLOY : BLTOUCH_STOW);
2015
       bltouch_command(deploy ? BLTOUCH_DEPLOY : BLTOUCH_STOW);
2014
       #if ENABLED(DEBUG_LEVELING_FEATURE)
2016
       #if ENABLED(DEBUG_LEVELING_FEATURE)
2015
         if (DEBUGGING(LEVELING)) {
2017
         if (DEBUGGING(LEVELING)) {
2266
 
2268
 
2267
 #endif // HAS_BED_PROBE
2269
 #endif // HAS_BED_PROBE
2268
 
2270
 
2269
-#if PLANNER_LEVELING || ENABLED(AUTO_BED_LEVELING_UBL)
2271
+#if PLANNER_LEVELING
2270
   /**
2272
   /**
2271
    * Turn bed leveling on or off, fixing the current
2273
    * Turn bed leveling on or off, fixing the current
2272
    * position as-needed.
2274
    * position as-needed.
2284
 
2286
 
2285
         mbl.set_active(enable && mbl.has_mesh());
2287
         mbl.set_active(enable && mbl.has_mesh());
2286
 
2288
 
2287
-        if (enable) planner.unapply_leveling(current_position);
2289
+        if (enable && mbl.has_mesh()) planner.unapply_leveling(current_position);
2288
       }
2290
       }
2289
 
2291
 
2290
     #elif HAS_ABL && !ENABLED(AUTO_BED_LEVELING_UBL)
2292
     #elif HAS_ABL && !ENABLED(AUTO_BED_LEVELING_UBL)
2309
           planner.unapply_leveling(current_position);
2311
           planner.unapply_leveling(current_position);
2310
       }
2312
       }
2311
     #elif ENABLED(AUTO_BED_LEVELING_UBL)
2313
     #elif ENABLED(AUTO_BED_LEVELING_UBL)
2312
-        ubl.state.active = enable;
2314
+      ubl.state.active = enable;
2315
+      //set_current_from_steppers_for_axis(Z_AXIS);
2313
     #endif
2316
     #endif
2314
   }
2317
   }
2315
 
2318
 
3481
  *
3484
  *
3482
  */
3485
  */
3483
 inline void gcode_G28() {
3486
 inline void gcode_G28() {
3484
-  #if ENABLED(AUTO_BED_LEVELING_UBL)
3485
-  bool bed_leveling_state_at_entry=0;
3486
-    bed_leveling_state_at_entry = ubl.state.active;
3487
-    set_bed_leveling_enabled(false);
3488
-  #endif
3489
 
3487
 
3490
   #if ENABLED(DEBUG_LEVELING_FEATURE)
3488
   #if ENABLED(DEBUG_LEVELING_FEATURE)
3491
     if (DEBUGGING(LEVELING)) {
3489
     if (DEBUGGING(LEVELING)) {
3498
   stepper.synchronize();
3496
   stepper.synchronize();
3499
 
3497
 
3500
   // Disable the leveling matrix before homing
3498
   // Disable the leveling matrix before homing
3501
-  #if PLANNER_LEVELING || ENABLED(MESH_BED_LEVELING)
3499
+  #if PLANNER_LEVELING
3500
+    #if ENABLED(AUTO_BED_LEVELING_UBL)
3501
+      const bool bed_leveling_state_at_entry = ubl.state.active;
3502
+    #endif
3502
     set_bed_leveling_enabled(false);
3503
     set_bed_leveling_enabled(false);
3503
   #endif
3504
   #endif
3504
 
3505
 
5305
 
5306
 
5306
 #endif // Z_MIN_PROBE_REPEATABILITY_TEST
5307
 #endif // Z_MIN_PROBE_REPEATABILITY_TEST
5307
 
5308
 
5309
+#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_MESH_EDIT_ENABLED)
5310
+
5311
+  inline void gcode_M49() {
5312
+    SERIAL_PROTOCOLPGM("UBL Debug Flag turned ");
5313
+    if ((g26_debug_flag = !g26_debug_flag))
5314
+      SERIAL_PROTOCOLLNPGM("on.");
5315
+    else
5316
+      SERIAL_PROTOCOLLNPGM("off.");
5317
+  }
5318
+
5319
+#endif // AUTO_BED_LEVELING_UBL && UBL_MESH_EDIT_ENABLED
5320
+
5308
 /**
5321
 /**
5309
  * M75: Start print timer
5322
  * M75: Start print timer
5310
  */
5323
  */
8512
           break;
8525
           break;
8513
       #endif // INCH_MODE_SUPPORT
8526
       #endif // INCH_MODE_SUPPORT
8514
 
8527
 
8515
-      #if ENABLED(AUTO_BED_LEVELING_UBL)
8528
+      #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_MESH_EDIT_ENABLED)
8516
         case 26: // G26: Mesh Validation Pattern generation
8529
         case 26: // G26: Mesh Validation Pattern generation
8517
           gcode_G26();
8530
           gcode_G26();
8518
           break;
8531
           break;
8528
         gcode_G28();
8541
         gcode_G28();
8529
         break;
8542
         break;
8530
 
8543
 
8531
-      #if PLANNER_LEVELING || HAS_ABL
8544
+      #if PLANNER_LEVELING
8532
         case 29: // G29 Detailed Z probe, probes the bed at 3 or more points,
8545
         case 29: // G29 Detailed Z probe, probes the bed at 3 or more points,
8533
                  // or provides access to the UBL System if enabled.
8546
                  // or provides access to the UBL System if enabled.
8534
           gcode_G29();
8547
           gcode_G29();
8644
           break;
8657
           break;
8645
       #endif // Z_MIN_PROBE_REPEATABILITY_TEST
8658
       #endif // Z_MIN_PROBE_REPEATABILITY_TEST
8646
 
8659
 
8647
-      #if ENABLED(AUTO_BED_LEVELING_UBL)
8660
+      #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_MESH_EDIT_ENABLED)
8648
         case 49: // M49: Turn on or off g26_debug_flag for verbose output
8661
         case 49: // M49: Turn on or off g26_debug_flag for verbose output
8649
-    if (g26_debug_flag) {
8650
-            SERIAL_PROTOCOLPGM("UBL Debug Flag turned off.\n");
8651
-            g26_debug_flag = 0; }
8652
-    else {
8653
-            SERIAL_PROTOCOLPGM("UBL Debug Flag turned on.\n");
8654
-            g26_debug_flag++; }
8662
+          gcode_M49();
8655
           break;
8663
           break;
8656
-      #endif // Z_MIN_PROBE_REPEATABILITY_TEST
8664
+      #endif // AUTO_BED_LEVELING_UBL && UBL_MESH_EDIT_ENABLED
8657
 
8665
 
8658
       case 75: // M75: Start print timer
8666
       case 75: // M75: Start print timer
8659
         gcode_M75(); break;
8667
         gcode_M75(); break;
9547
  */
9555
  */
9548
 void set_current_from_steppers_for_axis(const AxisEnum axis) {
9556
 void set_current_from_steppers_for_axis(const AxisEnum axis) {
9549
   get_cartesian_from_steppers();
9557
   get_cartesian_from_steppers();
9550
-  #if PLANNER_LEVELING
9558
+  #if PLANNER_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL)
9551
     planner.unapply_leveling(cartes);
9559
     planner.unapply_leveling(cartes);
9552
   #endif
9560
   #endif
9553
   if (axis == ALL_AXES)
9561
   if (axis == ALL_AXES)
9584
     float normalized_dist, end[XYZE];
9592
     float normalized_dist, end[XYZE];
9585
 
9593
 
9586
     // Split at the left/front border of the right/top square
9594
     // Split at the left/front border of the right/top square
9587
-    int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
9595
+    const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
9588
     if (cx2 != cx1 && TEST(x_splits, gcx)) {
9596
     if (cx2 != cx1 && TEST(x_splits, gcx)) {
9589
       COPY(end, destination);
9597
       COPY(end, destination);
9590
       destination[X_AXIS] = LOGICAL_X_POSITION(mbl.get_probe_x(gcx));
9598
       destination[X_AXIS] = LOGICAL_X_POSITION(mbl.get_probe_x(gcx));
9647
     float normalized_dist, end[XYZE];
9655
     float normalized_dist, end[XYZE];
9648
 
9656
 
9649
     // Split at the left/front border of the right/top square
9657
     // Split at the left/front border of the right/top square
9650
-    int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
9658
+    const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
9651
     if (cx2 != cx1 && TEST(x_splits, gcx)) {
9659
     if (cx2 != cx1 && TEST(x_splits, gcx)) {
9652
       COPY(end, destination);
9660
       COPY(end, destination);
9653
       destination[X_AXIS] = LOGICAL_X_POSITION(bilinear_start[X_AXIS] + ABL_BG_SPACING(X_AXIS) * gcx);
9661
       destination[X_AXIS] = LOGICAL_X_POSITION(bilinear_start[X_AXIS] + ABL_BG_SPACING(X_AXIS) * gcx);
10288
 
10296
 
10289
 float calculate_volumetric_multiplier(float diameter) {
10297
 float calculate_volumetric_multiplier(float diameter) {
10290
   if (!volumetric_enabled || diameter == 0) return 1.0;
10298
   if (!volumetric_enabled || diameter == 0) return 1.0;
10291
-  return 1.0 / (M_PI * diameter * 0.5 * diameter * 0.5);
10299
+  return 1.0 / (M_PI * sq(diameter * 0.5));
10292
 }
10300
 }
10293
 
10301
 
10294
 void calculate_volumetric_multipliers() {
10302
 void calculate_volumetric_multipliers() {

+ 87
- 73
Marlin/UBL.h Ver fichero

22
 
22
 
23
 #include "Marlin.h"
23
 #include "Marlin.h"
24
 #include "math.h"
24
 #include "math.h"
25
+#include "vector_3.h"
25
 
26
 
26
 #ifndef UNIFIED_BED_LEVELING_H
27
 #ifndef UNIFIED_BED_LEVELING_H
27
 #define UNIFIED_BED_LEVELING_H
28
 #define UNIFIED_BED_LEVELING_H
32
     #define UBL_ERR true
33
     #define UBL_ERR true
33
 
34
 
34
     typedef struct {
35
     typedef struct {
35
-      int x_index, y_index;
36
-      float distance; // Not always used. But when populated, it is the distance
37
-                      // from the search location
36
+      int8_t x_index, y_index;
37
+      float distance; // When populated, the distance from the search location
38
     } mesh_index_pair;
38
     } mesh_index_pair;
39
 
39
 
40
-    typedef struct { double dx, dy, dz; } vector;
41
-
42
     enum MeshPointType { INVALID, REAL, SET_IN_BITMAP };
40
     enum MeshPointType { INVALID, REAL, SET_IN_BITMAP };
43
 
41
 
44
     bool axis_unhomed_error(bool, bool, bool);
42
     bool axis_unhomed_error(bool, bool, bool);
45
-    void dump(char *str, float f);
43
+    void dump(char * const str, const float &f);
46
     bool ubl_lcd_clicked();
44
     bool ubl_lcd_clicked();
47
-    void probe_entire_mesh(float, float, bool, bool);
45
+    void probe_entire_mesh(const float&, const float&, const bool, const bool);
46
+    void debug_current_and_destination(char *title);
48
     void ubl_line_to_destination(const float&, const float&, const float&, const float&, const float&, uint8_t);
47
     void ubl_line_to_destination(const float&, const float&, const float&, const float&, const float&, uint8_t);
49
-    void manually_probe_remaining_mesh(float, float, float, float, bool);
50
-    vector tilt_mesh_based_on_3pts(float, float, float);
51
-    void new_set_bed_level_equation_3pts(float, float, float);
52
-    float measure_business_card_thickness(float);
53
-    mesh_index_pair find_closest_mesh_point_of_type(MeshPointType, float, float, bool, unsigned int[16]);
48
+    void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool);
49
+    vector_3 tilt_mesh_based_on_3pts(const float&, const float&, const float&);
50
+    float measure_business_card_thickness(const float&);
51
+    mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, unsigned int[16]);
54
     void find_mean_mesh_height();
52
     void find_mean_mesh_height();
55
     void shift_mesh_height();
53
     void shift_mesh_height();
56
     bool g29_parameter_parsing();
54
     bool g29_parameter_parsing();
57
     void g29_what_command();
55
     void g29_what_command();
58
     void g29_eeprom_dump();
56
     void g29_eeprom_dump();
59
     void g29_compare_current_mesh_to_stored_mesh();
57
     void g29_compare_current_mesh_to_stored_mesh();
60
-    void fine_tune_mesh(float, float, bool);
58
+    void fine_tune_mesh(const float&, const float&, const bool);
61
     void bit_clear(uint16_t bits[16], uint8_t x, uint8_t y);
59
     void bit_clear(uint16_t bits[16], uint8_t x, uint8_t y);
62
     void bit_set(uint16_t bits[16], uint8_t x, uint8_t y);
60
     void bit_set(uint16_t bits[16], uint8_t x, uint8_t y);
63
     bool is_bit_set(uint16_t bits[16], uint8_t x, uint8_t y);
61
     bool is_bit_set(uint16_t bits[16], uint8_t x, uint8_t y);
83
     #define MESH_X_DIST ((float(UBL_MESH_MAX_X) - float(UBL_MESH_MIN_X)) / (float(UBL_MESH_NUM_X_POINTS) - 1.0))
81
     #define MESH_X_DIST ((float(UBL_MESH_MAX_X) - float(UBL_MESH_MIN_X)) / (float(UBL_MESH_NUM_X_POINTS) - 1.0))
84
     #define MESH_Y_DIST ((float(UBL_MESH_MAX_Y) - float(UBL_MESH_MIN_Y)) / (float(UBL_MESH_NUM_Y_POINTS) - 1.0))
82
     #define MESH_Y_DIST ((float(UBL_MESH_MAX_Y) - float(UBL_MESH_MIN_Y)) / (float(UBL_MESH_NUM_Y_POINTS) - 1.0))
85
 
83
 
86
-    extern bool g26_debug_flag;
84
+    #if ENABLED(UBL_MESH_EDIT_ENABLED)
85
+      extern bool g26_debug_flag;
86
+    #else
87
+      constexpr bool g26_debug_flag = false;
88
+    #endif
87
     extern float last_specified_z;
89
     extern float last_specified_z;
88
     extern float fade_scaling_factor_for_current_height;
90
     extern float fade_scaling_factor_for_current_height;
89
     extern float z_values[UBL_MESH_NUM_X_POINTS][UBL_MESH_NUM_Y_POINTS];
91
     extern float z_values[UBL_MESH_NUM_X_POINTS][UBL_MESH_NUM_Y_POINTS];
103
               mesh_x_max = UBL_MESH_MAX_X,
105
               mesh_x_max = UBL_MESH_MAX_X,
104
               mesh_y_max = UBL_MESH_MAX_Y,
106
               mesh_y_max = UBL_MESH_MAX_Y,
105
               mesh_x_dist = MESH_X_DIST,
107
               mesh_x_dist = MESH_X_DIST,
106
-              mesh_y_dist = MESH_Y_DIST,
107
-              g29_correction_fade_height = 10.0,
108
-              g29_fade_height_multiplier = 1.0 / 10.0; // It is cheaper to do a floating point multiply than a floating
109
-                                                       // point divide. So, we keep this number in both forms. The first
110
-                                                       // is for the user. The second one is the one that is actually used
111
-                                                       // again and again and again during the correction calculations.
108
+              mesh_y_dist = MESH_Y_DIST;
109
+
110
+        #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
111
+          float g29_correction_fade_height = 10.0,
112
+                g29_fade_height_multiplier = 1.0 / 10.0; // It is cheaper to do a floating point multiply than a floating
113
+                                                         // point divide. So, we keep this number in both forms. The first
114
+                                                         // is for the user. The second one is the one that is actually used
115
+                                                         // again and again and again during the correction calculations.
116
+        #endif
112
 
117
 
113
         unsigned char padding[24];  // This is just to allow room to add state variables without
118
         unsigned char padding[24];  // This is just to allow room to add state variables without
114
                                     // changing the location of data structures in the EEPROM.
119
                                     // changing the location of data structures in the EEPROM.
122
       unified_bed_leveling();
127
       unified_bed_leveling();
123
       //  ~unified_bed_leveling();  // No destructor because this object never goes away!
128
       //  ~unified_bed_leveling();  // No destructor because this object never goes away!
124
 
129
 
125
-      void display_map(int);
130
+      void display_map(const int);
126
 
131
 
127
       void reset();
132
       void reset();
128
       void invalidate();
133
       void invalidate();
129
 
134
 
130
       void store_state();
135
       void store_state();
131
       void load_state();
136
       void load_state();
132
-      void store_mesh(int);
133
-      void load_mesh(int);
137
+      void store_mesh(const int16_t);
138
+      void load_mesh(const int16_t);
134
 
139
 
135
       bool sanity_check();
140
       bool sanity_check();
136
 
141
 
137
-      FORCE_INLINE float map_x_index_to_bed_location(int8_t i){ return ((float) UBL_MESH_MIN_X) + (((float) MESH_X_DIST) * (float) i); };
138
-      FORCE_INLINE float map_y_index_to_bed_location(int8_t i){ return ((float) UBL_MESH_MIN_Y) + (((float) MESH_Y_DIST) * (float) i); };
142
+      FORCE_INLINE static float map_x_index_to_bed_location(const int8_t i) { return ((float) UBL_MESH_MIN_X) + (((float) MESH_X_DIST) * (float) i); };
143
+      FORCE_INLINE static float map_y_index_to_bed_location(const int8_t i) { return ((float) UBL_MESH_MIN_Y) + (((float) MESH_Y_DIST) * (float) i); };
139
 
144
 
140
-      void set_z(const int8_t px, const int8_t py, const float z) { z_values[px][py] = z; }
145
+      FORCE_INLINE void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; }
141
 
146
 
142
-      int8_t get_cell_index_x(float x) {
143
-        int8_t cx = (x - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST));
147
+      static int8_t get_cell_index_x(const float &x) {
148
+        const int8_t cx = (x - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST));
144
         return constrain(cx, 0, (UBL_MESH_NUM_X_POINTS) - 1);   // -1 is appropriate if we want all movement to the X_MAX
149
         return constrain(cx, 0, (UBL_MESH_NUM_X_POINTS) - 1);   // -1 is appropriate if we want all movement to the X_MAX
145
       }                                                         // position. But with this defined this way, it is possible
150
       }                                                         // position. But with this defined this way, it is possible
146
                                                                 // to extrapolate off of this point even further out. Probably
151
                                                                 // to extrapolate off of this point even further out. Probably
147
                                                                 // that is OK because something else should be keeping that from
152
                                                                 // that is OK because something else should be keeping that from
148
                                                                 // happening and should not be worried about at this level.
153
                                                                 // happening and should not be worried about at this level.
149
-      int8_t get_cell_index_y(float y) {
150
-        int8_t cy = (y - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST));
154
+      static int8_t get_cell_index_y(const float &y) {
155
+        const int8_t cy = (y - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST));
151
         return constrain(cy, 0, (UBL_MESH_NUM_Y_POINTS) - 1);   // -1 is appropriate if we want all movement to the Y_MAX
156
         return constrain(cy, 0, (UBL_MESH_NUM_Y_POINTS) - 1);   // -1 is appropriate if we want all movement to the Y_MAX
152
       }                                                         // position. But with this defined this way, it is possible
157
       }                                                         // position. But with this defined this way, it is possible
153
                                                                 // to extrapolate off of this point even further out. Probably
158
                                                                 // to extrapolate off of this point even further out. Probably
154
                                                                 // that is OK because something else should be keeping that from
159
                                                                 // that is OK because something else should be keeping that from
155
                                                                 // happening and should not be worried about at this level.
160
                                                                 // happening and should not be worried about at this level.
156
 
161
 
157
-      int8_t find_closest_x_index(float x) {
158
-        int8_t px = (x - (UBL_MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST));
162
+      static int8_t find_closest_x_index(const float &x) {
163
+        const int8_t px = (x - (UBL_MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST));
159
         return (px >= 0 && px < (UBL_MESH_NUM_X_POINTS)) ? px : -1;
164
         return (px >= 0 && px < (UBL_MESH_NUM_X_POINTS)) ? px : -1;
160
       }
165
       }
161
 
166
 
162
-      int8_t find_closest_y_index(float y) {
163
-        int8_t py = (y - (UBL_MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST));
167
+      static int8_t find_closest_y_index(const float &y) {
168
+        const int8_t py = (y - (UBL_MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST));
164
         return (py >= 0 && py < (UBL_MESH_NUM_Y_POINTS)) ? py : -1;
169
         return (py >= 0 && py < (UBL_MESH_NUM_Y_POINTS)) ? py : -1;
165
       }
170
       }
166
 
171
 
174
        *    |<---delta_a---------->|
179
        *    |<---delta_a---------->|
175
        *
180
        *
176
        *  calc_z0 is the basis for all the Mesh Based correction. It is used to
181
        *  calc_z0 is the basis for all the Mesh Based correction. It is used to
177
-       *  find the expected Z Height at a position between two known Z-Height locations
182
+       *  find the expected Z Height at a position between two known Z-Height locations.
178
        *
183
        *
179
-       *  It is farly expensive with its 4 floating point additions and 2 floating point
184
+       *  It is fairly expensive with its 4 floating point additions and 2 floating point
180
        *  multiplications.
185
        *  multiplications.
181
        */
186
        */
182
-      inline float calc_z0(float a0, float a1, float z1, float a2, float z2) {
183
-        float delta_z = (z2 - z1);
184
-        float delta_a = (a0 - a1) / (a2 - a1);
187
+      static FORCE_INLINE float calc_z0(const float &a0, const float &a1, const float &z1, const float &a2, const float &z2) {
188
+        const float delta_z = (z2 - z1),
189
+                    delta_a = (a0 - a1) / (a2 - a1);
185
         return z1 + delta_a * delta_z;
190
         return z1 + delta_a * delta_z;
186
       }
191
       }
187
 
192
 
193
        * the X index of the x0 intersection available and we don't want to perform any extra floating
198
        * the X index of the x0 intersection available and we don't want to perform any extra floating
194
        * point operations.
199
        * point operations.
195
        */
200
        */
196
-      inline float get_z_correction_along_horizontal_mesh_line_at_specific_X(float x0, int x1_i, int yi) {
201
+      inline float get_z_correction_along_horizontal_mesh_line_at_specific_X(const float &x0, const int x1_i, const int yi) {
197
         if (x1_i < 0 || yi < 0 || x1_i >= UBL_MESH_NUM_X_POINTS || yi >= UBL_MESH_NUM_Y_POINTS) {
202
         if (x1_i < 0 || yi < 0 || x1_i >= UBL_MESH_NUM_X_POINTS || yi >= UBL_MESH_NUM_Y_POINTS) {
198
           SERIAL_ECHOPAIR("? in get_z_correction_along_horizontal_mesh_line_at_specific_X(x0=", x0);
203
           SERIAL_ECHOPAIR("? in get_z_correction_along_horizontal_mesh_line_at_specific_X(x0=", x0);
199
           SERIAL_ECHOPAIR(",x1_i=", x1_i);
204
           SERIAL_ECHOPAIR(",x1_i=", x1_i);
203
           return NAN;
208
           return NAN;
204
         }
209
         }
205
 
210
 
206
-        const float a0ma1diva2ma1 = (x0 - mesh_index_to_x_location[x1_i]) * (1.0 / (MESH_X_DIST)),
211
+        const float xratio = (RAW_X_POSITION(x0) - mesh_index_to_x_location[x1_i]) * (1.0 / (MESH_X_DIST)),
207
                     z1 = z_values[x1_i][yi],
212
                     z1 = z_values[x1_i][yi],
208
                     z2 = z_values[x1_i + 1][yi],
213
                     z2 = z_values[x1_i + 1][yi],
209
                     dz = (z2 - z1);
214
                     dz = (z2 - z1);
210
 
215
 
211
-        return z1 + a0ma1diva2ma1 * dz;
216
+        return z1 + xratio * dz;
212
       }
217
       }
213
 
218
 
214
       //
219
       //
215
       // See comments above for get_z_correction_along_horizontal_mesh_line_at_specific_X
220
       // See comments above for get_z_correction_along_horizontal_mesh_line_at_specific_X
216
       //
221
       //
217
-      inline float get_z_correction_along_vertical_mesh_line_at_specific_Y(float y0, int xi, int y1_i) {
222
+      inline float get_z_correction_along_vertical_mesh_line_at_specific_Y(const float &y0, const int xi, const int y1_i) {
218
         if (xi < 0 || y1_i < 0 || xi >= UBL_MESH_NUM_X_POINTS || y1_i >= UBL_MESH_NUM_Y_POINTS) {
223
         if (xi < 0 || y1_i < 0 || xi >= UBL_MESH_NUM_X_POINTS || y1_i >= UBL_MESH_NUM_Y_POINTS) {
219
           SERIAL_ECHOPAIR("? in get_z_correction_along_vertical_mesh_line_at_specific_X(y0=", y0);
224
           SERIAL_ECHOPAIR("? in get_z_correction_along_vertical_mesh_line_at_specific_X(y0=", y0);
220
           SERIAL_ECHOPAIR(", x1_i=", xi);
225
           SERIAL_ECHOPAIR(", x1_i=", xi);
224
           return NAN;
229
           return NAN;
225
         }
230
         }
226
 
231
 
227
-        const float a0ma1diva2ma1 = (y0 - mesh_index_to_y_location[y1_i]) * (1.0 / (MESH_Y_DIST)),
232
+        const float yratio = (RAW_Y_POSITION(y0) - mesh_index_to_y_location[y1_i]) * (1.0 / (MESH_Y_DIST)),
228
                     z1 = z_values[xi][y1_i],
233
                     z1 = z_values[xi][y1_i],
229
                     z2 = z_values[xi][y1_i + 1],
234
                     z2 = z_values[xi][y1_i + 1],
230
                     dz = (z2 - z1);
235
                     dz = (z2 - z1);
231
 
236
 
232
-        return z1 + a0ma1diva2ma1 * dz;
237
+        return z1 + yratio * dz;
233
       }
238
       }
234
 
239
 
235
       /**
240
       /**
238
        * Z-Height at both ends. Then it does a linear interpolation of these heights based
243
        * Z-Height at both ends. Then it does a linear interpolation of these heights based
239
        * on the Y position within the cell.
244
        * on the Y position within the cell.
240
        */
245
        */
241
-      float get_z_correction(float x0, float y0) {
242
-        int8_t cx = get_cell_index_x(x0),
243
-        cy = get_cell_index_y(y0);
246
+      float get_z_correction(const float &x0, const float &y0) const {
247
+        const int8_t cx = get_cell_index_x(RAW_X_POSITION(x0)),
248
+                     cy = get_cell_index_y(RAW_Y_POSITION(y0));
244
 
249
 
245
         if (cx < 0 || cy < 0 || cx >= UBL_MESH_NUM_X_POINTS || cy >= UBL_MESH_NUM_Y_POINTS) {
250
         if (cx < 0 || cy < 0 || cx >= UBL_MESH_NUM_X_POINTS || cy >= UBL_MESH_NUM_Y_POINTS) {
246
 
251
 
256
           return 0.0; // this used to return state.z_offset
261
           return 0.0; // this used to return state.z_offset
257
         }
262
         }
258
 
263
 
259
-        float z1 = calc_z0(x0,
260
-          map_x_index_to_bed_location(cx), z_values[cx][cy],
261
-          map_x_index_to_bed_location(cx + 1), z_values[cx + 1][cy]);
262
-        float z2 = calc_z0(x0,
263
-          map_x_index_to_bed_location(cx), z_values[cx][cy + 1],
264
-          map_x_index_to_bed_location(cx + 1), z_values[cx + 1][cy + 1]);
265
-        float z0 = calc_z0(y0,
266
-          map_y_index_to_bed_location(cy), z1,
267
-          map_y_index_to_bed_location(cy + 1), z2);
264
+        const float z1 = calc_z0(RAW_X_POSITION(x0),
265
+                      map_x_index_to_bed_location(cx), z_values[cx][cy],
266
+                      map_x_index_to_bed_location(cx + 1), z_values[cx + 1][cy]),
267
+                    z2 = calc_z0(RAW_X_POSITION(x0),
268
+                      map_x_index_to_bed_location(cx), z_values[cx][cy + 1],
269
+                      map_x_index_to_bed_location(cx + 1), z_values[cx + 1][cy + 1]);
270
+              float z0 = calc_z0(RAW_Y_POSITION(y0),
271
+                  map_y_index_to_bed_location(cy), z1,
272
+                  map_y_index_to_bed_location(cy + 1), z2);
268
 
273
 
269
         #if ENABLED(DEBUG_LEVELING_FEATURE)
274
         #if ENABLED(DEBUG_LEVELING_FEATURE)
270
           if (DEBUGGING(MESH_ADJUST)) {
275
           if (DEBUGGING(MESH_ADJUST)) {
308
        * factor is going to be the same as the last time the function calculated a value. If so, it just
313
        * factor is going to be the same as the last time the function calculated a value. If so, it just
309
        * returns it.
314
        * returns it.
310
        *
315
        *
311
-       * If it must do a calcuation, it will return a scaling factor of 0.0 if the UBL System is not active
312
-       * or if the current Z Height is past the specified 'Fade Height'
316
+       * It returns a scaling factor of 1.0 if UBL is inactive.
317
+       * It returns a scaling factor of 0.0 if Z is past the specified 'Fade Height'
313
        */
318
        */
314
-      FORCE_INLINE float fade_scaling_factor_for_z(float current_z) {
315
-      #ifndef ENABLE_LEVELING_FADE_HEIGHT   // if turned off, just return 0.000    Note that we assume the
316
-        return 0.000;                       // compiler will do 'Dead Code' elimination so there is no need
317
-      #endif                                // for an #else clause here.
318
-        if (last_specified_z == current_z)
319
+      #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
320
+
321
+        FORCE_INLINE float fade_scaling_factor_for_z(const float &lz) const {
322
+          const float rz = RAW_Z_POSITION(lz);
323
+          if (last_specified_z != rz) {
324
+            last_specified_z = rz;
325
+            fade_scaling_factor_for_current_height =
326
+              state.active && rz < state.g29_correction_fade_height
327
+                ? 1.0 - (rz * state.g29_fade_height_multiplier)
328
+                : 0.0;
329
+          }
319
           return fade_scaling_factor_for_current_height;
330
           return fade_scaling_factor_for_current_height;
331
+        }
320
 
332
 
321
-        last_specified_z = current_z;
322
-        fade_scaling_factor_for_current_height =
323
-          state.active && current_z < state.g29_correction_fade_height
324
-          ? 1.0 - (current_z * state.g29_fade_height_multiplier)
325
-          : 0.0;
326
-        return fade_scaling_factor_for_current_height;
327
-      }
328
-    };
333
+      #else
334
+
335
+        static constexpr float fade_scaling_factor_for_z(const float &lz) { UNUSED(lz); return 1.0; }
336
+
337
+      #endif
338
+
339
+    }; // class unified_bed_leveling
329
 
340
 
330
     extern unified_bed_leveling ubl;
341
     extern unified_bed_leveling ubl;
331
     extern int ubl_eeprom_start;
342
     extern int ubl_eeprom_start;
332
 
343
 
333
-#endif // AUTO_BED_LEVELING_UBL
344
+    #define UBL_LAST_EEPROM_INDEX (E2END - sizeof(unified_bed_leveling::state))
345
+
346
+  #endif // AUTO_BED_LEVELING_UBL
347
+
334
 #endif // UNIFIED_BED_LEVELING_H
348
 #endif // UNIFIED_BED_LEVELING_H

+ 39
- 31
Marlin/UBL_Bed_Leveling.cpp Ver fichero

24
 #include "math.h"
24
 #include "math.h"
25
 
25
 
26
 #if ENABLED(AUTO_BED_LEVELING_UBL)
26
 #if ENABLED(AUTO_BED_LEVELING_UBL)
27
+
27
   #include "UBL.h"
28
   #include "UBL.h"
28
   #include "hex_print_routines.h"
29
   #include "hex_print_routines.h"
29
 
30
 
30
   /**
31
   /**
32
+   * These support functions allow the use of large bit arrays of flags that take very
33
+   * little RAM. Currently they are limited to being 16x16 in size. Changing the declaration
34
+   * to unsigned long will allow us to go to 32x32 if higher resolution Mesh's are needed
35
+   * in the future.
36
+   */
37
+  void bit_clear(uint16_t bits[16], uint8_t x, uint8_t y) { CBI(bits[y], x); }
38
+  void bit_set(uint16_t bits[16], uint8_t x, uint8_t y) { SBI(bits[y], x); }
39
+  bool is_bit_set(uint16_t bits[16], uint8_t x, uint8_t y) { return TEST(bits[y], x); }
40
+
41
+  /**
31
    * These variables used to be declared inside the unified_bed_leveling class. We are going to
42
    * These variables used to be declared inside the unified_bed_leveling class. We are going to
32
    * still declare them within the .cpp file for bed leveling. But there is only one instance of
43
    * still declare them within the .cpp file for bed leveling. But there is only one instance of
33
    * the bed leveling object and we can get rid of a level of inderection by not making them
44
    * the bed leveling object and we can get rid of a level of inderection by not making them
51
   }
62
   }
52
 
63
 
53
   void unified_bed_leveling::store_state() {
64
   void unified_bed_leveling::store_state() {
54
-    int k = E2END - sizeof(ubl.state);
55
-    eeprom_write_block((void *)&ubl.state, (void *)k, sizeof(ubl.state));
65
+    const uint16_t i = UBL_LAST_EEPROM_INDEX;
66
+    eeprom_write_block((void *)&ubl.state, (void *)i, sizeof(state));
56
   }
67
   }
57
 
68
 
58
   void unified_bed_leveling::load_state() {
69
   void unified_bed_leveling::load_state() {
59
-    int k = E2END - sizeof(ubl.state);
60
-    eeprom_read_block((void *)&ubl.state, (void *)k, sizeof(ubl.state));
70
+    const uint16_t i = UBL_LAST_EEPROM_INDEX;
71
+    eeprom_read_block((void *)&ubl.state, (void *)i, sizeof(state));
61
 
72
 
62
     if (sanity_check())
73
     if (sanity_check())
63
       SERIAL_PROTOCOLLNPGM("?In load_state() sanity_check() failed.\n");
74
       SERIAL_PROTOCOLLNPGM("?In load_state() sanity_check() failed.\n");
64
 
75
 
65
-    /**
66
-     * These lines can go away in a few weeks.  They are just
67
-     * to make sure people updating thier firmware won't be using
68
-     * an incomplete Bed_Leveling.state structure. For speed
69
-     * we now multiply by the inverse of the Fade Height instead of
70
-     * dividing by it. Soon... all of the old structures will be
71
-     * updated, but until then, we try to ease the transition
72
-     * for our Beta testers.
73
-     */
74
-    if (ubl.state.g29_fade_height_multiplier != 1.0 / ubl.state.g29_correction_fade_height) {
75
-      ubl.state.g29_fade_height_multiplier = 1.0 / ubl.state.g29_correction_fade_height;
76
-      store_state();
77
-    }
78
-
76
+    #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
77
+      /**
78
+       * These lines can go away in a few weeks.  They are just
79
+       * to make sure people updating thier firmware won't be using
80
+       * an incomplete Bed_Leveling.state structure. For speed
81
+       * we now multiply by the inverse of the Fade Height instead of
82
+       * dividing by it. Soon... all of the old structures will be
83
+       * updated, but until then, we try to ease the transition
84
+       * for our Beta testers.
85
+       */
86
+      if (ubl.state.g29_fade_height_multiplier != 1.0 / ubl.state.g29_correction_fade_height) {
87
+        ubl.state.g29_fade_height_multiplier = 1.0 / ubl.state.g29_correction_fade_height;
88
+        store_state();
89
+      }
90
+    #endif
79
   }
91
   }
80
 
92
 
81
-  void unified_bed_leveling::load_mesh(int m) {
82
-    int k = E2END - sizeof(ubl.state),
83
-        j = (k - ubl_eeprom_start) / sizeof(z_values);
93
+  void unified_bed_leveling::load_mesh(const int16_t m) {
94
+    int16_t j = (UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(z_values);
84
 
95
 
85
     if (m == -1) {
96
     if (m == -1) {
86
       SERIAL_PROTOCOLLNPGM("?No mesh saved in EEPROM. Zeroing mesh in memory.\n");
97
       SERIAL_PROTOCOLLNPGM("?No mesh saved in EEPROM. Zeroing mesh in memory.\n");
93
       return;
104
       return;
94
     }
105
     }
95
 
106
 
96
-    j = k - (m + 1) * sizeof(z_values);
107
+    j = UBL_LAST_EEPROM_INDEX - (m + 1) * sizeof(z_values);
97
     eeprom_read_block((void *)&z_values , (void *)j, sizeof(z_values));
108
     eeprom_read_block((void *)&z_values , (void *)j, sizeof(z_values));
98
 
109
 
99
     SERIAL_PROTOCOLPGM("Mesh loaded from slot ");
110
     SERIAL_PROTOCOLPGM("Mesh loaded from slot ");
103
     SERIAL_EOL;
114
     SERIAL_EOL;
104
   }
115
   }
105
 
116
 
106
-  void unified_bed_leveling:: store_mesh(int m) {
107
-    int k = E2END - sizeof(state),
108
-        j = (k - ubl_eeprom_start) / sizeof(z_values);
117
+  void unified_bed_leveling::store_mesh(const int16_t m) {
118
+    int16_t j = (UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(z_values);
109
 
119
 
110
     if (m < 0 || m >= j || ubl_eeprom_start <= 0) {
120
     if (m < 0 || m >= j || ubl_eeprom_start <= 0) {
111
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n");
121
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n");
112
       SERIAL_PROTOCOL(m);
122
       SERIAL_PROTOCOL(m);
113
       SERIAL_PROTOCOLLNPGM(" mesh slots available.\n");
123
       SERIAL_PROTOCOLLNPGM(" mesh slots available.\n");
114
       SERIAL_PROTOCOLLNPAIR("E2END     : ", E2END);
124
       SERIAL_PROTOCOLLNPAIR("E2END     : ", E2END);
115
-      SERIAL_PROTOCOLLNPAIR("k         : ", k);
125
+      SERIAL_PROTOCOLLNPAIR("k         : ", (int)UBL_LAST_EEPROM_INDEX);
116
       SERIAL_PROTOCOLLNPAIR("j         : ", j);
126
       SERIAL_PROTOCOLLNPAIR("j         : ", j);
117
       SERIAL_PROTOCOLLNPAIR("m         : ", m);
127
       SERIAL_PROTOCOLLNPAIR("m         : ", m);
118
       SERIAL_EOL;
128
       SERIAL_EOL;
119
       return;
129
       return;
120
     }
130
     }
121
 
131
 
122
-    j = k - (m + 1) * sizeof(z_values);
132
+    j = UBL_LAST_EEPROM_INDEX - (m + 1) * sizeof(z_values);
123
     eeprom_write_block((const void *)&z_values, (void *)j, sizeof(z_values));
133
     eeprom_write_block((const void *)&z_values, (void *)j, sizeof(z_values));
124
 
134
 
125
     SERIAL_PROTOCOLPGM("Mesh saved in slot ");
135
     SERIAL_PROTOCOLPGM("Mesh saved in slot ");
151
         z_values[x][y] = NAN;
161
         z_values[x][y] = NAN;
152
   }
162
   }
153
 
163
 
154
-  void unified_bed_leveling::display_map(int map_type) {
164
+  void unified_bed_leveling::display_map(const int map_type) {
155
     float f, current_xi, current_yi;
165
     float f, current_xi, current_yi;
156
     int8_t i, j;
166
     int8_t i, j;
157
     UNUSED(map_type);
167
     UNUSED(map_type);
287
       error_flag++;
297
       error_flag++;
288
     }
298
     }
289
 
299
 
290
-    const int k = E2END - sizeof(ubl.state),
291
-              j = (k - ubl_eeprom_start) / sizeof(z_values);
292
-
300
+    const int j = (UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(z_values);
293
     if (j < 1) {
301
     if (j < 1) {
294
       SERIAL_PROTOCOLLNPGM("?No EEPROM storage available for a mesh of this size.\n");
302
       SERIAL_PROTOCOLLNPGM("?No EEPROM storage available for a mesh of this size.\n");
295
       error_flag++;
303
       error_flag++;

+ 110
- 157
Marlin/UBL_G29.cpp Ver fichero

20
  *
20
  *
21
  */
21
  */
22
 
22
 
23
-#include "Marlin.h"
23
+#include "MarlinConfig.h"
24
+
24
 #if ENABLED(AUTO_BED_LEVELING_UBL)
25
 #if ENABLED(AUTO_BED_LEVELING_UBL)
25
   //#include "vector_3.h"
26
   //#include "vector_3.h"
26
   //#include "qr_solve.h"
27
   //#include "qr_solve.h"
27
 
28
 
28
   #include "UBL.h"
29
   #include "UBL.h"
30
+  #include "Marlin.h"
29
   #include "hex_print_routines.h"
31
   #include "hex_print_routines.h"
30
   #include "configuration_store.h"
32
   #include "configuration_store.h"
31
   #include "planner.h"
33
   #include "planner.h"
49
   #define DEPLOY_PROBE() set_probe_deployed(true)
51
   #define DEPLOY_PROBE() set_probe_deployed(true)
50
   #define STOW_PROBE() set_probe_deployed(false)
52
   #define STOW_PROBE() set_probe_deployed(false)
51
   bool ProbeStay = true;
53
   bool ProbeStay = true;
52
-  float ubl_3_point_1_X = UBL_PROBE_PT_1_X;
53
-  float ubl_3_point_1_Y = UBL_PROBE_PT_1_Y;
54
-  float ubl_3_point_2_X = UBL_PROBE_PT_2_X;
55
-  float ubl_3_point_2_Y = UBL_PROBE_PT_2_Y;
56
-  float ubl_3_point_3_X = UBL_PROBE_PT_3_X;
57
-  float ubl_3_point_3_Y = UBL_PROBE_PT_3_Y;
54
+
55
+  constexpr float ubl_3_point_1_X = UBL_PROBE_PT_1_X,
56
+                  ubl_3_point_1_Y = UBL_PROBE_PT_1_Y,
57
+                  ubl_3_point_2_X = UBL_PROBE_PT_2_X,
58
+                  ubl_3_point_2_Y = UBL_PROBE_PT_2_Y,
59
+                  ubl_3_point_3_X = UBL_PROBE_PT_3_X,
60
+                  ubl_3_point_3_Y = UBL_PROBE_PT_3_Y;
58
 
61
 
59
   #define SIZE_OF_LITTLE_RAISE 0
62
   #define SIZE_OF_LITTLE_RAISE 0
60
   #define BIG_RAISE_NOT_NEEDED 0
63
   #define BIG_RAISE_NOT_NEEDED 0
293
   volatile uint8_t ubl_encoderDiff = 0; // Volatile because it's changed by Temperature ISR button update
296
   volatile uint8_t ubl_encoderDiff = 0; // Volatile because it's changed by Temperature ISR button update
294
 
297
 
295
   // The simple parameter flags and values are 'static' so parameter parsing can be in a support routine.
298
   // The simple parameter flags and values are 'static' so parameter parsing can be in a support routine.
296
-  static int g29_verbose_level = 0, test_value = 0,
297
-             phase_value = -1, repetition_cnt = 1;
299
+  static int g29_verbose_level = 0, phase_value = -1, repetition_cnt = 1,
300
+             storage_slot = 0, test_pattern = 0;
298
   static bool repeat_flag = UBL_OK, c_flag = false, x_flag = UBL_OK, y_flag = UBL_OK, statistics_flag = UBL_OK, business_card_mode = false;
301
   static bool repeat_flag = UBL_OK, c_flag = false, x_flag = UBL_OK, y_flag = UBL_OK, statistics_flag = UBL_OK, business_card_mode = false;
299
   static float x_pos = 0.0, y_pos = 0.0, height_value = 5.0, measured_z, card_thickness = 0.0, constant = 0.0;
302
   static float x_pos = 0.0, y_pos = 0.0, height_value = 5.0, measured_z, card_thickness = 0.0, constant = 0.0;
300
-  static int storage_slot = 0, test_pattern = 0;
301
 
303
 
302
   #if ENABLED(ULTRA_LCD)
304
   #if ENABLED(ULTRA_LCD)
303
     void lcd_setstatus(const char* message, bool persist);
305
     void lcd_setstatus(const char* message, bool persist);
304
   #endif
306
   #endif
305
 
307
 
306
   void gcode_G29() {
308
   void gcode_G29() {
307
-    mesh_index_pair location;
308
-    int j, k;
309
     float Z1, Z2, Z3;
309
     float Z1, Z2, Z3;
310
 
310
 
311
     g29_verbose_level = 0;  // These may change, but let's get some reasonable values into them.
311
     g29_verbose_level = 0;  // These may change, but let's get some reasonable values into them.
331
     if (code_seen('I')) {
331
     if (code_seen('I')) {
332
       repetition_cnt = code_has_value() ? code_value_int() : 1;
332
       repetition_cnt = code_has_value() ? code_value_int() : 1;
333
       while (repetition_cnt--) {
333
       while (repetition_cnt--) {
334
-        location = find_closest_mesh_point_of_type(REAL, x_pos, y_pos, 0, NULL);  // The '0' says we want to use the nozzle's position
334
+        const mesh_index_pair location = find_closest_mesh_point_of_type(REAL, x_pos, y_pos, 0, NULL);  // The '0' says we want to use the nozzle's position
335
         if (location.x_index < 0) {
335
         if (location.x_index < 0) {
336
           SERIAL_PROTOCOLLNPGM("Entire Mesh invalidated.\n");
336
           SERIAL_PROTOCOLLNPGM("Entire Mesh invalidated.\n");
337
           break;            // No more invalid Mesh Points to populate
337
           break;            // No more invalid Mesh Points to populate
409
             SERIAL_ECHOPAIR(",", y_pos);
409
             SERIAL_ECHOPAIR(",", y_pos);
410
             SERIAL_PROTOCOLLNPGM(")\n");
410
             SERIAL_PROTOCOLLNPGM(")\n");
411
           }
411
           }
412
-          probe_entire_mesh( x_pos+X_PROBE_OFFSET_FROM_EXTRUDER, y_pos+Y_PROBE_OFFSET_FROM_EXTRUDER,
413
-                             code_seen('O') || code_seen('M'), code_seen('E'));
412
+          probe_entire_mesh(x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER,
413
+                            code_seen('O') || code_seen('M'), code_seen('E'));
414
           break;
414
           break;
415
         //
415
         //
416
         // Manually Probe Mesh in areas that can not be reached by the probe
416
         // Manually Probe Mesh in areas that can not be reached by the probe
455
           // If no repetition is specified, do the whole Mesh
455
           // If no repetition is specified, do the whole Mesh
456
           if (!repeat_flag) repetition_cnt = 9999;
456
           if (!repeat_flag) repetition_cnt = 9999;
457
           while (repetition_cnt--) {
457
           while (repetition_cnt--) {
458
-            location = find_closest_mesh_point_of_type(INVALID, x_pos, y_pos, 0, NULL); // The '0' says we want to use the nozzle's position
458
+            const mesh_index_pair location = find_closest_mesh_point_of_type(INVALID, x_pos, y_pos, 0, NULL); // The '0' says we want to use the nozzle's position
459
             if (location.x_index < 0) break; // No more invalid Mesh Points to populate
459
             if (location.x_index < 0) break; // No more invalid Mesh Points to populate
460
             z_values[location.x_index][location.y_index] = height_value;
460
             z_values[location.x_index][location.y_index] = height_value;
461
           }
461
           }
534
     if (code_seen('L')) {     // Load Current Mesh Data
534
     if (code_seen('L')) {     // Load Current Mesh Data
535
       storage_slot = code_has_value() ? code_value_int() : ubl.state.eeprom_storage_slot;
535
       storage_slot = code_has_value() ? code_value_int() : ubl.state.eeprom_storage_slot;
536
 
536
 
537
-      k = E2END - sizeof(ubl.state);
538
-      j = (k - ubl_eeprom_start) / sizeof(z_values);
537
+      const int16_t j = (UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(z_values);
539
 
538
 
540
       if (storage_slot < 0 || storage_slot >= j || ubl_eeprom_start <= 0) {
539
       if (storage_slot < 0 || storage_slot >= j || ubl_eeprom_start <= 0) {
541
         SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
540
         SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
569
         return;
568
         return;
570
       }
569
       }
571
 
570
 
572
-      int k = E2END - sizeof(ubl.state),
573
-          j = (k - ubl_eeprom_start) / sizeof(z_values);
571
+      const int16_t j = (UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(z_values);
574
 
572
 
575
       if (storage_slot < 0 || storage_slot >= j || ubl_eeprom_start <= 0) {
573
       if (storage_slot < 0 || storage_slot >= j || ubl_eeprom_start <= 0) {
576
         SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
574
         SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
691
             z_values[x][y] -= mean + constant;
689
             z_values[x][y] -= mean + constant;
692
   }
690
   }
693
 
691
 
694
-  void shift_mesh_height( ) {
692
+  void shift_mesh_height() {
695
     for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
693
     for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
696
       for (uint8_t y = 0; y < UBL_MESH_NUM_Y_POINTS; y++)
694
       for (uint8_t y = 0; y < UBL_MESH_NUM_Y_POINTS; y++)
697
         if (!isnan(z_values[x][y]))
695
         if (!isnan(z_values[x][y]))
702
    * Probe all invalidated locations of the mesh that can be reached by the probe.
700
    * Probe all invalidated locations of the mesh that can be reached by the probe.
703
    * This attempts to fill in locations closest to the nozzle's start location first.
701
    * This attempts to fill in locations closest to the nozzle's start location first.
704
    */
702
    */
705
-  void probe_entire_mesh(float x_pos, float y_pos, bool do_ubl_mesh_map, bool stow_probe) {
703
+  void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe) {
706
     mesh_index_pair location;
704
     mesh_index_pair location;
707
-    float xProbe, yProbe, measured_z;
708
 
705
 
709
     ubl_has_control_of_lcd_panel++;
706
     ubl_has_control_of_lcd_panel++;
710
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
707
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
720
         restore_ubl_active_state_and_leave();
717
         restore_ubl_active_state_and_leave();
721
         return;
718
         return;
722
       }
719
       }
723
-      location = find_closest_mesh_point_of_type(INVALID, x_pos, y_pos, 1, NULL);  // the '1' says we want the location to be relative to the probe
720
+
721
+      location = find_closest_mesh_point_of_type(INVALID, lx, ly, 1, NULL);  // the '1' says we want the location to be relative to the probe
724
       if (location.x_index >= 0 && location.y_index >= 0) {
722
       if (location.x_index >= 0 && location.y_index >= 0) {
725
-        xProbe = ubl.map_x_index_to_bed_location(location.x_index);
726
-        yProbe = ubl.map_y_index_to_bed_location(location.y_index);
723
+        const float xProbe = ubl.map_x_index_to_bed_location(location.x_index),
724
+                    yProbe = ubl.map_y_index_to_bed_location(location.y_index);
727
         if (xProbe < MIN_PROBE_X || xProbe > MAX_PROBE_X || yProbe < MIN_PROBE_Y || yProbe > MAX_PROBE_Y) {
725
         if (xProbe < MIN_PROBE_X || xProbe > MAX_PROBE_X || yProbe < MIN_PROBE_Y || yProbe > MAX_PROBE_Y) {
728
           SERIAL_PROTOCOLLNPGM("?Error: Attempt to probe off the bed.");
726
           SERIAL_PROTOCOLLNPGM("?Error: Attempt to probe off the bed.");
729
           ubl_has_control_of_lcd_panel = false;
727
           ubl_has_control_of_lcd_panel = false;
730
           goto LEAVE;
728
           goto LEAVE;
731
         }
729
         }
732
-        measured_z = probe_pt(xProbe, yProbe, stow_probe, g29_verbose_level);
730
+        const float measured_z = probe_pt(xProbe, yProbe, stow_probe, g29_verbose_level);
733
         z_values[location.x_index][location.y_index] = measured_z + Z_PROBE_OFFSET_FROM_EXTRUDER;
731
         z_values[location.x_index][location.y_index] = measured_z + Z_PROBE_OFFSET_FROM_EXTRUDER;
734
       }
732
       }
735
 
733
 
736
       if (do_ubl_mesh_map) ubl.display_map(1);
734
       if (do_ubl_mesh_map) ubl.display_map(1);
735
+
737
     } while (location.x_index >= 0 && location.y_index >= 0);
736
     } while (location.x_index >= 0 && location.y_index >= 0);
738
 
737
 
739
     LEAVE:
738
     LEAVE:
742
     STOW_PROBE();
741
     STOW_PROBE();
743
     restore_ubl_active_state_and_leave();
742
     restore_ubl_active_state_and_leave();
744
 
743
 
745
-    x_pos = constrain(x_pos - (X_PROBE_OFFSET_FROM_EXTRUDER), X_MIN_POS, X_MAX_POS);
746
-    y_pos = constrain(y_pos - (Y_PROBE_OFFSET_FROM_EXTRUDER), Y_MIN_POS, Y_MAX_POS);
747
-
748
-    do_blocking_move_to_xy(x_pos, y_pos);
744
+    do_blocking_move_to_xy(
745
+      constrain(lx - (X_PROBE_OFFSET_FROM_EXTRUDER), X_MIN_POS, X_MAX_POS),
746
+      constrain(ly - (Y_PROBE_OFFSET_FROM_EXTRUDER), Y_MIN_POS, Y_MAX_POS)
747
+    );
749
   }
748
   }
750
 
749
 
751
-  vector tilt_mesh_based_on_3pts(float pt1, float pt2, float pt3) {
752
-    vector v1, v2, normal;
750
+  vector_3 tilt_mesh_based_on_3pts(const float &pt1, const float &pt2, const float &pt3) {
753
     float c, d, t;
751
     float c, d, t;
754
     int i, j;
752
     int i, j;
755
 
753
 
756
-    v1.dx = (ubl_3_point_1_X - ubl_3_point_2_X);
757
-    v1.dy = (ubl_3_point_1_Y - ubl_3_point_2_Y);
758
-    v1.dz = (pt1 - pt2);
759
-
760
-    v2.dx = (ubl_3_point_3_X - ubl_3_point_2_X);
761
-    v2.dy = (ubl_3_point_3_Y - ubl_3_point_2_Y);
762
-    v2.dz = (pt3 - pt2);
754
+    vector_3 v1 = vector_3( (ubl_3_point_1_X - ubl_3_point_2_X),
755
+                            (ubl_3_point_1_Y - ubl_3_point_2_Y),
756
+                            (pt1 - pt2) ),
763
 
757
 
764
-    // do cross product
758
+             v2 = vector_3( (ubl_3_point_3_X - ubl_3_point_2_X),
759
+                            (ubl_3_point_3_Y - ubl_3_point_2_Y),
760
+                            (pt3 - pt2) ),
765
 
761
 
766
-    normal.dx = v1.dy * v2.dz - v1.dz * v2.dy;
767
-    normal.dy = v1.dz * v2.dx - v1.dx * v2.dz;
768
-    normal.dz = v1.dx * v2.dy - v1.dy * v2.dx;
762
+             normal = vector_3::cross(v1, v2);
769
 
763
 
770
-    // printf("[%f,%f,%f]    ", normal.dx, normal.dy, normal.dz);
764
+    // printf("[%f,%f,%f]    ", normal.x, normal.y, normal.z);
771
 
765
 
772
     /**
766
     /**
773
      * This code does two things. This vector is normal to the tilted plane.
767
      * This code does two things. This vector is normal to the tilted plane.
776
      * We also need Z to be unity because we are going to be treating this triangle
770
      * We also need Z to be unity because we are going to be treating this triangle
777
      * as the sin() and cos() of the bed's tilt
771
      * as the sin() and cos() of the bed's tilt
778
      */
772
      */
779
-    normal.dx /= normal.dz;
780
-    normal.dy /= normal.dz;
781
-    normal.dz /= normal.dz;
773
+    const float inv_z = 1.0 / normal.z;
774
+    normal.x *= inv_z;
775
+    normal.y *= inv_z;
776
+    normal.z = 1.0;
782
 
777
 
783
     //
778
     //
784
     // All of 3 of these points should give us the same d constant
779
     // All of 3 of these points should give us the same d constant
785
     //
780
     //
786
-    t = normal.dx * ubl_3_point_1_X + normal.dy * ubl_3_point_1_Y;
787
-    d = t + normal.dz * pt1;
781
+    t = normal.x * ubl_3_point_1_X + normal.y * ubl_3_point_1_Y;
782
+    d = t + normal.z * pt1;
788
     c = d - t;
783
     c = d - t;
789
     SERIAL_ECHOPGM("d from 1st point: ");
784
     SERIAL_ECHOPGM("d from 1st point: ");
790
     SERIAL_ECHO_F(d, 6);
785
     SERIAL_ECHO_F(d, 6);
791
     SERIAL_ECHOPGM("  c: ");
786
     SERIAL_ECHOPGM("  c: ");
792
     SERIAL_ECHO_F(c, 6);
787
     SERIAL_ECHO_F(c, 6);
793
     SERIAL_EOL;
788
     SERIAL_EOL;
794
-    t = normal.dx * ubl_3_point_2_X + normal.dy * ubl_3_point_2_Y;
795
-    d = t + normal.dz * pt2;
789
+    t = normal.x * ubl_3_point_2_X + normal.y * ubl_3_point_2_Y;
790
+    d = t + normal.z * pt2;
796
     c = d - t;
791
     c = d - t;
797
     SERIAL_ECHOPGM("d from 2nd point: ");
792
     SERIAL_ECHOPGM("d from 2nd point: ");
798
     SERIAL_ECHO_F(d, 6);
793
     SERIAL_ECHO_F(d, 6);
799
     SERIAL_ECHOPGM("  c: ");
794
     SERIAL_ECHOPGM("  c: ");
800
     SERIAL_ECHO_F(c, 6);
795
     SERIAL_ECHO_F(c, 6);
801
     SERIAL_EOL;
796
     SERIAL_EOL;
802
-    t = normal.dx * ubl_3_point_3_X + normal.dy * ubl_3_point_3_Y;
803
-    d = t + normal.dz * pt3;
797
+    t = normal.x * ubl_3_point_3_X + normal.y * ubl_3_point_3_Y;
798
+    d = t + normal.z * pt3;
804
     c = d - t;
799
     c = d - t;
805
     SERIAL_ECHOPGM("d from 3rd point: ");
800
     SERIAL_ECHOPGM("d from 3rd point: ");
806
     SERIAL_ECHO_F(d, 6);
801
     SERIAL_ECHO_F(d, 6);
810
 
805
 
811
     for (i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
806
     for (i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
812
       for (j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
807
       for (j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
813
-        c = -((normal.dx * (UBL_MESH_MIN_X + i * (MESH_X_DIST)) + normal.dy * (UBL_MESH_MIN_Y + j * (MESH_Y_DIST))) - d);
808
+        c = -((normal.x * (UBL_MESH_MIN_X + i * (MESH_X_DIST)) + normal.y * (UBL_MESH_MIN_Y + j * (MESH_Y_DIST))) - d);
814
         z_values[i][j] += c;
809
         z_values[i][j] += c;
815
       }
810
       }
816
     }
811
     }
829
     return current_position[Z_AXIS];
824
     return current_position[Z_AXIS];
830
   }
825
   }
831
 
826
 
832
-  float measure_business_card_thickness(float height_value) {
827
+  float measure_business_card_thickness(const float &height_value) {
833
 
828
 
834
     ubl_has_control_of_lcd_panel++;
829
     ubl_has_control_of_lcd_panel++;
835
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
830
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
856
     return abs(Z1 - Z2);
851
     return abs(Z1 - Z2);
857
   }
852
   }
858
 
853
 
859
-  void manually_probe_remaining_mesh(float x_pos, float y_pos, float z_clearance, float card_thickness, bool do_ubl_mesh_map) {
860
-    mesh_index_pair location;
861
-    float last_x, last_y, dx, dy,
862
-          xProbe, yProbe;
854
+  void manually_probe_remaining_mesh(const float &lx, const float &ly, const float &z_clearance, const float &card_thickness, const bool do_ubl_mesh_map) {
863
 
855
 
864
     ubl_has_control_of_lcd_panel++;
856
     ubl_has_control_of_lcd_panel++;
865
-    last_x = last_y = -9999.99;
866
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
857
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
867
     do_blocking_move_to_z(z_clearance);
858
     do_blocking_move_to_z(z_clearance);
868
-    do_blocking_move_to_xy(x_pos, y_pos);
859
+    do_blocking_move_to_xy(lx, ly);
869
 
860
 
861
+    float last_x = -9999.99, last_y = -9999.99;
862
+    mesh_index_pair location;
870
     do {
863
     do {
871
       if (do_ubl_mesh_map) ubl.display_map(1);
864
       if (do_ubl_mesh_map) ubl.display_map(1);
872
 
865
 
873
-      location = find_closest_mesh_point_of_type(INVALID, x_pos, y_pos, 0, NULL); // The '0' says we want to use the nozzle's position
866
+      location = find_closest_mesh_point_of_type(INVALID, lx, ly, 0, NULL); // The '0' says we want to use the nozzle's position
874
       // It doesn't matter if the probe can not reach the
867
       // It doesn't matter if the probe can not reach the
875
       // NAN location. This is a manual probe.
868
       // NAN location. This is a manual probe.
876
       if (location.x_index < 0 && location.y_index < 0) continue;
869
       if (location.x_index < 0 && location.y_index < 0) continue;
877
 
870
 
878
-      xProbe = ubl.map_x_index_to_bed_location(location.x_index);
879
-      yProbe = ubl.map_y_index_to_bed_location(location.y_index);
871
+      const float xProbe = ubl.map_x_index_to_bed_location(location.x_index),
872
+                  yProbe = ubl.map_y_index_to_bed_location(location.y_index);
873
+
874
+      // Modify to use if (position_is_reachable(pos[XYZ]))
880
       if (xProbe < (X_MIN_POS) || xProbe > (X_MAX_POS) || yProbe < (Y_MIN_POS) || yProbe > (Y_MAX_POS)) {
875
       if (xProbe < (X_MIN_POS) || xProbe > (X_MAX_POS) || yProbe < (Y_MIN_POS) || yProbe > (Y_MAX_POS)) {
881
         SERIAL_PROTOCOLLNPGM("?Error: Attempt to probe off the bed.");
876
         SERIAL_PROTOCOLLNPGM("?Error: Attempt to probe off the bed.");
882
         ubl_has_control_of_lcd_panel = false;
877
         ubl_has_control_of_lcd_panel = false;
883
         goto LEAVE;
878
         goto LEAVE;
884
       }
879
       }
885
 
880
 
886
-      dx = xProbe - last_x;
887
-      dy = yProbe - last_y;
881
+      const float dx = xProbe - last_x,
882
+                  dy = yProbe - last_y;
888
 
883
 
889
       if (HYPOT(dx, dy) < BIG_RAISE_NOT_NEEDED)
884
       if (HYPOT(dx, dy) < BIG_RAISE_NOT_NEEDED)
890
         do_blocking_move_to_z(current_position[Z_AXIS] + SIZE_OF_LITTLE_RAISE);
885
         do_blocking_move_to_z(current_position[Z_AXIS] + SIZE_OF_LITTLE_RAISE);
891
       else
886
       else
892
         do_blocking_move_to_z(z_clearance);
887
         do_blocking_move_to_z(z_clearance);
893
 
888
 
889
+      do_blocking_move_to_xy(xProbe, yProbe);
890
+
894
       last_x = xProbe;
891
       last_x = xProbe;
895
       last_y = yProbe;
892
       last_y = yProbe;
896
-      do_blocking_move_to_xy(xProbe, yProbe);
897
 
893
 
898
       wait_for_user = true;
894
       wait_for_user = true;
899
       while (wait_for_user) {     // we need the loop to move the nozzle based on the encoder wheel here!
895
       while (wait_for_user) {     // we need the loop to move the nozzle based on the encoder wheel here!
931
     LEAVE:
927
     LEAVE:
932
     restore_ubl_active_state_and_leave();
928
     restore_ubl_active_state_and_leave();
933
     do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
929
     do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
934
-    do_blocking_move_to_xy(x_pos, y_pos);
930
+    do_blocking_move_to_xy(lx, ly);
935
   }
931
   }
936
 
932
 
937
   bool g29_parameter_parsing() {
933
   bool g29_parameter_parsing() {
983
       ubl.store_state();
979
       ubl.store_state();
984
     }
980
     }
985
 
981
 
986
-    if ((c_flag = code_seen('C')) && code_has_value())
982
+    if ((c_flag = code_seen('C') && code_has_value()))
987
       constant = code_value_float();
983
       constant = code_value_float();
988
 
984
 
989
     if (code_seen('D')) {     // Disable the Unified Bed Leveling System
985
     if (code_seen('D')) {     // Disable the Unified Bed Leveling System
992
       ubl.store_state();
988
       ubl.store_state();
993
     }
989
     }
994
 
990
 
995
-    if (code_seen('F')) {
996
-      ubl.state.g29_correction_fade_height = 10.00;
997
-      if (code_has_value()) {
998
-        ubl.state.g29_correction_fade_height = code_value_float();
999
-        ubl.state.g29_fade_height_multiplier = 1.0 / ubl.state.g29_correction_fade_height;
1000
-      }
1001
-      if (ubl.state.g29_correction_fade_height < 0.0 || ubl.state.g29_correction_fade_height > 100.0) {
1002
-        SERIAL_PROTOCOLLNPGM("?Bed Level Correction Fade Height Not Plausible.\n");
1003
-        ubl.state.g29_correction_fade_height = 10.00;
1004
-        ubl.state.g29_fade_height_multiplier = 1.0 / ubl.state.g29_correction_fade_height;
1005
-        return UBL_ERR;
991
+    #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
992
+      if (code_seen('F') && code_has_value()) {
993
+        const float fh = code_value_float();
994
+        if (fh < 0.0 || fh > 100.0) {
995
+          SERIAL_PROTOCOLLNPGM("?Bed Level Correction Fade Height Not Plausible.\n");
996
+          return UBL_ERR;
997
+        }
998
+        ubl.state.g29_correction_fade_height = fh;
999
+        ubl.state.g29_fade_height_multiplier = 1.0 / fh;
1006
       }
1000
       }
1007
-    }
1001
+    #endif
1008
 
1002
 
1009
     if ((repeat_flag = code_seen('R'))) {
1003
     if ((repeat_flag = code_seen('R'))) {
1010
       repetition_cnt = code_has_value() ? code_value_int() : 9999;
1004
       repetition_cnt = code_has_value() ? code_value_int() : 9999;
1020
    * This function goes away after G29 debug is complete. But for right now, it is a handy
1014
    * This function goes away after G29 debug is complete. But for right now, it is a handy
1021
    * routine to dump binary data structures.
1015
    * routine to dump binary data structures.
1022
    */
1016
    */
1023
-  void dump(char *str, float f) {
1017
+  void dump(char * const str, const float &f) {
1024
     char *ptr;
1018
     char *ptr;
1025
 
1019
 
1026
     SERIAL_PROTOCOL(str);
1020
     SERIAL_PROTOCOL(str);
1056
     }
1050
     }
1057
     ubl_state_at_invocation = ubl.state.active;
1051
     ubl_state_at_invocation = ubl.state.active;
1058
     ubl.state.active = 0;
1052
     ubl.state.active = 0;
1059
-    return;
1060
   }
1053
   }
1061
 
1054
 
1062
   void restore_ubl_active_state_and_leave() {
1055
   void restore_ubl_active_state_and_leave() {
1075
    * good to have the extra information. Soon... we prune this to just a few items
1068
    * good to have the extra information. Soon... we prune this to just a few items
1076
    */
1069
    */
1077
   void g29_what_command() {
1070
   void g29_what_command() {
1078
-    int k = E2END - ubl_eeprom_start;
1071
+    const uint16_t k = E2END - ubl_eeprom_start;
1079
     statistics_flag++;
1072
     statistics_flag++;
1080
 
1073
 
1081
     SERIAL_PROTOCOLPGM("Unified Bed Leveling System Version 1.00 ");
1074
     SERIAL_PROTOCOLPGM("Unified Bed Leveling System Version 1.00 ");
1082
-    if (ubl.state.active)
1083
-      SERIAL_PROTOCOLPGM("Active.\n");
1084
-    else
1085
-      SERIAL_PROTOCOLPGM("Inactive.\n");
1086
-    SERIAL_EOL;
1075
+    ubl.state.active ? SERIAL_PROTOCOLCHAR('A') : SERIAL_PROTOCOLPGM("In");
1076
+    SERIAL_PROTOCOLLNPGM("ctive.\n");
1087
     delay(50);
1077
     delay(50);
1088
 
1078
 
1089
-    if (ubl.state.eeprom_storage_slot == 0xFFFF) {
1079
+    if (ubl.state.eeprom_storage_slot == -1)
1090
       SERIAL_PROTOCOLPGM("No Mesh Loaded.");
1080
       SERIAL_PROTOCOLPGM("No Mesh Loaded.");
1091
-    }
1092
     else {
1081
     else {
1093
       SERIAL_PROTOCOLPGM("Mesh: ");
1082
       SERIAL_PROTOCOLPGM("Mesh: ");
1094
       prt_hex_word(ubl.state.eeprom_storage_slot);
1083
       prt_hex_word(ubl.state.eeprom_storage_slot);
1095
-      SERIAL_PROTOCOLPGM(" Loaded. ");
1084
+      SERIAL_PROTOCOLPGM(" Loaded.");
1096
     }
1085
     }
1097
-
1098
     SERIAL_EOL;
1086
     SERIAL_EOL;
1099
-    delay(50);
1100
 
1087
 
1101
-    SERIAL_PROTOCOLPAIR("g29_correction_fade_height : ", ubl.state.g29_correction_fade_height );
1102
-    SERIAL_EOL;
1103
-
1104
-    idle();
1088
+    #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
1089
+      SERIAL_PROTOCOLPAIR("g29_correction_fade_height : ", ubl.state.g29_correction_fade_height);
1090
+      SERIAL_EOL;
1091
+    #endif
1105
 
1092
 
1106
     SERIAL_PROTOCOLPGM("z_offset: ");
1093
     SERIAL_PROTOCOLPGM("z_offset: ");
1107
     SERIAL_PROTOCOL_F(ubl.state.z_offset, 6);
1094
     SERIAL_PROTOCOL_F(ubl.state.z_offset, 6);
1111
     for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
1098
     for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
1112
       SERIAL_PROTOCOL_F( ubl.map_x_index_to_bed_location(i), 1);
1099
       SERIAL_PROTOCOL_F( ubl.map_x_index_to_bed_location(i), 1);
1113
       SERIAL_PROTOCOLPGM("  ");
1100
       SERIAL_PROTOCOLPGM("  ");
1114
-      delay(10);
1115
     }
1101
     }
1116
     SERIAL_EOL;
1102
     SERIAL_EOL;
1117
-    delay(50);
1118
-    idle();
1119
 
1103
 
1120
     SERIAL_PROTOCOLPGM("Y-Axis Mesh Points at: ");
1104
     SERIAL_PROTOCOLPGM("Y-Axis Mesh Points at: ");
1121
     for (uint8_t i = 0; i < UBL_MESH_NUM_Y_POINTS; i++) {
1105
     for (uint8_t i = 0; i < UBL_MESH_NUM_Y_POINTS; i++) {
1122
       SERIAL_PROTOCOL_F( ubl.map_y_index_to_bed_location(i), 1);
1106
       SERIAL_PROTOCOL_F( ubl.map_y_index_to_bed_location(i), 1);
1123
       SERIAL_PROTOCOLPGM("  ");
1107
       SERIAL_PROTOCOLPGM("  ");
1124
-      delay(10);
1125
     }
1108
     }
1126
     SERIAL_EOL;
1109
     SERIAL_EOL;
1127
-    delay(50);
1128
-    idle();
1129
 
1110
 
1130
     #if HAS_KILL
1111
     #if HAS_KILL
1131
       SERIAL_PROTOCOLPAIR("Kill pin on :", KILL_PIN);
1112
       SERIAL_PROTOCOLPAIR("Kill pin on :", KILL_PIN);
1132
       SERIAL_PROTOCOLLNPAIR("  state:", READ(KILL_PIN));
1113
       SERIAL_PROTOCOLLNPAIR("  state:", READ(KILL_PIN));
1133
     #endif
1114
     #endif
1134
-    delay(50);
1135
-    idle();
1136
     SERIAL_EOL;
1115
     SERIAL_EOL;
1137
 
1116
 
1138
     SERIAL_PROTOCOLLNPAIR("ubl_state_at_invocation :", ubl_state_at_invocation);
1117
     SERIAL_PROTOCOLLNPAIR("ubl_state_at_invocation :", ubl_state_at_invocation);
1142
     SERIAL_PROTOCOLPGM("Free EEPROM space starts at: 0x");
1121
     SERIAL_PROTOCOLPGM("Free EEPROM space starts at: 0x");
1143
     prt_hex_word(ubl_eeprom_start);
1122
     prt_hex_word(ubl_eeprom_start);
1144
     SERIAL_EOL;
1123
     SERIAL_EOL;
1145
-    delay(50);
1146
-    idle();
1147
 
1124
 
1148
     SERIAL_PROTOCOLPGM("end of EEPROM              : ");
1125
     SERIAL_PROTOCOLPGM("end of EEPROM              : ");
1149
     prt_hex_word(E2END);
1126
     prt_hex_word(E2END);
1150
     SERIAL_EOL;
1127
     SERIAL_EOL;
1151
-    delay(50);
1152
-    idle();
1153
 
1128
 
1154
     SERIAL_PROTOCOLLNPAIR("sizeof(ubl) :  ", (int)sizeof(ubl));
1129
     SERIAL_PROTOCOLLNPAIR("sizeof(ubl) :  ", (int)sizeof(ubl));
1155
     SERIAL_EOL;
1130
     SERIAL_EOL;
1156
     SERIAL_PROTOCOLLNPAIR("z_value[][] size: ", (int)sizeof(z_values));
1131
     SERIAL_PROTOCOLLNPAIR("z_value[][] size: ", (int)sizeof(z_values));
1157
     SERIAL_EOL;
1132
     SERIAL_EOL;
1158
-    delay(50);
1159
-    idle();
1160
 
1133
 
1161
     SERIAL_PROTOCOLPGM("EEPROM free for UBL: 0x");
1134
     SERIAL_PROTOCOLPGM("EEPROM free for UBL: 0x");
1162
     prt_hex_word(k);
1135
     prt_hex_word(k);
1163
     SERIAL_EOL;
1136
     SERIAL_EOL;
1164
-    idle();
1165
 
1137
 
1166
     SERIAL_PROTOCOLPGM("EEPROM can hold 0x");
1138
     SERIAL_PROTOCOLPGM("EEPROM can hold 0x");
1167
     prt_hex_word(k / sizeof(z_values));
1139
     prt_hex_word(k / sizeof(z_values));
1168
     SERIAL_PROTOCOLLNPGM(" meshes.\n");
1140
     SERIAL_PROTOCOLLNPGM(" meshes.\n");
1169
-    delay(50);
1170
 
1141
 
1171
     SERIAL_PROTOCOLPGM("sizeof(ubl.state) :");
1142
     SERIAL_PROTOCOLPGM("sizeof(ubl.state) :");
1172
     prt_hex_word(sizeof(ubl.state));
1143
     prt_hex_word(sizeof(ubl.state));
1173
-    idle();
1174
 
1144
 
1175
     SERIAL_PROTOCOLPAIR("\nUBL_MESH_NUM_X_POINTS  ", UBL_MESH_NUM_X_POINTS);
1145
     SERIAL_PROTOCOLPAIR("\nUBL_MESH_NUM_X_POINTS  ", UBL_MESH_NUM_X_POINTS);
1176
     SERIAL_PROTOCOLPAIR("\nUBL_MESH_NUM_Y_POINTS  ", UBL_MESH_NUM_Y_POINTS);
1146
     SERIAL_PROTOCOLPAIR("\nUBL_MESH_NUM_Y_POINTS  ", UBL_MESH_NUM_Y_POINTS);
1177
     SERIAL_PROTOCOLPAIR("\nUBL_MESH_MIN_X         ", UBL_MESH_MIN_X);
1147
     SERIAL_PROTOCOLPAIR("\nUBL_MESH_MIN_X         ", UBL_MESH_MIN_X);
1178
-    delay(50);
1179
-    idle();
1180
     SERIAL_PROTOCOLPAIR("\nUBL_MESH_MIN_Y         ", UBL_MESH_MIN_Y);
1148
     SERIAL_PROTOCOLPAIR("\nUBL_MESH_MIN_Y         ", UBL_MESH_MIN_Y);
1181
     SERIAL_PROTOCOLPAIR("\nUBL_MESH_MAX_X         ", UBL_MESH_MAX_X);
1149
     SERIAL_PROTOCOLPAIR("\nUBL_MESH_MAX_X         ", UBL_MESH_MAX_X);
1182
     SERIAL_PROTOCOLPAIR("\nUBL_MESH_MAX_Y         ", UBL_MESH_MAX_Y);
1150
     SERIAL_PROTOCOLPAIR("\nUBL_MESH_MAX_Y         ", UBL_MESH_MAX_Y);
1183
-    delay(50);
1184
-    idle();
1185
     SERIAL_PROTOCOLPGM("\nMESH_X_DIST        ");
1151
     SERIAL_PROTOCOLPGM("\nMESH_X_DIST        ");
1186
     SERIAL_PROTOCOL_F(MESH_X_DIST, 6);
1152
     SERIAL_PROTOCOL_F(MESH_X_DIST, 6);
1187
     SERIAL_PROTOCOLPGM("\nMESH_Y_DIST        ");
1153
     SERIAL_PROTOCOLPGM("\nMESH_Y_DIST        ");
1188
     SERIAL_PROTOCOL_F(MESH_Y_DIST, 6);
1154
     SERIAL_PROTOCOL_F(MESH_Y_DIST, 6);
1189
     SERIAL_EOL;
1155
     SERIAL_EOL;
1190
 
1156
 
1191
-    idle();
1192
-
1193
     if (!ubl.sanity_check())
1157
     if (!ubl.sanity_check())
1194
       SERIAL_PROTOCOLLNPGM("Unified Bed Leveling sanity checks passed.");
1158
       SERIAL_PROTOCOLLNPGM("Unified Bed Leveling sanity checks passed.");
1195
   }
1159
   }
1205
     SERIAL_ECHO_START;
1169
     SERIAL_ECHO_START;
1206
     SERIAL_ECHOLNPGM("EEPROM Dump:");
1170
     SERIAL_ECHOLNPGM("EEPROM Dump:");
1207
     for (uint16_t i = 0; i < E2END + 1; i += 16) {
1171
     for (uint16_t i = 0; i < E2END + 1; i += 16) {
1208
-      if (i & 0x3 == 0) idle();
1172
+      if (!(i & 0x3)) idle();
1209
       prt_hex_word(i);
1173
       prt_hex_word(i);
1210
       SERIAL_ECHOPGM(": ");
1174
       SERIAL_ECHOPGM(": ");
1211
       for (uint16_t j = 0; j < 16; j++) {
1175
       for (uint16_t j = 0; j < 16; j++) {
1217
       SERIAL_EOL;
1181
       SERIAL_EOL;
1218
     }
1182
     }
1219
     SERIAL_EOL;
1183
     SERIAL_EOL;
1220
-    return;
1221
   }
1184
   }
1222
 
1185
 
1223
   /**
1186
   /**
1233
     }
1196
     }
1234
     storage_slot = code_value_int();
1197
     storage_slot = code_value_int();
1235
 
1198
 
1236
-    uint16_t k = E2END - sizeof(ubl.state),
1237
-             j = (k - ubl_eeprom_start) / sizeof(tmp_z_values);
1199
+    int16_t j = (UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(tmp_z_values);
1238
 
1200
 
1239
     if (storage_slot < 0 || storage_slot > j || ubl_eeprom_start <= 0) {
1201
     if (storage_slot < 0 || storage_slot > j || ubl_eeprom_start <= 0) {
1240
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
1202
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
1241
       return;
1203
       return;
1242
     }
1204
     }
1243
 
1205
 
1244
-    j = k - (storage_slot + 1) * sizeof(tmp_z_values);
1206
+    j = UBL_LAST_EEPROM_INDEX - (storage_slot + 1) * sizeof(tmp_z_values);
1245
     eeprom_read_block((void *)&tmp_z_values, (void *)j, sizeof(tmp_z_values));
1207
     eeprom_read_block((void *)&tmp_z_values, (void *)j, sizeof(tmp_z_values));
1246
 
1208
 
1247
     SERIAL_ECHOPAIR("Subtracting Mesh ", storage_slot);
1209
     SERIAL_ECHOPAIR("Subtracting Mesh ", storage_slot);
1254
         z_values[x][y] = z_values[x][y] - tmp_z_values[x][y];
1216
         z_values[x][y] = z_values[x][y] - tmp_z_values[x][y];
1255
   }
1217
   }
1256
 
1218
 
1257
-  mesh_index_pair find_closest_mesh_point_of_type(MeshPointType type, float X, float Y, bool probe_as_reference, unsigned int bits[16]) {
1219
+  mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType type, const float &lx, const float &ly, const bool probe_as_reference, unsigned int bits[16]) {
1258
     int i, j;
1220
     int i, j;
1259
-    float f, px, py, mx, my, dx, dy, closest = 99999.99,
1260
-          current_x, current_y, distance;
1221
+    float closest = 99999.99;
1261
     mesh_index_pair return_val;
1222
     mesh_index_pair return_val;
1262
 
1223
 
1263
     return_val.x_index = return_val.y_index = -1;
1224
     return_val.x_index = return_val.y_index = -1;
1264
 
1225
 
1265
-    current_x = current_position[X_AXIS];
1266
-    current_y = current_position[Y_AXIS];
1226
+    const float current_x = current_position[X_AXIS],
1227
+                current_y = current_position[Y_AXIS];
1267
 
1228
 
1268
-    px = X;       // Get our reference position. Either the nozzle or
1269
-    py = Y;       // the probe location.
1270
-    if (probe_as_reference) {
1271
-      px -= X_PROBE_OFFSET_FROM_EXTRUDER;
1272
-      py -= Y_PROBE_OFFSET_FROM_EXTRUDER;
1273
-    }
1229
+    // Get our reference position. Either the nozzle or probe location.
1230
+    const float px = lx - (probe_as_reference ? X_PROBE_OFFSET_FROM_EXTRUDER : 0),
1231
+                py = ly - (probe_as_reference ? Y_PROBE_OFFSET_FROM_EXTRUDER : 0);
1274
 
1232
 
1275
     for (i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
1233
     for (i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
1276
       for (j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
1234
       for (j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
1282
 
1240
 
1283
           // We only get here if we found a Mesh Point of the specified type
1241
           // We only get here if we found a Mesh Point of the specified type
1284
 
1242
 
1285
-          mx = ubl.map_x_index_to_bed_location(i); // Check if we can probe this mesh location
1286
-          my = ubl.map_y_index_to_bed_location(j);
1243
+          const float mx = LOGICAL_X_POSITION(ubl.map_x_index_to_bed_location(i)), // Check if we can probe this mesh location
1244
+                      my = LOGICAL_Y_POSITION(ubl.map_y_index_to_bed_location(j));
1287
 
1245
 
1288
           // If we are using the probe as the reference there are some locations we can't get to.
1246
           // If we are using the probe as the reference there are some locations we can't get to.
1289
           // We prune these out of the list and ignore them until the next Phase where we do the
1247
           // We prune these out of the list and ignore them until the next Phase where we do the
1290
           // manual nozzle probing.
1248
           // manual nozzle probing.
1291
-	  
1249
+
1292
           if (probe_as_reference &&
1250
           if (probe_as_reference &&
1293
-            ( mx < (MIN_PROBE_X) || mx > (MAX_PROBE_X) || my < (MIN_PROBE_Y) || my > (MAX_PROBE_Y) )
1251
+            (mx < (MIN_PROBE_X) || mx > (MAX_PROBE_X) || my < (MIN_PROBE_Y) || my > (MAX_PROBE_Y))
1294
           ) continue;
1252
           ) continue;
1295
 
1253
 
1296
-          dx = px - mx;         // We can get to it. Let's see if it is the
1297
-          dy = py - my;         // closest location to the nozzle.
1298
-          distance = HYPOT(dx, dy);
1299
-
1300
-          dx = current_x - mx;                    // We are going to add in a weighting factor that considers
1301
-          dy = current_y - my;                    // the current location of the nozzle. If two locations are equal
1302
-          distance += HYPOT(dx, dy) * 0.01;       // distance from the measurement location, we are going to give
1254
+          // We can get to it. Let's see if it is the closest location to the nozzle.
1255
+          // Add in a weighting factor that considers the current location of the nozzle.
1256
+          const float distance = HYPOT(px - mx, py - my) + HYPOT(current_x - mx, current_y - my) * 0.01;
1303
 
1257
 
1304
           if (distance < closest) {
1258
           if (distance < closest) {
1305
             closest = distance;       // We found a closer location with
1259
             closest = distance;       // We found a closer location with
1313
     return return_val;
1267
     return return_val;
1314
   }
1268
   }
1315
 
1269
 
1316
-  void fine_tune_mesh(float x_pos, float y_pos, bool do_ubl_mesh_map) {
1270
+  void fine_tune_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map) {
1317
     mesh_index_pair location;
1271
     mesh_index_pair location;
1318
-    float xProbe, yProbe;
1319
-    uint16_t i, not_done[16];
1272
+    uint16_t not_done[16];
1320
     int32_t round_off;
1273
     int32_t round_off;
1321
 
1274
 
1322
     save_ubl_active_state_and_disable();
1275
     save_ubl_active_state_and_disable();
1327
     #endif
1280
     #endif
1328
 
1281
 
1329
     do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
1282
     do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
1330
-    do_blocking_move_to_xy(x_pos, y_pos);
1283
+    do_blocking_move_to_xy(lx, ly);
1331
     do {
1284
     do {
1332
       if (do_ubl_mesh_map) ubl.display_map(1);
1285
       if (do_ubl_mesh_map) ubl.display_map(1);
1333
 
1286
 
1334
-      location = find_closest_mesh_point_of_type( SET_IN_BITMAP, x_pos,  y_pos, 0, not_done); // The '0' says we want to use the nozzle's position
1287
+      location = find_closest_mesh_point_of_type( SET_IN_BITMAP, lx,  ly, 0, not_done); // The '0' says we want to use the nozzle's position
1335
                                                                                               // It doesn't matter if the probe can not reach this
1288
                                                                                               // It doesn't matter if the probe can not reach this
1336
                                                                                               // location. This is a manual edit of the Mesh Point.
1289
                                                                                               // location. This is a manual edit of the Mesh Point.
1337
       if (location.x_index < 0 && location.y_index < 0) continue; // abort if we can't find any more points.
1290
       if (location.x_index < 0 && location.y_index < 0) continue; // abort if we can't find any more points.
1339
       bit_clear(not_done, location.x_index, location.y_index);  // Mark this location as 'adjusted' so we will find a
1292
       bit_clear(not_done, location.x_index, location.y_index);  // Mark this location as 'adjusted' so we will find a
1340
                                                                 // different location the next time through the loop
1293
                                                                 // different location the next time through the loop
1341
 
1294
 
1342
-      xProbe = ubl.map_x_index_to_bed_location(location.x_index);
1343
-      yProbe = ubl.map_y_index_to_bed_location(location.y_index);
1295
+      const float xProbe = ubl.map_x_index_to_bed_location(location.x_index),
1296
+                  yProbe = ubl.map_y_index_to_bed_location(location.y_index);
1344
       if (xProbe < X_MIN_POS || xProbe > X_MAX_POS || yProbe < Y_MIN_POS || yProbe > Y_MAX_POS) { // In theory, we don't need this check.
1297
       if (xProbe < X_MIN_POS || xProbe > X_MAX_POS || yProbe < Y_MIN_POS || yProbe > Y_MAX_POS) { // In theory, we don't need this check.
1345
         SERIAL_PROTOCOLLNPGM("?Error: Attempt to edit off the bed.");                             // This really can't happen, but for now,
1298
         SERIAL_PROTOCOLLNPGM("?Error: Attempt to edit off the bed.");                             // This really can't happen, but for now,
1346
         ubl_has_control_of_lcd_panel = false;                                                         // Let's do the check.
1299
         ubl_has_control_of_lcd_panel = false;                                                         // Let's do the check.
1406
     restore_ubl_active_state_and_leave();
1359
     restore_ubl_active_state_and_leave();
1407
     do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
1360
     do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
1408
 
1361
 
1409
-    do_blocking_move_to_xy(x_pos, y_pos);
1362
+    do_blocking_move_to_xy(lx, ly);
1410
 
1363
 
1411
     #if ENABLED(ULTRA_LCD)
1364
     #if ENABLED(ULTRA_LCD)
1412
       lcd_setstatus("Done Editing Mesh", true);
1365
       lcd_setstatus("Done Editing Mesh", true);

+ 134
- 91
Marlin/UBL_line_to_destination.cpp Ver fichero

29
   #include <avr/io.h>
29
   #include <avr/io.h>
30
   #include <math.h>
30
   #include <math.h>
31
 
31
 
32
+  extern float destination[XYZE];
32
   extern void set_current_to_destination();
33
   extern void set_current_to_destination();
33
-  extern void debug_current_and_destination(char *title);
34
 
34
 
35
-  void ubl_line_to_destination(const float &x_end, const float &y_end, const float &z_end, const float &e_end, const float &feed_rate, uint8_t extruder) {
35
+  void debug_current_and_destination(char *title) {
36
+
37
+    // if the title message starts with a '!' it is so important, we are going to
38
+    // ignore the status of the g26_debug_flag
39
+    if (*title != '!' && !g26_debug_flag) return;
40
+
41
+    const float de = destination[E_AXIS] - current_position[E_AXIS];
42
+
43
+    if (de == 0.0) return;
44
+
45
+    const float dx = current_position[X_AXIS] - destination[X_AXIS],
46
+                dy = current_position[Y_AXIS] - destination[Y_AXIS],
47
+                xy_dist = HYPOT(dx, dy);
48
+
49
+    if (xy_dist == 0.0) {
50
+      return;
51
+      //SERIAL_ECHOPGM("   FPMM=");
52
+      //const float fpmm = de / xy_dist;
53
+      //SERIAL_PROTOCOL_F(fpmm, 6);
54
+    }
55
+    else {
56
+      SERIAL_ECHOPGM("   fpmm=");
57
+      const float fpmm = de / xy_dist;
58
+      SERIAL_ECHO_F(fpmm, 6);
59
+    }
36
 
60
 
37
-    int cell_start_xi, cell_start_yi, cell_dest_xi, cell_dest_yi,
38
-        current_xi, current_yi,
39
-        dxi, dyi, xi_cnt, yi_cnt;
40
-    float x_start, y_start,
41
-          x, y, z1, z2, z0 /*, z_optimized */,
42
-          next_mesh_line_x, next_mesh_line_y, a0ma1diva2ma1,
43
-          on_axis_distance, e_normalized_dist, e_position, e_start, z_normalized_dist, z_position, z_start,
44
-          dx, dy, adx, ady, m, c;
61
+    SERIAL_ECHOPGM("    current=( ");
62
+    SERIAL_ECHO_F(current_position[X_AXIS], 6);
63
+    SERIAL_ECHOPGM(", ");
64
+    SERIAL_ECHO_F(current_position[Y_AXIS], 6);
65
+    SERIAL_ECHOPGM(", ");
66
+    SERIAL_ECHO_F(current_position[Z_AXIS], 6);
67
+    SERIAL_ECHOPGM(", ");
68
+    SERIAL_ECHO_F(current_position[E_AXIS], 6);
69
+    SERIAL_ECHOPGM(" )   destination=( ");
70
+    if (current_position[X_AXIS] == destination[X_AXIS])
71
+      SERIAL_ECHOPGM("-------------");
72
+    else
73
+      SERIAL_ECHO_F(destination[X_AXIS], 6);
74
+
75
+    SERIAL_ECHOPGM(", ");
76
+
77
+    if (current_position[Y_AXIS] == destination[Y_AXIS])
78
+      SERIAL_ECHOPGM("-------------");
79
+    else
80
+      SERIAL_ECHO_F(destination[Y_AXIS], 6);
81
+
82
+    SERIAL_ECHOPGM(", ");
83
+
84
+    if (current_position[Z_AXIS] == destination[Z_AXIS])
85
+      SERIAL_ECHOPGM("-------------");
86
+    else
87
+      SERIAL_ECHO_F(destination[Z_AXIS], 6);
88
+
89
+    SERIAL_ECHOPGM(", ");
90
+
91
+    if (current_position[E_AXIS] == destination[E_AXIS])
92
+      SERIAL_ECHOPGM("-------------");
93
+    else
94
+      SERIAL_ECHO_F(destination[E_AXIS], 6);
95
+
96
+    SERIAL_ECHOPGM(" )   ");
97
+    SERIAL_ECHO(title);
98
+    SERIAL_EOL;
99
+
100
+    SET_INPUT_PULLUP(66); // Roxy's Left Switch is on pin 66.  Right Switch is on pin 65
101
+
102
+    //if (been_to_2_6) {
103
+    //while ((digitalRead(66) & 0x01) != 0)
104
+    //  idle();
105
+    //}
106
+  }
45
 
107
 
108
+  void ubl_line_to_destination(const float &x_end, const float &y_end, const float &z_end, const float &e_end, const float &feed_rate, uint8_t extruder) {
46
     /**
109
     /**
47
      * Much of the nozzle movement will be within the same cell. So we will do as little computation
110
      * Much of the nozzle movement will be within the same cell. So we will do as little computation
48
      * as possible to determine if this is the case. If this move is within the same cell, we will
111
      * as possible to determine if this is the case. If this move is within the same cell, we will
49
      * just do the required Z-Height correction, call the Planner's buffer_line() routine, and leave
112
      * just do the required Z-Height correction, call the Planner's buffer_line() routine, and leave
50
      */
113
      */
114
+    const float x_start = current_position[X_AXIS],
115
+                y_start = current_position[Y_AXIS],
116
+                z_start = current_position[Z_AXIS],
117
+                e_start = current_position[E_AXIS];
51
 
118
 
52
-    x_start = current_position[X_AXIS];
53
-    y_start = current_position[Y_AXIS];
54
-    z_start = current_position[Z_AXIS];
55
-    e_start = current_position[E_AXIS];
56
-
57
-    cell_start_xi = ubl.get_cell_index_x(x_start);
58
-    cell_start_yi = ubl.get_cell_index_y(y_start);
59
-    cell_dest_xi  = ubl.get_cell_index_x(x_end);
60
-    cell_dest_yi  = ubl.get_cell_index_y(y_end);
119
+    const int cell_start_xi = ubl.get_cell_index_x(RAW_X_POSITION(x_start)),
120
+              cell_start_yi = ubl.get_cell_index_y(RAW_Y_POSITION(y_start)),
121
+              cell_dest_xi  = ubl.get_cell_index_x(RAW_X_POSITION(x_end)),
122
+              cell_dest_yi  = ubl.get_cell_index_y(RAW_Y_POSITION(y_end));
61
 
123
 
62
     if (g26_debug_flag) {
124
     if (g26_debug_flag) {
63
       SERIAL_ECHOPGM(" ubl_line_to_destination(xe=");
125
       SERIAL_ECHOPGM(" ubl_line_to_destination(xe=");
68
       SERIAL_ECHO(z_end);
130
       SERIAL_ECHO(z_end);
69
       SERIAL_ECHOPGM(", ee=");
131
       SERIAL_ECHOPGM(", ee=");
70
       SERIAL_ECHO(e_end);
132
       SERIAL_ECHO(e_end);
71
-      SERIAL_ECHOPGM(")\n");
133
+      SERIAL_ECHOLNPGM(")");
72
       debug_current_and_destination((char*)"Start of ubl_line_to_destination()");
134
       debug_current_and_destination((char*)"Start of ubl_line_to_destination()");
73
     }
135
     }
74
 
136
 
82
 
144
 
83
       if (cell_dest_xi < 0 || cell_dest_yi < 0 || cell_dest_xi >= UBL_MESH_NUM_X_POINTS || cell_dest_yi >= UBL_MESH_NUM_Y_POINTS) {
145
       if (cell_dest_xi < 0 || cell_dest_yi < 0 || cell_dest_xi >= UBL_MESH_NUM_X_POINTS || cell_dest_yi >= UBL_MESH_NUM_Y_POINTS) {
84
 
146
 
85
-        // Note:  There is no Z Correction in this case. We are off the grid and don't know what
147
+        // Note: There is no Z Correction in this case. We are off the grid and don't know what
86
         // a reasonable correction would be.
148
         // a reasonable correction would be.
87
 
149
 
88
         planner.buffer_line(x_end, y_end, z_end + ubl.state.z_offset, e_end, feed_rate, extruder);
150
         planner.buffer_line(x_end, y_end, z_end + ubl.state.z_offset, e_end, feed_rate, extruder);
105
        * to create a 1-over number for us. That will allow us to do a floating point multiply instead of a floating point divide.
167
        * to create a 1-over number for us. That will allow us to do a floating point multiply instead of a floating point divide.
106
        */
168
        */
107
 
169
 
108
-      a0ma1diva2ma1 = (x_end - mesh_index_to_x_location[cell_dest_xi]) * 0.1 * (MESH_X_DIST);
109
-
110
-      z1 = z_values[cell_dest_xi    ][cell_dest_yi    ] + a0ma1diva2ma1 *
111
-          (z_values[cell_dest_xi + 1][cell_dest_yi    ] - z_values[cell_dest_xi][cell_dest_yi    ]);
112
-
113
-      z2 = z_values[cell_dest_xi    ][cell_dest_yi + 1] + a0ma1diva2ma1 *
114
-          (z_values[cell_dest_xi + 1][cell_dest_yi + 1] - z_values[cell_dest_xi][cell_dest_yi + 1]);
170
+      const float xratio = (RAW_X_POSITION(x_end) - mesh_index_to_x_location[cell_dest_xi]) * (1.0 / (MESH_X_DIST)),
171
+                  z1 = z_values[cell_dest_xi    ][cell_dest_yi    ] + xratio *
172
+                      (z_values[cell_dest_xi + 1][cell_dest_yi    ] - z_values[cell_dest_xi][cell_dest_yi    ]),
173
+                  z2 = z_values[cell_dest_xi    ][cell_dest_yi + 1] + xratio *
174
+                      (z_values[cell_dest_xi + 1][cell_dest_yi + 1] - z_values[cell_dest_xi][cell_dest_yi + 1]);
115
 
175
 
116
       // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we
176
       // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we
117
       // are going to apply the Y-Distance into the cell to interpolate the final Z correction.
177
       // are going to apply the Y-Distance into the cell to interpolate the final Z correction.
118
 
178
 
119
-      a0ma1diva2ma1 = (y_end - mesh_index_to_y_location[cell_dest_yi]) * 0.1 * (MESH_Y_DIST);
179
+      const float yratio = (RAW_Y_POSITION(y_end) - mesh_index_to_y_location[cell_dest_yi]) * (1.0 / (MESH_Y_DIST));
120
 
180
 
121
-      z0 = z1 + (z2 - z1) * a0ma1diva2ma1;
181
+      float z0 = z1 + (z2 - z1) * yratio;
122
 
182
 
123
       /**
183
       /**
124
        * Debug code to use non-optimized get_z_correction() and to do a sanity check
184
        * Debug code to use non-optimized get_z_correction() and to do a sanity check
126
        */
186
        */
127
       /*
187
       /*
128
         z_optimized = z0;
188
         z_optimized = z0;
129
-        z0 = ubl.get_z_correction( x_end, y_end);
189
+        z0 = ubl.get_z_correction(x_end, y_end);
130
         if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
190
         if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
131
         debug_current_and_destination((char*)"FINAL_MOVE: z_correction()");
191
         debug_current_and_destination((char*)"FINAL_MOVE: z_correction()");
132
         if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
192
         if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
139
         SERIAL_EOL;
199
         SERIAL_EOL;
140
         }
200
         }
141
       //*/
201
       //*/
142
-      z0 = z0 * ubl.fade_scaling_factor_for_z(z_end);
202
+      z0 *= ubl.fade_scaling_factor_for_z(z_end);
143
 
203
 
144
       /**
204
       /**
145
        * If part of the Mesh is undefined, it will show up as NAN
205
        * If part of the Mesh is undefined, it will show up as NAN
167
      * blocks of code:
227
      * blocks of code:
168
      */
228
      */
169
 
229
 
170
-    dx = x_end - x_start;
171
-    dy = y_end - y_start;
230
+    const float dx = x_end - x_start,
231
+                dy = y_end - y_start;
172
 
232
 
173
     const int left_flag = dx < 0.0 ? 1 : 0,
233
     const int left_flag = dx < 0.0 ? 1 : 0,
174
               down_flag = dy < 0.0 ? 1 : 0;
234
               down_flag = dy < 0.0 ? 1 : 0;
175
 
235
 
176
-    if (left_flag) { // figure out which way we need to move to get to the next cell
177
-      dxi = -1;
178
-      adx = -dx;  // absolute value of dx. We already need to check if dx and dy are negative.
179
-    }
180
-    else {      // We may as well generate the appropriate values for adx and ady right now
181
-      dxi = 1;  // to save setting up the abs() function call and actually doing the call.
182
-      adx = dx;
183
-    }
184
-    if (dy < 0.0) {
185
-      dyi = -1;
186
-      ady = -dy;  // absolute value of dy
187
-    }
188
-    else {
189
-      dyi = 1;
190
-      ady = dy;
191
-    }
236
+    const float adx = left_flag ? -dx : dx,
237
+                ady = down_flag ? -dy : dy;
192
 
238
 
193
-    if (cell_start_xi == cell_dest_xi) dxi = 0;
194
-    if (cell_start_yi == cell_dest_yi) dyi = 0;
239
+    const int dxi = cell_start_xi == cell_dest_xi ? 0 : left_flag ? -1 : 1,
240
+              dyi = cell_start_yi == cell_dest_yi ? 0 : down_flag ? -1 : 1;
195
 
241
 
196
     /**
242
     /**
197
      * Compute the scaling factor for the extruder for each partial move.
243
      * Compute the scaling factor for the extruder for each partial move.
204
 
250
 
205
     const bool use_x_dist = adx > ady;
251
     const bool use_x_dist = adx > ady;
206
 
252
 
207
-    on_axis_distance = use_x_dist ? x_end - x_start : y_end - y_start;
208
-
209
-    e_position = e_end - e_start;
210
-    e_normalized_dist = e_position / on_axis_distance;
253
+    float on_axis_distance = use_x_dist ? dx : dy,
254
+          e_position = e_end - e_start,
255
+          z_position = z_end - z_start;
211
 
256
 
212
-    z_position = z_end - z_start;
213
-    z_normalized_dist = z_position / on_axis_distance;
257
+    const float e_normalized_dist = e_position / on_axis_distance,
258
+                z_normalized_dist = z_position / on_axis_distance;
214
 
259
 
215
-    const bool inf_normalized_flag = e_normalized_dist == INFINITY || e_normalized_dist == -INFINITY;
260
+    int current_xi = cell_start_xi, current_yi = cell_start_yi;
216
 
261
 
217
-    current_xi = cell_start_xi;
218
-    current_yi = cell_start_yi;
262
+    const float m = dy / dx,
263
+                c = y_start - m * x_start;
219
 
264
 
220
-    m = dy / dx;
221
-    c = y_start - m * x_start;
222
-    const bool inf_m_flag = (m == INFINITY || m == -INFINITY);
265
+    const bool inf_normalized_flag = NEAR_ZERO(on_axis_distance),
266
+               inf_m_flag = NEAR_ZERO(dx);
223
 
267
 
224
     /**
268
     /**
225
      * This block handles vertical lines. These are lines that stay within the same
269
      * This block handles vertical lines. These are lines that stay within the same
230
       current_yi += down_flag;  // Line is heading down, we just want to go to the bottom
274
       current_yi += down_flag;  // Line is heading down, we just want to go to the bottom
231
       while (current_yi != cell_dest_yi + down_flag) {
275
       while (current_yi != cell_dest_yi + down_flag) {
232
         current_yi += dyi;
276
         current_yi += dyi;
233
-        next_mesh_line_y = mesh_index_to_y_location[current_yi];
277
+        const float next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_y_location[current_yi]);
234
 
278
 
235
         /**
279
         /**
236
          * inf_m_flag? the slope of the line is infinite, we won't do the calculations
280
          * inf_m_flag? the slope of the line is infinite, we won't do the calculations
237
          * else, we know the next X is the same so we can recover and continue!
281
          * else, we know the next X is the same so we can recover and continue!
238
          * Calculate X at the next Y mesh line
282
          * Calculate X at the next Y mesh line
239
          */
283
          */
240
-        x = inf_m_flag ? x_start : (next_mesh_line_y - c) / m;
284
+        const float x = inf_m_flag ? x_start : (next_mesh_line_y - c) / m;
241
 
285
 
242
-        z0 = ubl.get_z_correction_along_horizontal_mesh_line_at_specific_X(x, current_xi, current_yi);
286
+        float z0 = ubl.get_z_correction_along_horizontal_mesh_line_at_specific_X(x, current_xi, current_yi);
243
 
287
 
244
         /**
288
         /**
245
          * Debug code to use non-optimized get_z_correction() and to do a sanity check
289
          * Debug code to use non-optimized get_z_correction() and to do a sanity check
247
          */
291
          */
248
         /*
292
         /*
249
           z_optimized = z0;
293
           z_optimized = z0;
250
-          z0 = ubl.get_z_correction( x, next_mesh_line_y);
294
+          z0 = ubl.get_z_correction(x, next_mesh_line_y);
251
           if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
295
           if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
252
             debug_current_and_destination((char*)"VERTICAL z_correction()");
296
             debug_current_and_destination((char*)"VERTICAL z_correction()");
253
           if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
297
           if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
261
           }
305
           }
262
         //*/
306
         //*/
263
 
307
 
264
-        z0 = z0 * ubl.fade_scaling_factor_for_z(z_end);
308
+        z0 *= ubl.fade_scaling_factor_for_z(z_end);
265
 
309
 
266
         /**
310
         /**
267
          * If part of the Mesh is undefined, it will show up as NAN
311
          * If part of the Mesh is undefined, it will show up as NAN
272
          */
316
          */
273
         if (isnan(z0)) z0 = 0.0;     
317
         if (isnan(z0)) z0 = 0.0;     
274
 
318
 
275
-        y = mesh_index_to_y_location[current_yi];
319
+        const float y = LOGICAL_Y_POSITION(mesh_index_to_y_location[current_yi]);
276
 
320
 
277
         /**
321
         /**
278
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
322
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
321
                                 // edge of this cell for the first move.
365
                                 // edge of this cell for the first move.
322
       while (current_xi != cell_dest_xi + left_flag) {
366
       while (current_xi != cell_dest_xi + left_flag) {
323
         current_xi += dxi;
367
         current_xi += dxi;
324
-        next_mesh_line_x = mesh_index_to_x_location[current_xi];
325
-        y = m * next_mesh_line_x + c;   // Calculate X at the next Y mesh line
368
+        const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_x_location[current_xi]),
369
+                    y = m * next_mesh_line_x + c;   // Calculate X at the next Y mesh line
326
 
370
 
327
-        z0 = ubl.get_z_correction_along_vertical_mesh_line_at_specific_Y(y, current_xi, current_yi);
371
+        float z0 = ubl.get_z_correction_along_vertical_mesh_line_at_specific_Y(y, current_xi, current_yi);
328
 
372
 
329
         /**
373
         /**
330
          * Debug code to use non-optimized get_z_correction() and to do a sanity check
374
          * Debug code to use non-optimized get_z_correction() and to do a sanity check
332
          */
376
          */
333
         /*
377
         /*
334
           z_optimized = z0;
378
           z_optimized = z0;
335
-          z0 = ubl.get_z_correction( next_mesh_line_x, y);
379
+          z0 = ubl.get_z_correction(next_mesh_line_x, y);
336
           if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
380
           if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
337
             debug_current_and_destination((char*)"HORIZONTAL z_correction()");
381
             debug_current_and_destination((char*)"HORIZONTAL z_correction()");
338
           if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
382
           if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
357
          */
401
          */
358
         if (isnan(z0)) z0 = 0.0;
402
         if (isnan(z0)) z0 = 0.0;
359
 
403
 
360
-        x = mesh_index_to_x_location[current_xi];
404
+        const float x = LOGICAL_X_POSITION(mesh_index_to_x_location[current_xi]);
361
 
405
 
362
         /**
406
         /**
363
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
407
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
396
      *
440
      *
397
      */
441
      */
398
 
442
 
399
-    xi_cnt = cell_start_xi - cell_dest_xi;
400
-    if (xi_cnt < 0) xi_cnt = -xi_cnt;
443
+    int xi_cnt = cell_start_xi - cell_dest_xi,
444
+        yi_cnt = cell_start_yi - cell_dest_yi;
401
 
445
 
402
-    yi_cnt = cell_start_yi - cell_dest_yi;
446
+    if (xi_cnt < 0) xi_cnt = -xi_cnt;
403
     if (yi_cnt < 0) yi_cnt = -yi_cnt;
447
     if (yi_cnt < 0) yi_cnt = -yi_cnt;
404
 
448
 
405
     current_xi += left_flag;
449
     current_xi += left_flag;
407
 
451
 
408
     while (xi_cnt > 0 || yi_cnt > 0) {
452
     while (xi_cnt > 0 || yi_cnt > 0) {
409
 
453
 
410
-      next_mesh_line_x = mesh_index_to_x_location[current_xi + dxi];
411
-      next_mesh_line_y = mesh_index_to_y_location[current_yi + dyi];
412
-
413
-      y = m * next_mesh_line_x + c; // Calculate Y at the next X mesh line
414
-      x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line    (we don't have to worry
415
-      // about m being equal to 0.0  If this was the case, we would have
416
-      // detected this as a vertical line move up above and we wouldn't
417
-      // be down here doing a generic type of move.
454
+      const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_x_location[current_xi + dxi]),
455
+                  next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_y_location[current_yi + dyi]),
456
+                  y = m * next_mesh_line_x + c,   // Calculate Y at the next X mesh line
457
+                  x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line    (we don't have to worry
458
+                                                  // about m being equal to 0.0  If this was the case, we would have
459
+                                                  // detected this as a vertical line move up above and we wouldn't
460
+                                                  // be down here doing a generic type of move.
418
 
461
 
419
       if (left_flag == (x > next_mesh_line_x)) { // Check if we hit the Y line first
462
       if (left_flag == (x > next_mesh_line_x)) { // Check if we hit the Y line first
420
         //
463
         //
421
         // Yes!  Crossing a Y Mesh Line next
464
         // Yes!  Crossing a Y Mesh Line next
422
         //
465
         //
423
-        z0 = ubl.get_z_correction_along_horizontal_mesh_line_at_specific_X(x, current_xi - left_flag, current_yi + dyi);
466
+        float z0 = ubl.get_z_correction_along_horizontal_mesh_line_at_specific_X(x, current_xi - left_flag, current_yi + dyi);
424
 
467
 
425
         /**
468
         /**
426
          * Debug code to use non-optimized get_z_correction() and to do a sanity check
469
          * Debug code to use non-optimized get_z_correction() and to do a sanity check
428
          */
471
          */
429
         /*
472
         /*
430
           z_optimized = z0;
473
           z_optimized = z0;
431
-          z0 = ubl.get_z_correction( x, next_mesh_line_y);
474
+          z0 = ubl.get_z_correction(x, next_mesh_line_y);
432
           if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
475
           if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
433
             debug_current_and_destination((char*)"General_1: z_correction()");
476
             debug_current_and_destination((char*)"General_1: z_correction()");
434
             if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
477
             if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
471
         //
514
         //
472
         // Yes!  Crossing a X Mesh Line next
515
         // Yes!  Crossing a X Mesh Line next
473
         //
516
         //
474
-        z0 = ubl.get_z_correction_along_vertical_mesh_line_at_specific_Y(y, current_xi + dxi, current_yi - down_flag);
517
+        float z0 = ubl.get_z_correction_along_vertical_mesh_line_at_specific_Y(y, current_xi + dxi, current_yi - down_flag);
475
 
518
 
476
         /**
519
         /**
477
          * Debug code to use non-optimized get_z_correction() and to do a sanity check
520
          * Debug code to use non-optimized get_z_correction() and to do a sanity check
479
          */
522
          */
480
         /*
523
         /*
481
           z_optimized = z0;
524
           z_optimized = z0;
482
-          z0 = ubl.get_z_correction( next_mesh_line_x, y);
525
+          z0 = ubl.get_z_correction(next_mesh_line_x, y);
483
           if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
526
           if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
484
           debug_current_and_destination((char*)"General_2: z_correction()");
527
           debug_current_and_destination((char*)"General_2: z_correction()");
485
           if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
528
           if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
493
           }
536
           }
494
         //*/
537
         //*/
495
 
538
 
496
-        z0 = z0 * ubl.fade_scaling_factor_for_z(z_end);
539
+        z0 *= ubl.fade_scaling_factor_for_z(z_end);
497
 
540
 
498
         /**
541
         /**
499
          * If part of the Mesh is undefined, it will show up as NAN
542
          * If part of the Mesh is undefined, it will show up as NAN

+ 45
- 39
Marlin/configuration_store.cpp Ver fichero

847
 
847
 
848
       #if ENABLED(AUTO_BED_LEVELING_UBL)
848
       #if ENABLED(AUTO_BED_LEVELING_UBL)
849
         ubl_eeprom_start = (eeprom_index + 32) & 0xFFF8; // Pad the end of configuration data so it
849
         ubl_eeprom_start = (eeprom_index + 32) & 0xFFF8; // Pad the end of configuration data so it
850
-                                                                          // can float up or down a little bit without
851
-                                                                          // disrupting the Unified Bed Leveling data
850
+                                                         // can float up or down a little bit without
851
+                                                         // disrupting the Unified Bed Leveling data
852
         ubl.load_state();
852
         ubl.load_state();
853
 
853
 
854
         SERIAL_ECHOPGM(" UBL ");
854
         SERIAL_ECHOPGM(" UBL ");
879
         }
879
         }
880
         else {
880
         else {
881
           ubl.reset();
881
           ubl.reset();
882
-          SERIAL_ECHOPGM("UBL System reset() \n");
882
+          SERIAL_ECHOLNPGM("UBL System reset()");
883
         }
883
         }
884
       #endif
884
       #endif
885
     }
885
     }
1178
       SERIAL_ECHOPAIR(" Z", home_offset[Z_AXIS]);
1178
       SERIAL_ECHOPAIR(" Z", home_offset[Z_AXIS]);
1179
       SERIAL_EOL;
1179
       SERIAL_EOL;
1180
     #endif
1180
     #endif
1181
-  #if ENABLED(AUTO_BED_LEVELING_UBL)
1182
-    SERIAL_ECHOLNPGM("Unified Bed Leveling:");
1183
-    CONFIG_ECHO_START;
1184
-
1185
-    SERIAL_ECHOPGM("System is: ");
1186
-    if (ubl.state.active)
1187
-       SERIAL_ECHOLNPGM("Active\n");
1188
-    else
1189
-       SERIAL_ECHOLNPGM("Deactive\n");
1190
-
1191
-    SERIAL_ECHOPAIR("Active Mesh Slot: ", ubl.state.eeprom_storage_slot);
1192
-    SERIAL_EOL;
1193
-
1194
-    SERIAL_ECHOPGM("z_offset: ");
1195
-    SERIAL_ECHO_F(ubl.state.z_offset, 6);
1196
-    SERIAL_EOL;
1197
-
1198
-    SERIAL_ECHOPAIR("EEPROM can hold ", (int)((E2END - sizeof(ubl.state) - ubl_eeprom_start) / sizeof(z_values)));
1199
-    SERIAL_ECHOLNPGM(" meshes. \n");
1200
-
1201
-    SERIAL_ECHOPAIR("\nUBL_MESH_NUM_X_POINTS  ", UBL_MESH_NUM_X_POINTS);
1202
-    SERIAL_ECHOPAIR("\nUBL_MESH_NUM_Y_POINTS  ", UBL_MESH_NUM_Y_POINTS);
1203
-
1204
-    SERIAL_ECHOPAIR("\nUBL_MESH_MIN_X         ", UBL_MESH_MIN_X);
1205
-    SERIAL_ECHOPAIR("\nUBL_MESH_MIN_Y         ", UBL_MESH_MIN_Y);
1206
-
1207
-    SERIAL_ECHOPAIR("\nUBL_MESH_MAX_X         ", UBL_MESH_MAX_X);
1208
-    SERIAL_ECHOPAIR("\nUBL_MESH_MAX_Y         ", UBL_MESH_MAX_Y);
1209
-
1210
-    SERIAL_ECHOPGM("\nMESH_X_DIST        ");
1211
-    SERIAL_ECHO_F(MESH_X_DIST, 6);
1212
-    SERIAL_ECHOPGM("\nMESH_Y_DIST        ");
1213
-    SERIAL_ECHO_F(MESH_Y_DIST, 6);
1214
-    SERIAL_EOL;
1215
-    SERIAL_EOL;
1216
-  #endif
1217
 
1181
 
1218
     #if HOTENDS > 1
1182
     #if HOTENDS > 1
1219
       CONFIG_ECHO_START;
1183
       CONFIG_ECHO_START;
1233
     #endif
1197
     #endif
1234
 
1198
 
1235
     #if ENABLED(MESH_BED_LEVELING)
1199
     #if ENABLED(MESH_BED_LEVELING)
1200
+
1236
       if (!forReplay) {
1201
       if (!forReplay) {
1237
         SERIAL_ECHOLNPGM("Mesh Bed Leveling:");
1202
         SERIAL_ECHOLNPGM("Mesh Bed Leveling:");
1238
         CONFIG_ECHO_START;
1203
         CONFIG_ECHO_START;
1248
           SERIAL_EOL;
1213
           SERIAL_EOL;
1249
         }
1214
         }
1250
       }
1215
       }
1216
+
1217
+    #elif ENABLED(AUTO_BED_LEVELING_UBL)
1218
+
1219
+      if (!forReplay) {
1220
+        SERIAL_ECHOLNPGM("Unified Bed Leveling:");
1221
+        CONFIG_ECHO_START;
1222
+      }
1223
+
1224
+      SERIAL_ECHOLNPAIR("  M420 S", ubl.state.active ? 1 : 0);
1225
+
1226
+      if (!forReplay) {
1227
+        SERIAL_ECHOPGM("\nUBL is ");
1228
+        ubl.state.active ? SERIAL_CHAR('A') : SERIAL_ECHOPGM("Ina");
1229
+        SERIAL_ECHOLNPAIR("ctive\n\nActive Mesh Slot: ", ubl.state.eeprom_storage_slot);
1230
+
1231
+        SERIAL_ECHOPGM("z_offset: ");
1232
+        SERIAL_ECHO_F(ubl.state.z_offset, 6);
1233
+        SERIAL_EOL;
1234
+
1235
+        SERIAL_ECHOPAIR("EEPROM can hold ", (int)((UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(z_values)));
1236
+        SERIAL_ECHOLNPGM(" meshes.\n");
1237
+
1238
+        SERIAL_ECHOPAIR("\nUBL_MESH_NUM_X_POINTS  ", UBL_MESH_NUM_X_POINTS);
1239
+        SERIAL_ECHOPAIR("\nUBL_MESH_NUM_Y_POINTS  ", UBL_MESH_NUM_Y_POINTS);
1240
+
1241
+        SERIAL_ECHOPAIR("\nUBL_MESH_MIN_X         ", UBL_MESH_MIN_X);
1242
+        SERIAL_ECHOPAIR("\nUBL_MESH_MIN_Y         ", UBL_MESH_MIN_Y);
1243
+
1244
+        SERIAL_ECHOPAIR("\nUBL_MESH_MAX_X         ", UBL_MESH_MAX_X);
1245
+        SERIAL_ECHOPAIR("\nUBL_MESH_MAX_Y         ", UBL_MESH_MAX_Y);
1246
+
1247
+        SERIAL_ECHOPGM("\nMESH_X_DIST        ");
1248
+        SERIAL_ECHO_F(MESH_X_DIST, 6);
1249
+        SERIAL_ECHOPGM("\nMESH_Y_DIST        ");
1250
+        SERIAL_ECHO_F(MESH_Y_DIST, 6);
1251
+        SERIAL_EOL;
1252
+        SERIAL_EOL;
1253
+      }
1254
+
1251
     #elif HAS_ABL
1255
     #elif HAS_ABL
1256
+
1252
       if (!forReplay) {
1257
       if (!forReplay) {
1253
         SERIAL_ECHOLNPGM("Auto Bed Leveling:");
1258
         SERIAL_ECHOLNPGM("Auto Bed Leveling:");
1254
         CONFIG_ECHO_START;
1259
         CONFIG_ECHO_START;
1255
       }
1260
       }
1256
       SERIAL_ECHOLNPAIR("  M420 S", planner.abl_enabled ? 1 : 0);
1261
       SERIAL_ECHOLNPAIR("  M420 S", planner.abl_enabled ? 1 : 0);
1262
+
1257
     #endif
1263
     #endif
1258
 
1264
 
1259
     #if ENABLED(DELTA)
1265
     #if ENABLED(DELTA)

+ 1
- 0
Marlin/example_configurations/Cartesio/Configuration.h Ver fichero

863
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_2_Y 20
864
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_X 180
865
   #define UBL_PROBE_PT_3_Y 20
865
   #define UBL_PROBE_PT_3_Y 20
866
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
866
 
867
 
867
 #elif ENABLED(MESH_BED_LEVELING)
868
 #elif ENABLED(MESH_BED_LEVELING)
868
 
869
 

+ 1
- 0
Marlin/example_configurations/Felix/Configuration.h Ver fichero

846
   #define UBL_PROBE_PT_2_Y 20
846
   #define UBL_PROBE_PT_2_Y 20
847
   #define UBL_PROBE_PT_3_X 180
847
   #define UBL_PROBE_PT_3_X 180
848
   #define UBL_PROBE_PT_3_Y 20
848
   #define UBL_PROBE_PT_3_Y 20
849
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
849
 
850
 
850
 #elif ENABLED(MESH_BED_LEVELING)
851
 #elif ENABLED(MESH_BED_LEVELING)
851
 
852
 

+ 1
- 0
Marlin/example_configurations/Felix/DUAL/Configuration.h Ver fichero

846
   #define UBL_PROBE_PT_2_Y 20
846
   #define UBL_PROBE_PT_2_Y 20
847
   #define UBL_PROBE_PT_3_X 180
847
   #define UBL_PROBE_PT_3_X 180
848
   #define UBL_PROBE_PT_3_Y 20
848
   #define UBL_PROBE_PT_3_Y 20
849
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
849
 
850
 
850
 #elif ENABLED(MESH_BED_LEVELING)
851
 #elif ENABLED(MESH_BED_LEVELING)
851
 
852
 

+ 1
- 0
Marlin/example_configurations/Hephestos/Configuration.h Ver fichero

855
   #define UBL_PROBE_PT_2_Y 20
855
   #define UBL_PROBE_PT_2_Y 20
856
   #define UBL_PROBE_PT_3_X 180
856
   #define UBL_PROBE_PT_3_X 180
857
   #define UBL_PROBE_PT_3_Y 20
857
   #define UBL_PROBE_PT_3_Y 20
858
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
858
 
859
 
859
 #elif ENABLED(MESH_BED_LEVELING)
860
 #elif ENABLED(MESH_BED_LEVELING)
860
 
861
 

+ 1
- 0
Marlin/example_configurations/Hephestos_2/Configuration.h Ver fichero

857
   #define UBL_PROBE_PT_2_Y 20
857
   #define UBL_PROBE_PT_2_Y 20
858
   #define UBL_PROBE_PT_3_X 180
858
   #define UBL_PROBE_PT_3_X 180
859
   #define UBL_PROBE_PT_3_Y 20
859
   #define UBL_PROBE_PT_3_Y 20
860
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
860
 
861
 
861
 #elif ENABLED(MESH_BED_LEVELING)
862
 #elif ENABLED(MESH_BED_LEVELING)
862
 
863
 

+ 1
- 0
Marlin/example_configurations/K8200/Configuration.h Ver fichero

892
   #define UBL_PROBE_PT_2_Y 20
892
   #define UBL_PROBE_PT_2_Y 20
893
   #define UBL_PROBE_PT_3_X 180
893
   #define UBL_PROBE_PT_3_X 180
894
   #define UBL_PROBE_PT_3_Y 20
894
   #define UBL_PROBE_PT_3_Y 20
895
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
895
 
896
 
896
 #elif ENABLED(MESH_BED_LEVELING)
897
 #elif ENABLED(MESH_BED_LEVELING)
897
 
898
 

+ 1
- 0
Marlin/example_configurations/K8400/Configuration.h Ver fichero

863
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_2_Y 20
864
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_X 180
865
   #define UBL_PROBE_PT_3_Y 20
865
   #define UBL_PROBE_PT_3_Y 20
866
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
866
 
867
 
867
 #elif ENABLED(MESH_BED_LEVELING)
868
 #elif ENABLED(MESH_BED_LEVELING)
868
 
869
 

+ 1
- 0
Marlin/example_configurations/K8400/Dual-head/Configuration.h Ver fichero

863
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_2_Y 20
864
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_X 180
865
   #define UBL_PROBE_PT_3_Y 20
865
   #define UBL_PROBE_PT_3_Y 20
866
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
866
 
867
 
867
 #elif ENABLED(MESH_BED_LEVELING)
868
 #elif ENABLED(MESH_BED_LEVELING)
868
 
869
 

+ 1
- 0
Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h Ver fichero

863
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_2_Y 20
864
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_X 180
865
   #define UBL_PROBE_PT_3_Y 20
865
   #define UBL_PROBE_PT_3_Y 20
866
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
866
 
867
 
867
 #elif ENABLED(MESH_BED_LEVELING)
868
 #elif ENABLED(MESH_BED_LEVELING)
868
 
869
 

+ 1
- 0
Marlin/example_configurations/RigidBot/Configuration.h Ver fichero

862
   #define UBL_PROBE_PT_2_Y 20
862
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_3_X 180
863
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_Y 20
864
   #define UBL_PROBE_PT_3_Y 20
865
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
865
 
866
 
866
 #elif ENABLED(MESH_BED_LEVELING)
867
 #elif ENABLED(MESH_BED_LEVELING)
867
 
868
 

+ 1
- 0
Marlin/example_configurations/SCARA/Configuration.h Ver fichero

878
   #define UBL_PROBE_PT_2_Y 20
878
   #define UBL_PROBE_PT_2_Y 20
879
   #define UBL_PROBE_PT_3_X 180
879
   #define UBL_PROBE_PT_3_X 180
880
   #define UBL_PROBE_PT_3_Y 20
880
   #define UBL_PROBE_PT_3_Y 20
881
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
881
 
882
 
882
 #elif ENABLED(MESH_BED_LEVELING)
883
 #elif ENABLED(MESH_BED_LEVELING)
883
 
884
 

+ 1
- 0
Marlin/example_configurations/TAZ4/Configuration.h Ver fichero

884
   #define UBL_PROBE_PT_2_Y 20
884
   #define UBL_PROBE_PT_2_Y 20
885
   #define UBL_PROBE_PT_3_X 180
885
   #define UBL_PROBE_PT_3_X 180
886
   #define UBL_PROBE_PT_3_Y 20
886
   #define UBL_PROBE_PT_3_Y 20
887
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
887
 
888
 
888
 #elif ENABLED(MESH_BED_LEVELING)
889
 #elif ENABLED(MESH_BED_LEVELING)
889
 
890
 

+ 1
- 0
Marlin/example_configurations/WITBOX/Configuration.h Ver fichero

855
   #define UBL_PROBE_PT_2_Y 20
855
   #define UBL_PROBE_PT_2_Y 20
856
   #define UBL_PROBE_PT_3_X 180
856
   #define UBL_PROBE_PT_3_X 180
857
   #define UBL_PROBE_PT_3_Y 20
857
   #define UBL_PROBE_PT_3_Y 20
858
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
858
 
859
 
859
 #elif ENABLED(MESH_BED_LEVELING)
860
 #elif ENABLED(MESH_BED_LEVELING)
860
 
861
 

+ 1
- 0
Marlin/example_configurations/adafruit/ST7565/Configuration.h Ver fichero

863
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_2_Y 20
864
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_X 180
865
   #define UBL_PROBE_PT_3_Y 20
865
   #define UBL_PROBE_PT_3_Y 20
866
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
866
 
867
 
867
 #elif ENABLED(MESH_BED_LEVELING)
868
 #elif ENABLED(MESH_BED_LEVELING)
868
 
869
 

+ 1
- 0
Marlin/example_configurations/delta/flsun_kossel_mini/Configuration.h Ver fichero

968
   #define UBL_PROBE_PT_2_Y 20
968
   #define UBL_PROBE_PT_2_Y 20
969
   #define UBL_PROBE_PT_3_X 180
969
   #define UBL_PROBE_PT_3_X 180
970
   #define UBL_PROBE_PT_3_Y 20
970
   #define UBL_PROBE_PT_3_Y 20
971
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
971
 
972
 
972
 #elif ENABLED(MESH_BED_LEVELING)
973
 #elif ENABLED(MESH_BED_LEVELING)
973
 
974
 

+ 1
- 0
Marlin/example_configurations/delta/generic/Configuration.h Ver fichero

954
   #define UBL_PROBE_PT_2_Y 20
954
   #define UBL_PROBE_PT_2_Y 20
955
   #define UBL_PROBE_PT_3_X 180
955
   #define UBL_PROBE_PT_3_X 180
956
   #define UBL_PROBE_PT_3_Y 20
956
   #define UBL_PROBE_PT_3_Y 20
957
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
957
 
958
 
958
 #elif ENABLED(MESH_BED_LEVELING)
959
 #elif ENABLED(MESH_BED_LEVELING)
959
 
960
 

+ 1
- 0
Marlin/example_configurations/delta/kossel_mini/Configuration.h Ver fichero

958
   #define UBL_PROBE_PT_2_Y 20
958
   #define UBL_PROBE_PT_2_Y 20
959
   #define UBL_PROBE_PT_3_X 180
959
   #define UBL_PROBE_PT_3_X 180
960
   #define UBL_PROBE_PT_3_Y 20
960
   #define UBL_PROBE_PT_3_Y 20
961
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
961
 
962
 
962
 #elif ENABLED(MESH_BED_LEVELING)
963
 #elif ENABLED(MESH_BED_LEVELING)
963
 
964
 

+ 1
- 0
Marlin/example_configurations/delta/kossel_pro/Configuration.h Ver fichero

957
   #define UBL_PROBE_PT_2_Y 20
957
   #define UBL_PROBE_PT_2_Y 20
958
   #define UBL_PROBE_PT_3_X 180
958
   #define UBL_PROBE_PT_3_X 180
959
   #define UBL_PROBE_PT_3_Y 20
959
   #define UBL_PROBE_PT_3_Y 20
960
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
960
 
961
 
961
 #elif ENABLED(MESH_BED_LEVELING)
962
 #elif ENABLED(MESH_BED_LEVELING)
962
 
963
 

+ 1
- 0
Marlin/example_configurations/delta/kossel_xl/Configuration.h Ver fichero

967
   #define UBL_PROBE_PT_2_Y 20
967
   #define UBL_PROBE_PT_2_Y 20
968
   #define UBL_PROBE_PT_3_X 180
968
   #define UBL_PROBE_PT_3_X 180
969
   #define UBL_PROBE_PT_3_Y 20
969
   #define UBL_PROBE_PT_3_Y 20
970
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
970
 
971
 
971
 #elif ENABLED(MESH_BED_LEVELING)
972
 #elif ENABLED(MESH_BED_LEVELING)
972
 
973
 

+ 1
- 0
Marlin/example_configurations/makibox/Configuration.h Ver fichero

866
   #define UBL_PROBE_PT_2_Y 20
866
   #define UBL_PROBE_PT_2_Y 20
867
   #define UBL_PROBE_PT_3_X 180
867
   #define UBL_PROBE_PT_3_X 180
868
   #define UBL_PROBE_PT_3_Y 20
868
   #define UBL_PROBE_PT_3_Y 20
869
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
869
 
870
 
870
 #elif ENABLED(MESH_BED_LEVELING)
871
 #elif ENABLED(MESH_BED_LEVELING)
871
 
872
 

+ 1
- 0
Marlin/example_configurations/tvrrug/Round2/Configuration.h Ver fichero

859
   #define UBL_PROBE_PT_2_Y 20
859
   #define UBL_PROBE_PT_2_Y 20
860
   #define UBL_PROBE_PT_3_X 180
860
   #define UBL_PROBE_PT_3_X 180
861
   #define UBL_PROBE_PT_3_Y 20
861
   #define UBL_PROBE_PT_3_Y 20
862
+  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
862
 
863
 
863
 #elif ENABLED(MESH_BED_LEVELING)
864
 #elif ENABLED(MESH_BED_LEVELING)
864
 
865
 

+ 2
- 2
Marlin/mesh_bed_leveling.h Ver fichero

87
     }
87
     }
88
 
88
 
89
     int8_t probe_index_x(const float &x) const {
89
     int8_t probe_index_x(const float &x) const {
90
-      int8_t px = (x - (MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST));
90
+      int8_t px = (x - (MESH_MIN_X) + 0.5 * (MESH_X_DIST)) * (1.0 / (MESH_X_DIST));
91
       return (px >= 0 && px < (MESH_NUM_X_POINTS)) ? px : -1;
91
       return (px >= 0 && px < (MESH_NUM_X_POINTS)) ? px : -1;
92
     }
92
     }
93
 
93
 
94
     int8_t probe_index_y(const float &y) const {
94
     int8_t probe_index_y(const float &y) const {
95
-      int8_t py = (y - (MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST));
95
+      int8_t py = (y - (MESH_MIN_Y) + 0.5 * (MESH_Y_DIST)) * (1.0 / (MESH_Y_DIST));
96
       return (py >= 0 && py < (MESH_NUM_Y_POINTS)) ? py : -1;
96
       return (py >= 0 && py < (MESH_NUM_Y_POINTS)) ? py : -1;
97
     }
97
     }
98
 
98
 

+ 3
- 3
Marlin/planner.cpp Ver fichero

530
   #endif
530
   #endif
531
 }
531
 }
532
 
532
 
533
-#if PLANNER_LEVELING
533
+#if PLANNER_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL)
534
   /**
534
   /**
535
    * lx, ly, lz - logical (cartesian, not delta) positions in mm
535
    * lx, ly, lz - logical (cartesian, not delta) positions in mm
536
    */
536
    */
634
     #endif
634
     #endif
635
   }
635
   }
636
 
636
 
637
-#endif // PLANNER_LEVELING
637
+#endif // PLANNER_LEVELING && !AUTO_BED_LEVELING_UBL
638
 
638
 
639
 /**
639
 /**
640
  * Planner::_buffer_line
640
  * Planner::_buffer_line
1408
 }
1408
 }
1409
 
1409
 
1410
 void Planner::set_position_mm_kinematic(const float position[NUM_AXIS]) {
1410
 void Planner::set_position_mm_kinematic(const float position[NUM_AXIS]) {
1411
-  #if PLANNER_LEVELING
1411
+  #if PLANNER_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL)
1412
     float lpos[XYZ] = { position[X_AXIS], position[Y_AXIS], position[Z_AXIS] };
1412
     float lpos[XYZ] = { position[X_AXIS], position[Y_AXIS], position[Z_AXIS] };
1413
     apply_leveling(lpos);
1413
     apply_leveling(lpos);
1414
   #else
1414
   #else

+ 4
- 4
Marlin/planner.h Ver fichero

244
 
244
 
245
     static bool is_full() { return (block_buffer_tail == BLOCK_MOD(block_buffer_head + 1)); }
245
     static bool is_full() { return (block_buffer_tail == BLOCK_MOD(block_buffer_head + 1)); }
246
 
246
 
247
-    #if PLANNER_LEVELING
247
+    #if PLANNER_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL)
248
 
248
 
249
       #define ARG_X float lx
249
       #define ARG_X float lx
250
       #define ARG_Y float ly
250
       #define ARG_Y float ly
300
      *  extruder     - target extruder
300
      *  extruder     - target extruder
301
      */
301
      */
302
     static FORCE_INLINE void buffer_line(ARG_X, ARG_Y, ARG_Z, const float &e, const float &fr_mm_s, const uint8_t extruder) {
302
     static FORCE_INLINE void buffer_line(ARG_X, ARG_Y, ARG_Z, const float &e, const float &fr_mm_s, const uint8_t extruder) {
303
-      #if PLANNER_LEVELING && IS_CARTESIAN
303
+      #if PLANNER_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL) && IS_CARTESIAN
304
         apply_leveling(lx, ly, lz);
304
         apply_leveling(lx, ly, lz);
305
       #endif
305
       #endif
306
       _buffer_line(lx, ly, lz, e, fr_mm_s, extruder);
306
       _buffer_line(lx, ly, lz, e, fr_mm_s, extruder);
316
      *  extruder - target extruder
316
      *  extruder - target extruder
317
      */
317
      */
318
     static FORCE_INLINE void buffer_line_kinematic(const float ltarget[XYZE], const float &fr_mm_s, const uint8_t extruder) {
318
     static FORCE_INLINE void buffer_line_kinematic(const float ltarget[XYZE], const float &fr_mm_s, const uint8_t extruder) {
319
-      #if PLANNER_LEVELING
319
+      #if PLANNER_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL)
320
         float lpos[XYZ] = { ltarget[X_AXIS], ltarget[Y_AXIS], ltarget[Z_AXIS] };
320
         float lpos[XYZ] = { ltarget[X_AXIS], ltarget[Y_AXIS], ltarget[Z_AXIS] };
321
         apply_leveling(lpos);
321
         apply_leveling(lpos);
322
       #else
322
       #else
340
      * Clears previous speed values.
340
      * Clears previous speed values.
341
      */
341
      */
342
     static FORCE_INLINE void set_position_mm(ARG_X, ARG_Y, ARG_Z, const float &e) {
342
     static FORCE_INLINE void set_position_mm(ARG_X, ARG_Y, ARG_Z, const float &e) {
343
-      #if PLANNER_LEVELING && IS_CARTESIAN
343
+      #if PLANNER_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL) && IS_CARTESIAN
344
         apply_leveling(lx, ly, lz);
344
         apply_leveling(lx, ly, lz);
345
       #endif
345
       #endif
346
       _set_position_mm(lx, ly, lz, e);
346
       _set_position_mm(lx, ly, lz, e);

+ 18
- 29
Marlin/stepper.cpp Ver fichero

535
 
535
 
536
     // If a minimum pulse time was specified get the CPU clock
536
     // If a minimum pulse time was specified get the CPU clock
537
     #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_CODE
537
     #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_CODE
538
-      static uint32_t pulse_start;
539
-      pulse_start = TCNT0;
538
+      uint32_t pulse_start = TCNT0;
540
     #endif
539
     #endif
541
 
540
 
542
     #if HAS_X_STEP
541
     #if HAS_X_STEP
802
     for (uint8_t i = 0; i < step_loops; i++) {
801
     for (uint8_t i = 0; i < step_loops; i++) {
803
 
802
 
804
       #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_E
803
       #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_E
805
-        static uint32_t pulse_start;
806
-        pulse_start = TCNT0;
804
+        uint32_t pulse_start = TCNT0;
807
       #endif
805
       #endif
808
 
806
 
809
       START_E_PULSE(0);
807
       START_E_PULSE(0);
1232
 #if ENABLED(BABYSTEPPING)
1230
 #if ENABLED(BABYSTEPPING)
1233
 
1231
 
1234
   #define CYCLES_EATEN_BY_BABYSTEP 60
1232
   #define CYCLES_EATEN_BY_BABYSTEP 60
1233
+
1235
   #define _ENABLE(axis) enable_## axis()
1234
   #define _ENABLE(axis) enable_## axis()
1236
   #define _READ_DIR(AXIS) AXIS ##_DIR_READ
1235
   #define _READ_DIR(AXIS) AXIS ##_DIR_READ
1237
   #define _INVERT_DIR(AXIS) INVERT_## AXIS ##_DIR
1236
   #define _INVERT_DIR(AXIS) INVERT_## AXIS ##_DIR
1238
   #define _APPLY_DIR(AXIS, INVERT) AXIS ##_APPLY_DIR(INVERT, true)
1237
   #define _APPLY_DIR(AXIS, INVERT) AXIS ##_APPLY_DIR(INVERT, true)
1239
 
1238
 
1239
+  #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP
1240
+    #define _SAVE_START (pulse_start = TCNT0)
1241
+    #define _PULSE_WAIT while ((uint32_t)(TCNT0 - pulse_start) < STEP_PULSE_CYCLES - CYCLES_EATEN_BY_BABYSTEP) { /* nada */ }
1242
+  #else
1243
+    #define _SAVE_START NOOP
1244
+    #define _PULSE_WAIT NOOP
1245
+  #endif
1246
+
1240
   #define START_BABYSTEP_AXIS(AXIS, INVERT) { \
1247
   #define START_BABYSTEP_AXIS(AXIS, INVERT) { \
1248
+      old_dir = _READ_DIR(AXIS); \
1249
+      _SAVE_START; \
1241
       _APPLY_DIR(AXIS, _INVERT_DIR(AXIS)^direction^INVERT); \
1250
       _APPLY_DIR(AXIS, _INVERT_DIR(AXIS)^direction^INVERT); \
1242
       _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), true); \
1251
       _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), true); \
1243
     }
1252
     }
1244
 
1253
 
1245
   #define STOP_BABYSTEP_AXIS(AXIS) { \
1254
   #define STOP_BABYSTEP_AXIS(AXIS) { \
1255
+      _PULSE_WAIT; \
1246
       _APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS), true); \
1256
       _APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS), true); \
1247
-      _APPLY_DIR(AXIS, old_pin); \
1257
+      _APPLY_DIR(AXIS, old_dir); \
1248
     }
1258
     }
1249
 
1259
 
1250
   // MUST ONLY BE CALLED BY AN ISR,
1260
   // MUST ONLY BE CALLED BY AN ISR,
1251
   // No other ISR should ever interrupt this!
1261
   // No other ISR should ever interrupt this!
1252
   void Stepper::babystep(const AxisEnum axis, const bool direction) {
1262
   void Stepper::babystep(const AxisEnum axis, const bool direction) {
1253
     cli();
1263
     cli();
1254
-    static uint8_t old_pin;
1264
+    uint8_t old_dir;
1255
     #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP
1265
     #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP
1256
-      static uint32_t pulse_start;
1266
+      uint32_t pulse_start;
1257
     #endif
1267
     #endif
1258
     
1268
     
1259
     switch (axis) {
1269
     switch (axis) {
1260
 
1270
 
1261
       case X_AXIS:
1271
       case X_AXIS:
1262
         _ENABLE(x);
1272
         _ENABLE(x);
1263
-        old_pin = _READ_DIR(X);
1264
-        #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP
1265
-          pulse_start = TCNT0;
1266
-        #endif 
1267
         START_BABYSTEP_AXIS(X, false);
1273
         START_BABYSTEP_AXIS(X, false);
1268
-        #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP
1269
-          while ((uint32_t)(TCNT0 - pulse_start) < STEP_PULSE_CYCLES - CYCLES_EATEN_BY_BABYSTEP) { /* nada */ }
1270
-        #endif
1271
         STOP_BABYSTEP_AXIS(X);
1274
         STOP_BABYSTEP_AXIS(X);
1272
         break;
1275
         break;
1273
 
1276
 
1274
       case Y_AXIS:
1277
       case Y_AXIS:
1275
         _ENABLE(y);
1278
         _ENABLE(y);
1276
-        old_pin = _READ_DIR(Y);
1277
-        #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP
1278
-          pulse_start = TCNT0;
1279
-        #endif
1280
         START_BABYSTEP_AXIS(Y, false);
1279
         START_BABYSTEP_AXIS(Y, false);
1281
-        #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP
1282
-          while ((uint32_t)(TCNT0 - pulse_start) < STEP_PULSE_CYCLES - CYCLES_EATEN_BY_BABYSTEP) { /* nada */ }
1283
-        #endif
1284
         STOP_BABYSTEP_AXIS(Y);
1280
         STOP_BABYSTEP_AXIS(Y);
1285
         break;
1281
         break;
1286
 
1282
 
1289
         #if DISABLED(DELTA)
1285
         #if DISABLED(DELTA)
1290
 
1286
 
1291
           _ENABLE(z);
1287
           _ENABLE(z);
1292
-          old_pin = _READ_DIR(Z);
1293
-          #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP
1294
-            pulse_start = TCNT0;
1295
-          #endif
1296
           START_BABYSTEP_AXIS(Z, BABYSTEP_INVERT_Z);
1288
           START_BABYSTEP_AXIS(Z, BABYSTEP_INVERT_Z);
1297
-          #if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP
1298
-            while ((uint32_t)(TCNT0 - pulse_start) < STEP_PULSE_CYCLES - CYCLES_EATEN_BY_BABYSTEP) { /* nada */ }
1299
-          #endif
1300
           STOP_BABYSTEP_AXIS(Z);
1289
           STOP_BABYSTEP_AXIS(Z);
1301
 
1290
 
1302
         #else // DELTA
1291
         #else // DELTA
1340
     sei();
1329
     sei();
1341
   }
1330
   }
1342
 
1331
 
1343
-#endif //BABYSTEPPING
1332
+#endif // BABYSTEPPING
1344
 
1333
 
1345
 /**
1334
 /**
1346
  * Software-controlled Stepper Motor Current
1335
  * Software-controlled Stepper Motor Current

+ 1
- 1
Marlin/ultralcd.cpp Ver fichero

860
 
860
 
861
     static void _lcd_mesh_fine_tune(const char* msg) {
861
     static void _lcd_mesh_fine_tune(const char* msg) {
862
       static millis_t next_click = 0;
862
       static millis_t next_click = 0;
863
-      int16_t last_digit, movement;
863
+      int16_t last_digit;
864
       int32_t rounded;
864
       int32_t rounded;
865
 
865
 
866
       defer_return_to_status = true;
866
       defer_return_to_status = true;

+ 11
- 11
Marlin/vector_3.cpp Ver fichero

66
 float vector_3::get_length() { return sqrt((x * x) + (y * y) + (z * z)); }
66
 float vector_3::get_length() { return sqrt((x * x) + (y * y) + (z * z)); }
67
 
67
 
68
 void vector_3::normalize() {
68
 void vector_3::normalize() {
69
-  float length = get_length();
70
-  x /= length;
71
-  y /= length;
72
-  z /= length;
69
+  const float inv_length = 1.0 / get_length();
70
+  x *= inv_length;
71
+  y *= inv_length;
72
+  z *= inv_length;
73
 }
73
 }
74
 
74
 
75
 void vector_3::apply_rotation(matrix_3x3 matrix) {
75
 void vector_3::apply_rotation(matrix_3x3 matrix) {
76
-  float resultX = x * matrix.matrix[3 * 0 + 0] + y * matrix.matrix[3 * 1 + 0] + z * matrix.matrix[3 * 2 + 0];
77
-  float resultY = x * matrix.matrix[3 * 0 + 1] + y * matrix.matrix[3 * 1 + 1] + z * matrix.matrix[3 * 2 + 1];
78
-  float resultZ = x * matrix.matrix[3 * 0 + 2] + y * matrix.matrix[3 * 1 + 2] + z * matrix.matrix[3 * 2 + 2];
76
+  const float resultX = x * matrix.matrix[3 * 0 + 0] + y * matrix.matrix[3 * 1 + 0] + z * matrix.matrix[3 * 2 + 0],
77
+              resultY = x * matrix.matrix[3 * 0 + 1] + y * matrix.matrix[3 * 1 + 1] + z * matrix.matrix[3 * 2 + 1],
78
+              resultZ = x * matrix.matrix[3 * 0 + 2] + y * matrix.matrix[3 * 1 + 2] + z * matrix.matrix[3 * 2 + 2];
79
   x = resultX;
79
   x = resultX;
80
   y = resultY;
80
   y = resultY;
81
   z = resultZ;
81
   z = resultZ;
92
   SERIAL_EOL;
92
   SERIAL_EOL;
93
 }
93
 }
94
 
94
 
95
-void apply_rotation_xyz(matrix_3x3 matrix, float& x, float& y, float& z) {
95
+void apply_rotation_xyz(matrix_3x3 matrix, float &x, float &y, float &z) {
96
   vector_3 vector = vector_3(x, y, z);
96
   vector_3 vector = vector_3(x, y, z);
97
   vector.apply_rotation(matrix);
97
   vector.apply_rotation(matrix);
98
   x = vector.x;
98
   x = vector.x;
144
 
144
 
145
 void matrix_3x3::debug(const char title[]) {
145
 void matrix_3x3::debug(const char title[]) {
146
   SERIAL_PROTOCOLLN(title);
146
   SERIAL_PROTOCOLLN(title);
147
-  int count = 0;
148
-  for (int i = 0; i < 3; i++) {
149
-    for (int j = 0; j < 3; j++) {
147
+  uint8_t count = 0;
148
+  for (uint8_t i = 0; i < 3; i++) {
149
+    for (uint8_t j = 0; j < 3; j++) {
150
       if (matrix[count] >= 0.0) SERIAL_PROTOCOLCHAR('+');
150
       if (matrix[count] >= 0.0) SERIAL_PROTOCOLCHAR('+');
151
       SERIAL_PROTOCOL_F(matrix[count], 6);
151
       SERIAL_PROTOCOL_F(matrix[count], 6);
152
       SERIAL_PROTOCOLCHAR(' ');
152
       SERIAL_PROTOCOLCHAR(' ');

Loading…
Cancelar
Guardar