Browse Source

UBL's Grid Based Leveling code

Pretty much...  The code is in place.  Still more work to do.    But it
has a lot of hooks and variables in other code, so commit and merge
before I pick up a million 'Conflicts'.
Roxy-3D 7 years ago
parent
commit
1451b7eacf

+ 16
- 16
Marlin/G26_Mesh_Validation_Tool.cpp View File

@@ -219,8 +219,8 @@
219 219
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0.0);
220 220
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], ooze_amount);
221 221
 
222
-    ubl.has_control_of_lcd_panel++;
223
-    //debug_current_and_destination((char*)"Starting G26 Mesh Validation Pattern.");
222
+    ubl.has_control_of_lcd_panel = true;
223
+    //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
224 224
 
225 225
     /**
226 226
      * Declare and generate a sin() & cos() table to be used during the circle drawing.  This will lighten
@@ -346,12 +346,12 @@
346 346
 
347 347
         }
348 348
 
349
-        //debug_current_and_destination((char*)"Looking for lines to connect.");
349
+        //debug_current_and_destination(PSTR("Looking for lines to connect."));
350 350
         look_for_lines_to_connect();
351
-        //debug_current_and_destination((char*)"Done with line connect.");
351
+        //debug_current_and_destination(PSTR("Done with line connect."));
352 352
       }
353 353
 
354
-      //debug_current_and_destination((char*)"Done with current circle.");
354
+      //debug_current_and_destination(PSTR("Done with current circle."));
355 355
 
356 356
     } while (location.x_index >= 0 && location.y_index >= 0);
357 357
 
@@ -362,16 +362,16 @@
362 362
     retract_filament(destination);
363 363
     destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES;
364 364
 
365
-    //debug_current_and_destination((char*)"ready to do Z-Raise.");
365
+    //debug_current_and_destination(PSTR("ready to do Z-Raise."));
366 366
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Raise the nozzle
367
-    //debug_current_and_destination((char*)"done doing Z-Raise.");
367
+    //debug_current_and_destination(PSTR("done doing Z-Raise."));
368 368
 
369 369
     destination[X_AXIS] = x_pos;                                               // Move back to the starting position
370 370
     destination[Y_AXIS] = y_pos;
371 371
     //destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES;                        // Keep the nozzle where it is
372 372
 
373 373
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Move back to the starting position
374
-    //debug_current_and_destination((char*)"done doing X/Y move.");
374
+    //debug_current_and_destination(PSTR("done doing X/Y move."));
375 375
 
376 376
     ubl.has_control_of_lcd_panel = false;     // Give back control of the LCD Panel!
377 377
 
@@ -458,7 +458,7 @@
458 458
                 SERIAL_ECHOPAIR(", ey=", ey);
459 459
                 SERIAL_CHAR(')');
460 460
                 SERIAL_EOL;
461
-                //debug_current_and_destination((char*)"Connecting horizontal line.");
461
+                //debug_current_and_destination(PSTR("Connecting horizontal line."));
462 462
               }
463 463
 
464 464
               print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), layer_height);
@@ -489,7 +489,7 @@
489 489
                   SERIAL_ECHOPAIR(", ey=", ey);
490 490
                   SERIAL_CHAR(')');
491 491
                   SERIAL_EOL;
492
-                  debug_current_and_destination((char*)"Connecting vertical line.");
492
+                  debug_current_and_destination(PSTR("Connecting vertical line."));
493 493
                 }
494 494
                 print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), layer_height);
495 495
                 bit_set(vertical_mesh_line_flags, i, j);   // Mark it as done so we don't do it again
@@ -525,7 +525,7 @@
525 525
       stepper.synchronize();
526 526
       set_destination_to_current();
527 527
 
528
-      //if (ubl.g26_debug_flag) debug_current_and_destination((char*)" in move_to() done with Z move");
528
+      //if (ubl.g26_debug_flag) debug_current_and_destination(PSTR(" in move_to() done with Z move"));
529 529
     }
530 530
 
531 531
     // Check if X or Y is involved in the movement.
@@ -538,11 +538,11 @@
538 538
     destination[Y_AXIS] = y;
539 539
     destination[E_AXIS] += e_delta;
540 540
 
541
-    //if (ubl.g26_debug_flag) debug_current_and_destination((char*)" in move_to() doing last move");
541
+    //if (ubl.g26_debug_flag) debug_current_and_destination(PSTR(" in move_to() doing last move"));
542 542
 
543 543
     ubl_line_to_destination(feed_value, 0);
544 544
 
545
-    //if (ubl.g26_debug_flag) debug_current_and_destination((char*)" in move_to() after last move");
545
+    //if (ubl.g26_debug_flag) debug_current_and_destination(PSTR(" in move_to() after last move"));
546 546
 
547 547
     stepper.synchronize();
548 548
     set_destination_to_current();
@@ -613,7 +613,7 @@
613 613
 
614 614
     //if (ubl.g26_debug_flag) {
615 615
     //  SERIAL_ECHOLNPGM("  doing printing move.");
616
-    //  debug_current_and_destination((char*)"doing final move_to() inside print_line_from_here_to_there()");
616
+    //  debug_current_and_destination(PSTR("doing final move_to() inside print_line_from_here_to_there()"));
617 617
     //}
618 618
     move_to(ex, ey, ez, e_pos_delta);  // Get to the ending point with an appropriate amount of extrusion
619 619
   }
@@ -771,7 +771,7 @@
771 771
           lcd_setstatuspgm(PSTR("G26 Heating Bed."), 99);
772 772
           lcd_quick_feedback();
773 773
       #endif
774
-          ubl.has_control_of_lcd_panel++;
774
+          ubl.has_control_of_lcd_panel = true;
775 775
           thermalManager.setTargetBed(bed_temp);
776 776
           while (abs(thermalManager.degBed() - bed_temp) > 3) {
777 777
             if (ubl_lcd_clicked()) return exit_from_g26();
@@ -808,7 +808,7 @@
808 808
 
809 809
     if (prime_flag == -1) {  // The user wants to control how much filament gets purged
810 810
 
811
-      ubl.has_control_of_lcd_panel++;
811
+      ubl.has_control_of_lcd_panel = true;
812 812
 
813 813
       lcd_setstatuspgm(PSTR("User-Controlled Prime"), 99);
814 814
       chirp_at_user();

+ 9
- 0
Marlin/Marlin.h View File

@@ -288,6 +288,13 @@ float code_value_temp_diff();
288 288
   void set_bed_leveling_enabled(bool enable=true);
289 289
 #endif
290 290
 
291
+#if ENABLED(AUTO_BED_LEVELING_UBL)
292
+struct linear_fit {
293
+	double A, B, D;
294
+};
295
+struct linear_fit *lsf_linear_fit( double *, double *, double *, int );
296
+#endif
297
+
291 298
 #if PLANNER_LEVELING
292 299
   void reset_bed_level();
293 300
 #endif
@@ -298,6 +305,8 @@ float code_value_temp_diff();
298 305
 
299 306
 #if HAS_BED_PROBE
300 307
   extern float zprobe_zoffset;
308
+  #define DEPLOY_PROBE() set_probe_deployed(true)
309
+  #define STOW_PROBE() set_probe_deployed(false)
301 310
 #endif
302 311
 
303 312
 #if ENABLED(HOST_KEEPALIVE_FEATURE)

+ 0
- 2
Marlin/Marlin_main.cpp View File

@@ -1983,8 +1983,6 @@ static void clean_up_after_endstop_or_probe_move() {
1983 1983
     #endif
1984 1984
   #endif
1985 1985
 
1986
-  #define DEPLOY_PROBE() set_probe_deployed(true)
1987
-  #define STOW_PROBE() set_probe_deployed(false)
1988 1986
 
1989 1987
   #if ENABLED(BLTOUCH)
1990 1988
     void bltouch_command(int angle) {

+ 110
- 0
Marlin/_Bootscreen.h View File

@@ -0,0 +1,110 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * Custom Bitmap for splashscreen
25
+ *
26
+ * You may use one of the following tools to generate the C++ bitmap array from
27
+ * a black and white image:
28
+ *
29
+ *  - http://www.marlinfw.org/tools/u8glib/converter.html
30
+ *  - http://www.digole.com/tools/PicturetoC_Hex_converter.php
31
+ */
32
+//custom screen can be up to 112 wide and 64 high
33
+
34
+#include <avr/pgmspace.h>
35
+
36
+#define CUSTOM_BOOTSCREEN_TIMEOUT   2500
37
+#define CUSTOM_BOOTSCREEN_BMPWIDTH  112
38
+#define CUSTOM_BOOTSCREEN_BMPHEIGHT 64
39
+
40
+// Width: 112, Height: 64
41
+const unsigned char custom_start_bmp[896] PROGMEM = {
42
+	0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
43
+	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
44
+	0x80, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
45
+	0x80, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
46
+	0x80, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
47
+	0x80, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
48
+	0x80, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
49
+	0x80, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
50
+	0x80, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
51
+	0x80, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01,
52
+	0x80, 0x00, 0x00, 0x01, 0xf9, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xc0, 0x01,
53
+	0x80, 0x00, 0x00, 0x06, 0x4d, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00, 0x01, 0xc0, 0x01,
54
+	0x80, 0x00, 0x00, 0x0c, 0x26, 0x00, 0x0e, 0xe7, 0x39, 0xd3, 0xe1, 0xf3, 0xe7, 0xc1,
55
+	0x80, 0x00, 0x00, 0x19, 0x12, 0x00, 0x0f, 0xe7, 0x39, 0xf7, 0xf3, 0xfb, 0xef, 0xe1,
56
+	0x80, 0x00, 0x00, 0x37, 0xce, 0x00, 0x0e, 0xe7, 0x01, 0xf7, 0x73, 0xb9, 0xce, 0xe1,
57
+	0x80, 0x00, 0x00, 0x64, 0x66, 0x00, 0x0e, 0xe7, 0x01, 0xc7, 0xf3, 0xb9, 0xcf, 0xe1,
58
+	0x80, 0x00, 0x00, 0x4b, 0xa6, 0x00, 0x0e, 0xe7, 0x39, 0xc7, 0xf0, 0xf9, 0xcf, 0xe1,
59
+	0x80, 0x00, 0x00, 0xca, 0xb4, 0x00, 0x0f, 0xe7, 0x39, 0xc7, 0x03, 0xf9, 0xce, 0x01,
60
+	0x80, 0x00, 0x00, 0xcd, 0xa4, 0x00, 0x06, 0xe7, 0x39, 0xc7, 0x73, 0xb9, 0xce, 0xe1,
61
+	0x80, 0x00, 0x03, 0xa6, 0x6c, 0x00, 0x00, 0xe7, 0x39, 0xc7, 0x73, 0xb9, 0xce, 0xe1,
62
+	0x80, 0x00, 0xff, 0x13, 0xd8, 0x00, 0x0e, 0xe3, 0xf1, 0xc7, 0xf3, 0xf9, 0xef, 0xe1,
63
+	0x80, 0x01, 0x21, 0x88, 0x18, 0x00, 0x0f, 0xe1, 0xe1, 0xc3, 0xe1, 0xb9, 0xe7, 0xc1,
64
+	0x80, 0x06, 0x61, 0x16, 0x30, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
65
+	0x80, 0x04, 0x41, 0x23, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
66
+	0x80, 0x04, 0xfe, 0x41, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
67
+	0x80, 0x0b, 0x86, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x1f, 0x80, 0x00, 0x00, 0x01,
68
+	0x80, 0x1e, 0x01, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x1f, 0x80, 0x00, 0x00, 0x01,
69
+	0x80, 0x1c, 0x07, 0x22, 0x00, 0x00, 0x07, 0xbc, 0x3f, 0x9f, 0x81, 0xf8, 0xf1, 0xe1,
70
+	0x80, 0x08, 0x1f, 0xe2, 0x00, 0x00, 0x0f, 0xfc, 0x3f, 0xbf, 0x87, 0xfe, 0x71, 0xc1,
71
+	0x80, 0x00, 0x33, 0x62, 0x00, 0x00, 0x0f, 0x3c, 0x3d, 0xb7, 0x87, 0x9e, 0x7b, 0xc1,
72
+	0x80, 0x00, 0xc2, 0x22, 0x00, 0x00, 0x0f, 0x3c, 0x3d, 0xb7, 0x87, 0x9e, 0x7b, 0xc1,
73
+	0x80, 0x00, 0xc2, 0x3e, 0x00, 0x00, 0x0f, 0x3c, 0x3d, 0xf7, 0x80, 0x7e, 0x3b, 0x81,
74
+	0x80, 0x01, 0xe6, 0x1e, 0x00, 0x00, 0x0f, 0x3c, 0x3d, 0xf7, 0x83, 0xfe, 0x3f, 0x81,
75
+	0x80, 0x01, 0x3c, 0x12, 0x00, 0x00, 0x0f, 0x3c, 0x3d, 0xf7, 0x87, 0x9e, 0x3b, 0x81,
76
+	0x80, 0x01, 0x1c, 0x26, 0x00, 0x00, 0x0f, 0xfc, 0x3d, 0xf7, 0x87, 0x9e, 0x7b, 0xc1,
77
+	0x80, 0x01, 0x70, 0x64, 0x00, 0x00, 0x07, 0xbc, 0x3c, 0xe7, 0x87, 0x9e, 0x7b, 0xc1,
78
+	0x80, 0x03, 0xc0, 0x58, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0xe7, 0x87, 0xfe, 0x71, 0xc1,
79
+	0x80, 0x0d, 0x80, 0xf0, 0x00, 0x00, 0x0f, 0x3c, 0x3c, 0xe7, 0x83, 0xde, 0xf1, 0xe1,
80
+	0x80, 0x1a, 0x00, 0xe0, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
81
+	0x80, 0x26, 0x00, 0x40, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
82
+	0x80, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
83
+	0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
84
+
85
+	0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1c, 0x03, 0xc0, 0x20, 0x10, 0x00, 0x01,
86
+	0x83, 0x24, 0x00, 0x00, 0x00, 0x00, 0x08, 0x92, 0x02, 0x20, 0x00, 0x10, 0x00, 0x01,
87
+	0x02, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x02, 0x23, 0x27, 0x39, 0x8c, 0xe1,
88
+	0x06, 0x38, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0x03, 0xc2, 0x24, 0x92, 0x49, 0x01,
89
+	0x04, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x02, 0x02, 0x24, 0x93, 0xc8, 0xc1,
90
+	0x0d, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x08, 0x92, 0x02, 0x02, 0x24, 0x92, 0x08, 0x21,
91
+	0x08, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1c, 0x02, 0x02, 0x24, 0x99, 0xc9, 0xc1,
92
+	0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
93
+
94
+	0x10, 0x30, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x0f, 0xe0, 0x0f, 0x00, 0x01,
95
+	0x30, 0x20, 0x00, 0x37, 0x00, 0x00, 0x00, 0x12, 0x24, 0x08, 0x10, 0x09, 0x00, 0x01,
96
+	0x20, 0x30, 0x00, 0x6d, 0x80, 0x00, 0x00, 0x12, 0x24, 0x09, 0x88, 0x09, 0x00, 0x01,
97
+	0x10, 0x18, 0x1f, 0x60, 0xc0, 0x00, 0x00, 0x12, 0x24, 0x09, 0x48, 0x09, 0x00, 0x01,
98
+	0x30, 0x0c, 0x39, 0xe0, 0x60, 0x00, 0x00, 0x12, 0x24, 0x09, 0x90, 0x09, 0x00, 0x01,
99
+	0x30, 0x07, 0x90, 0x70, 0x60, 0x00, 0x00, 0x12, 0x24, 0x08, 0x60, 0x09, 0x00, 0x01,
100
+	0x10, 0x16, 0xf0, 0x18, 0x20, 0x00, 0x00, 0x12, 0x24, 0x08, 0x10, 0x09, 0x00, 0x01,
101
+	0x1a, 0x10, 0x60, 0x08, 0x30, 0x00, 0x00, 0x12, 0x24, 0x09, 0xc8, 0x09, 0x00, 0x01,
102
+	0x0b, 0x09, 0x80, 0x00, 0x30, 0x00, 0x00, 0x12, 0x24, 0x09, 0x24, 0x09, 0x00, 0x01,
103
+	0x0e, 0x07, 0x80, 0x00, 0x10, 0x00, 0x00, 0x13, 0xe4, 0x89, 0xc4, 0x89, 0xf9, 0x01,
104
+	0x06, 0x1e, 0x40, 0x10, 0x10, 0x00, 0x00, 0x10, 0x05, 0xc8, 0x09, 0xc8, 0x0b, 0x81,
105
+	0x06, 0x00, 0x40, 0x20, 0x10, 0x00, 0x00, 0x0f, 0xf8, 0x8f, 0xf0, 0x8f, 0xf9, 0x01,
106
+	0x03, 0x80, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
107
+	0x01, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
108
+};
109
+
110
+

