Browse Source

Improve Bilinear Grid

- Extrapolate properly for even numbered grid points
- Extrapolate using average, not median
- Improve bilinear grid report output
- Add debug output for bilinear extrapolation
- Add option to extrapolate from edge, not center
Scott Lahteine 7 years ago
parent
commit
5100bdac81
1 changed files with 101 additions and 18 deletions
  1. 101
    18
      Marlin/Marlin_main.cpp

+ 101
- 18
Marlin/Marlin_main.cpp View File

@@ -2136,7 +2136,9 @@ static void clean_up_after_endstop_or_probe_move() {
2136 2136
     #if ABL_PLANAR
2137 2137
       planner.bed_level_matrix.set_to_identity();
2138 2138
     #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
2139
-      memset(bed_level_grid, 0, sizeof(bed_level_grid));
2139
+      for (uint8_t x = 0; x < ABL_GRID_POINTS_X; x++)
2140
+        for (uint8_t y = 0; y < ABL_GRID_POINTS_Y; y++)
2141
+          bed_level_grid[x][y] = 1000.0;
2140 2142
     #endif
2141 2143
   }
2142 2144
 
@@ -2148,44 +2150,125 @@ static void clean_up_after_endstop_or_probe_move() {
2148 2150
    * Extrapolate a single point from its neighbors
2149 2151
    */
2150 2152
   static void extrapolate_one_point(uint8_t x, uint8_t y, int8_t xdir, int8_t ydir) {
2151
-    if (bed_level_grid[x][y]) return;  // Don't overwrite good values.
2152
-    float a = 2 * bed_level_grid[x + xdir][y] - bed_level_grid[x + xdir * 2][y], // Left to right.
2153
-          b = 2 * bed_level_grid[x][y + ydir] - bed_level_grid[x][y + ydir * 2], // Front to back.
2154
-          c = 2 * bed_level_grid[x + xdir][y + ydir] - bed_level_grid[x + xdir * 2][y + ydir * 2]; // Diagonal.
2153
+    #if ENABLED(DEBUG_LEVELING_FEATURE)
2154
+      if (DEBUGGING(LEVELING)) {
2155
+        SERIAL_ECHOPGM("Extrapolate [");
2156
+        if (x < 10) SERIAL_CHAR(' ');
2157
+        SERIAL_ECHO((int)x);
2158
+        SERIAL_CHAR(xdir ? (xdir > 0 ? '+' : '-') : ' ');
2159
+        SERIAL_CHAR(' ');
2160
+        if (y < 10) SERIAL_CHAR(' ');
2161
+        SERIAL_ECHO((int)y);
2162
+        SERIAL_CHAR(ydir ? (ydir > 0 ? '+' : '-') : ' ');
2163
+        SERIAL_CHAR(']');
2164
+      }
2165
+    #endif
2166
+    if (bed_level_grid[x][y] < 999.0) {
2167
+      #if ENABLED(DEBUG_LEVELING_FEATURE)
2168
+        if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM(" (done)");
2169
+      #endif
2170
+      return;  // Don't overwrite good values.
2171
+    }
2172
+
2173
+    // Get X neighbors, Y neighbors, and XY neighbors
2174
+    float a1 = bed_level_grid[x + xdir][y], a2 = bed_level_grid[x + xdir * 2][y],
2175
+          b1 = bed_level_grid[x][y + ydir], b2 = bed_level_grid[x][y + ydir * 2],
2176
+          c1 = bed_level_grid[x + xdir][y + ydir], c2 = bed_level_grid[x + xdir * 2][y + ydir * 2];
2177
+
2178
+    // Treat far unprobed points as zero, near as equal to far
2179
+    if (a2 > 999.0) a2 = 0.0; if (a1 > 999.0) a1 = a2;
2180
+    if (b2 > 999.0) b2 = 0.0; if (b1 > 999.0) b1 = b2;
2181
+    if (c2 > 999.0) c2 = 0.0; if (c1 > 999.0) c1 = c2;
2182
+
2183
+    float a = 2 * a1 - a2, b = 2 * b1 - b2, c = 2 * c1 - c2;
2184
+
2185
+    // Take the average intstead of the median
2186
+    bed_level_grid[x][y] = (a + b + c) / 3.0;
2187
+
2155 2188
     // Median is robust (ignores outliers).
2156
-    bed_level_grid[x][y] = (a < b) ? ((b < c) ? b : (c < a) ? a : c)
2157
-                                   : ((c < b) ? b : (a < c) ? a : c);
2189
+    // bed_level_grid[x][y] = (a < b) ? ((b < c) ? b : (c < a) ? a : c)
2190
+    //                                : ((c < b) ? b : (a < c) ? a : c);
2158 2191
   }
2159 2192
 
2193
+  #define EXTRAPOLATE_FROM_EDGE
2194
+
2195
+  #if ENABLED(EXTRAPOLATE_FROM_EDGE)
2196
+    #if ABL_GRID_POINTS_X < ABL_GRID_POINTS_Y
2197
+      #define HALF_IN_X
2198
+    #elif ABL_GRID_POINTS_Y < ABL_GRID_POINTS_X
2199
+      #define HALF_IN_Y
2200
+    #endif
2201
+  #endif
2202
+
2160 2203
   /**
2161 2204
    * Fill in the unprobed points (corners of circular print surface)
2162 2205
    * using linear extrapolation, away from the center.
2163 2206
    */
2164 2207
   static void extrapolate_unprobed_bed_level() {
2165
-    int half_x = (ABL_GRID_POINTS_X - 1) / 2,
2166
-        half_y = (ABL_GRID_POINTS_Y - 1) / 2;
2167
-    for (uint8_t y = 0; y <= half_y; y++) {
2168
-      for (uint8_t x = 0; x <= half_x; x++) {
2169
-        if (x + y < 3) continue;
2170
-        extrapolate_one_point(half_x - x, half_y - y, x > 1 ? +1 : 0, y > 1 ? +1 : 0);
2171
-        extrapolate_one_point(half_x + x, half_y - y, x > 1 ? -1 : 0, y > 1 ? +1 : 0);
2172
-        extrapolate_one_point(half_x - x, half_y + y, x > 1 ? +1 : 0, y > 1 ? -1 : 0);
2173
-        extrapolate_one_point(half_x + x, half_y + y, x > 1 ? -1 : 0, y > 1 ? -1 : 0);
2208
+    #ifdef HALF_IN_X
2209
+      const uint8_t ctrx2 = 0, xlen = ABL_GRID_POINTS_X - 1;
2210
+    #else
2211
+      const uint8_t ctrx1 = (ABL_GRID_POINTS_X - 1) / 2, // left-of-center
2212
+                    ctrx2 = ABL_GRID_POINTS_X / 2,       // right-of-center
2213
+                    xlen = ctrx1;
2214
+    #endif
2215
+
2216
+    #ifdef HALF_IN_Y
2217
+      const uint8_t ctry2 = 0, ylen = ABL_GRID_POINTS_Y - 1;
2218
+    #else
2219
+      const uint8_t ctry1 = (ABL_GRID_POINTS_Y - 1) / 2, // top-of-center
2220
+                    ctry2 = ABL_GRID_POINTS_Y / 2,       // bottom-of-center
2221
+                    ylen = ctry1;
2222
+    #endif
2223
+
2224
+    for (uint8_t xo = 0; xo <= xlen; xo++)
2225
+      for (uint8_t yo = 0; yo <= ylen; yo++) {
2226
+        uint8_t x2 = ctrx2 + xo, y2 = ctry2 + yo;
2227
+        #ifndef HALF_IN_X
2228
+          uint8_t x1 = ctrx1 - xo;
2229
+        #endif
2230
+        #ifndef HALF_IN_Y
2231
+          uint8_t y1 = ctry1 - yo;
2232
+          #ifndef HALF_IN_X
2233
+            extrapolate_one_point(x1, y1, +1, +1);   //  left-below + +
2234
+          #endif
2235
+          extrapolate_one_point(x2, y1, -1, +1);     // right-below - +
2236
+        #endif
2237
+        #ifndef HALF_IN_X
2238
+          extrapolate_one_point(x1, y2, +1, -1);     //  left-above + -
2239
+        #endif
2240
+        extrapolate_one_point(x2, y2, -1, -1);       // right-above - -
2174 2241
       }
2175
-    }
2242
+
2176 2243
   }
2177 2244
 
2178 2245
   /**
2179 2246
    * Print calibration results for plotting or manual frame adjustment.
2180 2247
    */
2181 2248
   static void print_bed_level() {
2249
+    SERIAL_ECHOPGM("Bilinear Leveling Grid:\n ");
2250
+    for (uint8_t x = 1; x < ABL_GRID_POINTS_X + 1; x++) {
2251
+      SERIAL_PROTOCOLPGM("    ");
2252
+      if (x < 10) SERIAL_PROTOCOLCHAR(' ');
2253
+      SERIAL_PROTOCOL((int)x);
2254
+    }
2255
+    SERIAL_EOL;
2182 2256
     for (uint8_t y = 0; y < ABL_GRID_POINTS_Y; y++) {
2257
+      if (y < 9) SERIAL_PROTOCOLCHAR(' ');
2258
+      SERIAL_PROTOCOL(y + 1);
2183 2259
       for (uint8_t x = 0; x < ABL_GRID_POINTS_X; x++) {
2184
-        SERIAL_PROTOCOL_F(bed_level_grid[x][y], 2);
2185 2260
         SERIAL_PROTOCOLCHAR(' ');
2261
+        float offset = bed_level_grid[x][y];
2262
+        if (offset < 999.0) {
2263
+          if (offset > 0) SERIAL_CHAR('+');
2264
+          SERIAL_PROTOCOL_F(offset, 2);
2265
+        }
2266
+        else
2267
+          SERIAL_PROTOCOLPGM(" ====");
2186 2268
       }
2187 2269
       SERIAL_EOL;
2188 2270
     }
2271
+    SERIAL_EOL;
2189 2272
   }
2190 2273
 
2191 2274
 #endif // AUTO_BED_LEVELING_BILINEAR

Loading…
Cancel
Save