Преглед на файлове

Spend some SRAM to optimize bilinear leveling

Scott Lahteine преди 7 години
родител
ревизия
830851df13
променени са 2 файла, в които са добавени 68 реда и са изтрити 31 реда
  1. 3
    2
      Marlin/Marlin.h
  2. 65
    29
      Marlin/Marlin_main.cpp

+ 3
- 2
Marlin/Marlin.h Целия файл

@@ -313,8 +313,9 @@ float code_value_temp_diff();
313 313
 
314 314
 #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
315 315
   extern int bilinear_grid_spacing[2], bilinear_start[2];
316
-  extern float z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
317
-  float bilinear_z_offset(float logical[XYZ]);
316
+  extern float bilinear_grid_factor[2],
317
+               z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
318
+  float bilinear_z_offset(const float logical[XYZ]);
318 319
   void set_bed_leveling_enabled(bool enable=true);
319 320
 #endif
320 321
 

+ 65
- 29
Marlin/Marlin_main.cpp Целия файл

@@ -599,7 +599,8 @@ static uint8_t target_extruder;
599 599
 
600 600
 #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
601 601
   int bilinear_grid_spacing[2], bilinear_start[2];
602
-  float z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
602
+  float bilinear_grid_factor[2],
603
+        z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
603 604
 #endif
604 605
 
605 606
 #if IS_SCARA