+ 134
- 0
Marlin/least_squares_fit.cpp View File

@@ -0,0 +1,134 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * Least Squares Best Fit  By Roxy and Ed Williams
25
+ *
26
+ * This algorythm is high speed and has a very small code footprint.
27
+ * Its results are identical to both the Iterative Least Squares published
28
+ * earlier by Roxy and the QR_SOLVE solution.   If used in place of QR_SOLVE
29
+ * it saves roughly 10KB of program memory.
30
+ *
31
+ */
32
+
33
+#include "MarlinConfig.h"
34
+
35
+#if ENABLED(AUTO_BED_LEVELING_UBL)
36
+  #include <math.h>
37
+  #include "UBL.h"
38
+  #include "Marlin.h"
39
+
40
+double linear_fit_average(double *, int);
41
+double linear_fit_average_squared(double *, int);
42
+double linear_fit_average_mixed_terms(double *, double *, int );
43
+double linear_fit_average_product(double *matrix1, double *matrix2, int n);
44
+void   linear_fit_subtract_mean(double *matrix, double bar, int n);
45
+double linear_fit_max_abs(double *, int);
46
+
47
+struct linear_fit linear_fit_results;
48
+
49
+struct linear_fit *lsf_linear_fit(double *x, double *y, double *z, int n) {
50
+	double xbar, ybar, zbar;
51
+	double x2bar, y2bar;
52
+	double xybar, xzbar, yzbar;
53
+	double D;
54
+	int i;
55
+
56
+	linear_fit_results.A = 0.0;
57
+	linear_fit_results.B = 0.0;
58
+	linear_fit_results.D = 0.0;
59
+
60
+	xbar = linear_fit_average(x, n);
61
+	ybar = linear_fit_average(y, n);
62
+	zbar = linear_fit_average(z, n);
63
+
64
+	linear_fit_subtract_mean( x, xbar, n);
65
+	linear_fit_subtract_mean( y, ybar, n);
66
+	linear_fit_subtract_mean( z, zbar, n);
67
+
68
+	x2bar = linear_fit_average_product( x, x, n);
69
+	y2bar = linear_fit_average_product( y, y, n);
70
+	xybar =	linear_fit_average_product( x, y, n);
71
+	xzbar =	linear_fit_average_product( x, z, n);
72
+	yzbar =	linear_fit_average_product( y, z, n);
73
+
74
+	D = x2bar*y2bar - xybar*xybar;
75
+	for(i=0; i<n; i++) {
76
+		if (fabs(D) <= 1e-15*( linear_fit_max_abs(x, n) + linear_fit_max_abs(y, n))) {
77
+			printf( "error: x,y points are collinear at index:%d \n", i );
78
+			return NULL;
79
+		}
80
+	}
81
+
82
+	linear_fit_results.A = -(xzbar*y2bar - yzbar*xybar) / D;
83
+	linear_fit_results.B = -(yzbar*x2bar - xzbar*xybar) / D;
84
+//	linear_fit_results.D = -(zbar - linear_fit_results->A*xbar - linear_fit_results->B*ybar);
85
+	linear_fit_results.D = -(zbar + linear_fit_results.A*xbar + linear_fit_results.B*ybar);
86
+
87
+	return &linear_fit_results;
88
+}
89
+
90
+
91
+
92
+
93
+double linear_fit_average(double *matrix, int n)
94
+{
95
+	int i;
96
+	double sum=0.0;
97
+
98
+	for (i = 0; i < n; i++)
99
+		sum += matrix[i];
100
+	return sum / (double) n;
101
+}
102
+
103
+double linear_fit_average_product(double *matrix1, double *matrix2, int n) {
104
+	int i;
105
+	double sum = 0.0;
106
+
107
+	for (i = 0; i < n; i++)
108
+		sum += matrix1[i] * matrix2[i];
109
+	return sum / (double) n;
110
+}
111
+
112
+
113
+
114
+void linear_fit_subtract_mean(double *matrix, double bar, int n) {
115
+	int i;
116
+
117
+	for (i = 0; i < n; i++) {
118
+		matrix[i] -= bar;
119
+	}
120
+	return;
121
+}
122
+
123
+double linear_fit_max_abs(double *matrix, int n) {
124
+	int i;
125
+	double max_abs = 0.0;
126
+
127
+	for(i=0; i<n; i++)
128
+		if ( max_abs < fabs(matrix[i]))
129
+			max_abs = fabs(matrix[i]);
130
+	return max_abs;
131
+}
132
+#endif
133
+
134
+

