Browse Source

🐛 Fix backlash applied steps when config changes (#23826)

Followup to #23814
tombrazier 2 years ago
parent
commit
6b7868d943
No account linked to committer's email address

+ 46
- 30
Marlin/src/feature/backlash.cpp View File

30
 #include "../module/planner.h"
30
 #include "../module/planner.h"
31
 
31
 
32
 axis_bits_t Backlash::last_direction_bits;
32
 axis_bits_t Backlash::last_direction_bits;
33
-#ifdef BACKLASH_SMOOTHING_MM
34
-  xyz_long_t Backlash::residual_error{0};
35
-#endif
33
+xyz_long_t Backlash::residual_error{0};
36
 
34
 
37
 #ifdef BACKLASH_DISTANCE_MM
35
 #ifdef BACKLASH_DISTANCE_MM
38
   #if ENABLED(BACKLASH_GCODE)
36
   #if ENABLED(BACKLASH_GCODE)
43
 #endif
41
 #endif
44
 
42
 
45
 #if ENABLED(BACKLASH_GCODE)
43
 #if ENABLED(BACKLASH_GCODE)
46
-  uint8_t Backlash::correction = (BACKLASH_CORRECTION) * 0xFF;
44
+  uint8_t Backlash::correction = (BACKLASH_CORRECTION) * all_on;
47
   #ifdef BACKLASH_SMOOTHING_MM
45
   #ifdef BACKLASH_SMOOTHING_MM
48
     float Backlash::smoothing_mm = BACKLASH_SMOOTHING_MM;
46
     float Backlash::smoothing_mm = BACKLASH_SMOOTHING_MM;
49
   #endif
47
   #endif
87
   #endif
85
   #endif
88
   last_direction_bits ^= changed_dir;
86
   last_direction_bits ^= changed_dir;
89
 
87
 
90
-  if (correction == 0) return;
88
+  if (!correction && !residual_error) return;
91
 
89
 
92
   #ifdef BACKLASH_SMOOTHING_MM
90
   #ifdef BACKLASH_SMOOTHING_MM
93
     // The segment proportion is a value greater than 0.0 indicating how much residual_error
91
     // The segment proportion is a value greater than 0.0 indicating how much residual_error
95
     // smoothing distance. Since the computation of this proportion involves a floating point
93
     // smoothing distance. Since the computation of this proportion involves a floating point
96
     // division, defer computation until needed.
94
     // division, defer computation until needed.
97
     float segment_proportion = 0;
95
     float segment_proportion = 0;
98
-  #else
99
-    // No direction change, no correction.
100
-    if (!changed_dir) return;
101
-    // No leftover residual error from segment to segment
102
-    xyz_long_t residual_error{0};
103
   #endif
96
   #endif
104
 
97
 
105
-  const float f_corr = float(correction) / 255.0f;
98
+  const float f_corr = float(correction) / all_on;
106
 
99
 
107
   LOOP_LINEAR_AXES(axis) {
100
   LOOP_LINEAR_AXES(axis) {
108
     if (distance_mm[axis]) {
101
     if (distance_mm[axis]) {
109
-      const bool reversing = TEST(dm,axis);
102
+      const bool reverse = TEST(dm, axis);
110
 
103
 
111
       // When an axis changes direction, add axis backlash to the residual error
104
       // When an axis changes direction, add axis backlash to the residual error
112
       if (TEST(changed_dir, axis))
105
       if (TEST(changed_dir, axis))
113
-        residual_error[axis] += (reversing ? -f_corr : f_corr) * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis];
106
+        residual_error[axis] += (reverse ? -f_corr : f_corr) * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis];
114
 
107
 
115
       // Decide how much of the residual error to correct in this segment
108
       // Decide how much of the residual error to correct in this segment
116
       int32_t error_correction = residual_error[axis];
109
       int32_t error_correction = residual_error[axis];
110
+      if (reverse != (error_correction < 0))
111
+        error_correction = 0; // Don't take up any backlash in this segment, as it would subtract steps
112
+
117
       #ifdef BACKLASH_SMOOTHING_MM
113
       #ifdef BACKLASH_SMOOTHING_MM
118
         if (error_correction && smoothing_mm != 0) {
114
         if (error_correction && smoothing_mm != 0) {
119
-          // Take up a portion of the residual_error in this segment, but only when
120
-          // the current segment travels in the same direction as the correction
121
-          if (reversing == (error_correction < 0)) {
122
-            if (segment_proportion == 0) segment_proportion = _MIN(1.0f, block->millimeters / smoothing_mm);
123
-            error_correction = CEIL(segment_proportion * error_correction);
124
-          }
125
-          else
126
-            error_correction = 0; // Don't take up any backlash in this segment, as it would subtract steps
115
+          // Take up a portion of the residual_error in this segment
116
+          if (segment_proportion == 0) segment_proportion = _MIN(1.0f, block->millimeters / smoothing_mm);
117
+          error_correction = CEIL(segment_proportion * error_correction);
127
         }
118
         }
128
       #endif
119
       #endif
129
 
120
 
153
   }
144
   }
154
 }
145
 }
155
 
146
 
