Browse Source

Merge pull request #10443 from thinkyhead/bf2_fix_and_improve

[2.0.x] Improve UBL mesh report, M420 V T, M421 N, and…
Scott Lahteine 7 years ago
parent
commit
f57a008c58
No account linked to committer's email address

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

@@ -208,7 +208,7 @@
208 208
 #define NEAR(x,y) NEAR_ZERO((x)-(y))
209 209
 
210 210
 #define RECIPROCAL(x) (NEAR_ZERO(x) ? 0.0 : 1.0 / (x))
211
-#define FIXFLOAT(f) (f + 0.00001)
211
+#define FIXFLOAT(f) (f + (f < 0.0 ? -0.00001 : 0.00001))
212 212
 
213 213
 //
214 214
 // Maths macros that can be overridden by HAL

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

@@ -99,7 +99,21 @@ void set_bed_leveling_enabled(const bool enable/*=true*/) {
99 99
           planner.unapply_leveling(current_position);
100 100
         }
101 101
       #else
102
-        planner.leveling_active = enable;                    // just flip the bit, current_position will be wrong until next move.
102
+        // UBL equivalents for apply/unapply_leveling
103
+        #if ENABLED(SKEW_CORRECTION)
104
+          float pos[XYZ] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] };
105
+          planner.skew(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS]);
106
+        #else
107
+          const float (&pos)[XYZE] = current_position;
108
+        #endif
109
+        if (planner.leveling_active) {
110
+          current_position[Z_AXIS] += ubl.get_z_correction(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS]);
111
+          planner.leveling_active = false;
112
+        }
113
+        else {
114
+          planner.leveling_active = true;
115
+          current_position[Z_AXIS] -= ubl.get_z_correction(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS]);
116
+        }
103 117
       #endif
104 118
 
105 119
     #else // OLDSCHOOL_ABL

+ 78
- 58
Marlin/src/feature/bedlevel/ubl/ubl.cpp View File

@@ -51,7 +51,7 @@
51 51
   ) {
52 52
     if (!leveling_is_valid()) return;
53 53
     SERIAL_ECHO_START_P(port);
54
-    SERIAL_ECHOLNPGM_P(port, "  G29 I 999");
54
+    SERIAL_ECHOLNPGM_P(port, "  G29 I99");
55 55
     for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
56 56
       for (uint8_t y = 0;  y < GRID_MAX_POINTS_Y; y++)
57 57
         if (!isnan(z_values[x][y])) {
@@ -59,9 +59,7 @@
59 59
           SERIAL_ECHOPAIR_P(port, "  M421 I", x);
60 60
           SERIAL_ECHOPAIR_P(port, " J", y);
61 61
           SERIAL_ECHOPGM_P(port, " Z");
62
-          SERIAL_ECHO_F_P(port, z_values[x][y], 6);
63
-          SERIAL_ECHOPAIR_P(port, " ; X", LOGICAL_X_POSITION(mesh_index_to_xpos(x)));
64
-          SERIAL_ECHOPAIR_P(port, ", Y", LOGICAL_Y_POSITION(mesh_index_to_ypos(y)));
62
+          SERIAL_ECHO_F_P(port, z_values[x][y], 2);
65 63
           SERIAL_EOL_P(port);
66 64
           safe_delay(75); // Prevent Printrun from exploding
67 65
         }
@@ -83,15 +81,6 @@
83 81
     safe_delay(50);
84 82
   }
85 83
 
86
-  static void serial_echo_xy(const int16_t x, const int16_t y) {
87
-    SERIAL_CHAR('(');
88
-    SERIAL_ECHO(x);
89
-    SERIAL_CHAR(',');
90
-    SERIAL_ECHO(y);
91
-    SERIAL_CHAR(')');
92
-    safe_delay(10);
93
-  }
94
-
95 84
   #if ENABLED(UBL_DEVEL_DEBUGGING)
96 85
 
97 86
     static void debug_echo_axis(const AxisEnum axis) {
@@ -189,78 +178,109 @@
189 178
     }
190 179
   }
191 180
 