+ 5
- 14
Marlin/ubl.cpp View File

@@ -47,7 +47,7 @@
47 47
     safe_delay(10);
48 48
   }
49 49
 
50
-  static void serial_echo_10x_spaces() {
50
+  static void serial_echo_11x_spaces() {
51 51
     for (uint8_t i = GRID_MAX_POINTS_X - 1; --i;) {
52 52
       SERIAL_ECHOPGM("          ");
53 53
       #if TX_BUFFER_SIZE > 0
@@ -92,15 +92,6 @@
92 92
       SERIAL_PROTOCOLLNPGM("?In load_state() sanity_check() failed.\n");
93 93
 
94 94
     #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
95
-      /**
96
-       * These lines can go away in a few weeks.  They are just
97
-       * to make sure people updating their firmware won't be using
98
-       * an incomplete Bed_Leveling.state structure. For speed
99
-       * we now multiply by the inverse of the Fade Height instead of
100
-       * dividing by it. Soon... all of the old structures will be
101
-       * updated, but until then, we try to ease the transition
102
-       * for our Beta testers.
103
-       */
104 95
       const float recip = ubl.state.g29_correction_fade_height ? 1.0 / ubl.state.g29_correction_fade_height : 1.0;
105 96
       if (ubl.state.g29_fade_height_multiplier != recip) {
106 97
         ubl.state.g29_fade_height_multiplier = recip;
@@ -181,11 +172,11 @@
181 172
     }
182 173
 
183 174
     if (map0) {
184
-      serial_echo_10x_spaces();
175
+      serial_echo_11x_spaces();
185 176
       serial_echo_xy(GRID_MAX_POINTS_X - 1, GRID_MAX_POINTS_Y - 1);
186 177
       SERIAL_EOL;
187 178
       serial_echo_xy(UBL_MESH_MIN_X, UBL_MESH_MIN_Y);
188
-      serial_echo_10x_spaces();
179
+      serial_echo_11x_spaces();
189 180
       serial_echo_xy(UBL_MESH_MAX_X, UBL_MESH_MAX_Y);
190 181
       SERIAL_EOL;
191 182
     }
@@ -231,12 +222,12 @@
231 222
     if (map0) {
232 223
       serial_echo_xy(UBL_MESH_MIN_X, UBL_MESH_MIN_Y);
233 224
       SERIAL_ECHOPGM("    ");
234
-      serial_echo_10x_spaces();
225
+      serial_echo_11x_spaces();
235 226
       serial_echo_xy(UBL_MESH_MAX_X, UBL_MESH_MIN_Y);
236 227
       SERIAL_EOL;
237 228
       serial_echo_xy(0, 0);
238 229
       SERIAL_ECHOPGM("       ");
239
-      serial_echo_10x_spaces();
230
+      serial_echo_11x_spaces();
240 231
       serial_echo_xy(GRID_MAX_POINTS_X - 1, 0);
241 232
       SERIAL_EOL;
242 233
     }

+ 209
- 12
Marlin/ubl_G29.cpp View File

@@ -40,6 +40,7 @@
40 40
   bool lcd_clicked();
41 41
   void lcd_implementation_clear();
42 42
   void lcd_mesh_edit_setup(float initial);
43
+  void tilt_mesh_based_on_probed_grid( const bool );
43 44
   float lcd_mesh_edit();
44 45
   void lcd_z_offset_edit_setup(float);
45 46
   float lcd_z_offset_edit();
@@ -50,8 +51,7 @@
50 51
   extern bool code_has_value();
51 52
   extern float probe_pt(float x, float y, bool, int);
52 53
   extern bool set_probe_deployed(bool);
53
-  #define DEPLOY_PROBE() set_probe_deployed(true)
54
-  #define STOW_PROBE() set_probe_deployed(false)
54
+ 
55 55
   bool ProbeStay = true;
56 56
 
57 57
   constexpr float ubl_3_point_1_X = UBL_PROBE_PT_1_X,
@@ -302,7 +302,7 @@
302 302
 
303 303
   // The simple parameter flags and values are 'static' so parameter parsing can be in a support routine.
304 304
   static int g29_verbose_level, phase_value = -1, repetition_cnt,
305
-             storage_slot = 0, map_type; //unlevel_value = -1;
305
+             storage_slot = 0, map_type, grid_size_G ; //unlevel_value = -1;
306 306
   static bool repeat_flag, c_flag, x_flag, y_flag;
307 307
   static float x_pos, y_pos, measured_z, card_thickness = 0.0, ubl_constant = 0.0;
308 308
 
@@ -385,7 +385,20 @@
385 385
       //  return;
386 386
       //}
387 387
     }
388
-    //*/
388
+    */
389
+
390
+    if (code_seen('G')) {
391
+      uint8_t grid_size_G = code_has_value() ? code_value_int() : 3;
392
+      if (grid_size_G < 2) {
393
+        SERIAL_PROTOCOLLNPGM("ERROR - grid size must be 2 or more");
394
+        return;
395
+      }
396
+      if (grid_size_G > GRID_MAX_POINTS_X || grid_size_G > GRID_MAX_POINTS_Y ) {
397
+        SERIAL_PROTOCOLLNPGM("ERROR - grid size can NOT exceed GRID_MAX_POINTS_X nor GRID_MAX_POINTS_Y");
398
+        return;
399
+      }
400
+      tilt_mesh_based_on_probed_grid( code_seen('O')||code_seen('M'));
401
+    }
389 402
 
390 403
     if (code_seen('P')) {
391 404
       phase_value = code_value_int();
@@ -488,7 +501,7 @@
488 501
           SERIAL_ECHO_START;
489 502
           SERIAL_ECHOLNPGM("Checking G29 has control of LCD Panel:");
490 503
           KEEPALIVE_STATE(PAUSED_FOR_USER);
491
-          ubl.has_control_of_lcd_panel++;
504
+          ubl.has_control_of_lcd_panel = true;
492 505
           while (!ubl_lcd_clicked()) {
493 506
             safe_delay(250);
494 507
             if (ubl.encoder_diff) {
@@ -630,7 +643,7 @@
630 643
         save_ubl_active_state_and_disable();
631 644
         //measured_z = probe_pt(x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER, ProbeDeployAndStow, g29_verbose_level);
632 645
 
633
-        ubl.has_control_of_lcd_panel++;     // Grab the LCD Hardware
646
+        ubl.has_control_of_lcd_panel = true;     // Grab the LCD Hardware
634 647
         measured_z = 1.5;
635 648
         do_blocking_move_to_z(measured_z);  // Get close to the bed, but leave some space so we don't damage anything
636 649
                                             // The user is not going to be locking in a new Z-Offset very often so
@@ -646,7 +659,7 @@
646 659
           do_blocking_move_to_z(measured_z);
647 660
         } while (!ubl_lcd_clicked());
648 661
 
649
-        ubl.has_control_of_lcd_panel++;   // There is a race condition for the Encoder Wheel getting clicked.
662
+        ubl.has_control_of_lcd_panel = true;   // There is a race condition for the Encoder Wheel getting clicked.
650 663
                                           // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune)
651 664
                                           // or here. So, until we are done looking for a long Encoder Wheel Press,
652 665
                                           // we need to take control of the panel
@@ -744,7 +757,7 @@
744 757
   void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest) {
745 758
     mesh_index_pair location;
746 759
 
747
-    ubl.has_control_of_lcd_panel++;
760
+    ubl.has_control_of_lcd_panel = true;
748 761
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
749 762
     DEPLOY_PROBE();
750 763
 
@@ -872,7 +885,7 @@
872 885
 
873 886
   float measure_business_card_thickness(const float &in_height) {
874 887
 
875
-    ubl.has_control_of_lcd_panel++;
888
+    ubl.has_control_of_lcd_panel = true;
876 889
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
877 890
 
878 891
     SERIAL_PROTOCOLLNPGM("Place Shim Under Nozzle and Perform Measurement.");
@@ -899,7 +912,7 @@
899 912
 
900 913
   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) {
901 914
 
902
-    ubl.has_control_of_lcd_panel++;
915
+    ubl.has_control_of_lcd_panel = true;
903 916
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
904 917
     do_blocking_move_to_z(z_clearance);
905 918
     do_blocking_move_to_xy(lx, ly);
@@ -994,6 +1007,16 @@
994 1007
       return UBL_ERR;
995 1008
     }
996 1009
 
1010
+    if (code_seen('G')) {
1011
+      grid_size_G = 3;
1012
+      if (code_has_value())
1013
+        grid_size_G = code_value_int();
1014
+      if (!WITHIN(grid_size_G, 2, 10)) {
1015
+        SERIAL_PROTOCOLLNPGM("Invalid grid probe points specified.\n");
1016
+        return UBL_ERR;
1017
+      }
1018
+    }
1019
+
997 1020
     x_flag = code_seen('X') && code_has_value();
998 1021
     x_pos = x_flag ? code_value_float() : current_position[X_AXIS];
999 1022
     if (!WITHIN(RAW_X_POSITION(x_pos), X_MIN_POS, X_MAX_POS)) {
@@ -1053,7 +1076,6 @@
1053 1076
       return UBL_ERR;
1054 1077
     }
1055 1078
 
1056
-    /*
1057 1079
     if (code_seen('M')) {     // Check if a map type was specified
1058 1080
       map_type = code_has_value() ? code_value_int() : 0;
1059 1081
       if (!WITHIN(map_type, 0, 1)) {
@@ -1061,7 +1083,6 @@
1061 1083
         return UBL_ERR;
1062 1084
       }
1063 1085
     }
1064
-    //*/
1065 1086
 
1066 1087
     return UBL_OK;
1067 1088
   }
@@ -1070,6 +1091,7 @@
1070 1091
    * This function goes away after G29 debug is complete. But for right now, it is a handy
1071 1092
    * routine to dump binary data structures.
1072 1093
    */
1094
+/*
1073 1095
   void dump(char * const str, const float &f) {
1074 1096
     char *ptr;
1075 1097
 
@@ -1087,6 +1109,7 @@
1087 1109
 
1088 1110
     SERIAL_EOL;
1089 1111
   }
1112
+*/
1090 1113
 
1091 1114
   static int ubl_state_at_invocation = 0,
1092 1115
              ubl_state_recursion_chk = 0;
@@ -1438,4 +1461,178 @@
1438 1461
     SERIAL_ECHOLNPGM("Done Editing Mesh");
1439 1462
   }
1440 1463
 
1464
+
1465
+  void tilt_mesh_based_on_probed_grid( const bool do_ubl_mesh_map) {
1466
+      int8_t grid_G_index_to_xpos[grid_size_G];  //  UBL MESH X index to be probed
1467
+      int8_t grid_G_index_to_ypos[grid_size_G];  //  UBL MESH Y index to be probed
1468
+      int8_t i, j ,k, xCount, yCount, G_X_index, G_Y_index;  // counter variables
1469
+      float z_values_G[grid_size_G][grid_size_G];
1470
+
1471
+      struct linear_fit *results;
1472
+
1473
+      for (G_Y_index = 0; G_Y_index < grid_size_G; G_Y_index++)
1474
+       for (G_X_index = 0; G_X_index < grid_size_G; G_X_index++)
1475
+        z_values_G[G_X_index][G_Y_index] = NAN;
1476
+      
1477
+      uint8_t x_min = GRID_MAX_POINTS_X - 1;
1478
+      uint8_t x_max = 0;
1479
+      uint8_t y_min = GRID_MAX_POINTS_Y - 1;
1480
+      uint8_t y_max = 0;
1481
+      
1482
+      //find min & max probeable points in the mesh
1483
+      for (xCount = 0; xCount < GRID_MAX_POINTS_X ; xCount++) {
1484
+        for (yCount = 0; yCount < GRID_MAX_POINTS_Y ; yCount++) {
1485
+          if (WITHIN(ubl.mesh_index_to_xpos[xCount], MIN_PROBE_X, MAX_PROBE_X) && WITHIN(ubl.mesh_index_to_ypos[yCount], MIN_PROBE_Y, MAX_PROBE_Y)) {
1486
+            if (x_min > xCount) x_min = xCount;
1487
+            if (x_max < xCount) x_max = xCount;
1488
+            if (y_min > yCount) y_min = yCount;
1489
+            if (y_max < yCount) y_max = yCount;
1490
+          }
1491
+        }
1492
+      }
1493
+      
1494
+      if ((x_max - x_min + 1) < (grid_size_G) || (y_max - y_min + 1) < (grid_size_G)) {
1495
+        SERIAL_PROTOCOLPAIR("ERROR - probeable UBL MESH smaller than grid - X points: ", x_max - x_min + 1);
1496
+        SERIAL_PROTOCOLPAIR("  Y points: ", y_max - y_min + 1);
1497
+        SERIAL_PROTOCOLLNPAIR("  grid: ", grid_size_G);
1498
+        return;
1499
+      }
1500
+      
1501
+      // populate X matrix
1502
+      for (G_X_index = 0; G_X_index < grid_size_G; G_X_index++) {
1503
+        grid_G_index_to_xpos[G_X_index] = x_min + G_X_index * (x_max - x_min)/(grid_size_G - 1);
1504
+        if (G_X_index > 0 && grid_G_index_to_xpos[G_X_index - 1] == grid_G_index_to_xpos[G_X_index] ) {
1505
+          grid_G_index_to_xpos[G_X_index] = grid_G_index_to_xpos[G_X_index - 1] + 1;
1506
+        }
1507
+      }
1508
+      
1509
+      // populate Y matrix
1510
+      for (G_Y_index = 0; G_Y_index < grid_size_G; G_Y_index++) {
1511
+        grid_G_index_to_ypos[G_Y_index] = y_min + G_Y_index * (y_max - y_min)/(grid_size_G - 1);
1512
+        if (G_Y_index > 0 && grid_G_index_to_ypos[G_Y_index -1] == grid_G_index_to_ypos[G_Y_index] ) {
1513
+          grid_G_index_to_ypos[G_Y_index] = grid_G_index_to_ypos[G_Y_index - 1] + 1;
1514
+        }
1515
+      }
1516
+      
1517
+      ubl.has_control_of_lcd_panel = true;
1518
+      save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
1519
+      
1520
+      DEPLOY_PROBE();
1521
+      
1522
+      // this is a copy of the G29 AUTO_BED_LEVELING_BILINEAR method/code
1523
+      #undef PROBE_Y_FIRST
1524
+      #if ENABLED(PROBE_Y_FIRST)
1525
+        #define PR_OUTER_VAR xCount
1526
+        #define PR_OUTER_NUM grid_size_G
1527
+        #define PR_INNER_VAR yCount
1528
+        #define PR_INNER_NUM grid_size_G
1529
+        #else
1530
+        #define PR_OUTER_VAR yCount
1531
+        #define PR_OUTER_NUM grid_size_G
1532
+        #define PR_INNER_VAR xCount
1533
+        #define PR_INNER_NUM grid_size_G
1534
+      #endif
1535
+      
1536
+      bool zig = PR_OUTER_NUM & 1;  // Always end at RIGHT and BACK_PROBE_BED_POSITION
1537
+      
1538
+      // Outer loop is Y with PROBE_Y_FIRST disabled
1539
+      for (PR_OUTER_VAR = 0; PR_OUTER_VAR < PR_OUTER_NUM; PR_OUTER_VAR++) {
1540
+        
1541
+        int8_t inStart, inStop, inInc;
1542
+        
1543
+SERIAL_PROTOCOLPAIR("\nPR_OUTER_VAR: ", PR_OUTER_VAR);
1544
+
1545
+        if (zig) { // away from origin
1546
+          inStart = 0;
1547
+          inStop = PR_INNER_NUM;
1548
+          inInc = 1;
1549
+        }
1550
+        else {     // towards origin
1551
+          inStart = PR_INNER_NUM - 1;
1552
+          inStop = -1;
1553
+          inInc = -1;
1554
+        }
1555
+        
1556
+        zig = !zig; // zag
1557
+        
1558
+        // Inner loop is Y with PROBE_Y_FIRST enabled
1559
+        for (PR_INNER_VAR = inStart; PR_INNER_VAR != inStop; PR_INNER_VAR += inInc) {
1560
+SERIAL_PROTOCOLPAIR("\nPR_INNER_VAR: ", PR_INNER_VAR);
1561
+
1562
+SERIAL_PROTOCOLPAIR("\nCheckpoint: ", 1);
1563
+          
1564
+          // end of G29 AUTO_BED_LEVELING_BILINEAR method/code
1565
+          if (ubl_lcd_clicked()) {
1566
+SERIAL_PROTOCOLPAIR("\nCheckpoint: ", 2);
1567
+            SERIAL_PROTOCOLLNPGM("\nGrid only partially populated.\n");
1568
+            lcd_quick_feedback();
1569
+            STOW_PROBE();
1570
+SERIAL_PROTOCOLPAIR("\nCheckpoint: ", 3);
1571
+            while (ubl_lcd_clicked()) idle();
1572
+SERIAL_PROTOCOLPAIR("\nCheckpoint: ", 4);
1573
+              ubl.has_control_of_lcd_panel = false;
1574
+              restore_ubl_active_state_and_leave();
1575
+              safe_delay(50);  // Debounce the Encoder wheel
1576
+              return;
1577
+            }
1578
+SERIAL_PROTOCOLPAIR("\nCheckpoint: ", 5);
1579
+          
1580
+          const float probeX = ubl.mesh_index_to_xpos[grid_G_index_to_xpos[xCount]],  //where we want the probe to be
1581
+          probeY = ubl.mesh_index_to_ypos[grid_G_index_to_ypos[yCount]];
1582
+SERIAL_PROTOCOLPAIR("\nCheckpoint: ", 6);
1583
+          
1584
+          const float measured_z = probe_pt(LOGICAL_X_POSITION(probeX), LOGICAL_Y_POSITION(probeY), code_seen('E'), (code_seen('V') && code_has_value()) ? code_value_int() : 0 );  // takes into account the offsets
1585
+
1586
+SERIAL_PROTOCOLPAIR("\nmeasured_z: ", measured_z );
1587
+
1588
+          z_values_G[xCount][yCount] = measured_z;
1589
+//SERIAL_PROTOCOLLNPGM("\nFine Tuning of Mesh Stopped.");
1590
+        }
1591
+      }
1592
+      
1593
+SERIAL_PROTOCOL("\nDone probing...\n");
1594
+
1595
+      STOW_PROBE();
1596
+      restore_ubl_active_state_and_leave();
1597
+
1598
+// ??      ubl.has_control_of_lcd_panel = true;
1599
+//    do_blocking_move_to_xy(ubl.mesh_index_to_xpos[grid_G_index_to_xpos[0]], ubl.mesh_index_to_ypos[grid_G_index_to_ypos[0]]);
1600
+      
1601
+      // least squares code
1602
+double xxx9[] = { 0,50,100,150,200,           20,70,120,165,195,         0,50,100,150,200,           0,55,100,150,200,           0,65,100,150,205 };
1603
+double yyy9[] = { 0, 1,  2,  3, 4,            50, 51,  52,  53, 54,     100, 101,102,103,104,        150,151,152,153,154,        200,201,202,203,204 };
1604
+double zzz9[] = { 0.01,.002,-.01,-.02,0,      0.01,.002,-.01,-.02,0,     0.01,.002,-.01,-.02,0,      0.01,.002,-.01,-.02,0,      0.01,.002,-.01,-.012,0.01};
1605
+int nine_size = sizeof(xxx9) / sizeof(double);
1606
+
1607
+double xxx0[] = { 0.0, 0.0, 1.0 };	// Expect [0,0,0.1,0]
1608
+double yyy0[] = { 0.0, 1.0, 0.0 };
1609
+double zzz0[] = { 0.1, 0.1, 0.1 };
1610
+int zero_size = sizeof(xxx0) / sizeof(double);
1611
+
1612
+double xxx[] = { 0.0, 0.0, 1.0, 1.0 };	// Expect [0.1,0,0.05,0]
1613
+double yyy[] = { 0.0, 1.0, 0.0, 1.0 };
1614
+double zzz[] = { 0.05, 0.05, 0.15, 0.15 };      
1615
+int three_size = sizeof(xxx) / sizeof(double);
1616
+
1617
+      results = lsf_linear_fit(xxx9, yyy9, zzz9, nine_size);
1618
+SERIAL_PROTOCOLPAIR("\nxxx9->A =", results->A); 
1619
+SERIAL_PROTOCOLPAIR("\nxxx9->B =", results->B); 
1620
+SERIAL_PROTOCOLPAIR("\nxxx9->D =", results->D); 
1621
+SERIAL_PROTOCOL("\n");
1622
+
1623
+      results = lsf_linear_fit(xxx0, yyy0, zzz0, zero_size);
1624
+SERIAL_PROTOCOLPAIR("\nxxx0->A =", results->A); 
1625
+SERIAL_PROTOCOLPAIR("\nxxx0->B =", results->B); 
1626
+SERIAL_PROTOCOLPAIR("\nxxx0->D =", results->D); 
1627
+SERIAL_PROTOCOL("\n");
1628
+
1629
+      results = lsf_linear_fit(xxx, yyy, zzz, three_size);
1630
+SERIAL_PROTOCOLPAIR("\nxxx->A =", results->A); 
1631
+SERIAL_PROTOCOLPAIR("\nxxx->B =", results->B); 
1632
+SERIAL_PROTOCOLPAIR("\nxxx->D =", results->D); 
1633
+SERIAL_PROTOCOL("\n");
1634
+
1635
+      return;
1636
+    }  // end of tilt_mesh_based_on_probed_grid()
1637
+
1441 1638
 #endif // AUTO_BED_LEVELING_UBL

+ 18
- 23
Marlin/ubl_motion.cpp View File

@@ -39,7 +39,7 @@
39 39
       SERIAL_ECHO_F(destination[X_AXIS], 6);
40 40
   }
41 41
 
42
-  void debug_current_and_destination(char *title) {
42
+  void debug_current_and_destination(const char *title) {
43 43
 
44 44
     // if the title message starts with a '!' it is so important, we are going to
45 45
     // ignore the status of the g26_debug_flag
@@ -85,12 +85,6 @@
85 85
     SERIAL_ECHO(title);
86 86
     SERIAL_EOL;
87 87
 
88
-    SET_INPUT_PULLUP(66); // Roxy's Left Switch is on pin 66.  Right Switch is on pin 65
89
-
90
-    //if (been_to_2_6) {
91
-    //while ((digitalRead(66) & 0x01) != 0)
92
-    //  idle();
93
-    //}
94 88
   }
95 89
 
96 90
   void ubl_line_to_destination(const float &feed_rate, uint8_t extruder) {
@@ -124,7 +118,7 @@
124 118
       SERIAL_ECHOPAIR(", ee=", end[E_AXIS]);
125 119
       SERIAL_CHAR(')');
126 120
       SERIAL_EOL;
127
-      debug_current_and_destination((char*)"Start of ubl_line_to_destination()");
121
+      debug_current_and_destination(PSTR("Start of ubl_line_to_destination()"));
128 122
     }
129 123
 
130 124
     if (cell_start_xi == cell_dest_xi && cell_start_yi == cell_dest_yi) { // if the whole move is within the same cell,
@@ -144,7 +138,7 @@
144 138
         set_current_to_destination();
145 139
 
146 140
         if (ubl.g26_debug_flag)
147
-          debug_current_and_destination((char*)"out of bounds in ubl_line_to_destination()");
141
+          debug_current_and_destination(PSTR("out of bounds in ubl_line_to_destination()"));
148 142
 
149 143
         return;
150 144
       }
@@ -181,7 +175,7 @@
181 175
         z_optimized = z0;
182 176
         z0 = ubl.get_z_correction(end[X_AXIS], end[Y_AXIS]);
183 177
         if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
184
-        debug_current_and_destination((char*)"FINAL_MOVE: z_correction()");
178
+        debug_current_and_destination(PSTR("FINAL_MOVE: z_correction()"));
185 179
         if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
186 180
         if (isnan(z_optimized)) SERIAL_ECHO(" z_optimized==NAN  ");
187 181
         SERIAL_ECHOPAIR("  end[X_AXIS]=", end[X_AXIS]);
@@ -191,7 +185,8 @@
191 185
         SERIAL_ECHOPAIR("  err=",fabs(z_optimized - z0));
192 186
         SERIAL_EOL;
193 187
         }
194
-      //*/
188
+      */
189
+
195 190
       z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
196 191
 
197 192
       /**
@@ -206,7 +201,7 @@
206 201
       planner.buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z0 + ubl.state.z_offset, end[E_AXIS], feed_rate, extruder);
207 202
 
208 203
       if (ubl.g26_debug_flag)
209
-        debug_current_and_destination((char*)"FINAL_MOVE in ubl_line_to_destination()");
204
+        debug_current_and_destination(PSTR("FINAL_MOVE in ubl_line_to_destination()"));
210 205
 
211 206
       set_current_to_destination();
212 207
       return;
@@ -286,7 +281,7 @@
286 281
           z_optimized = z0;
287 282
           z0 = ubl.get_z_correction(x, next_mesh_line_y);
288 283
           if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
289
-            debug_current_and_destination((char*)"VERTICAL z_correction()");
284
+            debug_current_and_destination(PSTR("VERTICAL z_correction()"));
290 285
           if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
291 286
             if (isnan(z_optimized)) SERIAL_ECHO(" z_optimized==NAN  ");
292 287
           SERIAL_ECHOPAIR("  x=", x);
@@ -296,7 +291,7 @@
296 291
           SERIAL_ECHOPAIR("  err=",fabs(z_optimized-z0));
297 292
           SERIAL_ECHO("\n");
298 293
           }
299
-        //*/
294
+        */
300 295
 
301 296
         z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
302 297
 
@@ -333,7 +328,7 @@
333 328
       }