156
-int32_t Backlash::applied_steps(const AxisEnum axis) {
147
+int32_t Backlash::get_applied_steps(const AxisEnum axis) {
157
   if (axis >= LINEAR_AXES) return 0;
148
   if (axis >= LINEAR_AXES) return 0;
158
 
149
 
159
-  const bool reversing = TEST(last_direction_bits, axis);
150
+  const bool reverse = TEST(last_direction_bits, axis);
160
 
151
 
161
-  #ifdef BACKLASH_SMOOTHING_MM
162
-    const int32_t residual_error_axis = residual_error[axis];
163
-  #else
164
-    constexpr int32_t residual_error_axis = 0;
165
-  #endif
152
+  const int32_t residual_error_axis = residual_error[axis];
166
 
153
 
167
   // At startup it is assumed the last move was forwards. So the applied
154
   // At startup it is assumed the last move was forwards. So the applied
168
   // steps will always be a non-positive number.
155
   // steps will always be a non-positive number.
169
 
156
 
170
-  if (!reversing) return -residual_error_axis;
157
+  if (!reverse) return -residual_error_axis;
171
 
158
 
172
-  const float f_corr = float(correction) / 255.0f;
159
+  const float f_corr = float(correction) / all_on;
173
   const int32_t full_error_axis = -f_corr * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis];
160
   const int32_t full_error_axis = -f_corr * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis];
174
   return full_error_axis - residual_error_axis;
161
   return full_error_axis - residual_error_axis;
175
 }
162
 }
176
 
163
 
164
+class Backlash::StepAdjuster {
165
+  xyz_long_t applied_steps;
166
+public:
167
+  StepAdjuster() {
168
+    LOOP_LINEAR_AXES(axis) applied_steps[axis] = backlash.get_applied_steps((AxisEnum)axis);
169
+  }
170
+  ~StepAdjuster() {
171
+    // after backlash compensation parameter changes, ensure applied step count does not change
172
+    LOOP_LINEAR_AXES(axis) residual_error[axis] += backlash.get_applied_steps((AxisEnum)axis) - applied_steps[axis];
173
+  }
174
+};
175
+
176
+void Backlash::set_correction_uint8(const uint8_t v) {
177
+  StepAdjuster adjuster;
178
+  correction = v;
179
+}
180
+
181
+void Backlash::set_distance_mm(const AxisEnum axis, const float v) {
182
+  StepAdjuster adjuster;
183
+  distance_mm[axis] = v;
184
+}
185
+
186
+#ifdef BACKLASH_SMOOTHING_MM
187
+  void Backlash::set_smoothing_mm(const float v) {
188
+    StepAdjuster adjuster;
189
+    smoothing_mm = v;
190
+  }
191
+#endif
192
+
177
 #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
193
 #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
178
 
194
 
179
   #include "../module/probe.h"
195
   #include "../module/probe.h"

+ 29
- 17
Marlin/src/feature/backlash.h View File

24
 #include "../inc/MarlinConfigPre.h"
24
 #include "../inc/MarlinConfigPre.h"
25
 #include "../module/planner.h"
25
 #include "../module/planner.h"
26
 
26
 
27
-constexpr uint8_t all_on = 0xFF, all_off = 0x00;
28
-
29
 class Backlash {
27
 class Backlash {
28
+public:
29
+  static constexpr uint8_t all_on = 0xFF, all_off = 0x00;
30
+
30
 private:
31
 private:
31
   static axis_bits_t last_direction_bits;
32
   static axis_bits_t last_direction_bits;
32
-  #ifdef BACKLASH_SMOOTHING_MM
33
-    static xyz_long_t residual_error;
34
-  #endif
33
+  static xyz_long_t residual_error;
35
 
34
 
36
-public:
37
   #if ENABLED(BACKLASH_GCODE)
35
   #if ENABLED(BACKLASH_GCODE)
38
-    static xyz_float_t distance_mm;
39
     static uint8_t correction;
36
     static uint8_t correction;
37
+    static xyz_float_t distance_mm;
40
     #ifdef BACKLASH_SMOOTHING_MM
38
     #ifdef BACKLASH_SMOOTHING_MM
41
       static float smoothing_mm;
39
       static float smoothing_mm;
42
     #endif
40
     #endif
43
-
44
-    static void set_correction(const_float_t v) { correction = _MAX(0, _MIN(1.0, v)) * all_on; }
45
-    static float get_correction() { return float(ui8_to_percent(correction)) / 100.0f; }
46
   #else
41
   #else
47
-    static constexpr uint8_t correction = (BACKLASH_CORRECTION) * 0xFF;
42
+    static constexpr uint8_t correction = (BACKLASH_CORRECTION) * all_on;
48
     static const xyz_float_t distance_mm;
43
     static const xyz_float_t distance_mm;
49
     #ifdef BACKLASH_SMOOTHING_MM
44
     #ifdef BACKLASH_SMOOTHING_MM
50
       static constexpr float smoothing_mm = BACKLASH_SMOOTHING_MM;
45
       static constexpr float smoothing_mm = BACKLASH_SMOOTHING_MM;
52
   #endif
47
   #endif
53
 
48
 
54
   #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
49
   #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
55
-    private:
56
-      static xyz_float_t measured_mm;
57
-      static xyz_uint8_t measured_count;
58
-    public:
59
-      static void measure_with_probe();
50
+    static xyz_float_t measured_mm;
51
+    static xyz_uint8_t measured_count;
60
   #endif
52
   #endif
61
 
53
 
54
+  class StepAdjuster;
55
+
56
+public:
62
   static float get_measurement(const AxisEnum a) {
57
   static float get_measurement(const AxisEnum a) {
63
     UNUSED(a);
58
     UNUSED(a);
64
     // Return the measurement averaged over all readings
59
     // Return the measurement averaged over all readings
78
   }
73
   }
79
 
74
 
80
   static void add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const axis_bits_t dm, block_t * const block);
75
   static void add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const axis_bits_t dm, block_t * const block);
