Browse Source

Merge pull request #796 from MissionSt/any-pt-abl

Auto bed leveling at arbitrary points
alexborro 11 years ago
parent
commit
d3fcc28e64
4 changed files with 85 additions and 63 deletions
  1. 44
    15
      Marlin/Configuration.h
  2. 39
    44
      Marlin/Marlin_main.cpp
  3. 1
    3
      Marlin/qr_solve.cpp
  4. 1
    1
      Marlin/qr_solve.h

+ 44
- 15
Marlin/Configuration.h View File

@@ -335,11 +335,49 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
335 335
 
336 336
 #ifdef ENABLE_AUTO_BED_LEVELING
337 337
 
338
-  // these are the positions on the bed to do the probing
339
-  #define LEFT_PROBE_BED_POSITION 15
340
-  #define RIGHT_PROBE_BED_POSITION 170
341
-  #define BACK_PROBE_BED_POSITION 180
342
-  #define FRONT_PROBE_BED_POSITION 20
338
+// There are 2 different ways to pick the X and Y locations to probe:
339
+
340
+//  - "grid" mode
341
+//    Probe every point in a rectangular grid
342
+//    You must specify the rectangle, and the density of sample points
343
+//    This mode is preferred because there are more measurements.
344
+//    It used to be called ACCURATE_BED_LEVELING but "grid" is more descriptive
345
+
346
+//  - "3-point" mode
347
+//    Probe 3 arbitrary points on the bed (that aren't colinear)
348
+//    You must specify the X & Y coordinates of all 3 points
349
+
350
+  #define AUTO_BED_LEVELING_GRID
351
+  // with AUTO_BED_LEVELING_GRID, the bed is sampled in a
352
+  // AUTO_BED_LEVELING_GRID_POINTSxAUTO_BED_LEVELING_GRID_POINTS grid
353
+  // and least squares solution is calculated
354
+  // Note: this feature occupies 10'206 byte
355
+  #ifdef AUTO_BED_LEVELING_GRID
356
+
357
+    // set the rectangle in which to probe
358
+    #define LEFT_PROBE_BED_POSITION 15
359
+    #define RIGHT_PROBE_BED_POSITION 170
360
+    #define BACK_PROBE_BED_POSITION 180
361
+    #define FRONT_PROBE_BED_POSITION 20
362
+
363
+     // set the number of grid points per dimension
364
+     // I wouldn't see a reason to go above 3 (=9 probing points on the bed)
365
+    #define AUTO_BED_LEVELING_GRID_POINTS 2
366
+
367
+
368
+  #else  // not AUTO_BED_LEVELING_GRID
369
+    // with no grid, just probe 3 arbitrary points.  A simple cross-product
370
+    // is used to esimate the plane of the print bed
371
+
372
+      #define ABL_PROBE_PT_1_X 15
373
+      #define ABL_PROBE_PT_1_Y 180
374
+      #define ABL_PROBE_PT_2_X 15
375
+      #define ABL_PROBE_PT_2_Y 20
376
+      #define ABL_PROBE_PT_3_X 170
377
+      #define ABL_PROBE_PT_3_Y 20
378
+
379
+  #endif // AUTO_BED_LEVELING_GRID
380
+
343 381
 
344 382
   // these are the offsets to the probe relative to the extruder tip (Hotend - Probe)
345 383
   #define X_PROBE_OFFSET_FROM_EXTRUDER -25
@@ -379,16 +417,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
379 417
 
380 418
   #endif
381 419
 
382
-  // with accurate bed leveling, the bed is sampled in a ACCURATE_BED_LEVELING_POINTSxACCURATE_BED_LEVELING_POINTS grid and least squares solution is calculated
383
-  // Note: this feature occupies 10'206 byte
384
-  #define ACCURATE_BED_LEVELING
385
-
386
-  #ifdef ACCURATE_BED_LEVELING
387
-     // I wouldn't see a reason to go above 3 (=9 probing points on the bed)
388
-    #define ACCURATE_BED_LEVELING_POINTS 2
389
-  #endif
390
-
391
-#endif
420
+#endif // ENABLE_AUTO_BED_LEVELING
392 421
 
393 422
 
394 423
 // The position of the homing switches

+ 39
- 44
Marlin/Marlin_main.cpp View File

@@ -31,7 +31,7 @@
31 31
 
32 32
 #ifdef ENABLE_AUTO_BED_LEVELING