334 329
 
335 330
       if (ubl.g26_debug_flag)
336
-        debug_current_and_destination((char*)"vertical move done in ubl_line_to_destination()");
331
+        debug_current_and_destination(PSTR("vertical move done in ubl_line_to_destination()"));
337 332
 
338 333
       //
339 334
       // Check if we are at the final destination. Usually, we won't be, but if it is on a Y Mesh Line, we are done.
@@ -371,7 +366,7 @@
371 366
           z_optimized = z0;
372 367
           z0 = ubl.get_z_correction(next_mesh_line_x, y);
373 368
           if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
374
-            debug_current_and_destination((char*)"HORIZONTAL z_correction()");
369
+            debug_current_and_destination(PSTR("HORIZONTAL z_correction()"));
375 370
           if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
376 371
             if (isnan(z_optimized)) SERIAL_ECHO(" z_optimized==NAN  ");
377 372
           SERIAL_ECHOPAIR("  next_mesh_line_x=", next_mesh_line_x);
@@ -381,7 +376,7 @@
381 376
           SERIAL_ECHOPAIR("  err=",fabs(z_optimized-z0));
382 377
           SERIAL_ECHO("\n");
383 378
           }
384
-        //*/
379
+        */
385 380
 
386 381
         z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
387 382
 
@@ -418,7 +413,7 @@
418 413
       }