81
-  static int32_t applied_steps(const AxisEnum axis);
76
+  static int32_t get_applied_steps(const AxisEnum axis);
77
+
78
+  #if ENABLED(BACKLASH_GCODE)
79
+    static void set_correction_uint8(const uint8_t v);
80
+    static uint8_t get_correction_uint8() { return correction; }
81
+    static void set_correction(const float v) { set_correction_uint8(_MAX(0, _MIN(1.0, v)) * all_on + 0.5f); }
82
+    static float get_correction() { return float(get_correction_uint8()) / all_on; }
83
+    static void set_distance_mm(const AxisEnum axis, const float v);
84
+    static float get_distance_mm(const AxisEnum axis) {return distance_mm[axis];}
85
+    #ifdef BACKLASH_SMOOTHING_MM
86
+      static void set_smoothing_mm(const float v);
87
+      static float get_smoothing_mm() {return smoothing_mm;}
88
+    #endif
89
+  #endif
90
+
91
+  #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
92
+    static void measure_with_probe();
93
+  #endif
82
 };
94
 };
83
 
95
 
84
 extern Backlash backlash;
96
 extern Backlash backlash;

+ 37
- 23
Marlin/src/gcode/calibrate/G425.cpp View File

105
 };
105
 };
106
 
106
 
107
 #if ENABLED(BACKLASH_GCODE)
107
 #if ENABLED(BACKLASH_GCODE)
108
-  #define TEMPORARY_BACKLASH_CORRECTION(value) REMEMBER(tbst, backlash.correction, value)
108
+  class restorer_correction {
109
+    const uint8_t val_;
110
+  public:
111
+    restorer_correction(const uint8_t temp_val) : val_(backlash.get_correction_uint8()) { backlash.set_correction_uint8(temp_val); }
112
+    ~restorer_correction() { backlash.set_correction_uint8(val_); }
113
+  };
114
+
115
+  #define TEMPORARY_BACKLASH_CORRECTION(value) restorer_correction restorer_tbst(value)
109
 #else
116
 #else
110
   #define TEMPORARY_BACKLASH_CORRECTION(value)
117
   #define TEMPORARY_BACKLASH_CORRECTION(value)
111
 #endif
118
 #endif
112
 
119
 
113
 #if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
120
 #if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
114
-  #define TEMPORARY_BACKLASH_SMOOTHING(value) REMEMBER(tbsm, backlash.smoothing_mm, value)
121
+  class restorer_smoothing {
122
+    const float val_;
123
+  public:
124
+    restorer_smoothing(const float temp_val) : val_(backlash.get_smoothing_mm()) { backlash.set_smoothing_mm(temp_val); }
125
+    ~restorer_smoothing() { backlash.set_smoothing_mm(val_); }
126
+  };
127
+
128
+  #define TEMPORARY_BACKLASH_SMOOTHING(value) restorer_smoothing restorer_tbsm(value)
115
 #else
129
 #else
116
   #define TEMPORARY_BACKLASH_SMOOTHING(value)
130
   #define TEMPORARY_BACKLASH_SMOOTHING(value)
117
 #endif
131
 #endif
524
 
538
 
