Browse Source

Add OPTIMIZED_MESH_STORAGE option (for UBL) (#20371)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
ubik2 3 years ago
parent
commit
844a8c7074
No account linked to committer's email address

+ 4
- 0
Marlin/Configuration_adv.h View File

1739
   //#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
1739
   //#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
1740
 #endif
1740
 #endif
1741
 
1741
 
1742
+#if BOTH(AUTO_BED_LEVELING_UBL, EEPROM_SETTINGS)
1743
+  //#define OPTIMIZED_MESH_STORAGE  // Store mesh with less precision to save EEPROM space
1744
+#endif
1745
+
1742
 /**
1746
 /**
1743
  * Repeatedly attempt G29 leveling until it succeeds.
1747
  * Repeatedly attempt G29 leveling until it succeeds.
1744
  * Stop after G29_MAX_RETRIES attempts.
1748
  * Stop after G29_MAX_RETRIES attempts.

+ 1
- 0
Marlin/src/core/macros.h View File

286
 #define RSQRT(x)    (1.0f / sqrtf(x))
286
 #define RSQRT(x)    (1.0f / sqrtf(x))
287
 #define CEIL(x)     ceilf(x)
287
 #define CEIL(x)     ceilf(x)
288
 #define FLOOR(x)    floorf(x)
288
 #define FLOOR(x)    floorf(x)
289
+#define TRUNC(x)    truncf(x)
289
 #define LROUND(x)   lroundf(x)
290
 #define LROUND(x)   lroundf(x)
290
 #define FMOD(x, y)  fmodf(x, y)
291
 #define FMOD(x, y)  fmodf(x, y)
291
 #define HYPOT(x,y)  SQRT(HYPOT2(x,y))
292
 #define HYPOT(x,y)  SQRT(HYPOT2(x,y))

+ 28
- 7
Marlin/src/feature/bedlevel/ubl/ubl.cpp View File

42
 
42
 
43
   #include "math.h"
43
   #include "math.h"
44
 
44
 
45
-  void unified_bed_leveling::echo_name() {
46
-    SERIAL_ECHOPGM("Unified Bed Leveling");
47
-  }
45
+  void unified_bed_leveling::echo_name() { SERIAL_ECHOPGM("Unified Bed Leveling"); }
48
 
46
 
49
   void unified_bed_leveling::report_current_mesh() {
47
   void unified_bed_leveling::report_current_mesh() {
50
     if (!leveling_is_valid()) return;
48
     if (!leveling_is_valid()) return;
86
 
84
 
87
   volatile int16_t unified_bed_leveling::encoder_diff;
85
   volatile int16_t unified_bed_leveling::encoder_diff;
88
 
86
 
89
-  unified_bed_leveling::unified_bed_leveling() {
90
-    reset();
91
-  }
87
+  unified_bed_leveling::unified_bed_leveling() { reset(); }
92
 
88
 
93
   void unified_bed_leveling::reset() {
89
   void unified_bed_leveling::reset() {
94
     const bool was_enabled = planner.leveling_active;
90
     const bool was_enabled = planner.leveling_active;
113
     }
109
     }
114
   }
110
   }
115
 
111
 
112
+  #if ENABLED(OPTIMIZED_MESH_STORAGE)
113
+
114
+    constexpr float mesh_store_scaling = 1000;
115
+    constexpr int16_t Z_STEPS_NAN = INT16_MAX;
116
+
117
+    void unified_bed_leveling::set_store_from_mesh(const bed_mesh_t &in_values, mesh_store_t &stored_values) {
118
+      auto z_to_store = [](const float &z) {
119
+        if (isnan(z)) return Z_STEPS_NAN;
120
+        const int32_t z_scaled = TRUNC(z * mesh_store_scaling);
121
+        if (z_scaled == Z_STEPS_NAN || !WITHIN(z_scaled, INT16_MIN, INT16_MAX))
122
+          return Z_STEPS_NAN; // If Z is out of range, return our custom 'NaN'
123
+        return int16_t(z_scaled);
124
+      };
125
+      GRID_LOOP(x, y) stored_values[x][y] = z_to_store(in_values[x][y]);
126
+    }
127
+
128
+    void unified_bed_leveling::set_mesh_from_store(const mesh_store_t &stored_values, bed_mesh_t &out_values) {
129
+      auto store_to_z = [](const int16_t z_scaled) {
130
+        return z_scaled == Z_STEPS_NAN ? NAN : z_scaled / mesh_store_scaling;
131
+      };
132
+      GRID_LOOP(x, y) out_values[x][y] = store_to_z(stored_values[x][y]);
133
+    }
134
+
135
+  #endif // OPTIMIZED_MESH_STORAGE
136
+
116
   static void serial_echo_xy(const uint8_t sp, const int16_t x, const int16_t y) {
137
   static void serial_echo_xy(const uint8_t sp, const int16_t x, const int16_t y) {
117
     SERIAL_ECHO_SP(sp);
138
     SERIAL_ECHO_SP(sp);
118
     SERIAL_CHAR('(');
139
     SERIAL_CHAR('(');
127
 
148
 
128
   static void serial_echo_column_labels(const uint8_t sp) {
149
   static void serial_echo_column_labels(const uint8_t sp) {
129
     SERIAL_ECHO_SP(7);
150
     SERIAL_ECHO_SP(7);
130
-    for (int8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
151
+    LOOP_L_N(i, GRID_MAX_POINTS_X) {
131
       if (i < 10) SERIAL_CHAR(' ');
152
       if (i < 10) SERIAL_CHAR(' ');
132
       SERIAL_ECHO(i);
153
       SERIAL_ECHO(i);
133
       SERIAL_ECHO_SP(sp);
154
       SERIAL_ECHO_SP(sp);

+ 16
- 14
Marlin/src/feature/bedlevel/ubl/ubl.h View File

41
 #define MESH_X_DIST (float(MESH_MAX_X - (MESH_MIN_X)) / float(GRID_MAX_POINTS_X - 1))
41
 #define MESH_X_DIST (float(MESH_MAX_X - (MESH_MIN_X)) / float(GRID_MAX_POINTS_X - 1))
42
 #define MESH_Y_DIST (float(MESH_MAX_Y - (MESH_MIN_Y)) / float(GRID_MAX_POINTS_Y - 1))
42
 #define MESH_Y_DIST (float(MESH_MAX_Y - (MESH_MIN_Y)) / float(GRID_MAX_POINTS_Y - 1))
43
 
43
 
44
+#if ENABLED(OPTIMIZED_MESH_STORAGE)
45
+  typedef int16_t mesh_store_t[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
46
+#endif
47
+
44
 class unified_bed_leveling {
48
 class unified_bed_leveling {
45
   private:
49
   private:
46
 
50
 
106
     static int8_t storage_slot;
110
     static int8_t storage_slot;
107
 
111
 
108
     static bed_mesh_t z_values;
112
     static bed_mesh_t z_values;
113
+    #if ENABLED(OPTIMIZED_MESH_STORAGE)
114
+      static void set_store_from_mesh(const bed_mesh_t &in_values, mesh_store_t &stored_values);
115
+      static void set_mesh_from_store(const mesh_store_t &stored_values, bed_mesh_t &out_values);
116
+    #endif
109
     static const float _mesh_index_to_xpos[GRID_MAX_POINTS_X],
117
     static const float _mesh_index_to_xpos[GRID_MAX_POINTS_X],
110
                        _mesh_index_to_ypos[GRID_MAX_POINTS_Y];
118
                        _mesh_index_to_ypos[GRID_MAX_POINTS_Y];
111
 
119
 
182
       return z1 + (z2 - z1) * (a0 - a1) / (a2 - a1);
190
       return z1 + (z2 - z1) * (a0 - a1) / (a2 - a1);
183
     }
191
     }
184
 
192
 
193
+    #ifdef UBL_Z_RAISE_WHEN_OFF_MESH
194
+      #define _UBL_OUTER_Z_RAISE UBL_Z_RAISE_WHEN_OFF_MESH
195
+    #else
196
+      #define _UBL_OUTER_Z_RAISE NAN
197
+    #endif
198
+
185
     /**
199
     /**
186
      * z_correction_for_x_on_horizontal_mesh_line is an optimization for
200
      * z_correction_for_x_on_horizontal_mesh_line is an optimization for
187
      * the case where the printer is making a vertical line that only crosses horizontal mesh lines.
201
      * the case where the printer is making a vertical line that only crosses horizontal mesh lines.
195
         }
209
         }
196
 
210
 
197
         // The requested location is off the mesh. Return UBL_Z_RAISE_WHEN_OFF_MESH or NAN.
211
         // The requested location is off the mesh. Return UBL_Z_RAISE_WHEN_OFF_MESH or NAN.
198
-        return (
199
-          #ifdef UBL_Z_RAISE_WHEN_OFF_MESH
200
-            UBL_Z_RAISE_WHEN_OFF_MESH
201
-          #else
202
-            NAN
203
-          #endif
204
-        );
212
+        return _UBL_OUTER_Z_RAISE;
205
       }
213
       }
206
 
214
 
207
       const float xratio = (rx0 - mesh_index_to_xpos(x1_i)) * RECIPROCAL(MESH_X_DIST),
215
       const float xratio = (rx0 - mesh_index_to_xpos(x1_i)) * RECIPROCAL(MESH_X_DIST),
224
         }
232
         }
225
 
233
 
226
         // The requested location is off the mesh. Return UBL_Z_RAISE_WHEN_OFF_MESH or NAN.
234
         // The requested location is off the mesh. Return UBL_Z_RAISE_WHEN_OFF_MESH or NAN.
227
-        return (
228
-          #ifdef UBL_Z_RAISE_WHEN_OFF_MESH
229
-            UBL_Z_RAISE_WHEN_OFF_MESH
230
-          #else
231
-            NAN
232
-          #endif
233
-        );
235
+        return _UBL_OUTER_Z_RAISE;
234
       }
236
       }
235
 
237
 
236
       const float yratio = (ry0 - mesh_index_to_ypos(y1_i)) * RECIPROCAL(MESH_Y_DIST),
238
       const float yratio = (ry0 - mesh_index_to_ypos(y1_i)) * RECIPROCAL(MESH_Y_DIST),

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

543
           }
543
           }
544
           else {
544
           else {
545
             const float cvf = parser.value_float();
545
             const float cvf = parser.value_float();
546
-            switch ((int)truncf(cvf * 10.0f) - 30) {   // 3.1 -> 1
546
+            switch ((int)TRUNC(cvf * 10.0f) - 30) {   // 3.1 -> 1
547
               #if ENABLED(UBL_G29_P31)
547
               #if ENABLED(UBL_G29_P31)
548
                 case 1: {
548
                 case 1: {
549
 
549
 

+ 30
- 5
Marlin/src/module/settings.cpp View File

2385
                                                           // or down a little bit without disrupting the mesh data
2385
                                                           // or down a little bit without disrupting the mesh data
2386
     }
2386
     }
2387
 
2387
 
2388
+    #define MESH_STORE_SIZE sizeof(TERN(OPTIMIZED_MESH_STORAGE, mesh_store_t, ubl.z_values))
2389
+
2388
     uint16_t MarlinSettings::calc_num_meshes() {
2390
     uint16_t MarlinSettings::calc_num_meshes() {
2389
-      return (meshes_end - meshes_start_index()) / sizeof(ubl.z_values);
2391
+      return (meshes_end - meshes_start_index()) / MESH_STORE_SIZE;
2390
     }
2392
     }
2391
 
2393
 
2392
     int MarlinSettings::mesh_slot_offset(const int8_t slot) {
2394
     int MarlinSettings::mesh_slot_offset(const int8_t slot) {
2393
-      return meshes_end - (slot + 1) * sizeof(ubl.z_values);
2395
+      return meshes_end - (slot + 1) * MESH_STORE_SIZE;
2394
     }
2396
     }
2395
 
2397
 
2396
     void MarlinSettings::store_mesh(const int8_t slot) {
2398
     void MarlinSettings::store_mesh(const int8_t slot) {
2407
         int pos = mesh_slot_offset(slot);
2409
         int pos = mesh_slot_offset(slot);
2408
         uint16_t crc = 0;
2410
         uint16_t crc = 0;
2409
 
2411
 
2412
+        #if ENABLED(OPTIMIZED_MESH_STORAGE)
2413
+          int16_t z_mesh_store[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
2414
+          ubl.set_store_from_mesh(ubl.z_values, z_mesh_store);
2415
+          uint8_t * const src = (uint8_t*)&z_mesh_store;
2416
+        #else
2417
+          uint8_t * const src = (uint8_t*)&ubl.z_values;
2418
+        #endif
2419
+
2410
         // Write crc to MAT along with other data, or just tack on to the beginning or end
2420
         // Write crc to MAT along with other data, or just tack on to the beginning or end
2411
         persistentStore.access_start();
2421
         persistentStore.access_start();
2412
-        const bool status = persistentStore.write_data(pos, (uint8_t *)&ubl.z_values, sizeof(ubl.z_values), &crc);
2422
+        const bool status = persistentStore.write_data(pos, src, MESH_STORE_SIZE, &crc);
2413
         persistentStore.access_finish();
2423
         persistentStore.access_finish();
2414
 
2424
 
2415
         if (status) SERIAL_ECHOLNPGM("?Unable to save mesh data.");
2425
         if (status) SERIAL_ECHOLNPGM("?Unable to save mesh data.");
2435
 
2445
 
2436
         int pos = mesh_slot_offset(slot);
2446
         int pos = mesh_slot_offset(slot);
2437
         uint16_t crc = 0;
2447
         uint16_t crc = 0;
2438
-        uint8_t * const dest = into ? (uint8_t*)into : (uint8_t*)&ubl.z_values;
2448
+        #if ENABLED(OPTIMIZED_MESH_STORAGE)
2449
+          int16_t z_mesh_store[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
2450
+          uint8_t * const dest = (uint8_t*)&z_mesh_store;
2451
+        #else
2452
+          uint8_t * const dest = into ? (uint8_t*)into : (uint8_t*)&ubl.z_values;
2453
+        #endif
2439
 
2454
 
2440
         persistentStore.access_start();
2455
         persistentStore.access_start();
2441
-        const uint16_t status = persistentStore.read_data(pos, dest, sizeof(ubl.z_values), &crc);
2456
+        const uint16_t status = persistentStore.read_data(pos, dest, MESH_STORE_SIZE, &crc);
2442
         persistentStore.access_finish();
2457
         persistentStore.access_finish();
2443
 
2458
 
2459
+        #if ENABLED(OPTIMIZED_MESH_STORAGE)
2460
+          if (into) {
2461
+            float z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
2462
+            ubl.set_mesh_from_store(z_mesh_store, z_values);
2463
+            memcpy(into, z_values, sizeof(z_values));
2464
+          }
2465
+          else
2466
+            ubl.set_mesh_from_store(z_mesh_store, ubl.z_values);
2467
+        #endif
2468
+
2444
         if (status) SERIAL_ECHOLNPGM("?Unable to load mesh data.");
2469
         if (status) SERIAL_ECHOLNPGM("?Unable to load mesh data.");
2445
         else        DEBUG_ECHOLNPAIR("Mesh loaded from slot ", slot);
2470
         else        DEBUG_ECHOLNPAIR("Mesh loaded from slot ", slot);
2446
 
2471
 

Loading…
Cancel
Save