419 414
 
420 415
       if (ubl.g26_debug_flag)
421
-        debug_current_and_destination((char*)"horizontal move done in ubl_line_to_destination()");
416
+        debug_current_and_destination(PSTR("horizontal move done in ubl_line_to_destination()"));
422 417
 
423 418
       if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
424 419
         goto FINAL_MOVE;
@@ -466,7 +461,7 @@
466 461
           z_optimized = z0;
467 462
           z0 = ubl.get_z_correction(x, next_mesh_line_y);
468 463
           if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
469
-            debug_current_and_destination((char*)"General_1: z_correction()");
464
+            debug_current_and_destination(PSTR("General_1: z_correction()"));
470 465
             if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
471 466
             if (isnan(z_optimized)) SERIAL_ECHO(" z_optimized==NAN  "); {
472 467
               SERIAL_ECHOPAIR("  x=", x);
@@ -477,7 +472,7 @@
477 472
             SERIAL_ECHOPAIR("  err=",fabs(z_optimized-z0));
478 473
             SERIAL_ECHO("\n");
479 474
           }
480
-        //*/
475
+        */
481 476
 
482 477
         z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
483 478
 
@@ -517,7 +512,7 @@
517 512
           z_optimized = z0;
518 513
           z0 = ubl.get_z_correction(next_mesh_line_x, y);