525
   {
539
   {
526
     // New scope for TEMPORARY_BACKLASH_CORRECTION
540
     // New scope for TEMPORARY_BACKLASH_CORRECTION
527
-    TEMPORARY_BACKLASH_CORRECTION(all_off);
541
+    TEMPORARY_BACKLASH_CORRECTION(backlash.all_off);
528
     TEMPORARY_BACKLASH_SMOOTHING(0.0f);
542
     TEMPORARY_BACKLASH_SMOOTHING(0.0f);
529
 
543
 
530
     probe_sides(m, uncertainty);
544
     probe_sides(m, uncertainty);
532
     #if ENABLED(BACKLASH_GCODE)
546
     #if ENABLED(BACKLASH_GCODE)
533
 
547
 
534
       #if HAS_X_CENTER
548
       #if HAS_X_CENTER
535
-        backlash.distance_mm.x = (m.backlash[LEFT] + m.backlash[RIGHT]) / 2;
549
+        backlash.set_distance_mm(X_AXIS, (m.backlash[LEFT] + m.backlash[RIGHT]) / 2);
536
       #elif ENABLED(CALIBRATION_MEASURE_LEFT)
550
       #elif ENABLED(CALIBRATION_MEASURE_LEFT)
537
-        backlash.distance_mm.x = m.backlash[LEFT];
551
+        backlash.set_distance_mm(X_AXIS, m.backlash[LEFT]);
538
       #elif ENABLED(CALIBRATION_MEASURE_RIGHT)
552
       #elif ENABLED(CALIBRATION_MEASURE_RIGHT)
539
-        backlash.distance_mm.x = m.backlash[RIGHT];
553
+        backlash.set_distance_mm(X_AXIS, m.backlash[RIGHT]);
540
       #endif
554
       #endif
541
 
555
 
542
       #if HAS_Y_CENTER
556
       #if HAS_Y_CENTER
543
-        backlash.distance_mm.y = (m.backlash[FRONT] + m.backlash[BACK]) / 2;
557
+        backlash.set_distance_mm(Y_AXIS, (m.backlash[FRONT] + m.backlash[BACK]) / 2);
544
       #elif ENABLED(CALIBRATION_MEASURE_FRONT)
558
       #elif ENABLED(CALIBRATION_MEASURE_FRONT)
545
-        backlash.distance_mm.y = m.backlash[FRONT];
559
+        backlash.set_distance_mm(Y_AXIS, m.backlash[FRONT]);
546
       #elif ENABLED(CALIBRATION_MEASURE_BACK)
560
       #elif ENABLED(CALIBRATION_MEASURE_BACK)
547
-        backlash.distance_mm.y = m.backlash[BACK];
561
+        backlash.set_distance_mm(Y_AXIS, m.backlash[BACK]);
548
       #endif
562
       #endif
549
 
563
 
550
-      TERN_(HAS_Z_AXIS, if (AXIS_CAN_CALIBRATE(Z)) backlash.distance_mm.z = m.backlash[TOP]);
564
+      TERN_(HAS_Z_AXIS, if (AXIS_CAN_CALIBRATE(Z)) backlash.set_distance_mm(Z_AXIS, m.backlash[TOP]));
551
 
565
 
552
       #if HAS_I_CENTER
566
       #if HAS_I_CENTER
553
-        backlash.distance_mm.i = (m.backlash[IMINIMUM] + m.backlash[IMAXIMUM]) / 2;
567
+        backlash.set_distance_mm(I_AXIS, (m.backlash[IMINIMUM] + m.backlash[IMAXIMUM]) / 2);
554
       #elif ENABLED(CALIBRATION_MEASURE_IMIN)
568
       #elif ENABLED(CALIBRATION_MEASURE_IMIN)
555
-        backlash.distance_mm.i = m.backlash[IMINIMUM];
569
+        backlash.set_distance_mm(I_AXIS, m.backlash[IMINIMUM]);
556
       #elif ENABLED(CALIBRATION_MEASURE_IMAX)
570
       #elif ENABLED(CALIBRATION_MEASURE_IMAX)
557
-        backlash.distance_mm.i = m.backlash[IMAXIMUM];
571
+        backlash.set_distance_mm(I_AXIS, m.backlash[IMAXIMUM]);
558
       #endif
572
       #endif
559
 
573
 
560
       #if HAS_J_CENTER
574
       #if HAS_J_CENTER
561
-        backlash.distance_mm.j = (m.backlash[JMINIMUM] + m.backlash[JMAXIMUM]) / 2;
575
+        backlash.set_distance_mm(J_AXIS, (m.backlash[JMINIMUM] + m.backlash[JMAXIMUM]) / 2);
562
       #elif ENABLED(CALIBRATION_MEASURE_JMIN)
576
       #elif ENABLED(CALIBRATION_MEASURE_JMIN)
563
-        backlash.distance_mm.j = m.backlash[JMINIMUM];
577
+        backlash.set_distance_mm(J_AXIS, m.backlash[JMINIMUM]);
564
       #elif ENABLED(CALIBRATION_MEASURE_JMAX)
578
       #elif ENABLED(CALIBRATION_MEASURE_JMAX)
565
-        backlash.distance_mm.j = m.backlash[JMAXIMUM];
579
+        backlash.set_distance_mm(J_AXIS, m.backlash[JMAXIMUM]);
566
       #endif
580
       #endif
567
 
581
 
568
       #if HAS_K_CENTER
582
       #if HAS_K_CENTER
569
-        backlash.distance_mm.k = (m.backlash[KMINIMUM] + m.backlash[KMAXIMUM]) / 2;
583
+        backlash.set_distance_mm(K_AXIS, (m.backlash[KMINIMUM] + m.backlash[KMAXIMUM]) / 2);
570
       #elif ENABLED(CALIBRATION_MEASURE_KMIN)
584
       #elif ENABLED(CALIBRATION_MEASURE_KMIN)
571
-        backlash.distance_mm.k = m.backlash[KMINIMUM];
585
+        backlash.set_distance_mm(K_AXIS, m.backlash[KMINIMUM]);
572
       #elif ENABLED(CALIBRATION_MEASURE_KMAX)
586
       #elif ENABLED(CALIBRATION_MEASURE_KMAX)
573
-        backlash.distance_mm.k = m.backlash[KMAXIMUM];
587
+        backlash.set_distance_mm(K_AXIS, m.backlash[KMAXIMUM]);
574
       #endif
588
       #endif
575
 
589
 
576
     #endif // BACKLASH_GCODE
590
     #endif // BACKLASH_GCODE
581
     // allowed directions to take up any backlash
595
     // allowed directions to take up any backlash
582
     {
596
     {
583
       // New scope for TEMPORARY_BACKLASH_CORRECTION
597
       // New scope for TEMPORARY_BACKLASH_CORRECTION
584
-      TEMPORARY_BACKLASH_CORRECTION(all_on);
598
+      TEMPORARY_BACKLASH_CORRECTION(backlash.all_on);
585
       TEMPORARY_BACKLASH_SMOOTHING(0.0f);
599
       TEMPORARY_BACKLASH_SMOOTHING(0.0f);
586
       const xyz_float_t move = LINEAR_AXIS_ARRAY(
600
       const xyz_float_t move = LINEAR_AXIS_ARRAY(
587
         AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3,
601
         AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3,
611
  *    - Call calibrate_backlash() beforehand for best accuracy
625
  *    - Call calibrate_backlash() beforehand for best accuracy
612
  */
626
  */
613
 inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const uint8_t extruder) {
627
 inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const uint8_t extruder) {
614
-  TEMPORARY_BACKLASH_CORRECTION(all_on);
628
+  TEMPORARY_BACKLASH_CORRECTION(backlash.all_on);
615
   TEMPORARY_BACKLASH_SMOOTHING(0.0f);
629
   TEMPORARY_BACKLASH_SMOOTHING(0.0f);
616
 
630
 
617
   TERN(HAS_MULTI_HOTEND, set_nozzle(m, extruder), UNUSED(extruder));
631
   TERN(HAS_MULTI_HOTEND, set_nozzle(m, extruder), UNUSED(extruder));
648
  *   uncertainty    in     - How far away from the object to begin probing
662
  *   uncertainty    in     - How far away from the object to begin probing
649
  */
663
  */
650
 inline void calibrate_all_toolheads(measurements_t &m, const float uncertainty) {
664
 inline void calibrate_all_toolheads(measurements_t &m, const float uncertainty) {
651
-  TEMPORARY_BACKLASH_CORRECTION(all_on);
665
+  TEMPORARY_BACKLASH_CORRECTION(backlash.all_on);
652
   TEMPORARY_BACKLASH_SMOOTHING(0.0f);
666
   TEMPORARY_BACKLASH_SMOOTHING(0.0f);
653
 
667
 
654
   HOTEND_LOOP() calibrate_toolhead(m, uncertainty, e);
668
   HOTEND_LOOP() calibrate_toolhead(m, uncertainty, e);
674
 
688
 
675
   TERN_(HAS_HOTEND_OFFSET, reset_hotend_offsets());
689
   TERN_(HAS_HOTEND_OFFSET, reset_hotend_offsets());
676
 
690
 
677
-  TEMPORARY_BACKLASH_CORRECTION(all_on);
691
+  TEMPORARY_BACKLASH_CORRECTION(backlash.all_on);
678
   TEMPORARY_BACKLASH_SMOOTHING(0.0f);
692
   TEMPORARY_BACKLASH_SMOOTHING(0.0f);
679
 
693
 
680
   // Do a fast and rough calibration of the toolheads
694
   // Do a fast and rough calibration of the toolheads

+ 12
- 12
Marlin/src/gcode/calibrate/M425.cpp View File

63
   LOOP_LINEAR_AXES(a) {
63
   LOOP_LINEAR_AXES(a) {
64
     if (axis_can_calibrate(a) && parser.seen(AXIS_CHAR(a))) {
64
     if (axis_can_calibrate(a) && parser.seen(AXIS_CHAR(a))) {
65
       planner.synchronize();
65
       planner.synchronize();
66
-      backlash.distance_mm[a] = parser.has_value() ? parser.value_linear_units() : backlash.get_measurement(AxisEnum(a));
66
+      backlash.set_distance_mm(AxisEnum(a), parser.has_value() ? parser.value_linear_units() : backlash.get_measurement(AxisEnum(a)));
67
       noArgs = false;
67
       noArgs = false;
68
     }
68
     }
69
   }
69
   }
77
   #ifdef BACKLASH_SMOOTHING_MM
77
   #ifdef BACKLASH_SMOOTHING_MM
78
     if (parser.seen('S')) {
78
     if (parser.seen('S')) {
79
       planner.synchronize();
79
       planner.synchronize();
80
-      backlash.smoothing_mm = parser.value_linear_units();
80
+      backlash.set_smoothing_mm(parser.value_linear_units());
81
       noArgs = false;
81
       noArgs = false;
82
     }
82
     }
83
   #endif
83
   #endif
84
 
84
 
85
   if (noArgs) {
85
   if (noArgs) {
86
     SERIAL_ECHOPGM("Backlash Correction ");
86
     SERIAL_ECHOPGM("Backlash Correction ");
87
-    if (!backlash.correction) SERIAL_ECHOPGM("in");
87
+    if (!backlash.get_correction_uint8()) SERIAL_ECHOPGM("in");
88
     SERIAL_ECHOLNPGM("active:");
88
     SERIAL_ECHOLNPGM("active:");
89
     SERIAL_ECHOLNPGM("  Correction Amount/Fade-out:     F", backlash.get_correction(), " (F1.0 = full, F0.0 = none)");
89
     SERIAL_ECHOLNPGM("  Correction Amount/Fade-out:     F", backlash.get_correction(), " (F1.0 = full, F0.0 = none)");
90
     SERIAL_ECHOPGM("  Backlash Distance (mm):        ");
90
     SERIAL_ECHOPGM("  Backlash Distance (mm):        ");
91
     LOOP_LINEAR_AXES(a) if (axis_can_calibrate(a)) {
91
     LOOP_LINEAR_AXES(a) if (axis_can_calibrate(a)) {
92
       SERIAL_CHAR(' ', AXIS_CHAR(a));
92
       SERIAL_CHAR(' ', AXIS_CHAR(a));
93
-      SERIAL_ECHO(backlash.distance_mm[a]);
93
+      SERIAL_ECHO(backlash.get_distance_mm(AxisEnum(a)));
94
       SERIAL_EOL();
94
       SERIAL_EOL();
95
     }
95
     }
96
 
96
 
97
     #ifdef BACKLASH_SMOOTHING_MM
97
     #ifdef BACKLASH_SMOOTHING_MM
98
-      SERIAL_ECHOLNPGM("  Smoothing (mm):                 S", backlash.smoothing_mm);
98
+      SERIAL_ECHOLNPGM("  Smoothing (mm):                 S", backlash.get_smoothing_mm());
99
     #endif
99
     #endif
100
 
100
 
101
     #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
101
     #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
118
   SERIAL_ECHOLNPGM_P(
118
   SERIAL_ECHOLNPGM_P(
119
     PSTR("  M425 F"), backlash.get_correction()
119
     PSTR("  M425 F"), backlash.get_correction()
120
     #ifdef BACKLASH_SMOOTHING_MM
120
     #ifdef BACKLASH_SMOOTHING_MM
121
-      , PSTR(" S"), LINEAR_UNIT(backlash.smoothing_mm)
121
+      , PSTR(" S"), LINEAR_UNIT(backlash.get_smoothing_mm())
122
     #endif
122
     #endif
123
     , LIST_N(DOUBLE(LINEAR_AXES),
123
     , LIST_N(DOUBLE(LINEAR_AXES),
124
-        SP_X_STR, LINEAR_UNIT(backlash.distance_mm.x),
125
-        SP_Y_STR, LINEAR_UNIT(backlash.distance_mm.y),
126
-        SP_Z_STR, LINEAR_UNIT(backlash.distance_mm.z),
127
-        SP_I_STR, LINEAR_UNIT(backlash.distance_mm.i),
128
-        SP_J_STR, LINEAR_UNIT(backlash.distance_mm.j),
129
-        SP_K_STR, LINEAR_UNIT(backlash.distance_mm.k)
124
+        SP_X_STR, LINEAR_UNIT(backlash.get_distance_mm(X_AXIS)),
125
+        SP_Y_STR, LINEAR_UNIT(backlash.get_distance_mm(Y_AXIS)),
126
+        SP_Z_STR, LINEAR_UNIT(backlash.get_distance_mm(Z_AXIS)),
127
+        SP_I_STR, LINEAR_UNIT(backlash.get_distance_mm(I_AXIS)),
128
+        SP_J_STR, LINEAR_UNIT(backlash.get_distance_mm(J_AXIS)),
129
+        SP_K_STR, LINEAR_UNIT(backlash.get_distance_mm(K_AXIS))
130
       )
130
       )
131
   );
131
   );
132
 }
132
 }

+ 6
- 6
Marlin/src/lcd/extui/ui_api.cpp View File

861
   #endif
861
   #endif
862
 
862
 
863
   #if ENABLED(BACKLASH_GCODE)
863
   #if ENABLED(BACKLASH_GCODE)
864
-    float getAxisBacklash_mm(const axis_t axis)       { return backlash.distance_mm[axis]; }
864
+    float getAxisBacklash_mm(const axis_t axis)       { return backlash.get_distance_mm((AxisEnum)axis); }
865
     void setAxisBacklash_mm(const_float_t value, const axis_t axis)
865
     void setAxisBacklash_mm(const_float_t value, const axis_t axis)
866
-                                                      { backlash.distance_mm[axis] = constrain(value,0,5); }
866
+                                                      { backlash.set_distance_mm((AxisEnum)axis, constrain(value,0,5)); }
867
 
867
 
868
-    float getBacklashCorrection_percent()             { return ui8_to_percent(backlash.correction); }
869
-    void setBacklashCorrection_percent(const_float_t value) { backlash.correction = map(constrain(value, 0, 100), 0, 100, 0, 255); }
868
+    float getBacklashCorrection_percent()             { return backlash.get_correction() * 100.0f; }
869
+    void setBacklashCorrection_percent(const_float_t value) { backlash.set_correction(constrain(value, 0, 100) / 100.0f); }
870
 
870
 
871
     #ifdef BACKLASH_SMOOTHING_MM
871
     #ifdef BACKLASH_SMOOTHING_MM
872
-      float getBacklashSmoothing_mm()                 { return backlash.smoothing_mm; }
873
-      void setBacklashSmoothing_mm(const_float_t value) { backlash.smoothing_mm = constrain(value, 0, 999); }
872
+      float getBacklashSmoothing_mm()                 { return backlash.get_smoothing_mm(); }
873
+      void setBacklashSmoothing_mm(const_float_t value) { backlash.set_smoothing_mm(constrain(value, 0, 999)); }
874
     #endif
874
     #endif
875
   #endif
875
   #endif
876
 
876
 

+ 10
- 3
Marlin/src/lcd/menu/menu_backlash.cpp View File

36
   START_MENU();
36
   START_MENU();
37
   BACK_ITEM(MSG_MAIN);
37
   BACK_ITEM(MSG_MAIN);
38
 
38
 
39
-  EDIT_ITEM_FAST(percent, MSG_BACKLASH_CORRECTION, &backlash.correction, all_off, all_on);
39
+  editable.uint8 = backlash.get_correction_uint8();
40
+  EDIT_ITEM_FAST(percent, MSG_BACKLASH_CORRECTION, &editable.uint8, backlash.all_off, backlash.all_on, []{ backlash.set_correction_uint8(editable.uint8); });
40
 
41
 
41
   #if DISABLED(CORE_BACKLASH) || EITHER(MARKFORGED_XY, MARKFORGED_YX)
42
   #if DISABLED(CORE_BACKLASH) || EITHER(MARKFORGED_XY, MARKFORGED_YX)
42
     #define _CAN_CALI AXIS_CAN_CALIBRATE
43
     #define _CAN_CALI AXIS_CAN_CALIBRATE
43
   #else
44
   #else
44
     #define _CAN_CALI(A) true
45
     #define _CAN_CALI(A) true
45
   #endif
46
   #endif
46
-  #define EDIT_BACKLASH_DISTANCE(N) EDIT_ITEM_FAST(float43, MSG_BACKLASH_##N, &backlash.distance_mm[_AXIS(N)], 0.0f, 9.9f);
47
+
48
+  #define EDIT_BACKLASH_DISTANCE(N) do { \
49
+    editable.decimal = backlash.get_distance_mm(_AXIS(N)); \
50
+    EDIT_ITEM_FAST(float43, MSG_BACKLASH_##N, &editable.decimal, 0.0f, 9.9f, []{ backlash.set_distance_mm(_AXIS(N), editable.decimal); }); \
51
+  } while (0);
52
+
47
   if (_CAN_CALI(A)) EDIT_BACKLASH_DISTANCE(A);
53
   if (_CAN_CALI(A)) EDIT_BACKLASH_DISTANCE(A);
48
   #if HAS_Y_AXIS && _CAN_CALI(B)
54
   #if HAS_Y_AXIS && _CAN_CALI(B)
49
     EDIT_BACKLASH_DISTANCE(B);
55
     EDIT_BACKLASH_DISTANCE(B);
62
   #endif
68
   #endif
63
 
69
 
64
   #ifdef BACKLASH_SMOOTHING_MM
70
   #ifdef BACKLASH_SMOOTHING_MM
65
-    EDIT_ITEM_FAST(float43, MSG_BACKLASH_SMOOTHING, &backlash.smoothing_mm, 0.0f, 9.9f);
71
+    editable.decimal = backlash.get_smoothing_mm();
72
+    EDIT_ITEM_FAST(float43, MSG_BACKLASH_SMOOTHING, &editable.decimal, 0.0f, 9.9f, []{ backlash.set_smoothing_mm(editable.decimal); });
66
   #endif
73
   #endif
67
 
74
 
68
   END_MENU();
75
   END_MENU();

+ 8
- 8
Marlin/src/module/planner.cpp View File

1706
 }
1706
 }
1707
 
1707
 
1708
 float Planner::triggered_position_mm(const AxisEnum axis) {
1708
 float Planner::triggered_position_mm(const AxisEnum axis) {
1709
-  const float result = DIFF_TERN(BACKLASH_COMPENSATION, stepper.triggered_position(axis), backlash.applied_steps(axis));
1709
+  const float result = DIFF_TERN(BACKLASH_COMPENSATION, stepper.triggered_position(axis), backlash.get_applied_steps(axis));
1710
   return result * mm_per_step[axis];
1710
   return result * mm_per_step[axis];
1711
 }
1711
 }
1712
 
1712
 
1729
       // Protect the access to the position.
1729
       // Protect the access to the position.
1730
       const bool was_enabled = stepper.suspend();
1730
       const bool was_enabled = stepper.suspend();
1731
 
1731
 
1732
-      const int32_t p1 = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(CORE_AXIS_1), backlash.applied_steps(CORE_AXIS_1)),
1733
-                    p2 = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(CORE_AXIS_2), backlash.applied_steps(CORE_AXIS_2));
1732
+      const int32_t p1 = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(CORE_AXIS_1), backlash.get_applied_steps(CORE_AXIS_1)),
1733
+                    p2 = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(CORE_AXIS_2), backlash.get_applied_steps(CORE_AXIS_2));
1734
 
1734
 
1735
       if (was_enabled) stepper.wake_up();
1735
       if (was_enabled) stepper.wake_up();
1736
 
1736
 
1739
       axis_steps = (axis == CORE_AXIS_2 ? CORESIGN(p1 - p2) : p1 + p2) * 0.5f;
1739
       axis_steps = (axis == CORE_AXIS_2 ? CORESIGN(p1 - p2) : p1 + p2) * 0.5f;
1740
     }
1740
     }
