Browse Source

UBL - Hilbert space-filling curve probing sequence (#21387)

Marcio T 3 years ago
parent
commit
eee726ec7d
No account linked to committer's email address

+ 2
- 0
Marlin/Configuration.h View File

@@ -1478,6 +1478,8 @@
1478 1478
   #define GRID_MAX_POINTS_X 10      // Don't use more than 15 points per axis, implementation limited.
1479 1479
   #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X
1480 1480
 
1481
+  //#define UBL_HILBERT_CURVE       // Use Hilbert distribution for less travel when probing multiple points
1482
+
1481 1483
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
1482 1484
   #define UBL_SAVE_ACTIVE_ON_M500   // Save the currently active mesh in the current slot on M500
1483 1485
 

+ 5
- 0
Marlin/src/feature/bedlevel/ubl/ubl.h View File

@@ -98,6 +98,11 @@ public:
98 98
   static void display_map(const int) _O0;
99 99
   static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const xy_pos_t&, const bool=false, MeshFlags *done_flags=nullptr) _O0;
100 100
   static mesh_index_pair find_furthest_invalid_mesh_point() _O0;
101
+  #if ENABLED(UBL_HILBERT_CURVE)
102
+    static void check_if_missing(mesh_index_pair &pt, int x, int y);
103
+    static void hilbert(mesh_index_pair &pt, int8_t x, int8_t y, int8_t xi, int8_t xj, int8_t yi, int8_t yj, uint8_t n);
104
+    static mesh_index_pair find_next_mesh_point();
105
+  #endif
101 106
   static void reset();
102 107
   static void invalidate();
103 108
   static void set_all_mesh_points_to_value(const float value);

+ 55
- 3
Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp View File

@@ -757,9 +757,11 @@ void unified_bed_leveling::shift_mesh_height() {
757 757
         }
758 758
       #endif
759 759
 
760
-      best = do_furthest
761
-        ? find_furthest_invalid_mesh_point()
762
-        : find_closest_mesh_point_of_type(INVALID, nearby, true);
760
+      best = do_furthest  ? find_furthest_invalid_mesh_point()
761
+                          : TERN(UBL_HILBERT_CURVE,
762
+                              next_point_in_grid(),
763
+                              find_closest_mesh_point_of_type(INVALID, nearby, true)
764
+                            );
763 765
 
764 766
       if (best.pos.x >= 0) {    // mesh point found and is reachable by probe
765 767
         TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::PROBE_START));
@@ -1298,6 +1300,56 @@ mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const Mesh
1298 1300
   return closest;
1299 1301
 }
1300 1302
 
1303
+#if ENABLED(UBL_HILBERT_CURVE)
1304
+
1305
+  constexpr int8_t  to_fix(int8_t  v) { return v << 1; }
1306
+  constexpr int8_t  to_int(int8_t  v) { return v >> 1; }
1307
+  constexpr uint8_t   log2(uint8_t n) { return (n > 1) ? 1 + log2(n >> 1) : 0; }
1308
+  constexpr uint8_t  order(uint8_t n) { return uint8_t(log2(n - 1)) + 1; }
1309
+
1310
+  void unified_bed_leveling::hilbert(mesh_index_pair &pt, int8_t x, int8_t y, int8_t xi, int8_t xj, int8_t yi, int8_t yj, uint8_t n) {
1311
+    /* Hilbert space filling curve implementation
1312
+     *
1313
+     * x and y are the coordinates of the bottom left corner
1314
+     * xi & xj are the i & j components of the unit x vector of the frame
1315
+     * similarly yi and yj
1316
+     *
1317
+     * From: http://www.fundza.com/algorithmic/space_filling/hilbert/basics/index.html
1318
+     */
1319
+    if (n <= 0)
1320
+      check_if_missing(pt, to_int(x+(xi+yi)/2),to_int(y+(xj+yj)/2));
1321
+    else {
1322
+      hilbert(pt, x,           y,           yi/2,  yj/2,  xi/2,  xj/2, n-1);
1323
+      hilbert(pt, x+xi/2,      y+xj/2,      xi/2,  xj/2,  yi/2,  yj/2, n-1);
1324
+      hilbert(pt, x+xi/2+yi/2, y+xj/2+yj/2, xi/2,  xj/2,  yi/2,  yj/2, n-1);
1325
+      hilbert(pt, x+xi/2+yi,   y+xj/2+yj,  -yi/2, -yj/2, -xi/2, -xj/2, n-1);
1326
+    }
1327
+  }
1328
+
1329
+  void unified_bed_leveling::check_if_missing(mesh_index_pair &pt, int x, int y) {
1330
+      if (   pt.distance < 0
1331
+          && x < GRID_MAX_POINTS_X
1332
+          && y < GRID_MAX_POINTS_Y
1333
+          && isnan(z_values[x][y])
1334
+          && probe.can_reach(mesh_index_to_xpos(x), mesh_index_to_ypos(y))
1335
+      ) {
1336
+        pt.pos.set(x, y);
1337
+        pt.distance = 1;
1338
+      }
1339
+   }
1340
+
1341
+   mesh_index_pair unified_bed_leveling::find_next_mesh_point() {
1342
+     mesh_index_pair pt;
1343
+     pt.invalidate();
1344
+     pt.distance = -99999.9f;
1345
+     constexpr uint8_t ord = order(_MAX(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y));
1346
+     constexpr uint8_t dim = _BV(ord);
1347
+     hilbert(pt, to_fix(0), to_fix(0), to_fix(dim), to_fix(0), to_fix(0), to_fix(dim), ord);
1348
+     return pt;
1349
+   }
1350
+
1351
+#endif // UBL_HILBERT_CURVE
1352
+
1301 1353
 /**
1302 1354
  * 'Smart Fill': Scan from the outward edges of the mesh towards the center.
1303 1355
  * If an invalid location is found, use the next two points (if valid) to

+ 1
- 1
buildroot/tests/mega2560 View File

@@ -36,7 +36,7 @@ opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO LCD_LANGUAGE jp_kana \
36 36
 opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER LIGHTWEIGHT_UI SHOW_CUSTOM_BOOTSCREEN BOOT_MARLIN_LOGO_SMALL \
37 37
            LCD_SET_PROGRESS_MANUALLY PRINT_PROGRESS_SHOW_DECIMALS SHOW_REMAINING_TIME STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES \
38 38
            SDSUPPORT SDCARD_SORT_ALPHA NO_SD_AUTOSTART USB_FLASH_DRIVE_SUPPORT CANCEL_OBJECTS \
39
-           Z_PROBE_SLED AUTO_BED_LEVELING_UBL RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATURE G26_MESH_VALIDATION ENABLE_LEVELING_FADE_HEIGHT \
39
+           Z_PROBE_SLED AUTO_BED_LEVELING_UBL UBL_HILBERT_CURVE RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATURE G26_MESH_VALIDATION ENABLE_LEVELING_FADE_HEIGHT \
40 40
            EEPROM_SETTINGS EEPROM_CHITCHAT GCODE_MACROS CUSTOM_USER_MENUS \
41 41
            MULTI_NOZZLE_DUPLICATION CLASSIC_JERK LIN_ADVANCE QUICK_HOME \
42 42
            NANODLP_Z_SYNC I2C_POSITION_ENCODERS M114_DETAIL \

Loading…
Cancel
Save