519 514
           if (fabs(z_optimized - z0) > .01 || isnan(z0) || isnan(z_optimized)) {
520
-          debug_current_and_destination((char*)"General_2: z_correction()");
515
+          debug_current_and_destination(PSTR("General_2: z_correction()"));
521 516
           if (isnan(z0)) SERIAL_ECHO(" z0==NAN  ");
522 517
           if (isnan(z_optimized)) SERIAL_ECHO(" z_optimized==NAN  ");
523 518
           SERIAL_ECHOPAIR("  next_mesh_line_x=", next_mesh_line_x);
@@ -527,7 +522,7 @@
527 522
           SERIAL_ECHOPAIR("  err=",fabs(z_optimized-z0));
528 523
           SERIAL_ECHO("\n");
529 524
           }
530
-        //*/
525
+        */
531 526
 
532 527
         z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
533 528
 
@@ -557,7 +552,7 @@
557 552
     }
558 553
 
559 554
     if (ubl.g26_debug_flag)
560
-      debug_current_and_destination((char*)"generic move done in ubl_line_to_destination()");
555
+      debug_current_and_destination(PSTR("generic move done in ubl_line_to_destination()"));
561 556
 
562 557
     if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
563 558
       goto FINAL_MOVE;

Loading…
Cancel
Save