1741
     else
1741
     else
1742
-      axis_steps = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(axis), backlash.applied_steps(axis));
1742
+      axis_steps = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(axis), backlash.get_applied_steps(axis));
1743
 
1743
 
1744
   #elif EITHER(MARKFORGED_XY, MARKFORGED_YX)
1744
   #elif EITHER(MARKFORGED_XY, MARKFORGED_YX)
1745
 
1745
 
1756
       axis_steps = ((axis == CORE_AXIS_1) ? p1 - p2 : p2);
1756
       axis_steps = ((axis == CORE_AXIS_1) ? p1 - p2 : p2);
1757
     }
1757
     }
1758
     else
1758
     else
1759
-      axis_steps = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(axis), backlash.applied_steps(axis));
1759
+      axis_steps = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(axis), backlash.get_applied_steps(axis));
1760
 
1760
 
1761
   #else
1761
   #else
1762
 
1762
 
1763
     axis_steps = stepper.position(axis);
1763
     axis_steps = stepper.position(axis);
1764
-    TERN_(BACKLASH_COMPENSATION, axis_steps -= backlash.applied_steps(axis));
1764
+    TERN_(BACKLASH_COMPENSATION, axis_steps -= backlash.get_applied_steps(axis));
1765
 
1765
 
1766
   #endif