192
-  // display_map() currently produces three different mesh map types
193
-  // 0 : suitable for PronterFace and Repetier's serial console
194
-  // 1 : .CSV file suitable for importation into various spread sheets
195
-  // 2 : disply of the map data on a RepRap Graphical LCD Panel
181
+  static void serial_echo_xy(const uint8_t sp, const int16_t x, const int16_t y) {
182
+    SERIAL_ECHO_SP(sp);
183
+    SERIAL_CHAR('(');
184
+    if (x < 100) { SERIAL_CHAR(' '); if (x < 10) SERIAL_CHAR(' '); }
185
+    SERIAL_ECHO(x);
186
+    SERIAL_CHAR(',');
187
+    if (y < 100) { SERIAL_CHAR(' '); if (y < 10) SERIAL_CHAR(' '); }
188
+    SERIAL_ECHO(y);
189
+    SERIAL_CHAR(')');
190
+    safe_delay(5);
191
+  }
192
+
193
+  static void serial_echo_column_labels(const uint8_t sp) {
194
+    SERIAL_ECHO_SP(7);
195
+    for (int8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
196
+      if (i < 10) SERIAL_CHAR(' ');
197
+      SERIAL_ECHO(i);
198
+      SERIAL_ECHO_SP(sp);
199
+    }
200
+    safe_delay(10);
201
+  }
196 202
 
