Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor fixed 3-point and UBL 'G29 J' #25522

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2152,13 +2152,10 @@
* Points to probe for all 3-point Leveling procedures.
* Override if the automatically selected points are inadequate.
*/
#if EITHER(AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_UBL)
//#define PROBE_PT_1_X 15
//#define PROBE_PT_1_Y 180
//#define PROBE_PT_2_X 15
//#define PROBE_PT_2_Y 20
//#define PROBE_PT_3_X 170
//#define PROBE_PT_3_Y 20
#if NEEDS_THREE_PROBE_POINTS
//#define PROBE_PT_1 { 15, 180 } // (mm) { x, y }
//#define PROBE_PT_2 { 15, 20 }
//#define PROBE_PT_3 { 170, 20 }
#endif

/**
Expand Down
170 changes: 66 additions & 104 deletions Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1479,82 +1479,33 @@ void unified_bed_leveling::smart_fill_mesh() {

void unified_bed_leveling::tilt_mesh_based_on_probed_grid(const bool do_3_pt_leveling) {

#ifdef G29J_MESH_TILT_MARGIN
const float x_min = _MAX(probe.min_x() + (G29J_MESH_TILT_MARGIN), X_MIN_POS),
x_max = _MIN(probe.max_x() - (G29J_MESH_TILT_MARGIN), X_MAX_POS),
y_min = _MAX(probe.min_y() + (G29J_MESH_TILT_MARGIN), Y_MIN_POS),
y_max = _MIN(probe.max_y() - (G29J_MESH_TILT_MARGIN), Y_MAX_POS);
#else
const float x_min = probe.min_x(), x_max = probe.max_x(),
y_min = probe.min_y(), y_max = probe.max_y();
#endif
const float dx = (x_max - x_min) / (param.J_grid_size - 1),
dy = (y_max - y_min) / (param.J_grid_size - 1);

xy_float_t points[3];
probe.get_three_points(points);

float measured_z;
bool abort_flag = false;

#if ENABLED(VALIDATE_MESH_TILT)
float z1, z2, z3; // Needed for algorithm validation below
#endif

struct linear_fit_data lsf_results;
incremental_LSF_reset(&lsf_results);

if (do_3_pt_leveling) {
SERIAL_ECHOLNPGM("Tilting mesh (1/3)");
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " 1/3"), GET_TEXT(MSG_LCD_TILTING_MESH)));
xy_float_t points[3];
probe.get_three_points(points);

measured_z = probe.probe_at_point(points[0], PROBE_PT_RAISE, param.V_verbosity);
if (isnan(measured_z))
abort_flag = true;
else {
measured_z -= get_z_correction(points[0]);
TERN_(VALIDATE_MESH_TILT, z1 = measured_z);
if (param.V_verbosity > 3) {
serial_spaces(16);
SERIAL_ECHOLNPGM("Corrected_Z=", measured_z);
}
incremental_LSF(&lsf_results, points[0], measured_z);
}
#if ENABLED(VALIDATE_MESH_TILT)
float gotz[3]; // Used for algorithm validation below
#endif

if (!abort_flag) {
SERIAL_ECHOLNPGM("Tilting mesh (2/3)");
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " 2/3"), GET_TEXT(MSG_LCD_TILTING_MESH)));
LOOP_L_N(i, 3) {
SERIAL_ECHOLNPGM("Tilting mesh (", i + 1, "/3)");
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), i + 1, GET_TEXT(MSG_LCD_TILTING_MESH)));

measured_z = probe.probe_at_point(points[1], PROBE_PT_RAISE, param.V_verbosity);
TERN_(VALIDATE_MESH_TILT, z2 = measured_z);
if (isnan(measured_z))
abort_flag = true;
else {
measured_z -= get_z_correction(points[1]);
if (param.V_verbosity > 3) {
serial_spaces(16);
SERIAL_ECHOLNPGM("Corrected_Z=", measured_z);
}
incremental_LSF(&lsf_results, points[1], measured_z);
}
}
measured_z = probe.probe_at_point(points[i], i < 2 ? PROBE_PT_RAISE : PROBE_PT_LAST_STOW, param.V_verbosity);
if ((abort_flag = isnan(measured_z))) break;

if (!abort_flag) {
SERIAL_ECHOLNPGM("Tilting mesh (3/3)");
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " 3/3"), GET_TEXT(MSG_LCD_TILTING_MESH)));
measured_z -= get_z_correction(points[i]);
TERN_(VALIDATE_MESH_TILT, gotz[i] = measured_z);

measured_z = probe.probe_at_point(points[2], PROBE_PT_LAST_STOW, param.V_verbosity);
TERN_(VALIDATE_MESH_TILT, z3 = measured_z);
if (isnan(measured_z))
abort_flag = true;
else {
measured_z -= get_z_correction(points[2]);
if (param.V_verbosity > 3) {
serial_spaces(16);
SERIAL_ECHOLNPGM("Corrected_Z=", measured_z);
}
incremental_LSF(&lsf_results, points[2], measured_z);
}
if (param.V_verbosity > 3) { serial_spaces(16); SERIAL_ECHOLNPGM("Corrected_Z=", measured_z); }

incremental_LSF(&lsf_results, points[i], measured_z);
}

probe.stow();
Expand All @@ -1567,54 +1518,62 @@ void unified_bed_leveling::smart_fill_mesh() {
}
else { // !do_3_pt_leveling

#ifdef G29J_MESH_TILT_MARGIN
const float x_min = _MAX(probe.min_x() + (G29J_MESH_TILT_MARGIN), X_MIN_POS),
x_max = _MIN(probe.max_x() - (G29J_MESH_TILT_MARGIN), X_MAX_POS),
y_min = _MAX(probe.min_y() + (G29J_MESH_TILT_MARGIN), Y_MIN_POS),
y_max = _MIN(probe.max_y() - (G29J_MESH_TILT_MARGIN), Y_MAX_POS);
#else
const float x_min = probe.min_x(), x_max = probe.max_x(),
y_min = probe.min_y(), y_max = probe.max_y();
#endif
const float dx = (x_max - x_min) / (param.J_grid_size - 1),
dy = (y_max - y_min) / (param.J_grid_size - 1);

bool zig_zag = false;

const uint16_t total_points = sq(param.J_grid_size);
uint16_t point_num = 1;

xy_pos_t rpos;
LOOP_L_N(ix, param.J_grid_size) {
xy_pos_t rpos;
rpos.x = x_min + ix * dx;
LOOP_L_N(iy, param.J_grid_size) {
rpos.y = y_min + dy * (zig_zag ? param.J_grid_size - 1 - iy : iy);

if (!abort_flag) {
SERIAL_ECHOLNPGM("Tilting mesh point ", point_num, "/", total_points, "\n");
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points));

measured_z = probe.probe_at_point(rpos, parser.seen_test('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, param.V_verbosity); // TODO: Needs error handling

abort_flag = isnan(measured_z);

#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) {
const xy_pos_t lpos = rpos.asLogical();
DEBUG_CHAR('(');
DEBUG_ECHO_F(rpos.x, 7);
DEBUG_CHAR(',');
DEBUG_ECHO_F(rpos.y, 7);
DEBUG_ECHOPAIR_F(") logical: (", lpos.x, 7);
DEBUG_CHAR(',');
DEBUG_ECHO_F(lpos.y, 7);
DEBUG_ECHOPAIR_F(") measured: ", measured_z, 7);
DEBUG_ECHOPAIR_F(" correction: ", get_z_correction(rpos), 7);
}
#endif
SERIAL_ECHOLNPGM("Tilting mesh point ", point_num, "/", total_points, "\n");
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points));

measured_z -= get_z_correction(rpos) /* + probe.offset.z */ ;
measured_z = probe.probe_at_point(rpos, parser.seen_test('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, param.V_verbosity); // TODO: Needs error handling

if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR_F(" final >>>---> ", measured_z, 7);
if ((abort_flag = isnan(measured_z))) break;

if (param.V_verbosity > 3) {
serial_spaces(16);
SERIAL_ECHOLNPGM("Corrected_Z=", measured_z);
const float zcorr = get_z_correction(rpos);

#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) {
const xy_pos_t lpos = rpos.asLogical();
DEBUG_CHAR('('); DEBUG_ECHO_F(rpos.x, 7); DEBUG_CHAR(','); DEBUG_ECHO_F(rpos.y, 7);
DEBUG_ECHOPAIR_F(") logical: (", lpos.x, 7); DEBUG_CHAR(','); DEBUG_ECHO_F(lpos.y, 7);
DEBUG_ECHOPAIR_F(") measured: ", measured_z, 7);
DEBUG_ECHOPAIR_F(" correction: ", zcorr, 7);
}
incremental_LSF(&lsf_results, rpos, measured_z);
#endif

measured_z -= zcorr;

if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR_F(" final >>>---> ", measured_z, 7);

if (param.V_verbosity > 3) {
serial_spaces(16);
SERIAL_ECHOLNPGM("Corrected_Z=", measured_z);
}
incremental_LSF(&lsf_results, rpos, measured_z);

point_num++;
}

if (abort_flag) break;
zig_zag ^= true;
}
}
Expand Down Expand Up @@ -1696,20 +1655,23 @@ void unified_bed_leveling::smart_fill_mesh() {
auto normed = [&](const xy_pos_t &pos, const_float_t zadd) {
return normal.x * pos.x + normal.y * pos.y + zadd;
};
auto debug_pt = [](FSTR_P const pre, const xy_pos_t &pos, const_float_t zadd) {
d_from(); SERIAL_ECHOF(pre);
auto debug_pt = [](const int num, const xy_pos_t &pos, const_float_t zadd) {
d_from(); DEBUG_ECHOPGM("Point ", num, ":");
DEBUG_ECHO_F(normed(pos, zadd), 6);
DEBUG_ECHOLNPAIR_F(" Z error = ", zadd - get_z_correction(pos), 6);
};
debug_pt(F("1st point: "), probe_pt[0], normal.z * z1);
debug_pt(F("2nd point: "), probe_pt[1], normal.z * z2);
debug_pt(F("3rd point: "), probe_pt[2], normal.z * z3);
d_from(); DEBUG_ECHOPGM("safe home with Z=");
DEBUG_ECHOLNPAIR_F("0 : ", normed(safe_homing_xy, 0), 6);
d_from(); DEBUG_ECHOPGM("safe home with Z=");
DEBUG_ECHOLNPAIR_F("mesh value ", normed(safe_homing_xy, get_z_correction(safe_homing_xy)), 6);
DEBUG_ECHOPGM(" Z error = (", Z_SAFE_HOMING_X_POINT, ",", Z_SAFE_HOMING_Y_POINT);
DEBUG_ECHOLNPAIR_F(") = ", get_z_correction(safe_homing_xy), 6);
debug_pt(1, probe_pt[0], normal.z * gotz[0]);
debug_pt(2, probe_pt[1], normal.z * gotz[1]);
debug_pt(3, probe_pt[2], normal.z * gotz[2]);
#if ENABLED(Z_SAFE_HOMING)
constexpr xy_float_t safe_xy = { Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT };
d_from(); DEBUG_ECHOPGM("safe home with Z=");
DEBUG_ECHOLNPAIR_F("0 : ", normed(safe_xy, 0), 6);
d_from(); DEBUG_ECHOPGM("safe home with Z=");
DEBUG_ECHOLNPAIR_F("mesh value ", normed(safe_xy, get_z_correction(safe_xy)), 6);
DEBUG_ECHOPGM(" Z error = (", Z_SAFE_HOMING_X_POINT, ",", Z_SAFE_HOMING_Y_POINT);
DEBUG_ECHOLNPAIR_F(") = ", get_z_correction(safe_xy), 6);
#endif
#endif
} // DEBUGGING(LEVELING)

Expand Down
8 changes: 2 additions & 6 deletions Marlin/src/inc/Conditionals_post.h
Original file line number Diff line number Diff line change
Expand Up @@ -3188,13 +3188,9 @@
#undef MESH_MAX_Y
#endif

#define _POINT_COUNT (defined(PROBE_PT_1_X) + defined(PROBE_PT_2_X) + defined(PROBE_PT_3_X) + defined(PROBE_PT_1_Y) + defined(PROBE_PT_2_Y) + defined(PROBE_PT_3_Y))
#if _POINT_COUNT == 6
#define HAS_FIXED_3POINT 1
#elif _POINT_COUNT > 0
#error "For 3-Point Leveling all XY points must be defined (or none for the defaults)."
#if NEEDS_THREE_PROBE_POINTS && defined(PROBE_PT_1)
#define HAS_FIXED_3POINT 1 // Points are defined for ABL/UBL. Else calculated in probe.get_three_points.
#endif
#undef _POINT_COUNT

/**
* Buzzer/Speaker
Expand Down
8 changes: 8 additions & 0 deletions Marlin/src/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,8 @@
#error "DISABLE_INACTIVE_E is now set with DISABLE_INACTIVE_EXTRUDER."
#elif defined(INVERT_X_STEP_PIN) || defined(INVERT_Y_STEP_PIN) || defined(INVERT_Z_STEP_PIN) || defined(INVERT_I_STEP_PIN) || defined(INVERT_J_STEP_PIN) || defined(INVERT_K_STEP_PIN) || defined(INVERT_U_STEP_PIN) || defined(INVERT_V_STEP_PIN) || defined(INVERT_W_STEP_PIN) || defined(INVERT_E_STEP_PIN)
#error "INVERT_*_STEP_PIN true is now STEP_STATE_* LOW, and INVERT_*_STEP_PIN false is now STEP_STATE_* HIGH."
#elif defined(PROBE_PT_1_X) || defined(PROBE_PT_1_Y) || defined(PROBE_PT_2_X) || defined(PROBE_PT_2_Y) || defined(PROBE_PT_3_X) || defined(PROBE_PT_3_Y)
#error "PROBE_PT_[123]_[XY] is now defined using PROBE_PT_[123] with an array { x, y }."
#endif

// L64xx stepper drivers have been removed
Expand Down Expand Up @@ -2102,6 +2104,12 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE, "Movement bounds (X_MIN_POS, X_MAX_POS

#endif

#define _POINT_COUNT (defined(PROBE_PT_1) + defined(PROBE_PT_2) + defined(PROBE_PT_3))
#if _POINT_COUNT != 0 && _POINT_COUNT != 3
#error "For 3-Point Procedures all XY points must be defined (or none for the defaults)."
#endif
#undef _POINT_COUNT

#if ALL(HAS_LEVELING, RESTORE_LEVELING_AFTER_G28, ENABLE_LEVELING_AFTER_G28)
#error "Only enable RESTORE_LEVELING_AFTER_G28 or ENABLE_LEVELING_AFTER_G28, but not both."
#endif
Expand Down
10 changes: 5 additions & 5 deletions Marlin/src/module/probe.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,12 +294,12 @@ class Probe {
template <typename T>
static void get_three_points(T points[3]) {
#if HAS_FIXED_3POINT
#define VALIDATE_PROBE_PT(N) static_assert(Probe::build_time::can_reach(xy_pos_t{PROBE_PT_##N##_X, PROBE_PT_##N##_Y}), \
"PROBE_PT_" STRINGIFY(N) "_(X|Y) is unreachable using default NOZZLE_TO_PROBE_OFFSET and PROBING_MARGIN");
#define VALIDATE_PROBE_PT(N) static_assert(Probe::build_time::can_reach(xy_pos_t(PROBE_PT_##N)), \
"PROBE_PT_" STRINGIFY(N) " is unreachable using default NOZZLE_TO_PROBE_OFFSET and PROBING_MARGIN.");
VALIDATE_PROBE_PT(1); VALIDATE_PROBE_PT(2); VALIDATE_PROBE_PT(3);
points[0] = xy_float_t({ PROBE_PT_1_X, PROBE_PT_1_Y });
points[1] = xy_float_t({ PROBE_PT_2_X, PROBE_PT_2_Y });
points[2] = xy_float_t({ PROBE_PT_3_X, PROBE_PT_3_Y });
points[0] = xy_float_t(PROBE_PT_1);
points[1] = xy_float_t(PROBE_PT_2);
points[2] = xy_float_t(PROBE_PT_3);
#else
#if IS_KINEMATIC
constexpr float SIN0 = 0.0, SIN120 = 0.866025, SIN240 = -0.866025,
Expand Down
3 changes: 2 additions & 1 deletion buildroot/tests/mega2560
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO NUM_SERVOS 1 \
NUM_RUNOUT_SENSORS 5 FIL_RUNOUT2_PIN 44 FIL_RUNOUT3_PIN 45 FIL_RUNOUT4_PIN 46 FIL_RUNOUT5_PIN 47 \
FIL_RUNOUT3_STATE HIGH FILAMENT_RUNOUT_SCRIPT '"M600 T%c"'
opt_enable VIKI2 BOOT_MARLIN_LOGO_ANIMATED SDSUPPORT AUTO_REPORT_SD_STATUS \
Z_PROBE_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE \
Z_PROBE_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE \
AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE PROBE_PT_1 PROBE_PT_2 PROBE_PT_3 \
EEPROM_SETTINGS EEPROM_CHITCHAT M114_DETAIL AUTO_REPORT_POSITION \
NO_VOLUMETRICS EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET JOYSTICK \
DIRECT_STEPPING DETECT_BROKEN_ENDSTOP \
Expand Down