1766
   #endif
1767
 
1767
 
2844
 
2844
 
2845
   block->position = position;
2845
   block->position = position;
2846
   #if ENABLED(BACKLASH_COMPENSATION)
2846
   #if ENABLED(BACKLASH_COMPENSATION)
2847
-    LOOP_LINEAR_AXES(axis) block->position[axis] += backlash.applied_steps((AxisEnum)axis);
2847
+    LOOP_LINEAR_AXES(axis) block->position[axis] += backlash.get_applied_steps((AxisEnum)axis);
2848
   #endif
2848
   #endif
2849
 
2849
 
2850
   #if BOTH(HAS_FAN, LASER_SYNCHRONOUS_M106_M107)
2850
   #if BOTH(HAS_FAN, LASER_SYNCHRONOUS_M106_M107)
3122
   else {
3122
   else {
3123
     #if ENABLED(BACKLASH_COMPENSATION)
3123
     #if ENABLED(BACKLASH_COMPENSATION)
3124
       abce_long_t stepper_pos = position;
3124
       abce_long_t stepper_pos = position;
3125
-      LOOP_LINEAR_AXES(axis) stepper_pos[axis] += backlash.applied_steps((AxisEnum)axis);
3125
+      LOOP_LINEAR_AXES(axis) stepper_pos[axis] += backlash.get_applied_steps((AxisEnum)axis);
3126
       stepper.set_position(stepper_pos);
3126
       stepper.set_position(stepper_pos);
3127
     #else
3127
     #else
3128
       stepper.set_position(position);
3128
       stepper.set_position(position);

+ 19
- 18
Marlin/src/module/settings.cpp View File

1426
     //
1426
     //
1427
     {
1427
     {
1428
       #if ENABLED(BACKLASH_GCODE)
1428
       #if ENABLED(BACKLASH_GCODE)
1429
-        const xyz_float_t &backlash_distance_mm = backlash.distance_mm;
1430
-        const uint8_t &backlash_correction = backlash.correction;
1429
+        xyz_float_t backlash_distance_mm;
1430
+        LOOP_LINEAR_AXES(axis) backlash_distance_mm[axis] = backlash.get_distance_mm((AxisEnum)axis);
1431
+        const uint8_t backlash_correction = backlash.get_correction_uint8();
1431
       #else
1432
       #else
1432
         const xyz_float_t backlash_distance_mm{0};
1433
         const xyz_float_t backlash_distance_mm{0};
1433
         const uint8_t backlash_correction = 0;
1434
         const uint8_t backlash_correction = 0;
1434
       #endif
1435
       #endif
1435
       #if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
1436
       #if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
1436
-        const float &backlash_smoothing_mm = backlash.smoothing_mm;
1437
+        const float backlash_smoothing_mm = backlash.get_smoothing_mm();
1437
       #else
1438
       #else
1438
         const float backlash_smoothing_mm = 3;
1439
         const float backlash_smoothing_mm = 3;
1439
       #endif
1440
       #endif
2364
       // Backlash Compensation
2365
       // Backlash Compensation
2365
       //
2366
       //
2366
       {
2367
       {
2367
-        #if ENABLED(BACKLASH_GCODE)
2368
-          const xyz_float_t &backlash_distance_mm = backlash.distance_mm;
2369
-          const uint8_t &backlash_correction = backlash.correction;
2370
-        #else
2371
-          xyz_float_t backlash_distance_mm;
2372
-          uint8_t backlash_correction;
2373
-        #endif
2374
-        #if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
2375
-          const float &backlash_smoothing_mm = backlash.smoothing_mm;
2376
-        #else
2377
-          float backlash_smoothing_mm;
2378
-        #endif
2368
+        xyz_float_t backlash_distance_mm;
2369
+        uint8_t backlash_correction;
2370
+        float backlash_smoothing_mm;
2371
+
2379
         _FIELD_TEST(backlash_distance_mm);
2372
         _FIELD_TEST(backlash_distance_mm);
2380
         EEPROM_READ(backlash_distance_mm);
2373
         EEPROM_READ(backlash_distance_mm);
2381
         EEPROM_READ(backlash_correction);
2374
         EEPROM_READ(backlash_correction);
2382
         EEPROM_READ(backlash_smoothing_mm);
2375
         EEPROM_READ(backlash_smoothing_mm);
2376
+
2377
+        #if ENABLED(BACKLASH_GCODE)
2378
+          LOOP_LINEAR_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, backlash_distance_mm[axis]);
2379
+          backlash.set_correction_uint8(backlash_correction);
2380
+          #ifdef BACKLASH_SMOOTHING_MM
2381
+            backlash.set_smoothing_mm(backlash_smoothing_mm);
2382
+          #endif
2383
+        #endif
2383
       }
2384
       }
2384
 
2385
 
2385
       //
2386
       //
2811
   #endif
2812
   #endif
2812
 
2813
 
2813
   #if ENABLED(BACKLASH_GCODE)
2814
   #if ENABLED(BACKLASH_GCODE)
2814
-    backlash.correction = (BACKLASH_CORRECTION) * 255;
2815
+    backlash.set_correction(BACKLASH_CORRECTION);
2815
     constexpr xyz_float_t tmp = BACKLASH_DISTANCE_MM;
2816
     constexpr xyz_float_t tmp = BACKLASH_DISTANCE_MM;
2816
-    backlash.distance_mm = tmp;
2817
+    LOOP_LINEAR_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, tmp[axis]);
2817
     #ifdef BACKLASH_SMOOTHING_MM
2818
     #ifdef BACKLASH_SMOOTHING_MM
2818
-      backlash.smoothing_mm = BACKLASH_SMOOTHING_MM;
2819
+      backlash.set_smoothing_mm(BACKLASH_SMOOTHING_MM);
2819
     #endif
2820
     #endif
2820
   #endif
2821
   #endif
2821
 
2822
 

Loading…
Cancel
Save