203
+  /**
204
+   * Produce one of these mesh maps:
205
+   *   0: Human-readable
206
+   *   1: CSV format for spreadsheet import
207
+   *   2: TODO: Display on Graphical LCD
208
+   *   4: Compact Human-Readable
209
+   */
197 210
   void unified_bed_leveling::display_map(const int map_type) {
198 211
     #if HAS_AUTO_REPORTING || ENABLED(HOST_KEEPALIVE_FEATURE)
199 212
       suspend_auto_report = true;
200 213
     #endif
201 214
 
202
-    constexpr uint8_t spaces = 8 * (GRID_MAX_POINTS_X - 2);
215
+    constexpr uint8_t eachsp = 1 + 6 + 1,                           // [-3.567]
216
+                      twixt = eachsp * (GRID_MAX_POINTS_X) - 9 * 2; // Leading 4sp, Coordinates 9sp each
203 217
 
204
-    SERIAL_PROTOCOLPGM("\nBed Topography Report");
205
-    if (map_type == 0) {
206
-      SERIAL_PROTOCOLPGM(":\n\n");
207
-      serial_echo_xy(0, GRID_MAX_POINTS_Y - 1);
208
-      SERIAL_ECHO_SP(spaces + 3);
209
-      serial_echo_xy(GRID_MAX_POINTS_X - 1, GRID_MAX_POINTS_Y - 1);
210
-      SERIAL_EOL();
211
-      serial_echo_xy(MESH_MIN_X, MESH_MAX_Y);
212
-      SERIAL_ECHO_SP(spaces);
213
-      serial_echo_xy(MESH_MAX_X, MESH_MAX_Y);
218
+    const bool human = !(map_type & 0x3), csv = map_type == 1, lcd = map_type == 2, comp = map_type & 0x4;
219
+
220
+    SERIAL_ECHOPGM("\nBed Topography Report");
221
+    if (human) {
222
+      SERIAL_ECHOPGM(":\n\n");
223
+      serial_echo_xy(4, MESH_MIN_X, MESH_MAX_Y);
224
+      serial_echo_xy(twixt, MESH_MAX_X, MESH_MAX_Y);
214 225
       SERIAL_EOL();
226
+      serial_echo_column_labels(eachsp - 2);
215 227
     }
216 228
     else {
217
-      SERIAL_PROTOCOLPGM(" for ");
218
-      serialprintPGM(map_type == 1 ? PSTR("CSV:\n\n") : PSTR("LCD:\n\n"));
229
+      SERIAL_ECHOPGM(" for ");
230
+      serialprintPGM(csv ? PSTR("CSV:\n") : PSTR("LCD:\n"));
219 231
     }
220 232
 
221 233
     const float current_xi = get_cell_index_x(current_position[X_AXIS] + (MESH_X_DIST) / 2.0),
222 234
                 current_yi = get_cell_index_y(current_position[Y_AXIS] + (MESH_Y_DIST) / 2.0);
223 235
 
236
+    if (!lcd) SERIAL_EOL();
224 237
     for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) {
238
+
239
+      // Row Label (J index)
240
+      if (human) {
241
+        if (j < 10) SERIAL_CHAR(' ');
242
+        SERIAL_ECHO(j);
243
+        SERIAL_ECHOPGM(" |");
244
+      }
245
+
246
+      // Row Values (I indexes)
225 247
       for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
226
-        const bool is_current = i == current_xi && j == current_yi;
227 248
 
228
-        // is the nozzle here? then mark the number
229
-        if (map_type == 0) SERIAL_CHAR(is_current ? '[' : ' ');
249
+        // Opening Brace or Space
250
+        const bool is_current = i == current_xi && j == current_yi;
251
+        if (human) SERIAL_CHAR(is_current ? '[' : ' ');
230 252
 
253
+        // Z Value at current I, J
231 254
         const float f = z_values[i][j];
232
-        if (isnan(f)) {
233
-          serialprintPGM(map_type == 0 ? PSTR("    .   ") : PSTR("NAN"));
255
+        if (lcd) {
256
+          // TODO: Display on Graphical LCD
234 257
         }
235
-        else if (map_type <= 1) {
236
-          // if we don't do this, the columns won't line up nicely
237
-          if (map_type == 0 && f >= 0.0) SERIAL_CHAR(' ');
238
-          SERIAL_PROTOCOL_F(f, 3);
258
+        else if (isnan(f))
259
+          serialprintPGM(human ? PSTR("  .   ") : PSTR("NAN"));
260
+        else if (human || csv) {
261
+          if (human && f >= 0.0) SERIAL_CHAR(f > 0 ? '+' : ' ');  // Space for positive ('-' for negative)
262
+          SERIAL_ECHO_F(f, 3);                                    // Positive: 5 digits, Negative: 6 digits
239 263
         }
240
-        idle();
241
-        if (map_type == 1 && i < GRID_MAX_POINTS_X - 1) SERIAL_CHAR(',');
264
+        if (csv && i < GRID_MAX_POINTS_X - 1) SERIAL_CHAR('\t');
265
+
266
+        // Closing Brace or Space
267
+        if (human) SERIAL_CHAR(is_current ? ']' : ' ');
268
+
242 269
         SERIAL_FLUSHTX();
243
-        safe_delay(15);
244
-        if (map_type == 0) {
245
-          SERIAL_CHAR(is_current ? ']' : ' ');
246
-          SERIAL_CHAR(' ');
247
-        }
248
-      }
249
-      SERIAL_EOL();
250
-      if (j && map_type == 0) { // we want the (0,0) up tight against the block of numbers
251
-        SERIAL_CHAR(' ');
252
-        SERIAL_EOL();
270
+        idle();
253 271
       }
272
+      if (!lcd) SERIAL_EOL();
273
+
274
+      // A blank line between rows (unless compact)
275
+      if (j && human && !comp) SERIAL_ECHOLNPGM("   |");
254 276
     }
255 277
 
256
-    if (map_type == 0) {
257
-      serial_echo_xy(MESH_MIN_X, MESH_MIN_Y);
258
-      SERIAL_ECHO_SP(spaces + 4);
259
-      serial_echo_xy(MESH_MAX_X, MESH_MIN_Y);
278
+    if (human) {
279
+      serial_echo_column_labels(eachsp - 2);
280
+      SERIAL_EOL();
281
+      serial_echo_xy(4, MESH_MIN_X, MESH_MIN_Y);
282
+      serial_echo_xy(twixt, MESH_MAX_X, MESH_MIN_Y);
260 283
       SERIAL_EOL();
261
-      serial_echo_xy(0, 0);
262
-      SERIAL_ECHO_SP(spaces + 5);
263
-      serial_echo_xy(GRID_MAX_POINTS_X - 1, 0);
264 284
       SERIAL_EOL();
265 285
     }
266 286
 

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

@@ -252,9 +252,7 @@
252 252
    *                    for subsequent Load and Store operations. Valid storage slot numbers begin at 0 and
253 253
    *                    extend to a limit related to the available EEPROM storage.
254 254
    *
255
-   *   S -1  Store      Store the current Mesh as a print out that is suitable to be feed back into the system
256
-   *                    at a later date. The GCode output can be saved and later replayed by the host software
257
-   *                    to reconstruct the current mesh on another machine.
255
+   *   S -1  Store      Print the current Mesh as G-code that can be used to restore the mesh anytime.
258 256
    *
259 257
    *   T     Topology   Display the Mesh Map Topology.
260 258
    *                    'T' can be used alone (e.g., G29 T) or in combination with most of the other commands.

+ 8
- 6
Marlin/src/feature/fwretract.cpp View File

@@ -122,6 +122,7 @@ void FWRetract::retract(const bool retracting
122 122
       SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
123 123
     }
124 124
     SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
125
+    SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
125 126
     SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
126 127
   //*/
127 128
 
@@ -138,7 +139,7 @@ void FWRetract::retract(const bool retracting
138 139
     feedrate_mm_s = retract_feedrate_mm_s;
139 140
     current_position[E_AXIS] += (swapping ? swap_retract_length : retract_length) * renormalize;
140 141
     sync_plan_position_e();
141
-    prepare_move_to_destination();
142
+    prepare_move_to_destination();  // set_current_to_destination
142 143
 
143 144
     // Is a Z hop set, and has the hop not yet been done?
144 145
     // No double zlifting
@@ -148,7 +149,7 @@ void FWRetract::retract(const bool retracting
148 149
       hop_amount += retract_zlift;                        // Add to the hop total (again, only once)
149 150
       destination[Z_AXIS] += retract_zlift;               // Raise Z by the zlift (M207 Z) amount
150 151
       feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS];  // Maximum Z feedrate
151
-      prepare_move_to_destination();                      // Raise up
152
+      prepare_move_to_destination();                      // Raise up, set_current_to_destination
152 153
       current_position[Z_AXIS] = old_z;                   // Spoof the Z position in the planner
153 154
       SYNC_PLAN_POSITION_KINEMATIC();
154 155
     }
@@ -159,17 +160,17 @@ void FWRetract::retract(const bool retracting
159 160
       current_position[Z_AXIS] += hop_amount;             // Set actual Z (due to the prior hop)
160 161
       SYNC_PLAN_POSITION_KINEMATIC();                     // Spoof the Z position in the planner
161 162
       feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS];  // Z feedrate to max
162
-      prepare_move_to_destination();                      // Lower Z and update current_position
163
+      prepare_move_to_destination();                      // Lower Z, set_current_to_destination
163 164
       hop_amount = 0.0;                                   // Clear the hop amount
164 165
     }
165 166
 
166 167
     // A retract multiplier has been added here to get faster swap recovery
167 168
     feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s;
168 169
 
169
-    const float move_e = swapping ? swap_retract_length + swap_retract_recover_length : retract_length + retract_recover_length;
170
-    current_position[E_AXIS] -= move_e * renormalize;
170
+    current_position[E_AXIS] -= (swapping ? swap_retract_length + swap_retract_recover_length
171
+                                          : retract_length + retract_recover_length) * renormalize;
171 172
     sync_plan_position_e();
172
-    prepare_move_to_destination();  // Recover E
173
+    prepare_move_to_destination();                        // Recover E, set_current_to_destination
173 174
   }
174 175
 
175 176
   feedrate_mm_s = old_feedrate_mm_s;                      // Restore original feedrate
@@ -192,6 +193,7 @@ void FWRetract::retract(const bool retracting
192 193
       SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
193 194
     }
194 195
     SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
196
+    SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
195 197
     SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
196 198
   //*/
197 199
 

+ 2
- 1
Marlin/src/gcode/bedlevel/M420.cpp View File

@@ -42,6 +42,7 @@
42 42
  * With AUTO_BED_LEVELING_UBL only:
43 43
  *
44 44
  *   L[index]  Load UBL mesh from index (0 is default)
45
+ *   T[map]    0:Human-readable 1:CSV 2:"LCD" 4:Compact
45 46
  */
46 47
 void GcodeSuite::M420() {
47 48
 
@@ -80,7 +81,7 @@ void GcodeSuite::M420() {
80 81
 
81 82
     // L or V display the map info
82 83
     if (parser.seen('L') || parser.seen('V')) {
83
-      ubl.display_map(0);  // Currently only supports one map type
84
+      ubl.display_map(parser.byteval('T'));
84 85
       SERIAL_ECHOLNPAIR("ubl.mesh_is_valid = ", ubl.mesh_is_valid());
85 86
       SERIAL_ECHOLNPAIR("ubl.storage_slot = ", ubl.storage_slot);
86 87
     }

+ 4
- 2
Marlin/src/gcode/bedlevel/ubl/M421.cpp View File

@@ -37,6 +37,7 @@
37 37
  * Usage:
38 38
  *   M421 I<xindex> J<yindex> Z<linear>
39 39
  *   M421 I<xindex> J<yindex> Q<offset>
40
+ *   M421 I<xindex> J<yindex> N
40 41
  *   M421 C Z<linear>
41 42
  *   M421 C Q<offset>
42 43
  */
@@ -45,6 +46,7 @@ void GcodeSuite::M421() {
45 46
   const bool hasI = ix >= 0,
46 47
              hasJ = iy >= 0,
47 48
              hasC = parser.seen('C'),
49
+             hasN = parser.seen('N'),
48 50
              hasZ = parser.seen('Z'),
49 51
              hasQ = !hasZ && parser.seen('Q');
50 52
 
@@ -54,7 +56,7 @@ void GcodeSuite::M421() {
54 56
     iy = location.y_index;
55 57
   }
56 58
 
57
-  if (int(hasC) + int(hasI && hasJ) != 1 || !(hasZ || hasQ)) {
59
+  if (int(hasC) + int(hasI && hasJ) != 1 || !(hasZ || hasQ || hasN)) {
58 60
     SERIAL_ERROR_START();
59 61
     SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS);
60 62
   }
@@ -63,7 +65,7 @@ void GcodeSuite::M421() {
63 65
     SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY);
64 66
   }
65 67
   else
66
-    ubl.z_values[ix][iy] = parser.value_linear_units() + (hasQ ? ubl.z_values[ix][iy] : 0);
68
+    ubl.z_values[ix][iy] = hasN ? NAN : parser.value_linear_units() + (hasQ ? ubl.z_values[ix][iy] : 0);
67 69
 }
68 70
 
69 71
 #endif // AUTO_BED_LEVELING_UBL

+ 8
- 0
Marlin/src/gcode/config/M221.cpp View File

@@ -32,4 +32,12 @@ void GcodeSuite::M221() {
32 32
     planner.flow_percentage[target_extruder] = parser.value_int();
33 33
     planner.refresh_e_factor(target_extruder);
34 34
   }
35
+  else {
36
+    SERIAL_ECHO_START();
37
+    SERIAL_CHAR('E');
38
+    SERIAL_CHAR('0' + target_extruder);
39
+    SERIAL_ECHOPAIR(" Flow: ", planner.flow_percentage[target_extruder]);
40
+    SERIAL_CHAR('%');
41
+    SERIAL_EOL();
42
+  }
35 43
 }

+ 4
- 0
Marlin/src/inc/Conditionals_post.h View File

@@ -1039,6 +1039,10 @@
1039 1039
 #define PLANNER_LEVELING      (OLDSCHOOL_ABL || ENABLED(MESH_BED_LEVELING) || UBL_SEGMENTED || ENABLED(SKEW_CORRECTION))
1040 1040
 #define HAS_PROBING_PROCEDURE (HAS_ABL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST))
1041 1041
 
1042
+#if ENABLED(AUTO_BED_LEVELING_UBL)
1043
+  #undef LCD_BED_LEVELING
1044
+#endif
1045
+
1042 1046
 /**
1043 1047
  * Heater & Fan Pausing
1044 1048
  */

+ 8
- 6
Marlin/src/lcd/ultralcd.cpp View File

@@ -2931,14 +2931,16 @@ void kill_screen(const char* lcd_msg) {
2931 2931
       const float diff = float((int32_t)encoderPosition) * move_menu_scale;
2932 2932
       #if IS_KINEMATIC
2933 2933
         manual_move_offset += diff;
2934
-        // Limit only when trying to move towards the limit
2935
-        if ((int32_t)encoderPosition < 0) NOLESS(manual_move_offset, min - current_position[axis]);
2936
-        if ((int32_t)encoderPosition > 0) NOMORE(manual_move_offset, max - current_position[axis]);
2934
+        if ((int32_t)encoderPosition < 0)
2935
+          NOLESS(manual_move_offset, min - current_position[axis]);
2936
+        else
2937
+          NOMORE(manual_move_offset, max - current_position[axis]);
2937 2938
       #else
2938 2939
         current_position[axis] += diff;
2939
-        // Limit only when trying to move towards the limit
2940
-        if ((int32_t)encoderPosition < 0) NOLESS(current_position[axis], min);
2941
-        if ((int32_t)encoderPosition > 0) NOMORE(current_position[axis], max);
2940
+        if ((int32_t)encoderPosition < 0)
2941
+          NOLESS(current_position[axis], min);
2942
+        else
2943
+          NOMORE(current_position[axis], max);
2942 2944
       #endif
2943 2945
 
2944 2946
       manual_move_to_current(axis);

Loading…
Cancel
Save