|
|
@ -24,36 +24,36 @@ |
|
|
|
|
|
|
|
#if ENABLED(AUTO_BED_LEVELING_UBL) |
|
|
|
|
|
|
|
#include "../bedlevel.h" |
|
|
|
|
|
|
|
#include "../../../MarlinCore.h" |
|
|
|
#include "../../../HAL/shared/eeprom_api.h" |
|
|
|
#include "../../../libs/hex_print.h" |
|
|
|
#include "../../../module/settings.h" |
|
|
|
#include "../../../lcd/marlinui.h" |
|
|
|
#include "../../../module/stepper.h" |
|
|
|
#include "../../../module/planner.h" |
|
|
|
#include "../../../module/motion.h" |
|
|
|
#include "../../../module/probe.h" |
|
|
|
#include "../../../gcode/gcode.h" |
|
|
|
#include "../../../libs/least_squares_fit.h" |
|
|
|
|
|
|
|
#if HAS_MULTI_HOTEND |
|
|
|
#include "../bedlevel.h" |
|
|
|
|
|
|
|
#include "../../../MarlinCore.h" |
|
|
|
#include "../../../HAL/shared/eeprom_api.h" |
|
|
|
#include "../../../libs/hex_print.h" |
|
|
|
#include "../../../module/settings.h" |
|
|
|
#include "../../../lcd/marlinui.h" |
|
|
|
#include "../../../module/stepper.h" |
|
|
|
#include "../../../module/planner.h" |
|
|
|
#include "../../../module/motion.h" |
|
|
|
#include "../../../module/probe.h" |
|
|
|
#include "../../../gcode/gcode.h" |
|
|
|
#include "../../../libs/least_squares_fit.h" |
|
|
|
|
|
|
|
#if HAS_MULTI_HOTEND |
|
|
|
#include "../../../module/tool_change.h" |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) |
|
|
|
#include "../../../core/debug_out.h" |
|
|
|
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) |
|
|
|
#include "../../../core/debug_out.h" |
|
|
|
|
|
|
|
#if ENABLED(EXTENSIBLE_UI) |
|
|
|
#if ENABLED(EXTENSIBLE_UI) |
|
|
|
#include "../../../lcd/extui/ui_api.h" |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
#include <math.h> |
|
|
|
#include <math.h> |
|
|
|
|
|
|
|
#define UBL_G29_P31 |
|
|
|
#define UBL_G29_P31 |
|
|
|
|
|
|
|
#if HAS_LCD_MENU |
|
|
|
#if HAS_LCD_MENU |
|
|
|
|
|
|
|
bool unified_bed_leveling::lcd_map_control = false; |
|
|
|
|
|
|
@ -66,27 +66,27 @@ |
|
|
|
|
|
|
|
void ubl_map_screen(); |
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
#define SIZE_OF_LITTLE_RAISE 1 |
|
|
|
#define BIG_RAISE_NOT_NEEDED 0 |
|
|
|
#define SIZE_OF_LITTLE_RAISE 1 |
|
|
|
#define BIG_RAISE_NOT_NEEDED 0 |
|
|
|
|
|
|
|
int unified_bed_leveling::g29_verbose_level, |
|
|
|
int unified_bed_leveling::g29_verbose_level, |
|
|
|
unified_bed_leveling::g29_phase_value, |
|
|
|
unified_bed_leveling::g29_repetition_cnt, |
|
|
|
unified_bed_leveling::g29_storage_slot = 0, |
|
|
|
unified_bed_leveling::g29_map_type; |
|
|
|
bool unified_bed_leveling::g29_c_flag; |
|
|
|
float unified_bed_leveling::g29_card_thickness = 0, |
|
|
|
bool unified_bed_leveling::g29_c_flag; |
|
|
|
float unified_bed_leveling::g29_card_thickness = 0, |
|
|
|
unified_bed_leveling::g29_constant = 0; |
|
|
|
xy_bool_t unified_bed_leveling::xy_seen; |
|
|
|
xy_pos_t unified_bed_leveling::g29_pos; |
|
|
|
xy_bool_t unified_bed_leveling::xy_seen; |
|
|
|
xy_pos_t unified_bed_leveling::g29_pos; |
|
|
|
|
|
|
|
#if HAS_BED_PROBE |
|
|
|
#if HAS_BED_PROBE |
|
|
|
int unified_bed_leveling::g29_grid_size; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* G29: Unified Bed Leveling by Roxy |
|
|
|
* |
|
|
|
* Parameters understood by this leveling system: |
|
|
@ -309,7 +309,7 @@ |
|
|
|
* features of all three systems combined. |
|
|
|
*/ |
|
|
|
|
|
|
|
void unified_bed_leveling::G29() { |
|
|
|
void unified_bed_leveling::G29() { |
|
|
|
|
|
|
|
bool probe_deployed = false; |
|
|
|
if (g29_parameter_parsing()) return; // Abort on parameter error
|
|
|
@ -680,9 +680,9 @@ |
|
|
|
|
|
|
|
TERN_(HAS_MULTI_HOTEND, tool_change(old_tool_index)); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const float value) { |
|
|
|
void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const float value) { |
|
|
|
float sum = 0; |
|
|
|
int n = 0; |
|
|
|
GRID_LOOP(x, y) |
|
|
@ -713,17 +713,17 @@ |
|
|
|
z_values[x][y] -= mean + value; |
|
|
|
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void unified_bed_leveling::shift_mesh_height() { |
|
|
|
void unified_bed_leveling::shift_mesh_height() { |
|
|
|
GRID_LOOP(x, y) |
|
|
|
if (!isnan(z_values[x][y])) { |
|
|
|
z_values[x][y] += g29_constant; |
|
|
|
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#if HAS_BED_PROBE |
|
|
|
#if HAS_BED_PROBE |
|
|
|
/**
|
|
|
|
* 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. |
|
|
@ -794,9 +794,9 @@ |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
#endif // HAS_BED_PROBE
|
|
|
|
#endif // HAS_BED_PROBE
|
|
|
|
|
|
|
|
#if HAS_LCD_MENU |
|
|
|
#if HAS_LCD_MENU |
|
|
|
|
|
|
|
typedef void (*clickFunc_t)(); |
|
|
|
|
|
|
@ -1051,9 +1051,9 @@ |
|
|
|
ui.return_to_status(); |
|
|
|
} |
|
|
|
|
|
|
|
#endif // HAS_LCD_MENU
|
|
|
|
#endif // HAS_LCD_MENU
|
|
|
|
|
|
|
|
bool unified_bed_leveling::g29_parameter_parsing() { |
|
|
|
bool unified_bed_leveling::g29_parameter_parsing() { |
|
|
|
bool err_flag = false; |
|
|
|
|
|
|
|
TERN_(HAS_LCD_MENU, set_message_with_feedback(GET_TEXT(MSG_UBL_DOING_G29))); |
|
|
@ -1165,15 +1165,15 @@ |
|
|
|
return UBL_ERR; |
|
|
|
} |
|
|
|
return UBL_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static uint8_t ubl_state_at_invocation = 0; |
|
|
|
static uint8_t ubl_state_at_invocation = 0; |
|
|
|
|
|
|
|
#if ENABLED(UBL_DEVEL_DEBUGGING) |
|
|
|
#if ENABLED(UBL_DEVEL_DEBUGGING) |
|
|
|
static uint8_t ubl_state_recursion_chk = 0; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
void unified_bed_leveling::save_ubl_active_state_and_disable() { |
|
|
|
void unified_bed_leveling::save_ubl_active_state_and_disable() { |
|
|
|
#if ENABLED(UBL_DEVEL_DEBUGGING) |
|
|
|
ubl_state_recursion_chk++; |
|
|
|
if (ubl_state_recursion_chk != 1) { |
|
|
@ -1184,9 +1184,9 @@ |
|
|
|
#endif |
|
|
|
ubl_state_at_invocation = planner.leveling_active; |
|
|
|
set_bed_leveling_enabled(false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void unified_bed_leveling::restore_ubl_active_state_and_leave() { |
|
|
|
void unified_bed_leveling::restore_ubl_active_state_and_leave() { |
|
|
|
TERN_(HAS_LCD_MENU, ui.release()); |
|
|
|
#if ENABLED(UBL_DEVEL_DEBUGGING) |
|
|
|
if (--ubl_state_recursion_chk) { |
|
|
@ -1196,9 +1196,9 @@ |
|
|
|
} |
|
|
|
#endif |
|
|
|
set_bed_leveling_enabled(ubl_state_at_invocation); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
mesh_index_pair unified_bed_leveling::find_furthest_invalid_mesh_point() { |
|
|
|
mesh_index_pair unified_bed_leveling::find_furthest_invalid_mesh_point() { |
|
|
|
|
|
|
|
bool found_a_NAN = false, found_a_real = false; |
|
|
|
|
|
|
@ -1247,9 +1247,9 @@ |
|
|
|
farthest.distance = 1; |
|
|
|
} |
|
|
|
return farthest; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const MeshPointType type, const xy_pos_t &pos, const bool probe_relative/*=false*/, MeshFlags *done_flags/*=nullptr*/) { |
|
|
|
mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const MeshPointType type, const xy_pos_t &pos, const bool probe_relative/*=false*/, MeshFlags *done_flags/*=nullptr*/) { |
|
|
|
mesh_index_pair closest; |
|
|
|
closest.invalidate(); |
|
|
|
closest.distance = -99999.9f; |
|
|
@ -1289,15 +1289,15 @@ |
|
|
|
} // GRID_LOOP
|
|
|
|
|
|
|
|
return closest; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 'Smart Fill': Scan from the outward edges of the mesh towards the center. |
|
|
|
* If an invalid location is found, use the next two points (if valid) to |
|
|
|
* calculate a 'reasonable' value for the unprobed mesh point. |
|
|
|
*/ |
|
|
|
|
|
|
|
bool unified_bed_leveling::smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir) { |
|
|
|
bool unified_bed_leveling::smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir) { |
|
|
|
const float v = z_values[x][y]; |
|
|
|
if (isnan(v)) { // A NAN...
|
|
|
|
const int8_t dx = x + xdir, dy = y + ydir; |
|
|
@ -1312,11 +1312,11 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
typedef struct { uint8_t sx, ex, sy, ey; bool yfirst; } smart_fill_info; |
|
|
|
typedef struct { uint8_t sx, ex, sy, ey; bool yfirst; } smart_fill_info; |
|
|
|
|
|
|
|
void unified_bed_leveling::smart_fill_mesh() { |
|
|
|
void unified_bed_leveling::smart_fill_mesh() { |
|
|
|
static const smart_fill_info |
|
|
|
info0 PROGMEM = { 0, GRID_MAX_POINTS_X, 0, GRID_MAX_POINTS_Y - 2, false }, // Bottom of the mesh looking up
|
|
|
|
info1 PROGMEM = { 0, GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y - 1, 0, false }, // Top of the mesh looking down
|
|
|
@ -1341,9 +1341,9 @@ |
|
|
|
if (smart_fill_one(x, y, 0, dir)) break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#if HAS_BED_PROBE |
|
|
|
#if HAS_BED_PROBE |
|
|
|
|
|
|
|
//#define VALIDATE_MESH_TILT
|
|
|
|
|
|
|
@ -1587,9 +1587,9 @@ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#endif // HAS_BED_PROBE
|
|
|
|
#endif // HAS_BED_PROBE
|
|
|
|
|
|
|
|
#if ENABLED(UBL_G29_P31) |
|
|
|
#if ENABLED(UBL_G29_P31) |
|
|
|
void unified_bed_leveling::smart_fill_wlsf(const float &weight_factor) { |
|
|
|
|
|
|
|
// For each undefined mesh point, compute a distance-weighted least squares fit
|
|
|
@ -1641,9 +1641,9 @@ |
|
|
|
|
|
|
|
SERIAL_ECHOLNPGM("done"); |
|
|
|
} |
|
|
|
#endif // UBL_G29_P31
|
|
|
|
#endif // UBL_G29_P31
|
|
|
|
|
|
|
|
#if ENABLED(UBL_DEVEL_DEBUGGING) |
|
|
|
#if ENABLED(UBL_DEVEL_DEBUGGING) |
|
|
|
/**
|
|
|
|
* Much of the 'What?' command can be eliminated. But until we are fully debugged, it is |
|
|
|
* good to have the extra information. Soon... we prune this to just a few items |
|
|
@ -1778,6 +1778,6 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endif // UBL_DEVEL_DEBUGGING
|
|
|
|
#endif // UBL_DEVEL_DEBUGGING
|
|
|
|
|
|
|
|
#endif // AUTO_BED_LEVELING_UBL
|
|
|
|