33 33
 #include "vector_3.h"
34
-  #ifdef ACCURATE_BED_LEVELING
34
+  #ifdef AUTO_BED_LEVELING_GRID
35 35
     #include "qr_solve.h"
36 36
   #endif
37 37
 #endif // ENABLE_AUTO_BED_LEVELING
@@ -822,7 +822,7 @@ static void axis_is_at_home(int axis) {
822 822
 }
823 823
 
824 824
 #ifdef ENABLE_AUTO_BED_LEVELING
825
-#ifdef ACCURATE_BED_LEVELING
825
+#ifdef AUTO_BED_LEVELING_GRID
826 826
 static void set_bed_level_equation_lsq(double *plane_equation_coefficients)
827 827
 {
828 828
     vector_3 planeNormal = vector_3(-plane_equation_coefficients[0], -plane_equation_coefficients[1], 1);
@@ -846,42 +846,36 @@ static void set_bed_level_equation_lsq(double *plane_equation_coefficients)
846 846
     plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
847 847
 }
848 848
 
849
-#else
850
-static void set_bed_level_equation(float z_at_xLeft_yFront, float z_at_xRight_yFront, float z_at_xLeft_yBack) {
851
-    plan_bed_level_matrix.set_to_identity();
849
+#else // not AUTO_BED_LEVELING_GRID
852 850
 
853
-    vector_3 xLeftyFront = vector_3(LEFT_PROBE_BED_POSITION, FRONT_PROBE_BED_POSITION, z_at_xLeft_yFront);
854
-    vector_3 xLeftyBack = vector_3(LEFT_PROBE_BED_POSITION, BACK_PROBE_BED_POSITION, z_at_xLeft_yBack);
855
-    vector_3 xRightyFront = vector_3(RIGHT_PROBE_BED_POSITION, FRONT_PROBE_BED_POSITION, z_at_xRight_yFront);
851
+static void set_bed_level_equation_3pts(float z_at_pt_1, float z_at_pt_2, float z_at_pt_3) {
856 852
 
857
-    vector_3 xPositive = (xRightyFront - xLeftyFront).get_normal();
858
-    vector_3 yPositive = (xLeftyBack - xLeftyFront).get_normal();
859
-    vector_3 planeNormal = vector_3::cross(xPositive, yPositive).get_normal();
853
+    plan_bed_level_matrix.set_to_identity();
860 854
 
861
-    //planeNormal.debug("planeNormal");
862
-    //yPositive.debug("yPositive");
863
-    plan_bed_level_matrix = matrix_3x3::create_look_at(planeNormal);
864
-    //bedLevel.debug("bedLevel");
855
+    vector_3 pt1 = vector_3(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, z_at_pt_1);
856
+    vector_3 pt2 = vector_3(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, z_at_pt_2);
857
+    vector_3 pt3 = vector_3(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, z_at_pt_3);
865 858
 
866
-    //plan_bed_level_matrix.debug("bed level before");
867
-    //vector_3 uncorrected_position = plan_get_position_mm();
868
-    //uncorrected_position.debug("position before");
859
+    vector_3 from_2_to_1 = (pt1 - pt2).get_normal();
860
+    vector_3 from_2_to_3 = (pt3 - pt2).get_normal();
861
+    vector_3 planeNormal = vector_3::cross(from_2_to_1, from_2_to_3).get_normal();
862
+    planeNormal = vector_3(planeNormal.x, planeNormal.y, abs(planeNormal.z));
869 863
 
870
-    // and set our bed level equation to do the right thing
871
-    //plan_bed_level_matrix.debug("bed level after");
864
+    plan_bed_level_matrix = matrix_3x3::create_look_at(planeNormal);
872 865
 
873 866
     vector_3 corrected_position = plan_get_position();
874
-    //corrected_position.debug("position after");
875 867
     current_position[X_AXIS] = corrected_position.x;
876 868
     current_position[Y_AXIS] = corrected_position.y;
877 869
     current_position[Z_AXIS] = corrected_position.z;
878 870
 
879
-    // but the bed at 0 so we don't go below it.
871
+    // put the bed at 0 so we don't go below it.
880 872
     current_position[Z_AXIS] = zprobe_zoffset;
881 873
 
882 874
     plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
875
+
883 876
 }
884
-#endif // ACCURATE_BED_LEVELING
877
+
878
+#endif // AUTO_BED_LEVELING_GRID
885 879
 
886 880
 static void run_z_probe() {
887 881
     plan_bed_level_matrix.set_to_identity();
@@ -1403,7 +1397,7 @@ void process_commands()
1403 1397
       break;
1404 1398
 
1405 1399
 #ifdef ENABLE_AUTO_BED_LEVELING
1406
-    case 29: // G29 Detailed Z-Probe, probes the bed at 3 points.
1400
+    case 29: // G29 Detailed Z-Probe, probes the bed at 3 or more points.
1407 1401
         {
1408 1402
             #if Z_MIN_PIN == -1
1409 1403
             #error "You must have a Z_MIN endstop in order to enable Auto Bed Leveling feature!!! Z_MIN_PIN must point to a valid hardware pin."
@@ -1432,10 +1426,11 @@ void process_commands()
1432 1426
             setup_for_endstop_move();
1433 1427
 
1434 1428
             feedrate = homing_feedrate[Z_AXIS];
1435
-#ifdef ACCURATE_BED_LEVELING
1429
+#ifdef AUTO_BED_LEVELING_GRID
1430
+            // probe at the points of a lattice grid
1436 1431
 
1437
-            int xGridSpacing = (RIGHT_PROBE_BED_POSITION - LEFT_PROBE_BED_POSITION) / (ACCURATE_BED_LEVELING_POINTS-1);
1438
-            int yGridSpacing = (BACK_PROBE_BED_POSITION - FRONT_PROBE_BED_POSITION) / (ACCURATE_BED_LEVELING_POINTS-1);
1432
+            int xGridSpacing = (RIGHT_PROBE_BED_POSITION - LEFT_PROBE_BED_POSITION) / (AUTO_BED_LEVELING_GRID_POINTS-1);
1433
+            int yGridSpacing = (BACK_PROBE_BED_POSITION - FRONT_PROBE_BED_POSITION) / (AUTO_BED_LEVELING_GRID_POINTS-1);
1439 1434
 
1440 1435
 
1441 1436
             // solve the plane equation ax + by + d = z
@@ -1445,9 +1440,9 @@ void process_commands()
1445 1440
             // so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z
1446 1441
 
1447 1442
             // "A" matrix of the linear system of equations
1448
-            double eqnAMatrix[ACCURATE_BED_LEVELING_POINTS*ACCURATE_BED_LEVELING_POINTS*3];
1443
+            double eqnAMatrix[AUTO_BED_LEVELING_GRID_POINTS*AUTO_BED_LEVELING_GRID_POINTS*3];
1449 1444
             // "B" vector of Z points
1450
-            double eqnBVector[ACCURATE_BED_LEVELING_POINTS*ACCURATE_BED_LEVELING_POINTS];
1445
+            double eqnBVector[AUTO_BED_LEVELING_GRID_POINTS*AUTO_BED_LEVELING_GRID_POINTS];
1451 1446
 
1452 1447
 
1453 1448
             int probePointCounter = 0;
@@ -1470,7 +1465,7 @@ void process_commands()
1470 1465
                 zig = true;
1471 1466
               }
1472 1467
 
1473
-              for (int xCount=0; xCount < ACCURATE_BED_LEVELING_POINTS; xCount++)
1468
+              for (int xCount=0; xCount < AUTO_BED_LEVELING_GRID_POINTS; xCount++)
1474 1469
               {
1475 1470
                 float z_before;
1476 1471
                 if (probePointCounter == 0)
@@ -1487,9 +1482,9 @@ void process_commands()
1487 1482
 
1488 1483
                 eqnBVector[probePointCounter] = measured_z;
1489 1484
 
1490
-                eqnAMatrix[probePointCounter + 0*ACCURATE_BED_LEVELING_POINTS*ACCURATE_BED_LEVELING_POINTS] = xProbe;
1491
-                eqnAMatrix[probePointCounter + 1*ACCURATE_BED_LEVELING_POINTS*ACCURATE_BED_LEVELING_POINTS] = yProbe;
1492
-                eqnAMatrix[probePointCounter + 2*ACCURATE_BED_LEVELING_POINTS*ACCURATE_BED_LEVELING_POINTS] = 1;
1485
+                eqnAMatrix[probePointCounter + 0*AUTO_BED_LEVELING_GRID_POINTS*AUTO_BED_LEVELING_GRID_POINTS] = xProbe;
1486
+                eqnAMatrix[probePointCounter + 1*AUTO_BED_LEVELING_GRID_POINTS*AUTO_BED_LEVELING_GRID_POINTS] = yProbe;
1487
+                eqnAMatrix[probePointCounter + 2*AUTO_BED_LEVELING_GRID_POINTS*AUTO_BED_LEVELING_GRID_POINTS] = 1;
1493 1488
                 probePointCounter++;
1494 1489
                 xProbe += xInc;
1495 1490
               }
@@ -1497,7 +1492,7 @@ void process_commands()
1497 1492
             clean_up_after_endstop_move();
1498 1493
 
1499 1494
             // solve lsq problem
1500
-            double *plane_equation_coefficients = qr_solve(ACCURATE_BED_LEVELING_POINTS*ACCURATE_BED_LEVELING_POINTS, 3, eqnAMatrix, eqnBVector);
1495
+            double *plane_equation_coefficients = qr_solve(AUTO_BED_LEVELING_GRID_POINTS*AUTO_BED_LEVELING_GRID_POINTS, 3, eqnAMatrix, eqnBVector);
1501 1496
 
1502 1497
             SERIAL_PROTOCOLPGM("Eqn coefficients: a: ");
1503 1498
             SERIAL_PROTOCOL(plane_equation_coefficients[0]);
@@ -1511,24 +1506,24 @@ void process_commands()
1511 1506
 
1512 1507
             free(plane_equation_coefficients);
1513 1508
 
1514
-#else // ACCURATE_BED_LEVELING not defined
1515
-
1509
+#else // AUTO_BED_LEVELING_GRID not defined
1516 1510
 
1517
-            // prob 1
1518
-            float z_at_xLeft_yBack = probe_pt(LEFT_PROBE_BED_POSITION, BACK_PROBE_BED_POSITION, Z_RAISE_BEFORE_PROBING);
1511
+            // Probe at 3 arbitrary points
1512
+            // probe 1
1513
+            float z_at_pt_1 = probe_pt(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, Z_RAISE_BEFORE_PROBING);
1519 1514
 
1520
-            // prob 2
1521
-            float z_at_xLeft_yFront = probe_pt(LEFT_PROBE_BED_POSITION, FRONT_PROBE_BED_POSITION, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS);
1515
+            // probe 2
1516
+            float z_at_pt_2 = probe_pt(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS);
1522 1517
 
1523
-            // prob 3
1524
-            float z_at_xRight_yFront = probe_pt(RIGHT_PROBE_BED_POSITION, FRONT_PROBE_BED_POSITION, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS);
1518
+            // probe 3
1519
+            float z_at_pt_3 = probe_pt(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS);
1525 1520
 
1526 1521
             clean_up_after_endstop_move();
1527 1522
 
1528
-            set_bed_level_equation(z_at_xLeft_yFront, z_at_xRight_yFront, z_at_xLeft_yBack);
1523
+            set_bed_level_equation_3pts(z_at_pt_1, z_at_pt_2, z_at_pt_3);
1529 1524
 
1530 1525
 
1531
-#endif // ACCURATE_BED_LEVELING
1526
+#endif // AUTO_BED_LEVELING_GRID
1532 1527
             st_synchronize();
1533 1528
 
1534 1529
             // The following code correct the Z height difference from z-probe position and hotend tip position.

+ 1
- 3
Marlin/qr_solve.cpp View File

@@ -1,11 +1,9 @@
1 1
 #include "qr_solve.h"
2 2
 
3
-#ifdef ACCURATE_BED_LEVELING
3
+#ifdef AUTO_BED_LEVELING_GRID
4 4
 
5 5
 #include <stdlib.h>
6 6
 #include <math.h>
7
-#include <time.h>
8
-
9 7
 
10 8
 //# include "r8lib.h"
11 9
 

+ 1
- 1
Marlin/qr_solve.h View File

@@ -1,6 +1,6 @@
1 1
 #include "Configuration.h"
2 2
 
3
-#ifdef ACCURATE_BED_LEVELING
3
+#ifdef AUTO_BED_LEVELING_GRID
4 4
 
5 5
 void daxpy ( int n, double da, double dx[], int incx, double dy[], int incy );
6 6
 double ddot ( int n, double dx[], int incx, double dy[], int incy );

Loading…
Cancel
Save