@@ -2371,6 +2372,13 @@ static void clean_up_after_endstop_or_probe_move() {
2371 2372
       #endif
2372 2373
 
2373 2374
       if (can_change && enable != planner.abl_enabled) {
2375
+
2376
+        #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
2377
+          // Force bilinear_z_offset to re-calculate next time
2378
+          const float reset[XYZ] = { -9999.999, -9999.999, 0 };
2379
+          (void)bilinear_z_offset(reset);
2380
+        #endif
2381
+
2374 2382
         planner.abl_enabled = enable;
2375 2383
         if (!enable)
2376 2384
           set_current_from_steppers_for_axis(
@@ -2629,6 +2637,7 @@ static void clean_up_after_endstop_or_probe_move() {
2629 2637
     #define ABL_TEMP_POINTS_Y (GRID_MAX_POINTS_Y + 2)
2630 2638
     float z_values_virt[ABL_GRID_POINTS_VIRT_X][ABL_GRID_POINTS_VIRT_Y];
2631 2639
     int bilinear_grid_spacing_virt[2] = { 0 };
2640
+    float bilinear_grid_factor_virt[2] = { 0 };
2632 2641
 
2633 2642
     static void bed_level_virt_print() {
2634 2643
       SERIAL_ECHOLNPGM("Subdivided with CATMULL ROM Leveling Grid:");
@@ -2698,6 +2707,8 @@ static void clean_up_after_endstop_or_probe_move() {
2698 2707
     void bed_level_virt_interpolate() {
2699 2708
       bilinear_grid_spacing_virt[X_AXIS] = bilinear_grid_spacing[X_AXIS] / (BILINEAR_SUBDIVISIONS);
2700 2709
       bilinear_grid_spacing_virt[Y_AXIS] = bilinear_grid_spacing[Y_AXIS] / (BILINEAR_SUBDIVISIONS);
2710
+      bilinear_grid_factor_virt[X_AXIS] = RECIPROCAL(bilinear_grid_spacing_virt[X_AXIS]);
2711
+      bilinear_grid_factor_virt[Y_AXIS] = RECIPROCAL(bilinear_grid_spacing_virt[Y_AXIS]);
2701 2712
       for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++)
2702 2713
         for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
2703 2714
           for (uint8_t ty = 0; ty < BILINEAR_SUBDIVISIONS; ty++)
@@ -2717,6 +2728,8 @@ static void clean_up_after_endstop_or_probe_move() {
2717 2728
 
2718 2729
   // Refresh after other values have been updated
2719 2730
   void refresh_bed_level() {
2731
+    bilinear_grid_factor[X_AXIS] = RECIPROCAL(bilinear_grid_spacing[X_AXIS]);
2732
+    bilinear_grid_factor[Y_AXIS] = RECIPROCAL(bilinear_grid_spacing[Y_AXIS]);
2720 2733
     #if ENABLED(ABL_BILINEAR_SUBDIVISION)
2721 2734
       bed_level_virt_interpolate();
2722 2735
     #endif
@@ -3130,7 +3143,7 @@ void unknown_command_error() {
3130 3143
 
3131 3144
 #endif //HOST_KEEPALIVE_FEATURE
3132 3145
 
3133
-bool position_is_reachable(float target[XYZ]
3146
+bool position_is_reachable(const float target[XYZ]
3134 3147
   #if HAS_BED_PROBE
3135 3148
     , bool by_probe=false
3136 3149
   #endif
@@ -4648,7 +4661,7 @@ inline void gcode_G28() {
4648 4661
 
4649 4662
             #if IS_KINEMATIC
4650 4663
               // Avoid probing outside the round or hexagonal area
4651
-              float pos[XYZ] = { xProbe, yProbe, 0 };
4664
+              const float pos[XYZ] = { xProbe, yProbe, 0 };
4652 4665
               if (!position_is_reachable(pos, true)) continue;
4653 4666
             #endif
4654 4667
 
@@ -10484,49 +10497,72 @@ void ok_to_send() {
10484 10497
 
10485 10498
   #if ENABLED(ABL_BILINEAR_SUBDIVISION)
10486 10499
     #define ABL_BG_SPACING(A) bilinear_grid_spacing_virt[A]
10500
+    #define ABL_BG_FACTOR(A)  bilinear_grid_factor_virt[A]
10487 10501
     #define ABL_BG_POINTS_X   ABL_GRID_POINTS_VIRT_X
10488 10502
     #define ABL_BG_POINTS_Y   ABL_GRID_POINTS_VIRT_Y
10489 10503
     #define ABL_BG_GRID(X,Y)  z_values_virt[X][Y]
10490 10504
   #else
10491 10505
     #define ABL_BG_SPACING(A) bilinear_grid_spacing[A]
10506
+    #define ABL_BG_FACTOR(A)  bilinear_grid_factor[A]
10492 10507
     #define ABL_BG_POINTS_X   GRID_MAX_POINTS_X
10493 10508
     #define ABL_BG_POINTS_Y   GRID_MAX_POINTS_Y
10494 10509
     #define ABL_BG_GRID(X,Y)  z_values[X][Y]
10495 10510
   #endif
10496 10511
 
10497 10512
   // Get the Z adjustment for non-linear bed leveling
10498
-  float bilinear_z_offset(float cartesian[XYZ]) {
10513
+  float bilinear_z_offset(const float logical[XYZ]) {
10514
+
10515
+    static float z1, d2, z3, d4, L, D, ratio_x, ratio_y,
10516
+                 last_x = -999.999, last_y = -999.999;
10517
+
10518
+    // Whole units for the grid line indices. Constrained within bounds.
10519
+    static int8_t gridx, gridy, nextx, nexty,
10520
+                  last_gridx = -99, last_gridy = -99;
10499 10521
 
10500 10522
     // XY relative to the probed area
10501
-    const float x = RAW_X_POSITION(cartesian[X_AXIS]) - bilinear_start[X_AXIS],
10502
-                y = RAW_Y_POSITION(cartesian[Y_AXIS]) - bilinear_start[Y_AXIS];
10523
+    const float x = RAW_X_POSITION(logical[X_AXIS]) - bilinear_start[X_AXIS],
10524
+                y = RAW_Y_POSITION(logical[Y_AXIS]) - bilinear_start[Y_AXIS];
10503 10525
 
10504
-    // Convert to grid box units
10505
-    float ratio_x = x / ABL_BG_SPACING(X_AXIS),
10506
-          ratio_y = y / ABL_BG_SPACING(Y_AXIS);
10526
+    if (last_x != x) {
10527
+      last_x = x;
10528
+      ratio_x = x * ABL_BG_FACTOR(X_AXIS);
10529
+      const float gx = constrain(floor(ratio_x), 0, ABL_BG_POINTS_X - 1);
10530
+      ratio_x -= gx;      // Subtract whole to get the ratio within the grid box
10531
+      NOLESS(ratio_x, 0); // Never < 0.0. (> 1.0 is ok when nextx==gridx.)
10532
+      gridx = gx;
10533
+      nextx = min(gridx + 1, ABL_BG_POINTS_X - 1);
10534
+    }
10507 10535
 
10508
-    // Whole units for the grid line indices. Constrained within bounds.
10509
-    const int gridx = constrain(floor(ratio_x), 0, ABL_BG_POINTS_X - 1),
10510
-              gridy = constrain(floor(ratio_y), 0, ABL_BG_POINTS_Y - 1),
10511
-              nextx = min(gridx + 1, ABL_BG_POINTS_X - 1),
10512
-              nexty = min(gridy + 1, ABL_BG_POINTS_Y - 1);
10536
+    if (last_y != y || last_gridx != gridx) {
10537
+
10538
+      if (last_y != y) {
10539
+        last_y = y;
10540
+        ratio_y = y * ABL_BG_FACTOR(Y_AXIS);
10541
+        const float gy = constrain(floor(ratio_y), 0, ABL_BG_POINTS_Y - 1);
10542
+        ratio_y -= gy;
10543
+        NOLESS(ratio_y, 0);
10544
+        gridy = gy;
10545
+        nexty = min(gridy + 1, ABL_BG_POINTS_Y - 1);
10546
+      }
10513 10547
 
10514
-    // Subtract whole to get the ratio within the grid box
10515
-    ratio_x -= gridx; ratio_y -= gridy;
10548
+      if (last_gridx != gridx || last_gridy != gridy) {
10549
+        last_gridx = gridx;
10550
+        last_gridy = gridy;
10551
+        // Z at the box corners
10552
+        z1 = ABL_BG_GRID(gridx, gridy);       // left-front
10553
+        d2 = ABL_BG_GRID(gridx, nexty) - z1;  // left-back (delta)
10554
+        z3 = ABL_BG_GRID(nextx, gridy);       // right-front
10555
+        d4 = ABL_BG_GRID(nextx, nexty) - z3;  // right-back (delta)
10556
+      }
10516 10557
 
10517
-    // Never less than 0.0. (Over 1.0 is fine due to previous contraints.)
10518
-    NOLESS(ratio_x, 0); NOLESS(ratio_y, 0);
10558
+      // Bilinear interpolate. Needed since y or gridx has changed.
10559
+                  L = z1 + d2 * ratio_y;   // Linear interp. LF -> LB
10560
+      const float R = z3 + d4 * ratio_y;   // Linear interp. RF -> RB
10519 10561
 
10520
-    // Z at the box corners
10521
-    const float z1 = ABL_BG_GRID(gridx, gridy),  // left-front
10522
-                z2 = ABL_BG_GRID(gridx, nexty),  // left-back
10523
-                z3 = ABL_BG_GRID(nextx, gridy),  // right-front
10524
-                z4 = ABL_BG_GRID(nextx, nexty),  // right-back
10562
+      D = R - L;
10563
+    }
10525 10564
 
10526
-                // Bilinear interpolate
10527
-                L = z1 + (z2 - z1) * ratio_y,   // Linear interp. LF -> LB
10528
-                R = z3 + (z4 - z3) * ratio_y,   // Linear interp. RF -> RB
10529
-                offset = L + ratio_x * (R - L);
10565
+    const float offset = L + ratio_x * D;   // the offset almost always changes
10530 10566
 
10531 10567
     /*
10532 10568
     static float last_offset = 0;
@@ -10549,7 +10585,7 @@ void ok_to_send() {
10549 10585
       SERIAL_ECHOLNPAIR(" offset=", offset);
10550 10586
     }
10551 10587
     last_offset = offset;
10552
-    */
10588
+    //*/
10553 10589
 
10554 10590
     return offset;
10555 10591
   }
@@ -10869,7 +10905,7 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
10869 10905
 
10870 10906
 #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) && !IS_KINEMATIC
10871 10907
 
10872
-  #define CELL_INDEX(A,V) ((RAW_##A##_POSITION(V) - bilinear_start[A##_AXIS]) / ABL_BG_SPACING(A##_AXIS))
10908
+  #define CELL_INDEX(A,V) ((RAW_##A##_POSITION(V) - bilinear_start[A##_AXIS]) * ABL_BG_FACTOR(A##_AXIS))
10873 10909
 
10874 10910
   /**
10875 10911
    * Prepare a bilinear-leveled linear move on Cartesian,

Loading…
Отказ
Запис