Map clean up of UBL

UBL's maps are cleaner.   And with a 1 value, G29 O 1  will generate a
map suitable to be Cut & Pasted into Excel so a Suface Map can be
generated.
This commit is contained in:
Roxy-3D
2017-03-25 18:37:54 -05:00
committed by Roxy-3D
parent 9a1949a91e
commit 9d3ac66f73
3 changed files with 137 additions and 81 deletions

View File

@@ -125,7 +125,10 @@
* O Map * Display the Mesh Map Topology.
* The parameter can be specified alone (ie. G29 O) or in combination with many of the
* other commands. The Mesh Map option works with all of the Phase
* commands (ie. G29 P4 R 5 X 50 Y100 C -.1 O)
* commands (ie. G29 P4 R 5 X 50 Y100 C -.1 O) The Map parameter can also of a Map Type
* specified. A map type of 0 is the default is user readable. A map type of 1 can
* be specified and is suitable to Cut & Paste into Excel to allow graphing of the user's
* mesh.
*
* N No Home G29 normally insists that a G28 has been performed. You can over rule this with an
* N option. In general, you should not do this. This can only be done safely with
@@ -250,6 +253,10 @@
*
* T 3-Point Perform a 3 Point Bed Leveling on the current Mesh
*
* U Unlevel Perform a probe of the outer perimeter to assist in physically leveling unlevel beds.
* Only used for G29 P1 O U It will speed up the probing of the edge of the bed. This
* is useful when the entire bed does not need to be probed because it will be adjusted.
*
* W What? Display valuable data the Unified Bed Leveling System knows.
*
* X # * * X Location for this line of commands
@@ -297,7 +304,7 @@
// The simple parameter flags and values are 'static' so parameter parsing can be in a support routine.
static int g29_verbose_level = 0, phase_value = -1, repetition_cnt = 1,
storage_slot = 0, test_pattern = 0;
storage_slot = 0, map_type = 0, test_pattern = 0, unlevel_value = -1;
static bool repeat_flag = UBL_OK, c_flag = false, x_flag = UBL_OK, y_flag = UBL_OK, statistics_flag = UBL_OK, business_card_mode = false;
static float x_pos = 0.0, y_pos = 0.0, height_value = 5.0, measured_z, card_thickness = 0.0, constant = 0.0;
@@ -331,7 +338,7 @@
if (code_seen('I')) {
repetition_cnt = code_has_value() ? code_value_int() : 1;
while (repetition_cnt--) {
const mesh_index_pair location = find_closest_mesh_point_of_type(REAL, x_pos, y_pos, 0, NULL); // The '0' says we want to use the nozzle's position
const mesh_index_pair location = find_closest_mesh_point_of_type(REAL, x_pos, y_pos, 0, NULL, false); // The '0' says we want to use the nozzle's position
if (location.x_index < 0) {
SERIAL_PROTOCOLLNPGM("Entire Mesh invalidated.\n");
break; // No more invalid Mesh Points to populate
@@ -381,6 +388,16 @@
}
}
/*
if (code_seen('U')) {
unlevel_value = code_value_int();
// if (unlevel_value < 0 || unlevel_value > 7) {
// SERIAL_PROTOCOLLNPGM("Invalid Unlevel value. (0-4)\n");
// return;
// }
}
*/
if (code_seen('P')) {
phase_value = code_value_int();
if (phase_value < 0 || phase_value > 7) {
@@ -410,7 +427,7 @@
SERIAL_PROTOCOLLNPGM(")\n");
}
probe_entire_mesh(x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER,
code_seen('O') || code_seen('M'), code_seen('E'));
code_seen('O') || code_seen('M'), code_seen('E'), code_seen('U'));
break;
//
// Manually Probe Mesh in areas that can not be reached by the probe
@@ -455,7 +472,7 @@
// If no repetition is specified, do the whole Mesh
if (!repeat_flag) repetition_cnt = 9999;
while (repetition_cnt--) {
const mesh_index_pair location = find_closest_mesh_point_of_type(INVALID, x_pos, y_pos, 0, NULL); // The '0' says we want to use the nozzle's position
const mesh_index_pair location = find_closest_mesh_point_of_type(INVALID, x_pos, y_pos, 0, NULL, false); // The '0' says we want to use the nozzle's position
if (location.x_index < 0) break; // No more invalid Mesh Points to populate
z_values[location.x_index][location.y_index] = height_value;
}
@@ -700,7 +717,7 @@
* Probe all invalidated locations of the mesh that can be reached by the probe.
* This attempts to fill in locations closest to the nozzle's start location first.
*/
void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe) {
void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest) {
mesh_index_pair location;
ubl_has_control_of_lcd_panel++;
@@ -721,7 +738,7 @@
return;
}
location = find_closest_mesh_point_of_type(INVALID, lx, ly, 1, NULL); // the '1' says we want the location to be relative to the probe
location = find_closest_mesh_point_of_type(INVALID, lx, ly, 1, NULL, do_furthest ); // the '1' says we want the location to be relative to the probe
if (location.x_index >= 0 && location.y_index >= 0) {
const float xProbe = ubl.map_x_index_to_bed_location(location.x_index),
yProbe = ubl.map_y_index_to_bed_location(location.y_index);
@@ -734,7 +751,7 @@
z_values[location.x_index][location.y_index] = measured_z + Z_PROBE_OFFSET_FROM_EXTRUDER;
}
if (do_ubl_mesh_map) ubl.display_map(1);
if (do_ubl_mesh_map) ubl.display_map(map_type);
} while (location.x_index >= 0 && location.y_index >= 0);
@@ -862,9 +879,9 @@
float last_x = -9999.99, last_y = -9999.99;
mesh_index_pair location;
do {
if (do_ubl_mesh_map) ubl.display_map(1);
if (do_ubl_mesh_map) ubl.display_map(map_type);
location = find_closest_mesh_point_of_type(INVALID, lx, ly, 0, NULL); // The '0' says we want to use the nozzle's position
location = find_closest_mesh_point_of_type(INVALID, lx, ly, 0, NULL, false); // The '0' says we want to use the nozzle's position
// It doesn't matter if the probe can not reach the
// NAN location. This is a manual probe.
if (location.x_index < 0 && location.y_index < 0) continue;
@@ -923,7 +940,7 @@
}
} while (location.x_index >= 0 && location.y_index >= 0);
if (do_ubl_mesh_map) ubl.display_map(1);
if (do_ubl_mesh_map) ubl.display_map(map_type);
LEAVE:
restore_ubl_active_state_and_leave();
@@ -941,6 +958,7 @@
x_pos = current_position[X_AXIS];
y_pos = current_position[Y_AXIS];
x_flag = y_flag = repeat_flag = false;
map_type = 0;
constant = 0.0;
repetition_cnt = 1;
@@ -1008,6 +1026,23 @@
return UBL_ERR;
}
}
if (code_seen('O')) { // Check if a map type was specified
map_type = code_value_int() ? code_has_value() : 0;
if ( map_type<0 || map_type>1) {
SERIAL_PROTOCOLLNPGM("Invalid map type.\n");
return UBL_ERR;
}
}
if (code_seen('M')) { // Check if a map type was specified
map_type = code_value_int() ? code_has_value() : 0;
if ( map_type<0 || map_type>1) {
SERIAL_PROTOCOLLNPGM("Invalid map type.\n");
return UBL_ERR;
}
}
return UBL_OK;
}
@@ -1217,9 +1252,9 @@
z_values[x][y] = z_values[x][y] - tmp_z_values[x][y];
}
mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType type, const float &lx, const float &ly, const bool probe_as_reference, unsigned int bits[16]) {
int i, j;
float closest = 99999.99;
mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType type, const float &lx, const float &ly, const bool probe_as_reference, unsigned int bits[16], bool far_flag) {
int i, j, k, l;
float distance, closest = far_flag ? -99999.99 : 99999.99;
mesh_index_pair return_val;
return_val.x_index = return_val.y_index = -1;
@@ -1254,9 +1289,21 @@
// We can get to it. Let's see if it is the closest location to the nozzle.
// Add in a weighting factor that considers the current location of the nozzle.
const float distance = HYPOT(px - mx, py - my) + HYPOT(current_x - mx, current_y - my) * 0.01;
if (distance < closest) {
distance = HYPOT(px - mx, py - my) + HYPOT(current_x - mx, current_y - my) * 0.1;
if (far_flag) { // If doing the far_flag action, we want to be as far as possible
for (k = 0; k < UBL_MESH_NUM_X_POINTS; k++) { // from the starting point and from any other probed points. We
for (l = 0; j < UBL_MESH_NUM_Y_POINTS; l++) { // want the next point spread out and filling in any blank spaces
if ( !isnan(z_values[k][l])) { // in the mesh. So we add in some of the distance to every probed
distance += (i-k)*(i-k)*MESH_X_DIST*.05; // point we can find.
distance += (j-l)*(j-l)*MESH_Y_DIST*.05;
}
}
}
}
if ( (!far_flag&&(distance < closest)) || (far_flag&&(distance > closest)) ) { // if far_flag, look for furthest away point
closest = distance; // We found a closer location with
return_val.x_index = i; // the specified type of mesh value.
return_val.y_index = j;
@@ -1283,9 +1330,9 @@
do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
do_blocking_move_to_xy(lx, ly);
do {
if (do_ubl_mesh_map) ubl.display_map(1);
if (do_ubl_mesh_map) ubl.display_map(map_type);
location = find_closest_mesh_point_of_type( SET_IN_BITMAP, lx, ly, 0, not_done); // The '0' says we want to use the nozzle's position
location = find_closest_mesh_point_of_type( SET_IN_BITMAP, lx, ly, 0, not_done, false); // The '0' says we want to use the nozzle's position
// It doesn't matter if the probe can not reach this
// location. This is a manual edit of the Mesh Point.
if (location.x_index < 0 && location.y_index < 0) continue; // abort if we can't find any more points.
@@ -1356,7 +1403,7 @@
ubl_has_control_of_lcd_panel = false;
if (do_ubl_mesh_map) ubl.display_map(1);
if (do_ubl_mesh_map) ubl.display_map(map_type);
restore_ubl_active_state_and_leave();
do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);