|
@@ -352,7 +352,6 @@
|
352
|
352
|
}
|
353
|
353
|
|
354
|
354
|
if (code_seen('Q')) {
|
355
|
|
-
|
356
|
355
|
const int test_pattern = code_has_value() ? code_value_int() : -1;
|
357
|
356
|
if (!WITHIN(test_pattern, 0, 2)) {
|
358
|
357
|
SERIAL_PROTOCOLLNPGM("Invalid test_pattern value. (0-2)\n");
|
|
@@ -433,13 +432,14 @@
|
433
|
432
|
//
|
434
|
433
|
SERIAL_PROTOCOLLNPGM("Manually probing unreachable mesh locations.\n");
|
435
|
434
|
do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
|
436
|
|
- if (!x_flag && !y_flag) { // use a good default location for the path
|
437
|
|
- // The flipped > and < operators on these two comparisons is
|
438
|
|
- // intentional. It should cause the probed points to follow a
|
439
|
|
- // nice path on Cartesian printers. It may make sense to
|
440
|
|
- // have Delta printers default to the center of the bed.
|
441
|
|
- // For now, until that is decided, it can be forced with the X
|
442
|
|
- // and Y parameters.
|
|
435
|
+ if (!x_flag && !y_flag) {
|
|
436
|
+ /**
|
|
437
|
+ * Use a good default location for the path.
|
|
438
|
+ * The flipped > and < operators in these comparisons is intentional.
|
|
439
|
+ * It should cause the probed points to follow a nice path on Cartesian printers.
|
|
440
|
+ * It may make sense to have Delta printers default to the center of the bed.
|
|
441
|
+ * Until that is decided, this can be forced with the X and Y parameters.
|
|
442
|
+ */
|
443
|
443
|
x_pos = X_PROBE_OFFSET_FROM_EXTRUDER > 0 ? UBL_MESH_MAX_X : UBL_MESH_MIN_X;
|
444
|
444
|
y_pos = Y_PROBE_OFFSET_FROM_EXTRUDER < 0 ? UBL_MESH_MAX_Y : UBL_MESH_MIN_Y;
|
445
|
445
|
}
|
|
@@ -461,27 +461,28 @@
|
461
|
461
|
}
|
462
|
462
|
manually_probe_remaining_mesh(x_pos, y_pos, height, card_thickness, code_seen('O') || code_seen('M'));
|
463
|
463
|
SERIAL_PROTOCOLLNPGM("G29 P2 finished");
|
464
|
|
- }
|
465
|
|
- break;
|
|
464
|
+
|
|
465
|
+ } break;
|
466
|
466
|
|
467
|
467
|
case 3: {
|
468
|
|
- //
|
469
|
|
- // Populate invalid Mesh areas. Two choices are available to the user. The user can
|
470
|
|
- // specify the constant to be used with a C # paramter. Or the user can allow the G29 P3 command to
|
471
|
|
- // apply a 'reasonable' constant to the invalid mesh point. Some caution and scrutiny should be used
|
472
|
|
- // on either of these paths!
|
473
|
|
- //
|
|
468
|
+ /**
|
|
469
|
+ * Populate invalid mesh areas. Proceed with caution.
|
|
470
|
+ * Two choices are available:
|
|
471
|
+ * - Specify a constant with the 'C' parameter.
|
|
472
|
+ * - Allow 'G29 P3' to choose a 'reasonable' constant.
|
|
473
|
+ */
|
474
|
474
|
if (c_flag) {
|
475
|
|
- while (repetition_cnt--) {
|
|
475
|
+ while (repetition_cnt--) {
|
476
|
476
|
const mesh_index_pair location = find_closest_mesh_point_of_type(INVALID, x_pos, y_pos, USE_NOZZLE_AS_REFERENCE, NULL, false);
|
477
|
|
- if (location.x_index < 0) break; // No more invalid Mesh Points to populate
|
478
|
|
- ubl.z_values[location.x_index][location.y_index] = ubl_constant;
|
|
477
|
+ if (location.x_index < 0) break; // No more invalid Mesh Points to populate
|
|
478
|
+ ubl.z_values[location.x_index][location.y_index] = ubl_constant;
|
479
|
479
|
}
|
480
|
480
|
break;
|
481
|
|
- } else // The user wants to do a 'Smart' fill where we use the surrounding known
|
482
|
|
- smart_fill_mesh(); // values to provide a good guess of what the unprobed mesh point should be
|
483
|
|
- break;
|
484
|
481
|
}
|
|
482
|
+ else
|
|
483
|
+ smart_fill_mesh(); // Do a 'Smart' fill using nearby known values
|
|
484
|
+
|
|
485
|
+ } break;
|
485
|
486
|
|
486
|
487
|
case 4:
|
487
|
488
|
//
|
|
@@ -535,9 +536,9 @@
|
535
|
536
|
|
536
|
537
|
if (code_seen('T')) {
|
537
|
538
|
|
538
|
|
- float z1 = probe_pt( LOGICAL_X_POSITION(UBL_PROBE_PT_1_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_1_Y), false, g29_verbose_level),
|
539
|
|
- z2 = probe_pt( LOGICAL_X_POSITION(UBL_PROBE_PT_2_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_2_Y), false, g29_verbose_level),
|
540
|
|
- z3 = probe_pt( LOGICAL_X_POSITION(UBL_PROBE_PT_3_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_3_Y), true, g29_verbose_level);
|
|
539
|
+ float z1 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_1_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_1_Y), false, g29_verbose_level),
|
|
540
|
+ z2 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_2_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_2_Y), false, g29_verbose_level),
|
|
541
|
+ z3 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_3_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_3_Y), true, g29_verbose_level);
|
541
|
542
|
|
542
|
543
|
// We need to adjust z1, z2, z3 by the Mesh Height at these points. Just because they are non-zero doesn't mean
|
543
|
544
|
// the Mesh is tilted! (We need to compensate each probe point by what the Mesh says that location's height is)
|
|
@@ -606,8 +607,8 @@
|
606
|
607
|
SERIAL_ECHOPAIR(" J ", y);
|
607
|
608
|
SERIAL_ECHOPGM(" Z ");
|
608
|
609
|
SERIAL_ECHO_F(ubl.z_values[x][y], 6);
|
609
|
|
- SERIAL_ECHOPAIR(" ; X ", LOGICAL_X_POSITION(pgm_read_float(&(ubl.mesh_index_to_xpos[x]))));
|
610
|
|
- SERIAL_ECHOPAIR(", Y ", LOGICAL_Y_POSITION(pgm_read_float(&(ubl.mesh_index_to_ypos[y]))));
|
|
610
|
+ SERIAL_ECHOPAIR(" ; X ", LOGICAL_X_POSITION(pgm_read_float(&ubl.mesh_index_to_xpos[x])));
|
|
611
|
+ SERIAL_ECHOPAIR(", Y ", LOGICAL_Y_POSITION(pgm_read_float(&ubl.mesh_index_to_ypos[y])));
|
611
|
612
|
SERIAL_EOL;
|
612
|
613
|
}
|
613
|
614
|
return;
|
|
@@ -653,9 +654,9 @@
|
653
|
654
|
} while (!ubl_lcd_clicked());
|
654
|
655
|
|
655
|
656
|
ubl.has_control_of_lcd_panel = true; // There is a race condition for the Encoder Wheel getting clicked.
|
656
|
|
- // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune)
|
657
|
|
- // or here. So, until we are done looking for a long Encoder Wheel Press,
|
658
|
|
- // we need to take control of the panel
|
|
657
|
+ // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune)
|
|
658
|
+ // or here. So, until we are done looking for a long Encoder Wheel Press,
|
|
659
|
+ // we need to take control of the panel
|
659
|
660
|
|
660
|
661
|
KEEPALIVE_STATE(IN_HANDLER);
|
661
|
662
|
|
|
@@ -692,44 +693,39 @@
|
692
|
693
|
}
|
693
|
694
|
|
694
|
695
|
void unified_bed_leveling::find_mean_mesh_height() {
|
695
|
|
- uint8_t x, y;
|
696
|
|
- int n;
|
697
|
|
- float sum, sum_of_diff_squared, sigma, difference, mean;
|
698
|
|
-
|
699
|
|
- sum = sum_of_diff_squared = 0.0;
|
700
|
|
- n = 0;
|
701
|
|
- for (x = 0; x < GRID_MAX_POINTS_X; x++)
|
702
|
|
- for (y = 0; y < GRID_MAX_POINTS_Y; y++)
|
|
696
|
+ float sum = 0.0;
|
|
697
|
+ int n = 0;
|
|
698
|
+ for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
|
|
699
|
+ for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++)
|
703
|
700
|
if (!isnan(ubl.z_values[x][y])) {
|
704
|
701
|
sum += ubl.z_values[x][y];
|
705
|
702
|
n++;
|
706
|
703
|
}
|
707
|
704
|
|
708
|
|
- mean = sum / n;
|
|
705
|
+ const float mean = sum / n;
|
709
|
706
|
|
710
|
707
|
//
|
711
|
708
|
// Now do the sumation of the squares of difference from mean
|
712
|
709
|
//
|
713
|
|
- for (x = 0; x < GRID_MAX_POINTS_X; x++)
|
714
|
|
- for (y = 0; y < GRID_MAX_POINTS_Y; y++)
|
715
|
|
- if (!isnan(ubl.z_values[x][y])) {
|
716
|
|
- difference = (ubl.z_values[x][y] - mean);
|
717
|
|
- sum_of_diff_squared += difference * difference;
|
718
|
|
- }
|
|
710
|
+ float sum_of_diff_squared = 0.0;
|
|
711
|
+ for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
|
|
712
|
+ for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++)
|
|
713
|
+ if (!isnan(ubl.z_values[x][y]))
|
|
714
|
+ sum_of_diff_squared += sq(ubl.z_values[x][y] - mean);
|
719
|
715
|
|
720
|
716
|
SERIAL_ECHOLNPAIR("# of samples: ", n);
|
721
|
717
|
SERIAL_ECHOPGM("Mean Mesh Height: ");
|
722
|
718
|
SERIAL_ECHO_F(mean, 6);
|
723
|
719
|
SERIAL_EOL;
|
724
|
720
|
|
725
|
|
- sigma = sqrt(sum_of_diff_squared / (n + 1));
|
|
721
|
+ const float sigma = sqrt(sum_of_diff_squared / (n + 1));
|
726
|
722
|
SERIAL_ECHOPGM("Standard Deviation: ");
|
727
|
723
|
SERIAL_ECHO_F(sigma, 6);
|
728
|
724
|
SERIAL_EOL;
|
729
|
725
|
|
730
|
726
|
if (c_flag)
|
731
|
|
- for (x = 0; x < GRID_MAX_POINTS_X; x++)
|
732
|
|
- for (y = 0; y < GRID_MAX_POINTS_Y; y++)
|
|
727
|
+ for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
|
|
728
|
+ for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++)
|
733
|
729
|
if (!isnan(ubl.z_values[x][y]))
|
734
|
730
|
ubl.z_values[x][y] -= mean + ubl_constant;
|
735
|
731
|
}
|
|
@@ -767,8 +763,8 @@
|
767
|
763
|
location = find_closest_mesh_point_of_type(INVALID, lx, ly, USE_PROBE_AS_REFERENCE, NULL, do_furthest);
|
768
|
764
|
if (location.x_index >= 0 && location.y_index >= 0) {
|
769
|
765
|
|
770
|
|
- const float rawx = pgm_read_float(&(ubl.mesh_index_to_xpos[location.x_index])),
|
771
|
|
- rawy = pgm_read_float(&(ubl.mesh_index_to_ypos[location.y_index]));
|
|
766
|
+ const float rawx = pgm_read_float(&ubl.mesh_index_to_xpos[location.x_index]),
|
|
767
|
+ rawy = pgm_read_float(&ubl.mesh_index_to_ypos[location.y_index]);
|
772
|
768
|
|
773
|
769
|
// TODO: Change to use `position_is_reachable` (for SCARA-compatibility)
|
774
|
770
|
if (!WITHIN(rawx, MIN_PROBE_X, MAX_PROBE_X) || !WITHIN(rawy, MIN_PROBE_Y, MAX_PROBE_Y)) {
|
|
@@ -797,7 +793,6 @@
|
797
|
793
|
}
|
798
|
794
|
|
799
|
795
|
void unified_bed_leveling::tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3) {
|
800
|
|
- float d, t, inv_z;
|
801
|
796
|
int i, j;
|
802
|
797
|
|
803
|
798
|
matrix_3x3 rotation;
|
|
@@ -818,96 +813,94 @@
|
818
|
813
|
* However, we don't know its direction. We need it to point up. So if
|
819
|
814
|
* Z is negative, we need to invert the sign of all components of the vector
|
820
|
815
|
*/
|
821
|
|
- if ( normal.z < 0.0 ) {
|
|
816
|
+ if (normal.z < 0.0) {
|
822
|
817
|
normal.x = -normal.x;
|
823
|
818
|
normal.y = -normal.y;
|
824
|
819
|
normal.z = -normal.z;
|
825
|
820
|
}
|
826
|
821
|
|
827
|
|
- rotation = matrix_3x3::create_look_at( vector_3( normal.x, normal.y, 1));
|
|
822
|
+ rotation = matrix_3x3::create_look_at(vector_3(normal.x, normal.y, 1));
|
828
|
823
|
|
829
|
|
- if (g29_verbose_level>2) {
|
|
824
|
+ if (g29_verbose_level > 2) {
|
830
|
825
|
SERIAL_ECHOPGM("bed plane normal = [");
|
831
|
|
- SERIAL_PROTOCOL_F( normal.x, 7);
|
832
|
|
- SERIAL_ECHOPGM(",");
|
833
|
|
- SERIAL_PROTOCOL_F( normal.y, 7);
|
834
|
|
- SERIAL_ECHOPGM(",");
|
835
|
|
- SERIAL_PROTOCOL_F( normal.z, 7);
|
836
|
|
- SERIAL_ECHOPGM("]\n");
|
837
|
|
- rotation.debug("rotation matrix:");
|
|
826
|
+ SERIAL_PROTOCOL_F(normal.x, 7);
|
|
827
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
828
|
+ SERIAL_PROTOCOL_F(normal.y, 7);
|
|
829
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
830
|
+ SERIAL_PROTOCOL_F(normal.z, 7);
|
|
831
|
+ SERIAL_ECHOLNPGM("]");
|
|
832
|
+ rotation.debug(PSTR("rotation matrix:"));
|
838
|
833
|
}
|
839
|
834
|
|
840
|
835
|
//
|
841
|
836
|
// All of 3 of these points should give us the same d constant
|
842
|
837
|
//
|
843
|
838
|
|
844
|
|
- t = normal.x * UBL_PROBE_PT_1_X + normal.y * UBL_PROBE_PT_1_Y;
|
845
|
|
- d = t + normal.z * z1;
|
|
839
|
+ float t = normal.x * (UBL_PROBE_PT_1_X) + normal.y * (UBL_PROBE_PT_1_Y),
|
|
840
|
+ d = t + normal.z * z1;
|
846
|
841
|
|
847
|
842
|
if (g29_verbose_level>2) {
|
848
|
843
|
SERIAL_ECHOPGM("D constant: ");
|
849
|
|
- SERIAL_PROTOCOL_F( d, 7);
|
850
|
|
- SERIAL_ECHOPGM(" \n");
|
|
844
|
+ SERIAL_PROTOCOL_F(d, 7);
|
|
845
|
+ SERIAL_ECHOLNPGM(" ");
|
851
|
846
|
}
|
852
|
847
|
|
853
|
848
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
854
|
849
|
if (DEBUGGING(LEVELING)) {
|
855
|
|
- SERIAL_ECHOPGM("d from 1st point: ");
|
856
|
|
- SERIAL_ECHO_F(d, 6);
|
857
|
|
- SERIAL_EOL;
|
858
|
|
- t = normal.x * UBL_PROBE_PT_2_X + normal.y * UBL_PROBE_PT_2_Y;
|
859
|
|
- d = t + normal.z * z2;
|
860
|
|
- SERIAL_ECHOPGM("d from 2nd point: ");
|
861
|
|
- SERIAL_ECHO_F(d, 6);
|
862
|
|
- SERIAL_EOL;
|
863
|
|
- t = normal.x * UBL_PROBE_PT_3_X + normal.y * UBL_PROBE_PT_3_Y;
|
864
|
|
- d = t + normal.z * z3;
|
865
|
|
- SERIAL_ECHOPGM("d from 3rd point: ");
|
866
|
|
- SERIAL_ECHO_F(d, 6);
|
867
|
|
- SERIAL_EOL;
|
|
850
|
+ SERIAL_ECHOPGM("d from 1st point: ");
|
|
851
|
+ SERIAL_ECHO_F(d, 6);
|
|
852
|
+ SERIAL_EOL;
|
|
853
|
+ t = normal.x * (UBL_PROBE_PT_2_X) + normal.y * (UBL_PROBE_PT_2_Y);
|
|
854
|
+ d = t + normal.z * z2;
|
|
855
|
+ SERIAL_ECHOPGM("d from 2nd point: ");
|
|
856
|
+ SERIAL_ECHO_F(d, 6);
|
|
857
|
+ SERIAL_EOL;
|
|
858
|
+ t = normal.x * (UBL_PROBE_PT_3_X) + normal.y * (UBL_PROBE_PT_3_Y);
|
|
859
|
+ d = t + normal.z * z3;
|
|
860
|
+ SERIAL_ECHOPGM("d from 3rd point: ");
|
|
861
|
+ SERIAL_ECHO_F(d, 6);
|
|
862
|
+ SERIAL_EOL;
|
868
|
863
|
}
|
869
|
864
|
#endif
|
870
|
865
|
|
871
|
|
- for (i = 0; i < GRID_MAX_POINTS_X; i++) {
|
872
|
|
- for (j = 0; j < GRID_MAX_POINTS_Y; j++) {
|
873
|
|
- float x_tmp, y_tmp, z_tmp;
|
874
|
|
- x_tmp = pgm_read_float(ubl.mesh_index_to_xpos[i]);
|
875
|
|
- y_tmp = pgm_read_float(ubl.mesh_index_to_ypos[j]);
|
876
|
|
- z_tmp = ubl.z_values[i][j];
|
877
|
|
- #if ENABLED(DEBUG_LEVELING_FEATURE)
|
878
|
|
- if (DEBUGGING(LEVELING)) {
|
879
|
|
- SERIAL_ECHOPGM("before rotation = [");
|
880
|
|
- SERIAL_PROTOCOL_F( x_tmp, 7);
|
881
|
|
- SERIAL_ECHOPGM(",");
|
882
|
|
- SERIAL_PROTOCOL_F( y_tmp, 7);
|
883
|
|
- SERIAL_ECHOPGM(",");
|
884
|
|
- SERIAL_PROTOCOL_F( z_tmp, 7);
|
885
|
|
- SERIAL_ECHOPGM("] ---> ");
|
886
|
|
- safe_delay(20);
|
|
866
|
+ for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
|
|
867
|
+ for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
|
|
868
|
+ float x_tmp = pgm_read_float(&ubl.mesh_index_to_xpos[i]),
|
|
869
|
+ y_tmp = pgm_read_float(&ubl.mesh_index_to_ypos[j]),
|
|
870
|
+ z_tmp = ubl.z_values[i][j];
|
|
871
|
+ #if ENABLED(DEBUG_LEVELING_FEATURE)
|
|
872
|
+ if (DEBUGGING(LEVELING)) {
|
|
873
|
+ SERIAL_ECHOPGM("before rotation = [");
|
|
874
|
+ SERIAL_PROTOCOL_F(x_tmp, 7);
|
|
875
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
876
|
+ SERIAL_PROTOCOL_F(y_tmp, 7);
|
|
877
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
878
|
+ SERIAL_PROTOCOL_F(z_tmp, 7);
|
|
879
|
+ SERIAL_ECHOPGM("] ---> ");
|
|
880
|
+ safe_delay(20);
|
|
881
|
+ }
|
|
882
|
+ #endif
|
|
883
|
+ apply_rotation_xyz(rotation, x_tmp, y_tmp, z_tmp);
|
|
884
|
+ #if ENABLED(DEBUG_LEVELING_FEATURE)
|
|
885
|
+ if (DEBUGGING(LEVELING)) {
|
|
886
|
+ SERIAL_ECHOPGM("after rotation = [");
|
|
887
|
+ SERIAL_PROTOCOL_F(x_tmp, 7);
|
|
888
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
889
|
+ SERIAL_PROTOCOL_F(y_tmp, 7);
|
|
890
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
891
|
+ SERIAL_PROTOCOL_F(z_tmp, 7);
|
|
892
|
+ SERIAL_ECHOLNPGM("]");
|
|
893
|
+ safe_delay(55);
|
|
894
|
+ }
|
|
895
|
+ #endif
|
|
896
|
+ ubl.z_values[i][j] += z_tmp - d;
|
887
|
897
|
}
|
888
|
|
- #endif
|
889
|
|
- apply_rotation_xyz(rotation, x_tmp, y_tmp, z_tmp);
|
890
|
|
- #if ENABLED(DEBUG_LEVELING_FEATURE)
|
891
|
|
- if (DEBUGGING(LEVELING)) {
|
892
|
|
- SERIAL_ECHOPGM("after rotation = [");
|
893
|
|
- SERIAL_PROTOCOL_F( x_tmp, 7);
|
894
|
|
- SERIAL_ECHOPGM(",");
|
895
|
|
- SERIAL_PROTOCOL_F( y_tmp, 7);
|
896
|
|
- SERIAL_ECHOPGM(",");
|
897
|
|
- SERIAL_PROTOCOL_F( z_tmp, 7);
|
898
|
|
- SERIAL_ECHOPGM("]\n");
|
899
|
|
- safe_delay(55);
|
900
|
|
- }
|
901
|
|
- #endif
|
902
|
|
- ubl.z_values[i][j] += z_tmp - d;
|
903
|
|
- }
|
904
|
898
|
}
|
905
|
|
- return;
|
906
|
899
|
}
|
907
|
900
|
|
908
|
901
|
float use_encoder_wheel_to_measure_point() {
|
909
|
902
|
|
910
|
|
- while (ubl_lcd_clicked()) delay(50);; // wait for user to release encoder wheel
|
|
903
|
+ while (ubl_lcd_clicked()) delay(50); // wait for user to release encoder wheel
|
911
|
904
|
delay(50); // debounce
|
912
|
905
|
|
913
|
906
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
@@ -922,24 +915,29 @@
|
922
|
915
|
return current_position[Z_AXIS];
|
923
|
916
|
}
|
924
|
917
|
|
925
|
|
- float measure_business_card_thickness(const float &in_height) {
|
|
918
|
+ static void say_and_take_a_measurement() {
|
|
919
|
+ SERIAL_PROTOCOLLNPGM(" and take a measurement.");
|
|
920
|
+ }
|
926
|
921
|
|
|
922
|
+ float measure_business_card_thickness(const float &in_height) {
|
927
|
923
|
ubl.has_control_of_lcd_panel = true;
|
928
|
|
- ubl.save_ubl_active_state_and_disable(); // we don't do bed level correction because we want the raw data when we probe
|
|
924
|
+ ubl.save_ubl_active_state_and_disable(); // Disable bed level correction for probing
|
929
|
925
|
|
930
|
926
|
do_blocking_move_to_z(in_height);
|
931
|
|
- do_blocking_move_to_xy((float(UBL_MESH_MAX_X) - float(UBL_MESH_MIN_X)) / 2.0, (float(UBL_MESH_MAX_Y) - float(UBL_MESH_MIN_Y)) / 2.0);
|
932
|
|
- //, min(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS])/2.0);
|
|
927
|
+ do_blocking_move_to_xy(0.5 * (UBL_MESH_MAX_X - (UBL_MESH_MIN_X)), 0.5 * (UBL_MESH_MAX_Y - (UBL_MESH_MIN_Y)));
|
|
928
|
+ //, min(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS]) / 2.0);
|
933
|
929
|
|
934
|
930
|
stepper.synchronize();
|
935
|
|
- SERIAL_PROTOCOLLNPGM("Place Shim Under Nozzle and Perform Measurement.");
|
936
|
|
-
|
|
931
|
+ SERIAL_PROTOCOLPGM("Place shim under nozzle");
|
|
932
|
+ say_and_take_a_measurement();
|
937
|
933
|
|
938
|
934
|
const float z1 = use_encoder_wheel_to_measure_point();
|
939
|
935
|
do_blocking_move_to_z(current_position[Z_AXIS] + SIZE_OF_LITTLE_RAISE);
|
940
|
|
-
|
941
|
936
|
stepper.synchronize();
|
942
|
|
- SERIAL_PROTOCOLLNPGM("Remove Shim and Measure Bed Height.");
|
|
937
|
+
|
|
938
|
+ SERIAL_PROTOCOLPGM("Remove shim");
|
|
939
|
+ say_and_take_a_measurement();
|
|
940
|
+
|
943
|
941
|
const float z2 = use_encoder_wheel_to_measure_point();
|
944
|
942
|
do_blocking_move_to_z(current_position[Z_AXIS] + SIZE_OF_LITTLE_RAISE);
|
945
|
943
|
|
|
@@ -968,8 +966,8 @@
|
968
|
966
|
// It doesn't matter if the probe can't reach the NAN location. This is a manual probe.
|
969
|
967
|
if (location.x_index < 0 && location.y_index < 0) continue;
|
970
|
968
|
|
971
|
|
- const float rawx = pgm_read_float(&(ubl.mesh_index_to_xpos[location.x_index])),
|
972
|
|
- rawy = pgm_read_float(&(ubl.mesh_index_to_ypos[location.y_index]));
|
|
969
|
+ const float rawx = pgm_read_float(&ubl.mesh_index_to_xpos[location.x_index]),
|
|
970
|
+ rawy = pgm_read_float(&ubl.mesh_index_to_ypos[location.y_index]);
|
973
|
971
|
|
974
|
972
|
// TODO: Change to use `position_is_reachable` (for SCARA-compatibility)
|
975
|
973
|
if (!WITHIN(rawx, UBL_MESH_MIN_X, UBL_MESH_MAX_X) || !WITHIN(rawy, UBL_MESH_MIN_Y, UBL_MESH_MAX_Y)) {
|
|
@@ -999,11 +997,9 @@
|
999
|
997
|
|
1000
|
998
|
if (do_ubl_mesh_map) ubl.display_map(map_type); // show user where we're probing
|
1001
|
999
|
|
1002
|
|
-
|
1003
|
|
- while (ubl_lcd_clicked()) delay(50);; // wait for user to release encoder wheel
|
1004
|
|
- delay(50); // debounce
|
1005
|
|
-
|
1006
|
|
- while (!ubl_lcd_clicked()) { // we need the loop to move the nozzle based on the encoder wheel here!
|
|
1000
|
+ while (ubl_lcd_clicked()) delay(50); // wait for user to release encoder wheel
|
|
1001
|
+ delay(50); // debounce
|
|
1002
|
+ while (!ubl_lcd_clicked()) { // we need the loop to move the nozzle based on the encoder wheel here!
|
1007
|
1003
|
idle();
|
1008
|
1004
|
if (ubl.encoder_diff) {
|
1009
|
1005
|
do_blocking_move_to_z(current_position[Z_AXIS] + float(ubl.encoder_diff) / 100.0);
|
|
@@ -1011,7 +1007,6 @@
|
1011
|
1007
|
}
|
1012
|
1008
|
}
|
1013
|
1009
|
|
1014
|
|
-
|
1015
|
1010
|
const millis_t nxt = millis() + 1500L;
|
1016
|
1011
|
while (ubl_lcd_clicked()) { // debounce and watch for abort
|
1017
|
1012
|
idle();
|
|
@@ -1044,33 +1039,43 @@
|
1044
|
1039
|
do_blocking_move_to_xy(lx, ly);
|
1045
|
1040
|
}
|
1046
|
1041
|
|
|
1042
|
+ static void say_ubl_name() {
|
|
1043
|
+ SERIAL_PROTOCOLPGM("Unified Bed Leveling ");
|
|
1044
|
+ }
|
|
1045
|
+
|
|
1046
|
+ static void report_ubl_state() {
|
|
1047
|
+ say_ubl_name();
|
|
1048
|
+ SERIAL_PROTOCOLPGM("System ");
|
|
1049
|
+ if (!ubl.state.active) SERIAL_PROTOCOLPGM("de");
|
|
1050
|
+ SERIAL_PROTOCOLLNPGM("activated.\n");
|
|
1051
|
+ }
|
|
1052
|
+
|
1047
|
1053
|
bool g29_parameter_parsing() {
|
1048
|
1054
|
bool err_flag = false;
|
1049
|
1055
|
|
1050
|
|
- LCD_MESSAGEPGM("Doing G29 UBL!");
|
|
1056
|
+ LCD_MESSAGEPGM("Doing G29 UBL!");
|
|
1057
|
+ lcd_quick_feedback();
|
|
1058
|
+
|
1051
|
1059
|
ubl_constant = 0.0;
|
1052
|
1060
|
repetition_cnt = 0;
|
1053
|
|
- lcd_quick_feedback();
|
1054
|
1061
|
|
1055
|
1062
|
x_flag = code_seen('X') && code_has_value();
|
1056
|
1063
|
x_pos = x_flag ? code_value_float() : current_position[X_AXIS];
|
1057
|
|
-
|
1058
|
1064
|
y_flag = code_seen('Y') && code_has_value();
|
1059
|
1065
|
y_pos = y_flag ? code_value_float() : current_position[Y_AXIS];
|
1060
|
1066
|
|
1061
|
|
-
|
1062
|
1067
|
repeat_flag = code_seen('R');
|
1063
|
1068
|
if (repeat_flag) {
|
1064
|
1069
|
repetition_cnt = code_has_value() ? code_value_int() : (GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y);
|
1065
|
1070
|
if (repetition_cnt < 1) {
|
1066
|
|
- SERIAL_PROTOCOLLNPGM("Invalid Repetition count.\n");
|
|
1071
|
+ SERIAL_PROTOCOLLNPGM("?(R)epetition count invalid (1+).\n");
|
1067
|
1072
|
return UBL_ERR;
|
1068
|
1073
|
}
|
1069
|
1074
|
}
|
1070
|
1075
|
|
1071
|
1076
|
g29_verbose_level = code_seen('V') ? code_value_int() : 0;
|
1072
|
1077
|
if (!WITHIN(g29_verbose_level, 0, 4)) {
|
1073
|
|
- SERIAL_PROTOCOLLNPGM("Invalid Verbose Level specified. (0-4)\n");
|
|
1078
|
+ SERIAL_PROTOCOLLNPGM("?(V)erbose Level is implausible (0-4)\n");
|
1074
|
1079
|
err_flag = true;
|
1075
|
1080
|
}
|
1076
|
1081
|
|
|
@@ -1099,32 +1104,35 @@
|
1099
|
1104
|
|
1100
|
1105
|
if (err_flag) return UBL_ERR;
|
1101
|
1106
|
|
1102
|
|
- if (code_seen('A')) { // Activate the Unified Bed Leveling System
|
|
1107
|
+ // Activate or deactivate UBL
|
|
1108
|
+ if (code_seen('A')) {
|
|
1109
|
+ if (code_seen('D')) {
|
|
1110
|
+ SERIAL_PROTOCOLLNPGM("?Can't activate and deactivate at the same time.\n");
|
|
1111
|
+ return UBL_ERR;
|
|
1112
|
+ }
|
1103
|
1113
|
ubl.state.active = 1;
|
1104
|
|
- SERIAL_PROTOCOLLNPGM("Unified Bed Leveling System activated.\n");
|
|
1114
|
+ report_ubl_state();
|
1105
|
1115
|
}
|
1106
|
|
-
|
1107
|
|
- c_flag = code_seen('C');
|
1108
|
|
- if (c_flag)
|
1109
|
|
- ubl_constant = code_value_float();
|
1110
|
|
-
|
1111
|
|
- if (code_seen('D')) { // Disable the Unified Bed Leveling System
|
|
1116
|
+ else if (code_seen('D')) {
|
1112
|
1117
|
ubl.state.active = 0;
|
1113
|
|
- SERIAL_PROTOCOLLNPGM("Unified Bed Leveling System de-activated.\n");
|
|
1118
|
+ report_ubl_state();
|
1114
|
1119
|
}
|
1115
|
1120
|
|
|
1121
|
+ // Set global 'C' flag and its value
|
|
1122
|
+ if ((c_flag = code_seen('C')))
|
|
1123
|
+ ubl_constant = code_value_float();
|
|
1124
|
+
|
1116
|
1125
|
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
1117
|
1126
|
if (code_seen('F') && code_has_value()) {
|
1118
|
1127
|
const float fh = code_value_float();
|
1119
|
1128
|
if (!WITHIN(fh, 0.0, 100.0)) {
|
1120
|
|
- SERIAL_PROTOCOLLNPGM("?Bed Level Correction Fade Height Not Plausible.\n");
|
|
1129
|
+ SERIAL_PROTOCOLLNPGM("?(F)ade height for Bed Level Correction not plausible.\n");
|
1121
|
1130
|
return UBL_ERR;
|
1122
|
1131
|
}
|
1123
|
1132
|
set_z_fade_height(fh);
|
1124
|
1133
|
}
|
1125
|
1134
|
#endif
|
1126
|
1135
|
|
1127
|
|
-
|
1128
|
1136
|
map_type = code_seen('O') && code_has_value() ? code_value_int() : 0;
|
1129
|
1137
|
if (!WITHIN(map_type, 0, 1)) {
|
1130
|
1138
|
SERIAL_PROTOCOLLNPGM("Invalid map type.\n");
|
|
@@ -1146,7 +1154,7 @@
|
1146
|
1154
|
* This function goes away after G29 debug is complete. But for right now, it is a handy
|
1147
|
1155
|
* routine to dump binary data structures.
|
1148
|
1156
|
*/
|
1149
|
|
-/*
|
|
1157
|
+ /*
|
1150
|
1158
|
void dump(char * const str, const float &f) {
|
1151
|
1159
|
char *ptr;
|
1152
|
1160
|
|
|
@@ -1164,7 +1172,7 @@
|
1164
|
1172
|
|
1165
|
1173
|
SERIAL_EOL;
|
1166
|
1174
|
}
|
1167
|
|
-*/
|
|
1175
|
+ //*/
|
1168
|
1176
|
|
1169
|
1177
|
static int ubl_state_at_invocation = 0,
|
1170
|
1178
|
ubl_state_recursion_chk = 0;
|
|
@@ -1191,7 +1199,6 @@
|
1191
|
1199
|
ubl.state.active = ubl_state_at_invocation;
|
1192
|
1200
|
}
|
1193
|
1201
|
|
1194
|
|
-
|
1195
|
1202
|
/**
|
1196
|
1203
|
* Much of the 'What?' command can be eliminated. But until we are fully debugged, it is
|
1197
|
1204
|
* good to have the extra information. Soon... we prune this to just a few items
|
|
@@ -1199,7 +1206,8 @@
|
1199
|
1206
|
void g29_what_command() {
|
1200
|
1207
|
const uint16_t k = E2END - ubl.eeprom_start;
|
1201
|
1208
|
|
1202
|
|
- SERIAL_PROTOCOLPGM("Unified Bed Leveling System Version " UBL_VERSION " ");
|
|
1209
|
+ say_ubl_name();
|
|
1210
|
+ SERIAL_PROTOCOLPGM("System Version " UBL_VERSION " ");
|
1203
|
1211
|
if (ubl.state.active)
|
1204
|
1212
|
SERIAL_PROTOCOLCHAR('A');
|
1205
|
1213
|
else
|
|
@@ -1230,11 +1238,11 @@
|
1230
|
1238
|
SERIAL_EOL;
|
1231
|
1239
|
safe_delay(25);
|
1232
|
1240
|
|
1233
|
|
- SERIAL_PROTOCOLLNPAIR("ubl.eeprom_start=0x", hex_word(ubl.eeprom_start));
|
|
1241
|
+ SERIAL_PROTOCOLLNPAIR("ubl.eeprom_start=", hex_address((void*)ubl.eeprom_start));
|
1234
|
1242
|
|
1235
|
1243
|
SERIAL_PROTOCOLPGM("X-Axis Mesh Points at: ");
|
1236
|
1244
|
for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
|
1237
|
|
- SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(pgm_read_float(&(ubl.mesh_index_to_xpos[i]))), 1);
|
|
1245
|
+ SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(pgm_read_float(&ubl.mesh_index_to_xpos[i])), 1);
|
1238
|
1246
|
SERIAL_PROTOCOLPGM(" ");
|
1239
|
1247
|
safe_delay(50);
|
1240
|
1248
|
}
|
|
@@ -1242,7 +1250,7 @@
|
1242
|
1250
|
|
1243
|
1251
|
SERIAL_PROTOCOLPGM("Y-Axis Mesh Points at: ");
|
1244
|
1252
|
for (uint8_t i = 0; i < GRID_MAX_POINTS_Y; i++) {
|
1245
|
|
- SERIAL_PROTOCOL_F(LOGICAL_Y_POSITION(pgm_read_float(&(ubl.mesh_index_to_ypos[i]))), 1);
|
|
1253
|
+ SERIAL_PROTOCOL_F(LOGICAL_Y_POSITION(pgm_read_float(&ubl.mesh_index_to_ypos[i])), 1);
|
1246
|
1254
|
SERIAL_PROTOCOLPGM(" ");
|
1247
|
1255
|
safe_delay(50);
|
1248
|
1256
|
}
|
|
@@ -1296,8 +1304,10 @@
|
1296
|
1304
|
SERIAL_EOL;
|
1297
|
1305
|
safe_delay(50);
|
1298
|
1306
|
|
1299
|
|
- if (!ubl.sanity_check())
|
1300
|
|
- SERIAL_PROTOCOLLNPGM("Unified Bed Leveling sanity checks passed.");
|
|
1307
|
+ if (!ubl.sanity_check()) {
|
|
1308
|
+ say_ubl_name();
|
|
1309
|
+ SERIAL_PROTOCOLLNPGM("sanity checks passed.");
|
|
1310
|
+ }
|
1301
|
1311
|
}
|
1302
|
1312
|
|
1303
|
1313
|
/**
|
|
@@ -1357,18 +1367,18 @@
|
1357
|
1367
|
ubl.z_values[x][y] -= tmp_z_values[x][y];
|
1358
|
1368
|
}
|
1359
|
1369
|
|
1360
|
|
- 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) {
|
1361
|
|
- float distance, closest = far_flag ? -99999.99 : 99999.99;
|
1362
|
|
- mesh_index_pair return_val;
|
1363
|
|
-
|
1364
|
|
- return_val.x_index = return_val.y_index = -1;
|
|
1370
|
+ 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], const bool far_flag) {
|
|
1371
|
+ mesh_index_pair out_mesh;
|
|
1372
|
+ out_mesh.x_index = out_mesh.y_index = -1;
|
1365
|
1373
|
|
1366
|
1374
|
const float current_x = current_position[X_AXIS],
|
1367
|
1375
|
current_y = current_position[Y_AXIS];
|
1368
|
1376
|
|
1369
|
1377
|
// Get our reference position. Either the nozzle or probe location.
|
1370
|
|
- const float px = lx - (probe_as_reference==USE_PROBE_AS_REFERENCE ? X_PROBE_OFFSET_FROM_EXTRUDER : 0),
|
1371
|
|
- py = ly - (probe_as_reference==USE_PROBE_AS_REFERENCE ? Y_PROBE_OFFSET_FROM_EXTRUDER : 0);
|
|
1378
|
+ const float px = lx - (probe_as_reference == USE_PROBE_AS_REFERENCE ? X_PROBE_OFFSET_FROM_EXTRUDER : 0),
|
|
1379
|
+ py = ly - (probe_as_reference == USE_PROBE_AS_REFERENCE ? Y_PROBE_OFFSET_FROM_EXTRUDER : 0);
|
|
1380
|
+
|
|
1381
|
+ float closest = far_flag ? -99999.99 : 99999.99;
|
1372
|
1382
|
|
1373
|
1383
|
for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
|
1374
|
1384
|
for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
|
|
@@ -1380,13 +1390,13 @@
|
1380
|
1390
|
|
1381
|
1391
|
// We only get here if we found a Mesh Point of the specified type
|
1382
|
1392
|
|
1383
|
|
- const float rawx = pgm_read_float(&(ubl.mesh_index_to_xpos[i])), // Check if we can probe this mesh location
|
1384
|
|
- rawy = pgm_read_float(&(ubl.mesh_index_to_ypos[j]));
|
|
1393
|
+ const float rawx = pgm_read_float(&ubl.mesh_index_to_xpos[i]), // Check if we can probe this mesh location
|
|
1394
|
+ rawy = pgm_read_float(&ubl.mesh_index_to_ypos[j]);
|
1385
|
1395
|
|
1386
|
1396
|
// If using the probe as the reference there are some unreachable locations.
|
1387
|
1397
|
// Prune them from the list and ignore them till the next Phase (manual nozzle probing).
|
1388
|
1398
|
|
1389
|
|
- if (probe_as_reference==USE_PROBE_AS_REFERENCE &&
|
|
1399
|
+ if (probe_as_reference == USE_PROBE_AS_REFERENCE &&
|
1390
|
1400
|
(!WITHIN(rawx, MIN_PROBE_X, MAX_PROBE_X) || !WITHIN(rawy, MIN_PROBE_Y, MAX_PROBE_Y))
|
1391
|
1401
|
) continue;
|
1392
|
1402
|
|
|
@@ -1396,30 +1406,38 @@
|
1396
|
1406
|
const float mx = LOGICAL_X_POSITION(rawx), // Check if we can probe this mesh location
|
1397
|
1407
|
my = LOGICAL_Y_POSITION(rawy);
|
1398
|
1408
|
|
1399
|
|
- distance = HYPOT(px - mx, py - my) + HYPOT(current_x - mx, current_y - my) * 0.1;
|
1400
|
|
-
|
1401
|
|
- if (far_flag) { // If doing the far_flag action, we want to be as far as possible
|
1402
|
|
- for (uint8_t k = 0; k < GRID_MAX_POINTS_X; k++) { // from the starting point and from any other probed points. We
|
1403
|
|
- for (uint8_t l = 0; l < GRID_MAX_POINTS_Y; l++) { // want the next point spread out and filling in any blank spaces
|
1404
|
|
- if (!isnan(ubl.z_values[k][l])) { // in the mesh. So we add in some of the distance to every probed
|
1405
|
|
- distance += sq(i - k) * (MESH_X_DIST) * .05 // point we can find.
|
|
1409
|
+ float distance = HYPOT(px - mx, py - my) + HYPOT(current_x - mx, current_y - my) * 0.1;
|
|
1410
|
+
|
|
1411
|
+ /**
|
|
1412
|
+ * If doing the far_flag action, we want to be as far as possible
|
|
1413
|
+ * from the starting point and from any other probed points. We
|
|
1414
|
+ * want the next point spread out and filling in any blank spaces
|
|
1415
|
+ * in the mesh. So we add in some of the distance to every probed
|
|
1416
|
+ * point we can find.
|
|
1417
|
+ */
|
|
1418
|
+ if (far_flag) {
|
|
1419
|
+ for (uint8_t k = 0; k < GRID_MAX_POINTS_X; k++) {
|
|
1420
|
+ for (uint8_t l = 0; l < GRID_MAX_POINTS_Y; l++) {
|
|
1421
|
+ if (!isnan(ubl.z_values[k][l])) {
|
|
1422
|
+ distance += sq(i - k) * (MESH_X_DIST) * .05
|
1406
|
1423
|
+ sq(j - l) * (MESH_Y_DIST) * .05;
|
1407
|
1424
|
}
|
1408
|
1425
|
}
|
1409
|
1426
|
}
|
1410
|
1427
|
}
|
1411
|
1428
|
|
1412
|
|
- if (far_flag == (distance > closest) && distance != closest) { // if far_flag, look for farthest point
|
|
1429
|
+ // if far_flag, look for farthest point
|
|
1430
|
+ if (far_flag == (distance > closest) && distance != closest) {
|
1413
|
1431
|
closest = distance; // We found a closer/farther location with
|
1414
|
|
- return_val.x_index = i; // the specified type of mesh value.
|
1415
|
|
- return_val.y_index = j;
|
1416
|
|
- return_val.distance = closest;
|
|
1432
|
+ out_mesh.x_index = i; // the specified type of mesh value.
|
|
1433
|
+ out_mesh.y_index = j;
|
|
1434
|
+ out_mesh.distance = closest;
|
1417
|
1435
|
}
|
1418
|
1436
|
}
|
1419
|
1437
|
} // for j
|
1420
|
1438
|
} // for i
|
1421
|
1439
|
|
1422
|
|
- return return_val;
|
|
1440
|
+ return out_mesh;
|
1423
|
1441
|
}
|
1424
|
1442
|
|
1425
|
1443
|
void fine_tune_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map) {
|
|
@@ -1439,15 +1457,15 @@
|
1439
|
1457
|
do_blocking_move_to_xy(lx, ly);
|
1440
|
1458
|
do {
|
1441
|
1459
|
location = find_closest_mesh_point_of_type(SET_IN_BITMAP, lx, ly, USE_NOZZLE_AS_REFERENCE, not_done, false);
|
1442
|
|
- // It doesn't matter if the probe can not reach this
|
1443
|
|
- // location. This is a manual edit of the Mesh Point.
|
|
1460
|
+ // It doesn't matter if the probe can't reach this
|
|
1461
|
+ // location. This is a manual edit of the Mesh Point.
|
1444
|
1462
|
if (location.x_index < 0 && location.y_index < 0) continue; // abort if we can't find any more points.
|
1445
|
1463
|
|
1446
|
1464
|
bit_clear(not_done, location.x_index, location.y_index); // Mark this location as 'adjusted' so we will find a
|
1447
|
1465
|
// different location the next time through the loop
|
1448
|
1466
|
|
1449
|
|
- const float rawx = pgm_read_float(&(ubl.mesh_index_to_xpos[location.x_index])),
|
1450
|
|
- rawy = pgm_read_float(&(ubl.mesh_index_to_ypos[location.y_index]));
|
|
1467
|
+ const float rawx = pgm_read_float(&ubl.mesh_index_to_xpos[location.x_index]),
|
|
1468
|
+ rawy = pgm_read_float(&ubl.mesh_index_to_ypos[location.y_index]);
|
1451
|
1469
|
|
1452
|
1470
|
// TODO: Change to use `position_is_reachable` (for SCARA-compatibility)
|
1453
|
1471
|
if (!WITHIN(rawx, X_MIN_POS, X_MAX_POS) || !WITHIN(rawy, Y_MIN_POS, Y_MAX_POS)) { // In theory, we don't need this check.
|
|
@@ -1464,45 +1482,31 @@
|
1464
|
1482
|
do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); // Move the nozzle to where we are going to edit
|
1465
|
1483
|
do_blocking_move_to_xy(LOGICAL_X_POSITION(rawx), LOGICAL_Y_POSITION(rawy));
|
1466
|
1484
|
|
1467
|
|
-
|
1468
|
|
-
|
1469
|
|
-
|
1470
|
|
-
|
1471
|
|
-
|
1472
|
1485
|
round_off = (int32_t)(new_z * 1000.0); // we chop off the last digits just to be clean. We are rounding to the
|
1473
|
1486
|
new_z = float(round_off) / 1000.0;
|
1474
|
1487
|
|
1475
|
|
-
|
1476
|
|
-
|
1477
|
1488
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
1478
|
1489
|
ubl.has_control_of_lcd_panel = true;
|
1479
|
1490
|
|
1480
|
|
-
|
1481
|
1491
|
if (do_ubl_mesh_map) ubl.display_map(map_type); // show the user which point is being adjusted
|
1482
|
1492
|
|
1483
|
|
-
|
1484
|
|
-
|
1485
|
1493
|
lcd_implementation_clear();
|
1486
|
1494
|
|
1487
|
1495
|
lcd_mesh_edit_setup(new_z);
|
1488
|
1496
|
|
1489
|
|
-
|
1490
|
|
-
|
1491
|
1497
|
do {
|
1492
|
1498
|
new_z = lcd_mesh_edit();
|
1493
|
1499
|
idle();
|
1494
|
1500
|
} while (!ubl_lcd_clicked());
|
1495
|
1501
|
|
1496
|
|
-
|
1497
|
1502
|
lcd_return_to_status();
|
1498
|
1503
|
|
1499
|
|
-
|
1500
|
|
-
|
1501
|
|
-
|
1502
|
|
- ubl.has_control_of_lcd_panel = true; // There is a race condition for the Encoder Wheel getting clicked.
|
1503
|
|
- // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune)
|
1504
|
|
- // or here.
|
|
1504
|
+ // There is a race condition for the Encoder Wheel getting clicked.
|
|
1505
|
+ // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune)
|
|
1506
|
+ // or here.
|
|
1507
|
+ ubl.has_control_of_lcd_panel = true;
|
1505
|
1508
|
}
|
|
1509
|
+
|
1506
|
1510
|
const millis_t nxt = millis() + 1500UL;
|
1507
|
1511
|
while (ubl_lcd_clicked()) { // debounce and watch for abort
|
1508
|
1512
|
idle();
|
|
@@ -1621,120 +1625,115 @@
|
1621
|
1625
|
|
1622
|
1626
|
|
1623
|
1627
|
void unified_bed_leveling::tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map) {
|
1624
|
|
- int8_t i, j ,k, xCount, yCount, xi, yi; // counter variables
|
1625
|
|
- int8_t ix, iy, zig_zag=0, status;
|
|
1628
|
+ constexpr int16_t x_min = max(MIN_PROBE_X, UBL_MESH_MIN_X),
|
|
1629
|
+ x_max = min(MAX_PROBE_X, UBL_MESH_MAX_X),
|
|
1630
|
+ y_min = max(MIN_PROBE_Y, UBL_MESH_MIN_Y),
|
|
1631
|
+ y_max = min(MAX_PROBE_Y, UBL_MESH_MAX_Y);
|
|
1632
|
+
|
|
1633
|
+ const float dx = float(x_max - x_min) / (grid_size - 1.0),
|
|
1634
|
+ dy = float(y_max - y_min) / (grid_size - 1.0);
|
1626
|
1635
|
|
1627
|
|
- float dx, dy, x, y, measured_z, inv_z;
|
1628
|
1636
|
struct linear_fit_data lsf_results;
|
1629
|
|
- matrix_3x3 rotation;
|
1630
|
|
- vector_3 normal;
|
|
1637
|
+ incremental_LSF_reset(&lsf_results);
|
1631
|
1638
|
|
1632
|
|
- int16_t x_min = max((MIN_PROBE_X),(UBL_MESH_MIN_X)),
|
1633
|
|
- x_max = min((MAX_PROBE_X),(UBL_MESH_MAX_X)),
|
1634
|
|
- y_min = max((MIN_PROBE_Y),(UBL_MESH_MIN_Y)),
|
1635
|
|
- y_max = min((MAX_PROBE_Y),(UBL_MESH_MAX_Y));
|
|
1639
|
+ bool zig_zag = false;
|
|
1640
|
+ for (uint8_t ix = 0; ix < grid_size; ix++) {
|
|
1641
|
+ const float x = float(x_min) + ix * dx;
|
|
1642
|
+ for (int8_t iy = 0; iy < grid_size; iy++) {
|
|
1643
|
+ const float y = float(y_min) + dy * (zig_zag ? grid_size - 1 - iy : iy);
|
|
1644
|
+ float measured_z = probe_pt(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y), code_seen('E'), g29_verbose_level);
|
|
1645
|
+ #if ENABLED(DEBUG_LEVELING_FEATURE)
|
|
1646
|
+ if (DEBUGGING(LEVELING)) {
|
|
1647
|
+ SERIAL_CHAR('(');
|
|
1648
|
+ SERIAL_PROTOCOL_F(x, 7);
|
|
1649
|
+ SERIAL_CHAR(',');
|
|
1650
|
+ SERIAL_PROTOCOL_F(y, 7);
|
|
1651
|
+ SERIAL_ECHOPGM(") logical: ");
|
|
1652
|
+ SERIAL_CHAR('(');
|
|
1653
|
+ SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(x), 7);
|
|
1654
|
+ SERIAL_CHAR(',');
|
|
1655
|
+ SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(y), 7);
|
|
1656
|
+ SERIAL_ECHOPGM(") measured: ");
|
|
1657
|
+ SERIAL_PROTOCOL_F(measured_z, 7);
|
|
1658
|
+ SERIAL_ECHOPGM(" correction: ");
|
|
1659
|
+ SERIAL_PROTOCOL_F(ubl.get_z_correction(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y)), 7);
|
|
1660
|
+ }
|
|
1661
|
+ #endif
|
1636
|
1662
|
|
1637
|
|
- dx = ((float)(x_max-x_min)) / (grid_size-1.0);
|
1638
|
|
- dy = ((float)(y_max-y_min)) / (grid_size-1.0);
|
|
1663
|
+ measured_z -= ubl.get_z_correction(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y)) /* + zprobe_zoffset */ ;
|
1639
|
1664
|
|
1640
|
|
- incremental_LSF_reset(&lsf_results);
|
1641
|
|
- for(ix=0; ix<grid_size; ix++) {
|
1642
|
|
- x = ((float)x_min) + ix*dx;
|
1643
|
|
- for(iy=0; iy<grid_size; iy++) {
|
1644
|
|
- if (zig_zag)
|
1645
|
|
- y = ((float)y_min) + (grid_size-iy-1)*dy;
|
1646
|
|
- else
|
1647
|
|
- y = ((float)y_min) + iy*dy;
|
1648
|
|
- measured_z = probe_pt(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y), code_seen('E'), g29_verbose_level);
|
1649
|
|
- #if ENABLED(DEBUG_LEVELING_FEATURE)
|
1650
|
|
- if (DEBUGGING(LEVELING)) {
|
1651
|
|
- SERIAL_ECHOPGM("(");
|
1652
|
|
- SERIAL_PROTOCOL_F( x, 7);
|
1653
|
|
- SERIAL_ECHOPGM(",");
|
1654
|
|
- SERIAL_PROTOCOL_F( y, 7);
|
1655
|
|
- SERIAL_ECHOPGM(") logical: ");
|
1656
|
|
- SERIAL_ECHOPGM("(");
|
1657
|
|
- SERIAL_PROTOCOL_F( LOGICAL_X_POSITION(x), 7);
|
1658
|
|
- SERIAL_ECHOPGM(",");
|
1659
|
|
- SERIAL_PROTOCOL_F( LOGICAL_X_POSITION(y), 7);
|
1660
|
|
- SERIAL_ECHOPGM(") measured: ");
|
1661
|
|
- SERIAL_PROTOCOL_F( measured_z, 7);
|
1662
|
|
- SERIAL_ECHOPGM(" correction: ");
|
1663
|
|
- SERIAL_PROTOCOL_F( ubl.get_z_correction(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y)), 7);
|
|
1665
|
+ #if ENABLED(DEBUG_LEVELING_FEATURE)
|
|
1666
|
+ if (DEBUGGING(LEVELING)) {
|
|
1667
|
+ SERIAL_ECHOPGM(" final >>>---> ");
|
|
1668
|
+ SERIAL_PROTOCOL_F(measured_z, 7);
|
|
1669
|
+ SERIAL_EOL;
|
1664
|
1670
|
}
|
1665
|
|
- #endif
|
1666
|
|
- measured_z -= ubl.get_z_correction(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y)) /* + zprobe_zoffset */ ;
|
1667
|
|
-
|
1668
|
|
- #if ENABLED(DEBUG_LEVELING_FEATURE)
|
1669
|
|
- if (DEBUGGING(LEVELING)) {
|
1670
|
|
- SERIAL_ECHOPGM(" final >>>---> ");
|
1671
|
|
- SERIAL_PROTOCOL_F( measured_z, 7);
|
1672
|
|
- SERIAL_ECHOPGM("\n");
|
1673
|
|
- }
|
1674
|
|
- #endif
|
1675
|
|
- incremental_LSF(&lsf_results, x, y, measured_z);
|
1676
|
|
- }
|
|
1671
|
+ #endif
|
1677
|
1672
|
|
1678
|
|
- zig_zag = !zig_zag;
|
|
1673
|
+ incremental_LSF(&lsf_results, x, y, measured_z);
|
1679
|
1674
|
}
|
1680
|
1675
|
|
1681
|
|
- status = finish_incremental_LSF(&lsf_results);
|
1682
|
|
- if (g29_verbose_level>3) {
|
|
1676
|
+ zig_zag ^= true;
|
|
1677
|
+ }
|
|
1678
|
+
|
|
1679
|
+ const int status = finish_incremental_LSF(&lsf_results);
|
|
1680
|
+
|
|
1681
|
+ if (g29_verbose_level > 3) {
|
1683
|
1682
|
SERIAL_ECHOPGM("LSF Results A=");
|
1684
|
|
- SERIAL_PROTOCOL_F( lsf_results.A, 7);
|
|
1683
|
+ SERIAL_PROTOCOL_F(lsf_results.A, 7);
|
1685
|
1684
|
SERIAL_ECHOPGM(" B=");
|
1686
|
|
- SERIAL_PROTOCOL_F( lsf_results.B, 7);
|
|
1685
|
+ SERIAL_PROTOCOL_F(lsf_results.B, 7);
|
1687
|
1686
|
SERIAL_ECHOPGM(" D=");
|
1688
|
|
- SERIAL_PROTOCOL_F( lsf_results.D, 7);
|
1689
|
|
- SERIAL_CHAR('\n');
|
|
1687
|
+ SERIAL_PROTOCOL_F(lsf_results.D, 7);
|
|
1688
|
+ SERIAL_EOL;
|
1690
|
1689
|
}
|
1691
|
1690
|
|
1692
|
|
- normal = vector_3( lsf_results.A, lsf_results.B, 1.0000);
|
1693
|
|
- normal = normal.get_normal();
|
|
1691
|
+ vector_3 normal = vector_3(lsf_results.A, lsf_results.B, 1.0000).get_normal();
|
1694
|
1692
|
|
1695
|
|
- if (g29_verbose_level>2) {
|
|
1693
|
+ if (g29_verbose_level > 2) {
|
1696
|
1694
|
SERIAL_ECHOPGM("bed plane normal = [");
|
1697
|
|
- SERIAL_PROTOCOL_F( normal.x, 7);
|
1698
|
|
- SERIAL_ECHOPGM(",");
|
1699
|
|
- SERIAL_PROTOCOL_F( normal.y, 7);
|
1700
|
|
- SERIAL_ECHOPGM(",");
|
1701
|
|
- SERIAL_PROTOCOL_F( normal.z, 7);
|
1702
|
|
- SERIAL_ECHOPGM("]\n");
|
|
1695
|
+ SERIAL_PROTOCOL_F(normal.x, 7);
|
|
1696
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
1697
|
+ SERIAL_PROTOCOL_F(normal.y, 7);
|
|
1698
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
1699
|
+ SERIAL_PROTOCOL_F(normal.z, 7);
|
|
1700
|
+ SERIAL_ECHOLNPGM("]");
|
1703
|
1701
|
}
|
1704
|
1702
|
|
1705
|
|
- rotation = matrix_3x3::create_look_at( vector_3( lsf_results.A, lsf_results.B, 1));
|
|
1703
|
+ matrix_3x3 rotation = matrix_3x3::create_look_at(vector_3(lsf_results.A, lsf_results.B, 1));
|
|
1704
|
+
|
|
1705
|
+ for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
|
|
1706
|
+ for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
|
|
1707
|
+ float x_tmp = pgm_read_float(&ubl.mesh_index_to_xpos[i]),
|
|
1708
|
+ y_tmp = pgm_read_float(&ubl.mesh_index_to_ypos[j]),
|
|
1709
|
+ z_tmp = ubl.z_values[i][j];
|
1706
|
1710
|
|
1707
|
|
- for (i = 0; i < GRID_MAX_POINTS_X; i++) {
|
1708
|
|
- for (j = 0; j < GRID_MAX_POINTS_Y; j++) {
|
1709
|
|
- float x_tmp, y_tmp, z_tmp;
|
1710
|
|
- x_tmp = pgm_read_float(&(ubl.mesh_index_to_xpos[i]));
|
1711
|
|
- y_tmp = pgm_read_float(&(ubl.mesh_index_to_ypos[j]));
|
1712
|
|
- z_tmp = ubl.z_values[i][j];
|
1713
|
1711
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
1714
|
1712
|
if (DEBUGGING(LEVELING)) {
|
1715
|
1713
|
SERIAL_ECHOPGM("before rotation = [");
|
1716
|
|
- SERIAL_PROTOCOL_F( x_tmp, 7);
|
1717
|
|
- SERIAL_ECHOPGM(",");
|
1718
|
|
- SERIAL_PROTOCOL_F( y_tmp, 7);
|
1719
|
|
- SERIAL_ECHOPGM(",");
|
1720
|
|
- SERIAL_PROTOCOL_F( z_tmp, 7);
|
|
1714
|
+ SERIAL_PROTOCOL_F(x_tmp, 7);
|
|
1715
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
1716
|
+ SERIAL_PROTOCOL_F(y_tmp, 7);
|
|
1717
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
1718
|
+ SERIAL_PROTOCOL_F(z_tmp, 7);
|
1721
|
1719
|
SERIAL_ECHOPGM("] ---> ");
|
1722
|
1720
|
safe_delay(20);
|
1723
|
1721
|
}
|
1724
|
1722
|
#endif
|
|
1723
|
+
|
1725
|
1724
|
apply_rotation_xyz(rotation, x_tmp, y_tmp, z_tmp);
|
|
1725
|
+
|
1726
|
1726
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
1727
|
1727
|
if (DEBUGGING(LEVELING)) {
|
1728
|
1728
|
SERIAL_ECHOPGM("after rotation = [");
|
1729
|
|
- SERIAL_PROTOCOL_F( x_tmp, 7);
|
1730
|
|
- SERIAL_ECHOPGM(",");
|
1731
|
|
- SERIAL_PROTOCOL_F( y_tmp, 7);
|
1732
|
|
- SERIAL_ECHOPGM(",");
|
1733
|
|
- SERIAL_PROTOCOL_F( z_tmp, 7);
|
1734
|
|
- SERIAL_ECHOPGM("]\n");
|
|
1729
|
+ SERIAL_PROTOCOL_F(x_tmp, 7);
|
|
1730
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
1731
|
+ SERIAL_PROTOCOL_F(y_tmp, 7);
|
|
1732
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
1733
|
+ SERIAL_PROTOCOL_F(z_tmp, 7);
|
|
1734
|
+ SERIAL_ECHOLNPGM("]");
|
1735
|
1735
|
safe_delay(55);
|
1736
|
1736
|
}
|
1737
|
|
-
|
1738
|
1737
|
#endif
|
1739
|
1738
|
|
1740
|
1739
|
ubl.z_values[i][j] += z_tmp - lsf_results.D;
|
|
@@ -1743,27 +1742,26 @@
|
1743
|
1742
|
|
1744
|
1743
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
1745
|
1744
|
if (DEBUGGING(LEVELING)) {
|
1746
|
|
- rotation.debug("rotation matrix:");
|
|
1745
|
+ rotation.debug(PSTR("rotation matrix:"));
|
1747
|
1746
|
SERIAL_ECHOPGM("LSF Results A=");
|
1748
|
|
- SERIAL_PROTOCOL_F( lsf_results.A, 7);
|
|
1747
|
+ SERIAL_PROTOCOL_F(lsf_results.A, 7);
|
1749
|
1748
|
SERIAL_ECHOPGM(" B=");
|
1750
|
|
- SERIAL_PROTOCOL_F( lsf_results.B, 7);
|
|
1749
|
+ SERIAL_PROTOCOL_F(lsf_results.B, 7);
|
1751
|
1750
|
SERIAL_ECHOPGM(" D=");
|
1752
|
|
- SERIAL_PROTOCOL_F( lsf_results.D, 7);
|
1753
|
|
- SERIAL_CHAR('\n');
|
|
1751
|
+ SERIAL_PROTOCOL_F(lsf_results.D, 7);
|
|
1752
|
+ SERIAL_EOL;
|
1754
|
1753
|
safe_delay(55);
|
1755
|
1754
|
|
1756
|
1755
|
SERIAL_ECHOPGM("bed plane normal = [");
|
1757
|
|
- SERIAL_PROTOCOL_F( normal.x, 7);
|
1758
|
|
- SERIAL_ECHOPGM(",");
|
1759
|
|
- SERIAL_PROTOCOL_F( normal.y, 7);
|
1760
|
|
- SERIAL_ECHOPGM(",");
|
1761
|
|
- SERIAL_PROTOCOL_F( normal.z, 7);
|
|
1756
|
+ SERIAL_PROTOCOL_F(normal.x, 7);
|
|
1757
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
1758
|
+ SERIAL_PROTOCOL_F(normal.y, 7);
|
|
1759
|
+ SERIAL_PROTOCOLCHAR(',');
|
|
1760
|
+ SERIAL_PROTOCOL_F(normal.z, 7);
|
1762
|
1761
|
SERIAL_ECHOPGM("]\n");
|
1763
|
|
- SERIAL_CHAR('\n');
|
|
1762
|
+ SERIAL_EOL;
|
1764
|
1763
|
}
|
1765
|
1764
|
#endif
|
1766
|
|
- return;
|
1767
|
1765
|
}
|
1768
|
1766
|
|
1769
|
1767
|
#endif // AUTO_BED_LEVELING_UBL
|