Operate in Native Machine Space

This commit is contained in:
Scott Lahteine
2017-11-02 23:59:42 -05:00
parent 31f112cf58
commit f8393a0908
36 changed files with 449 additions and 489 deletions

View File

@ -259,7 +259,7 @@ void refresh_bed_level() {
#endif
// Get the Z adjustment for non-linear bed leveling
float bilinear_z_offset(const float logical[XYZ]) {
float bilinear_z_offset(const float raw[XYZ]) {
static float z1, d2, z3, d4, L, D, ratio_x, ratio_y,
last_x = -999.999, last_y = -999.999;
@ -269,8 +269,8 @@ float bilinear_z_offset(const float logical[XYZ]) {
last_gridx = -99, last_gridy = -99;
// XY relative to the probed area
const float x = RAW_X_POSITION(logical[X_AXIS]) - bilinear_start[X_AXIS],
y = RAW_Y_POSITION(logical[Y_AXIS]) - bilinear_start[Y_AXIS];
const float rx = raw[X_AXIS] - bilinear_start[X_AXIS],
ry = raw[Y_AXIS] - bilinear_start[Y_AXIS];
#if ENABLED(EXTRAPOLATE_BEYOND_GRID)
// Keep using the last grid box
@ -280,9 +280,9 @@ float bilinear_z_offset(const float logical[XYZ]) {
#define FAR_EDGE_OR_BOX 1
#endif
if (last_x != x) {
last_x = x;
ratio_x = x * ABL_BG_FACTOR(X_AXIS);
if (last_x != rx) {
last_x = rx;
ratio_x = rx * ABL_BG_FACTOR(X_AXIS);
const float gx = constrain(FLOOR(ratio_x), 0, ABL_BG_POINTS_X - FAR_EDGE_OR_BOX);
ratio_x -= gx; // Subtract whole to get the ratio within the grid box
@ -295,11 +295,11 @@ float bilinear_z_offset(const float logical[XYZ]) {
nextx = min(gridx + 1, ABL_BG_POINTS_X - 1);
}
if (last_y != y || last_gridx != gridx) {
if (last_y != ry || last_gridx != gridx) {
if (last_y != y) {
last_y = y;
ratio_y = y * ABL_BG_FACTOR(Y_AXIS);
if (last_y != ry) {
last_y = ry;
ratio_y = ry * ABL_BG_FACTOR(Y_AXIS);
const float gy = constrain(FLOOR(ratio_y), 0, ABL_BG_POINTS_Y - FAR_EDGE_OR_BOX);
ratio_y -= gy;
@ -322,7 +322,7 @@ float bilinear_z_offset(const float logical[XYZ]) {
d4 = ABL_BG_GRID(nextx, nexty) - z3; // right-back (delta)
}
// Bilinear interpolate. Needed since y or gridx has changed.
// Bilinear interpolate. Needed since ry or gridx has changed.
L = z1 + d2 * ratio_y; // Linear interp. LF -> LB
const float R = z3 + d4 * ratio_y; // Linear interp. RF -> RB
@ -335,10 +335,10 @@ float bilinear_z_offset(const float logical[XYZ]) {
static float last_offset = 0;
if (FABS(last_offset - offset) > 0.2) {
SERIAL_ECHOPGM("Sudden Shift at ");
SERIAL_ECHOPAIR("x=", x);
SERIAL_ECHOPAIR("x=", rx);
SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[X_AXIS]);
SERIAL_ECHOLNPAIR(" -> gridx=", gridx);
SERIAL_ECHOPAIR(" y=", y);
SERIAL_ECHOPAIR(" y=", ry);
SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[Y_AXIS]);
SERIAL_ECHOLNPAIR(" -> gridy=", gridy);
SERIAL_ECHOPAIR(" ratio_x=", ratio_x);
@ -390,14 +390,14 @@ float bilinear_z_offset(const float logical[XYZ]) {
const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
if (cx2 != cx1 && TEST(x_splits, gcx)) {
COPY(end, destination);
destination[X_AXIS] = LOGICAL_X_POSITION(bilinear_start[X_AXIS] + ABL_BG_SPACING(X_AXIS) * gcx);
destination[X_AXIS] = bilinear_start[X_AXIS] + ABL_BG_SPACING(X_AXIS) * gcx;
normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]);
destination[Y_AXIS] = LINE_SEGMENT_END(Y);
CBI(x_splits, gcx);
}
else if (cy2 != cy1 && TEST(y_splits, gcy)) {
COPY(end, destination);
destination[Y_AXIS] = LOGICAL_Y_POSITION(bilinear_start[Y_AXIS] + ABL_BG_SPACING(Y_AXIS) * gcy);
destination[Y_AXIS] = bilinear_start[Y_AXIS] + ABL_BG_SPACING(Y_AXIS) * gcy;
normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]);
destination[X_AXIS] = LINE_SEGMENT_END(X);
CBI(y_splits, gcy);

View File

@ -32,7 +32,7 @@
extern int bilinear_grid_spacing[2], bilinear_start[2];
extern float bilinear_grid_factor[2],
z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
float bilinear_z_offset(const float logical[XYZ]);
float bilinear_z_offset(const float raw[XYZ]);
void extrapolate_unprobed_bed_level();
void print_bilinear_leveling_grid();

View File

@ -256,18 +256,18 @@ void reset_bed_level() {
#if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY)
void _manual_goto_xy(const float &x, const float &y) {
void _manual_goto_xy(const float &rx, const float &ry) {
const float old_feedrate_mm_s = feedrate_mm_s;
#if MANUAL_PROBE_HEIGHT > 0
const float prev_z = current_position[Z_AXIS];
feedrate_mm_s = homing_feedrate(Z_AXIS);
current_position[Z_AXIS] = LOGICAL_Z_POSITION(MANUAL_PROBE_HEIGHT);
current_position[Z_AXIS] = MANUAL_PROBE_HEIGHT;
line_to_current_position();
#endif
feedrate_mm_s = MMM_TO_MMS(XY_PROBE_SPEED);
current_position[X_AXIS] = LOGICAL_X_POSITION(x);
current_position[Y_AXIS] = LOGICAL_Y_POSITION(y);
current_position[X_AXIS] = rx;
current_position[Y_AXIS] = ry;
line_to_current_position();
#if MANUAL_PROBE_HEIGHT > 0

View File

@ -57,10 +57,10 @@
* splitting the move where it crosses mesh borders.
*/
void mesh_line_to_destination(const float fr_mm_s, uint8_t x_splits, uint8_t y_splits) {
int cx1 = mbl.cell_index_x(RAW_CURRENT_POSITION(X)),
cy1 = mbl.cell_index_y(RAW_CURRENT_POSITION(Y)),
cx2 = mbl.cell_index_x(RAW_X_POSITION(destination[X_AXIS])),
cy2 = mbl.cell_index_y(RAW_Y_POSITION(destination[Y_AXIS]));
int cx1 = mbl.cell_index_x(current_position[X_AXIS]),
cy1 = mbl.cell_index_y(current_position[Y_AXIS]),
cx2 = mbl.cell_index_x(destination[X_AXIS]),
cy2 = mbl.cell_index_y(destination[Y_AXIS]);
NOMORE(cx1, GRID_MAX_POINTS_X - 2);
NOMORE(cy1, GRID_MAX_POINTS_Y - 2);
NOMORE(cx2, GRID_MAX_POINTS_X - 2);
@ -81,14 +81,14 @@
const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
if (cx2 != cx1 && TEST(x_splits, gcx)) {
COPY(end, destination);
destination[X_AXIS] = LOGICAL_X_POSITION(mbl.index_to_xpos[gcx]);
destination[X_AXIS] = mbl.index_to_xpos[gcx];
normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]);
destination[Y_AXIS] = MBL_SEGMENT_END(Y);
CBI(x_splits, gcx);
}
else if (cy2 != cy1 && TEST(y_splits, gcy)) {
COPY(end, destination);
destination[Y_AXIS] = LOGICAL_Y_POSITION(mbl.index_to_ypos[gcy]);
destination[Y_AXIS] = mbl.index_to_ypos[gcy];
normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]);
destination[X_AXIS] = MBL_SEGMENT_END(X);
CBI(y_splits, gcy);

View File

@ -276,7 +276,7 @@ void unified_bed_leveling::G26() {
// If this mesh location is outside the printable_radius, skip it.
if (!position_is_reachable_raw_xy(circle_x, circle_y)) continue;
if (!position_is_reachable(circle_x, circle_y)) continue;
xi = location.x_index; // Just to shrink the next few lines and make them easier to understand
yi = location.y_index;
@ -325,16 +325,16 @@ void unified_bed_leveling::G26() {
if (tmp_div_30 < 0) tmp_div_30 += 360 / 30;
if (tmp_div_30 > 11) tmp_div_30 -= 360 / 30;
float x = circle_x + cos_table[tmp_div_30], // for speed, these are now a lookup table entry
y = circle_y + sin_table[tmp_div_30],
float rx = circle_x + cos_table[tmp_div_30], // for speed, these are now a lookup table entry
ry = circle_y + sin_table[tmp_div_30],
xe = circle_x + cos_table[tmp_div_30 + 1],
ye = circle_y + sin_table[tmp_div_30 + 1];
#if IS_KINEMATIC
// Check to make sure this segment is entirely on the bed, skip if not.
if (!position_is_reachable_raw_xy(x, y) || !position_is_reachable_raw_xy(xe, ye)) continue;
if (!position_is_reachable(rx, ry) || !position_is_reachable(xe, ye)) continue;
#else // not, we need to skip
x = constrain(x, X_MIN_POS + 1, X_MAX_POS - 1); // This keeps us from bumping the endstops
y = constrain(y, Y_MIN_POS + 1, Y_MAX_POS - 1);
rx = constrain(rx, X_MIN_POS + 1, X_MAX_POS - 1); // This keeps us from bumping the endstops
ry = constrain(ry, Y_MIN_POS + 1, Y_MAX_POS - 1);
xe = constrain(xe, X_MIN_POS + 1, X_MAX_POS - 1);
ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
#endif
@ -350,7 +350,7 @@ void unified_bed_leveling::G26() {
// debug_current_and_destination(seg_msg);
//}
print_line_from_here_to_there(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y), g26_layer_height, LOGICAL_X_POSITION(xe), LOGICAL_Y_POSITION(ye), g26_layer_height);
print_line_from_here_to_there(rx, ry, g26_layer_height, xe, ye, g26_layer_height);
}
if (look_for_lines_to_connect())
@ -456,7 +456,7 @@ bool unified_bed_leveling::look_for_lines_to_connect() {
sy = ey = constrain(mesh_index_to_ypos(j), Y_MIN_POS + 1, Y_MAX_POS - 1);
ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) {
if (position_is_reachable(sx, sy) && position_is_reachable(ex, ey)) {
if (g26_debug_flag) {
SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx);
@ -468,7 +468,7 @@ bool unified_bed_leveling::look_for_lines_to_connect() {
//debug_current_and_destination(PSTR("Connecting horizontal line."));
}
print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), g26_layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), g26_layer_height);
print_line_from_here_to_there(sx, sy, g26_layer_height, ex, ey, g26_layer_height);
}
bit_set(horizontal_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if we skipped it
}
@ -490,7 +490,7 @@ bool unified_bed_leveling::look_for_lines_to_connect() {
sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) {
if (position_is_reachable(sx, sy) && position_is_reachable(ex, ey)) {
if (g26_debug_flag) {
SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx);
@ -501,7 +501,7 @@ bool unified_bed_leveling::look_for_lines_to_connect() {
SERIAL_EOL();
debug_current_and_destination(PSTR("Connecting vertical line."));
}
print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), g26_layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), g26_layer_height);
print_line_from_here_to_there(sx, sy, g26_layer_height, ex, ey, g26_layer_height);
}
bit_set(vertical_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if skipped
}
@ -513,11 +513,11 @@ bool unified_bed_leveling::look_for_lines_to_connect() {
return false;
}
void unified_bed_leveling::move_to(const float &x, const float &y, const float &z, const float &e_delta) {
void unified_bed_leveling::move_to(const float &rx, const float &ry, const float &z, const float &e_delta) {
float feed_value;
static float last_z = -999.99;
bool has_xy_component = (x != current_position[X_AXIS] || y != current_position[Y_AXIS]); // Check if X or Y is involved in the movement.
bool has_xy_component = (rx != current_position[X_AXIS] || ry != current_position[Y_AXIS]); // Check if X or Y is involved in the movement.
if (z != last_z) {
last_z = z;
@ -540,8 +540,8 @@ void unified_bed_leveling::move_to(const float &x, const float &y, const float &
if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value);
destination[X_AXIS] = x;
destination[Y_AXIS] = y;
destination[X_AXIS] = rx;
destination[Y_AXIS] = ry;
destination[E_AXIS] += e_delta;
G26_line_to_destination(feed_value);
@ -734,9 +734,9 @@ bool unified_bed_leveling::parse_G26_parameters() {
return UBL_ERR;
}
g26_x_pos = parser.linearval('X', current_position[X_AXIS]);
g26_y_pos = parser.linearval('Y', current_position[Y_AXIS]);
if (!position_is_reachable_xy(g26_x_pos, g26_y_pos)) {
g26_x_pos = parser.seenval('X') ? RAW_X_POSITION(parser.value_linear_units()) : current_position[X_AXIS];
g26_y_pos = parser.seenval('Y') ? RAW_X_POSITION(parser.value_linear_units()) : current_position[Y_AXIS];
if (!position_is_reachable(g26_x_pos, g26_y_pos)) {
SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
return UBL_ERR;
}

View File

@ -108,14 +108,14 @@ class unified_bed_leveling {
static bool g29_parameter_parsing();
static void find_mean_mesh_height();
static void shift_mesh_height();
static void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest);
static void probe_entire_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest);
static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool);
static void tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3);
static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map);
static void g29_what_command();
static void g29_eeprom_dump();
static void g29_compare_current_mesh_to_stored_mesh();
static void fine_tune_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map);
static void fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map);
static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir);
static void smart_fill_mesh();
@ -243,12 +243,12 @@ class unified_bed_leveling {
* z_correction_for_x_on_horizontal_mesh_line is an optimization for
* the case where the printer is making a vertical line that only crosses horizontal mesh lines.
*/
inline static float z_correction_for_x_on_horizontal_mesh_line(const float &lx0, const int x1_i, const int yi) {
inline static float z_correction_for_x_on_horizontal_mesh_line(const float &rx0, const int x1_i, const int yi) {
if (!WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 2) || !WITHIN(yi, 0, GRID_MAX_POINTS_Y - 1)) {
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) {
serialprintPGM( !WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) ? PSTR("x1l_i") : PSTR("yi") );
SERIAL_ECHOPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(lx0=", lx0);
SERIAL_ECHOPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(rx0=", rx0);
SERIAL_ECHOPAIR(",x1_i=", x1_i);
SERIAL_ECHOPAIR(",yi=", yi);
SERIAL_CHAR(')');
@ -258,7 +258,7 @@ class unified_bed_leveling {
return NAN;
}
const float xratio = (RAW_X_POSITION(lx0) - mesh_index_to_xpos(x1_i)) * (1.0 / (MESH_X_DIST)),
const float xratio = (rx0 - mesh_index_to_xpos(x1_i)) * (1.0 / (MESH_X_DIST)),
z1 = z_values[x1_i][yi];
return z1 + xratio * (z_values[x1_i + 1][yi] - z1);
@ -267,12 +267,12 @@ class unified_bed_leveling {
//
// See comments above for z_correction_for_x_on_horizontal_mesh_line
//
inline static float z_correction_for_y_on_vertical_mesh_line(const float &ly0, const int xi, const int y1_i) {
inline static float z_correction_for_y_on_vertical_mesh_line(const float &ry0, const int xi, const int y1_i) {
if (!WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(y1_i, 0, GRID_MAX_POINTS_Y - 2)) {
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) {
serialprintPGM( !WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) ? PSTR("xi") : PSTR("yl_i") );
SERIAL_ECHOPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ly0=", ly0);
SERIAL_ECHOPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ry0=", ry0);
SERIAL_ECHOPAIR(", xi=", xi);
SERIAL_ECHOPAIR(", y1_i=", y1_i);
SERIAL_CHAR(')');
@ -282,7 +282,7 @@ class unified_bed_leveling {
return NAN;
}
const float yratio = (RAW_Y_POSITION(ly0) - mesh_index_to_ypos(y1_i)) * (1.0 / (MESH_Y_DIST)),
const float yratio = (ry0 - mesh_index_to_ypos(y1_i)) * (1.0 / (MESH_Y_DIST)),
z1 = z_values[xi][y1_i];
return z1 + yratio * (z_values[xi][y1_i + 1] - z1);
@ -294,14 +294,14 @@ class unified_bed_leveling {
* Z-Height at both ends. Then it does a linear interpolation of these heights based
* on the Y position within the cell.
*/
static float get_z_correction(const float &lx0, const float &ly0) {
const int8_t cx = get_cell_index_x(RAW_X_POSITION(lx0)),
cy = get_cell_index_y(RAW_Y_POSITION(ly0));
static float get_z_correction(const float &rx0, const float &ry0) {
const int8_t cx = get_cell_index_x(rx0),
cy = get_cell_index_y(ry0);
if (!WITHIN(cx, 0, GRID_MAX_POINTS_X - 2) || !WITHIN(cy, 0, GRID_MAX_POINTS_Y - 2)) {
SERIAL_ECHOPAIR("? in get_z_correction(lx0=", lx0);
SERIAL_ECHOPAIR(", ly0=", ly0);
SERIAL_ECHOPAIR("? in get_z_correction(rx0=", rx0);
SERIAL_ECHOPAIR(", ry0=", ry0);
SERIAL_CHAR(')');
SERIAL_EOL();
@ -312,23 +312,23 @@ class unified_bed_leveling {
return NAN;
}
const float z1 = calc_z0(RAW_X_POSITION(lx0),
const float z1 = calc_z0(rx0,
mesh_index_to_xpos(cx), z_values[cx][cy],
mesh_index_to_xpos(cx + 1), z_values[cx + 1][cy]);
const float z2 = calc_z0(RAW_X_POSITION(lx0),
const float z2 = calc_z0(rx0,
mesh_index_to_xpos(cx), z_values[cx][cy + 1],
mesh_index_to_xpos(cx + 1), z_values[cx + 1][cy + 1]);
float z0 = calc_z0(RAW_Y_POSITION(ly0),
float z0 = calc_z0(ry0,
mesh_index_to_ypos(cy), z1,
mesh_index_to_ypos(cy + 1), z2);
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(MESH_ADJUST)) {
SERIAL_ECHOPAIR(" raw get_z_correction(", lx0);
SERIAL_ECHOPAIR(" raw get_z_correction(", rx0);
SERIAL_CHAR(',');
SERIAL_ECHO(ly0);
SERIAL_ECHO(ry0);
SERIAL_ECHOPGM(") = ");
SERIAL_ECHO_F(z0, 6);
}
@ -350,9 +350,9 @@ class unified_bed_leveling {
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(MESH_ADJUST)) {
SERIAL_ECHOPAIR("??? Yikes! NAN in get_z_correction(", lx0);
SERIAL_ECHOPAIR("??? Yikes! NAN in get_z_correction(", rx0);
SERIAL_CHAR(',');
SERIAL_ECHO(ly0);
SERIAL_ECHO(ry0);
SERIAL_CHAR(')');
SERIAL_EOL();
}
@ -369,7 +369,7 @@ class unified_bed_leveling {
return i < GRID_MAX_POINTS_Y ? pgm_read_float(&_mesh_index_to_ypos[i]) : MESH_MIN_Y + i * (MESH_Y_DIST);
}
static bool prepare_segmented_line_to(const float ltarget[XYZE], const float &feedrate);
static bool prepare_segmented_line_to(const float rtarget[XYZE], const float &feedrate);
static void line_to_destination_cartesian(const float &fr, uint8_t e);
#define _CMPZ(a,b) (z_values[a][b] == z_values[a][b+1])

View File

@ -393,11 +393,11 @@
restore_ubl_active_state_and_leave();
}
else { // grid_size == 0 : A 3-Point leveling has been requested
float z3, z2, z1 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_1_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_1_Y), false, g29_verbose_level);
float z3, z2, z1 = probe_pt(UBL_PROBE_PT_1_X, UBL_PROBE_PT_1_Y, false, g29_verbose_level);
if (!isnan(z1)) {
z2 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_2_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_2_Y), false, g29_verbose_level);
z2 = probe_pt(UBL_PROBE_PT_2_X, UBL_PROBE_PT_2_Y, false, g29_verbose_level);
if (!isnan(z2))
z3 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_3_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_3_Y), true, g29_verbose_level);
z3 = probe_pt(UBL_PROBE_PT_3_X, UBL_PROBE_PT_3_Y, true, g29_verbose_level);
}
if (isnan(z1) || isnan(z2) || isnan(z3)) { // probe_pt will return NAN if unreachable
@ -411,9 +411,9 @@
// its height is.)
save_ubl_active_state_and_disable();
z1 -= get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_1_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_1_Y)) /* + zprobe_zoffset */ ;
z2 -= get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_2_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_2_Y)) /* + zprobe_zoffset */ ;
z3 -= get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_3_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_3_Y)) /* + zprobe_zoffset */ ;
z1 -= get_z_correction(UBL_PROBE_PT_1_X, UBL_PROBE_PT_1_Y) /* + zprobe_zoffset */ ;
z2 -= get_z_correction(UBL_PROBE_PT_2_X, UBL_PROBE_PT_2_Y) /* + zprobe_zoffset */ ;
z3 -= get_z_correction(UBL_PROBE_PT_3_X, UBL_PROBE_PT_3_Y) /* + zprobe_zoffset */ ;
do_blocking_move_to_xy(0.5 * (MESH_MAX_X - (MESH_MIN_X)), 0.5 * (MESH_MAX_Y - (MESH_MIN_Y)));
tilt_mesh_based_on_3pts(z1, z2, z3);
@ -497,7 +497,7 @@
}
}
if (!position_is_reachable_xy(g29_x_pos, g29_y_pos)) {
if (!position_is_reachable(g29_x_pos, g29_y_pos)) {
SERIAL_PROTOCOLLNPGM("XY outside printable radius.");
return;
}
@ -734,7 +734,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 unified_bed_leveling::probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool close_or_far) {
void unified_bed_leveling::probe_entire_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map, const bool stow_probe, bool close_or_far) {
mesh_index_pair location;
has_control_of_lcd_panel = true;
@ -762,13 +762,13 @@
if (close_or_far)
location = find_furthest_invalid_mesh_point();
else
location = find_closest_mesh_point_of_type(INVALID, lx, ly, USE_PROBE_AS_REFERENCE, NULL);
location = find_closest_mesh_point_of_type(INVALID, rx, ry, USE_PROBE_AS_REFERENCE, NULL);
if (location.x_index >= 0) { // mesh point found and is reachable by probe
const float rawx = mesh_index_to_xpos(location.x_index),
rawy = mesh_index_to_ypos(location.y_index);
const float measured_z = probe_pt(LOGICAL_X_POSITION(rawx), LOGICAL_Y_POSITION(rawy), stow_probe, g29_verbose_level); // TODO: Needs error handling
const float measured_z = probe_pt(rawx, rawy, stow_probe, g29_verbose_level); // TODO: Needs error handling
z_values[location.x_index][location.y_index] = measured_z;
}
@ -778,8 +778,8 @@
restore_ubl_active_state_and_leave();
do_blocking_move_to_xy(
constrain(lx - (X_PROBE_OFFSET_FROM_EXTRUDER), MESH_MIN_X, MESH_MAX_X),
constrain(ly - (Y_PROBE_OFFSET_FROM_EXTRUDER), MESH_MIN_Y, MESH_MAX_Y)
constrain(rx - (X_PROBE_OFFSET_FROM_EXTRUDER), MESH_MIN_X, MESH_MAX_X),
constrain(ry - (Y_PROBE_OFFSET_FROM_EXTRUDER), MESH_MIN_Y, MESH_MAX_Y)
);
}
@ -953,28 +953,26 @@
return thickness;
}
void unified_bed_leveling::manually_probe_remaining_mesh(const float &lx, const float &ly, const float &z_clearance, const float &thick, const bool do_ubl_mesh_map) {
void unified_bed_leveling::manually_probe_remaining_mesh(const float &rx, const float &ry, const float &z_clearance, const float &thick, const bool do_ubl_mesh_map) {
has_control_of_lcd_panel = true;
save_ubl_active_state_and_disable(); // we don't do bed level correction because we want the raw data when we probe
do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
do_blocking_move_to_xy(lx, ly);
do_blocking_move_to_xy(rx, ry);
lcd_return_to_status();
mesh_index_pair location;
do {
location = find_closest_mesh_point_of_type(INVALID, lx, ly, USE_NOZZLE_AS_REFERENCE, NULL);
location = find_closest_mesh_point_of_type(INVALID, rx, ry, USE_NOZZLE_AS_REFERENCE, NULL);
// It doesn't matter if the probe can't reach the NAN location. This is a manual probe.
if (location.x_index < 0 && location.y_index < 0) continue;
const float rawx = mesh_index_to_xpos(location.x_index),
rawy = mesh_index_to_ypos(location.y_index),
xProbe = LOGICAL_X_POSITION(rawx),
yProbe = LOGICAL_Y_POSITION(rawy);
const float xProbe = mesh_index_to_xpos(location.x_index),
yProbe = mesh_index_to_ypos(location.y_index);
if (!position_is_reachable_raw_xy(rawx, rawy)) break; // SHOULD NOT OCCUR (find_closest_mesh_point only returns reachable points)
if (!position_is_reachable(xProbe, yProbe)) break; // SHOULD NOT OCCUR (find_closest_mesh_point only returns reachable points)
do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
@ -1038,7 +1036,7 @@
restore_ubl_active_state_and_leave();
KEEPALIVE_STATE(IN_HANDLER);
do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
do_blocking_move_to_xy(lx, ly);
do_blocking_move_to_xy(rx, ry);
}
#endif // NEWPANEL
@ -1111,8 +1109,8 @@
}
// If X or Y are not valid, use center of the bed values
if (!WITHIN(RAW_X_POSITION(g29_x_pos), X_MIN_BED, X_MAX_BED)) g29_x_pos = LOGICAL_X_POSITION(X_CENTER);
if (!WITHIN(RAW_Y_POSITION(g29_y_pos), Y_MIN_BED, Y_MAX_BED)) g29_y_pos = LOGICAL_Y_POSITION(Y_CENTER);
if (!WITHIN(g29_x_pos, X_MIN_BED, X_MAX_BED)) g29_x_pos = X_CENTER;
if (!WITHIN(g29_y_pos, Y_MIN_BED, Y_MAX_BED)) g29_y_pos = Y_CENTER;
if (err_flag) return UBL_ERR;
@ -1365,7 +1363,7 @@
const float mx = mesh_index_to_xpos(i),
my = mesh_index_to_ypos(j);
if ( !position_is_reachable_by_probe_raw_xy(mx, my)) // make sure the probe can get to the mesh point
if ( !position_is_reachable_by_probe(mx, my)) // make sure the probe can get to the mesh point
continue;
found_a_NAN = true;
@ -1413,14 +1411,14 @@
return out_mesh;
}
mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const MeshPointType type, const float &lx, const float &ly, const bool probe_as_reference, uint16_t bits[16]) {
mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const MeshPointType type, const float &rx, const float &ry, const bool probe_as_reference, uint16_t bits[16]) {
mesh_index_pair out_mesh;
out_mesh.x_index = out_mesh.y_index = -1;
out_mesh.distance = -99999.9;
// Get our reference position. Either the nozzle or probe location.
const float px = RAW_X_POSITION(lx) - (probe_as_reference == USE_PROBE_AS_REFERENCE ? X_PROBE_OFFSET_FROM_EXTRUDER : 0),
py = RAW_Y_POSITION(ly) - (probe_as_reference == USE_PROBE_AS_REFERENCE ? Y_PROBE_OFFSET_FROM_EXTRUDER : 0);
const float px = rx - (probe_as_reference == USE_PROBE_AS_REFERENCE ? X_PROBE_OFFSET_FROM_EXTRUDER : 0),
py = ry - (probe_as_reference == USE_PROBE_AS_REFERENCE ? Y_PROBE_OFFSET_FROM_EXTRUDER : 0);
float best_so_far = 99999.99;
@ -1433,7 +1431,6 @@
) {
// We only get here if we found a Mesh Point of the specified type
float raw_x = RAW_CURRENT_POSITION(X), raw_y = RAW_CURRENT_POSITION(Y);
const float mx = mesh_index_to_xpos(i),
my = mesh_index_to_ypos(j);
@ -1441,7 +1438,7 @@
// Also for round beds, there are grid points outside the bed the nozzle can't reach.
// Prune them from the list and ignore them till the next Phase (manual nozzle probing).
if (probe_as_reference ? !position_is_reachable_by_probe_raw_xy(mx, my) : !position_is_reachable_raw_xy(mx, my))
if (probe_as_reference ? !position_is_reachable_by_probe(mx, my) : !position_is_reachable(mx, my))
continue;
// Reachable. Check if it's the best_so_far location to the nozzle.
@ -1450,7 +1447,7 @@
// factor in the distance from the current location for the normal case
// so the nozzle isn't running all over the bed.
distance += HYPOT(raw_x - mx, raw_y - my) * 0.1;
distance += HYPOT(current_position[X_AXIS] - mx, current_position[Y_AXIS] - my) * 0.1;
if (distance < best_so_far) {
best_so_far = distance; // We found a closer location with
out_mesh.x_index = i; // the specified type of mesh value.
@ -1465,7 +1462,7 @@
#if ENABLED(NEWPANEL)
void unified_bed_leveling::fine_tune_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map) {
void unified_bed_leveling::fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map) {
if (!parser.seen('R')) // fine_tune_mesh() is special. If no repetition count flag is specified
g29_repetition_cnt = 1; // do exactly one mesh location. Otherwise use what the parser decided.
@ -1480,7 +1477,7 @@
mesh_index_pair location;
if (!position_is_reachable_xy(lx, ly)) {
if (!position_is_reachable(rx, ry)) {
SERIAL_PROTOCOLLNPGM("(X,Y) outside printable radius.");
return;
}
@ -1490,12 +1487,12 @@
LCD_MESSAGEPGM(MSG_UBL_FINE_TUNE_MESH);
do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
do_blocking_move_to_xy(lx, ly);
do_blocking_move_to_xy(rx, ry);
uint16_t not_done[16];
memset(not_done, 0xFF, sizeof(not_done));
do {
location = find_closest_mesh_point_of_type(SET_IN_BITMAP, lx, ly, USE_NOZZLE_AS_REFERENCE, not_done);
location = find_closest_mesh_point_of_type(SET_IN_BITMAP, rx, ry, USE_NOZZLE_AS_REFERENCE, not_done);
if (location.x_index < 0) break; // stop when we can't find any more reachable points.
@ -1505,7 +1502,7 @@
const float rawx = mesh_index_to_xpos(location.x_index),
rawy = mesh_index_to_ypos(location.y_index);
if (!position_is_reachable_raw_xy(rawx, rawy)) // SHOULD NOT OCCUR because find_closest_mesh_point_of_type will only return reachable
if (!position_is_reachable(rawx, rawy)) // SHOULD NOT OCCUR because find_closest_mesh_point_of_type will only return reachable
break;
float new_z = z_values[location.x_index][location.y_index];
@ -1514,7 +1511,7 @@
new_z = 0.0;
do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); // Move the nozzle to where we are going to edit
do_blocking_move_to_xy(LOGICAL_X_POSITION(rawx), LOGICAL_Y_POSITION(rawy));
do_blocking_move_to_xy(rawx, rawy);
new_z = FLOOR(new_z * 1000.0) * 0.001; // Chop off digits after the 1000ths place
@ -1576,7 +1573,7 @@
restore_ubl_active_state_and_leave();
do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
do_blocking_move_to_xy(lx, ly);
do_blocking_move_to_xy(rx, ry);
LCD_MESSAGEPGM(MSG_UBL_DONE_EDITING_MESH);
SERIAL_ECHOLNPGM("Done Editing Mesh");
@ -1654,29 +1651,29 @@
bool zig_zag = false;
for (uint8_t ix = 0; ix < g29_grid_size; ix++) {
const float x = float(x_min) + ix * dx;
const float rx = float(x_min) + ix * dx;
for (int8_t iy = 0; iy < g29_grid_size; iy++) {
const float y = float(y_min) + dy * (zig_zag ? g29_grid_size - 1 - iy : iy);
float measured_z = probe_pt(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y), parser.seen('E'), g29_verbose_level); // TODO: Needs error handling
const float ry = float(y_min) + dy * (zig_zag ? g29_grid_size - 1 - iy : iy);
float measured_z = probe_pt(rx, ry, parser.seen('E'), g29_verbose_level); // TODO: Needs error handling
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) {
SERIAL_CHAR('(');
SERIAL_PROTOCOL_F(x, 7);
SERIAL_PROTOCOL_F(rx, 7);
SERIAL_CHAR(',');
SERIAL_PROTOCOL_F(y, 7);
SERIAL_PROTOCOL_F(ry, 7);
SERIAL_ECHOPGM(") logical: ");
SERIAL_CHAR('(');
SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(x), 7);
SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(rx), 7);
SERIAL_CHAR(',');
SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(y), 7);
SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(ry), 7);
SERIAL_ECHOPGM(") measured: ");
SERIAL_PROTOCOL_F(measured_z, 7);
SERIAL_ECHOPGM(" correction: ");
SERIAL_PROTOCOL_F(get_z_correction(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y)), 7);
SERIAL_PROTOCOL_F(get_z_correction(rx, ry), 7);
}
#endif
measured_z -= get_z_correction(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y)) /* + zprobe_zoffset */ ;
measured_z -= get_z_correction(rx, ry) /* + zprobe_zoffset */ ;
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) {
@ -1686,7 +1683,7 @@
}
#endif
incremental_LSF(&lsf_results, x, y, measured_z);
incremental_LSF(&lsf_results, rx, ry, measured_z);
}
zig_zag ^= true;

View File

@ -112,10 +112,10 @@
destination[E_AXIS]
};
const int cell_start_xi = get_cell_index_x(RAW_X_POSITION(start[X_AXIS])),
cell_start_yi = get_cell_index_y(RAW_Y_POSITION(start[Y_AXIS])),
cell_dest_xi = get_cell_index_x(RAW_X_POSITION(end[X_AXIS])),
cell_dest_yi = get_cell_index_y(RAW_Y_POSITION(end[Y_AXIS]));
const int cell_start_xi = get_cell_index_x(start[X_AXIS]),
cell_start_yi = get_cell_index_y(start[Y_AXIS]),
cell_dest_xi = get_cell_index_x(end[X_AXIS]),
cell_dest_yi = get_cell_index_y(end[Y_AXIS]);
if (g26_debug_flag) {
SERIAL_ECHOPAIR(" ubl.line_to_destination(xe=", end[X_AXIS]);
@ -160,7 +160,7 @@
* to create a 1-over number for us. That will allow us to do a floating point multiply instead of a floating point divide.
*/
const float xratio = (RAW_X_POSITION(end[X_AXIS]) - mesh_index_to_xpos(cell_dest_xi)) * (1.0 / (MESH_X_DIST));
const float xratio = (end[X_AXIS] - mesh_index_to_xpos(cell_dest_xi)) * (1.0 / (MESH_X_DIST));
float z1 = z_values[cell_dest_xi ][cell_dest_yi ] + xratio *
(z_values[cell_dest_xi + 1][cell_dest_yi ] - z_values[cell_dest_xi][cell_dest_yi ]),
@ -172,7 +172,7 @@
// we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we
// are going to apply the Y-Distance into the cell to interpolate the final Z correction.
const float yratio = (RAW_Y_POSITION(end[Y_AXIS]) - mesh_index_to_ypos(cell_dest_yi)) * (1.0 / (MESH_Y_DIST));
const float yratio = (end[Y_AXIS] - mesh_index_to_ypos(cell_dest_yi)) * (1.0 / (MESH_Y_DIST));
float z0 = cell_dest_yi < GRID_MAX_POINTS_Y - 1 ? (z1 + (z2 - z1) * yratio) * planner.fade_scaling_factor_for_z(end[Z_AXIS]) : 0.0;
/**
@ -248,16 +248,16 @@
current_yi += down_flag; // Line is heading down, we just want to go to the bottom
while (current_yi != cell_dest_yi + down_flag) {
current_yi += dyi;
const float next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi));
const float next_mesh_line_y = mesh_index_to_ypos(current_yi);
/**
* if the slope of the line is infinite, we won't do the calculations
* else, we know the next X is the same so we can recover and continue!
* Calculate X at the next Y mesh line
*/
const float x = inf_m_flag ? start[X_AXIS] : (next_mesh_line_y - c) / m;
const float rx = inf_m_flag ? start[X_AXIS] : (next_mesh_line_y - c) / m;
float z0 = z_correction_for_x_on_horizontal_mesh_line(x, current_xi, current_yi)
float z0 = z_correction_for_x_on_horizontal_mesh_line(rx, current_xi, current_yi)
* planner.fade_scaling_factor_for_z(end[Z_AXIS]);
/**
@ -269,7 +269,7 @@
*/
if (isnan(z0)) z0 = 0.0;
const float y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi));
const float ry = mesh_index_to_ypos(current_yi);
/**
* Without this check, it is possible for the algorithm to generate a zero length move in the case
@ -277,9 +277,9 @@
* happens, it might be best to remove the check and always 'schedule' the move because
* the planner._buffer_line() routine will filter it if that happens.
*/
if (y != start[Y_AXIS]) {
if (ry != start[Y_AXIS]) {
if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? x - start[X_AXIS] : y - start[Y_AXIS];
on_axis_distance = use_x_dist ? rx - start[X_AXIS] : ry - start[Y_AXIS];
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist;
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
}
@ -288,7 +288,7 @@
z_position = end[Z_AXIS];
}
planner._buffer_line(x, y, z_position + z0, e_position, feed_rate, extruder);
planner._buffer_line(rx, ry, z_position + z0, e_position, feed_rate, extruder);
} //else printf("FIRST MOVE PRUNED ");
}
@ -318,10 +318,10 @@
// edge of this cell for the first move.
while (current_xi != cell_dest_xi + left_flag) {
current_xi += dxi;
const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi)),
y = m * next_mesh_line_x + c; // Calculate Y at the next X mesh line
const float next_mesh_line_x = mesh_index_to_xpos(current_xi),
ry = m * next_mesh_line_x + c; // Calculate Y at the next X mesh line
float z0 = z_correction_for_y_on_vertical_mesh_line(y, current_xi, current_yi)
float z0 = z_correction_for_y_on_vertical_mesh_line(ry, current_xi, current_yi)
* planner.fade_scaling_factor_for_z(end[Z_AXIS]);
/**
@ -333,7 +333,7 @@
*/
if (isnan(z0)) z0 = 0.0;
const float x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi));
const float rx = mesh_index_to_xpos(current_xi);
/**
* Without this check, it is possible for the algorithm to generate a zero length move in the case
@ -341,9 +341,9 @@
* that happens, it might be best to remove the check and always 'schedule' the move because
* the planner._buffer_line() routine will filter it if that happens.
*/
if (x != start[X_AXIS]) {
if (rx != start[X_AXIS]) {
if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? x - start[X_AXIS] : y - start[Y_AXIS];
on_axis_distance = use_x_dist ? rx - start[X_AXIS] : ry - start[Y_AXIS];
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; // is based on X or Y because this is a horizontal move
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
}
@ -352,7 +352,7 @@
z_position = end[Z_AXIS];
}
planner._buffer_line(x, y, z_position + z0, e_position, feed_rate, extruder);
planner._buffer_line(rx, ry, z_position + z0, e_position, feed_rate, extruder);
} //else printf("FIRST MOVE PRUNED ");
}
@ -383,17 +383,17 @@
while (xi_cnt > 0 || yi_cnt > 0) {
const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi + dxi)),
next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi + dyi)),
y = m * next_mesh_line_x + c, // Calculate Y at the next X mesh line
x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line
// (No need to worry about m being zero.
// If that was the case, it was already detected
// as a vertical line move above.)
const float next_mesh_line_x = mesh_index_to_xpos(current_xi + dxi),
next_mesh_line_y = mesh_index_to_ypos(current_yi + dyi),
ry = m * next_mesh_line_x + c, // Calculate Y at the next X mesh line
rx = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line
// (No need to worry about m being zero.
// If that was the case, it was already detected
// as a vertical line move above.)
if (left_flag == (x > next_mesh_line_x)) { // Check if we hit the Y line first
if (left_flag == (rx > next_mesh_line_x)) { // Check if we hit the Y line first
// Yes! Crossing a Y Mesh Line next
float z0 = z_correction_for_x_on_horizontal_mesh_line(x, current_xi - left_flag, current_yi + dyi)
float z0 = z_correction_for_x_on_horizontal_mesh_line(rx, current_xi - left_flag, current_yi + dyi)
* planner.fade_scaling_factor_for_z(end[Z_AXIS]);
/**
@ -406,7 +406,7 @@
if (isnan(z0)) z0 = 0.0;
if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? x - start[X_AXIS] : next_mesh_line_y - start[Y_AXIS];
on_axis_distance = use_x_dist ? rx - start[X_AXIS] : next_mesh_line_y - start[Y_AXIS];
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist;
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
}
@ -414,13 +414,13 @@
e_position = end[E_AXIS];
z_position = end[Z_AXIS];
}
planner._buffer_line(x, next_mesh_line_y, z_position + z0, e_position, feed_rate, extruder);
planner._buffer_line(rx, next_mesh_line_y, z_position + z0, e_position, feed_rate, extruder);
current_yi += dyi;
yi_cnt--;
}
else {
// Yes! Crossing a X Mesh Line next
float z0 = z_correction_for_y_on_vertical_mesh_line(y, current_xi + dxi, current_yi - down_flag)
float z0 = z_correction_for_y_on_vertical_mesh_line(ry, current_xi + dxi, current_yi - down_flag)
* planner.fade_scaling_factor_for_z(end[Z_AXIS]);
/**
@ -433,7 +433,7 @@
if (isnan(z0)) z0 = 0.0;
if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? next_mesh_line_x - start[X_AXIS] : y - start[Y_AXIS];
on_axis_distance = use_x_dist ? next_mesh_line_x - start[X_AXIS] : ry - start[Y_AXIS];
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist;
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
}
@ -442,7 +442,7 @@
z_position = end[Z_AXIS];
}
planner._buffer_line(next_mesh_line_x, y, z_position + z0, e_position, feed_rate, extruder);
planner._buffer_line(next_mesh_line_x, ry, z_position + z0, e_position, feed_rate, extruder);
current_xi += dxi;
xi_cnt--;
}
@ -476,7 +476,7 @@
// We don't want additional apply_leveling() performed by regular buffer_line or buffer_line_kinematic,
// so we call _buffer_line directly here. Per-segmented leveling and kinematics performed first.
inline void _O2 ubl_buffer_segment_raw( float rx, float ry, float rz, float le, float fr ) {
inline void _O2 ubl_buffer_segment_raw(const float &rx, const float &ry, const float rz, const float &e, const float &fr) {
#if ENABLED(DELTA) // apply delta inverse_kinematics
@ -492,14 +492,11 @@
- HYPOT2( delta_tower[C_AXIS][X_AXIS] - rx,
delta_tower[C_AXIS][Y_AXIS] - ry ));
planner._buffer_line(delta_A, delta_B, delta_C, le, fr, active_extruder);
planner._buffer_line(delta_A, delta_B, delta_C, e, fr, active_extruder);
#elif IS_SCARA // apply scara inverse_kinematics (should be changed to save raw->logical->raw)
const float lseg[XYZ] = { LOGICAL_X_POSITION(rx),
LOGICAL_Y_POSITION(ry),
LOGICAL_Z_POSITION(rz)
};
const float lseg[XYZ] = { rx, ry, rz };
inverse_kinematics(lseg); // this writes delta[ABC] from lseg[XYZ]
// should move the feedrate scaling to scara inverse_kinematics
@ -510,17 +507,11 @@
scara_oldB = delta[B_AXIS];
float s_feedrate = max(adiff, bdiff) * scara_feed_factor;
planner._buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], le, s_feedrate, active_extruder);
planner._buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], e, s_feedrate, active_extruder);
#else // CARTESIAN
// Cartesian _buffer_line seems to take LOGICAL, not RAW coordinates
const float lx = LOGICAL_X_POSITION(rx),
ly = LOGICAL_Y_POSITION(ry),
lz = LOGICAL_Z_POSITION(rz);
planner._buffer_line(lx, ly, lz, le, fr, active_extruder);
planner._buffer_line(rx, ry, rz, e, fr, active_extruder);
#endif
@ -533,15 +524,15 @@
* Returns true if did NOT move, false if moved (requires current_position update).
*/
bool _O2 unified_bed_leveling::prepare_segmented_line_to(const float ltarget[XYZE], const float &feedrate) {
bool _O2 unified_bed_leveling::prepare_segmented_line_to(const float rtarget[XYZE], const float &feedrate) {
if (!position_is_reachable_xy(ltarget[X_AXIS], ltarget[Y_AXIS])) // fail if moving outside reachable boundary
if (!position_is_reachable(rtarget[X_AXIS], rtarget[Y_AXIS])) // fail if moving outside reachable boundary
return true; // did not move, so current_position still accurate
const float tot_dx = ltarget[X_AXIS] - current_position[X_AXIS],
tot_dy = ltarget[Y_AXIS] - current_position[Y_AXIS],
tot_dz = ltarget[Z_AXIS] - current_position[Z_AXIS],
tot_de = ltarget[E_AXIS] - current_position[E_AXIS];
const float tot_dx = rtarget[X_AXIS] - current_position[X_AXIS],
tot_dy = rtarget[Y_AXIS] - current_position[Y_AXIS],
tot_dz = rtarget[Z_AXIS] - current_position[Z_AXIS],
tot_de = rtarget[E_AXIS] - current_position[E_AXIS];
const float cartesian_xy_mm = HYPOT(tot_dx, tot_dy); // total horizontal xy distance
@ -571,14 +562,14 @@
// Note that E segment distance could vary slightly as z mesh height
// changes for each segment, but small enough to ignore.
float seg_rx = RAW_X_POSITION(current_position[X_AXIS]),
seg_ry = RAW_Y_POSITION(current_position[Y_AXIS]),
seg_rz = RAW_Z_POSITION(current_position[Z_AXIS]),
float seg_rx = current_position[X_AXIS],
seg_ry = current_position[Y_AXIS],
seg_rz = current_position[Z_AXIS],
seg_le = current_position[E_AXIS];
// Only compute leveling per segment if ubl active and target below z_fade_height.
if (!planner.leveling_active || !planner.leveling_active_at_z(ltarget[Z_AXIS])) { // no mesh leveling
if (!planner.leveling_active || !planner.leveling_active_at_z(rtarget[Z_AXIS])) { // no mesh leveling
do {
@ -588,13 +579,13 @@
seg_rz += seg_dz;
seg_le += seg_de;
} else { // last segment, use exact destination
seg_rx = RAW_X_POSITION(ltarget[X_AXIS]);
seg_ry = RAW_Y_POSITION(ltarget[Y_AXIS]);
seg_rz = RAW_Z_POSITION(ltarget[Z_AXIS]);
seg_le = ltarget[E_AXIS];
seg_rx = rtarget[X_AXIS];
seg_ry = rtarget[Y_AXIS];
seg_rz = rtarget[Z_AXIS];
seg_le = rtarget[E_AXIS];
}
ubl_buffer_segment_raw( seg_rx, seg_ry, seg_rz, seg_le, feedrate );
ubl_buffer_segment_raw(seg_rx, seg_ry, seg_rz, seg_le, feedrate);
} while (segments);
@ -604,7 +595,7 @@
// Otherwise perform per-segment leveling
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
const float fade_scaling_factor = planner.fade_scaling_factor_for_z(ltarget[Z_AXIS]);
const float fade_scaling_factor = planner.fade_scaling_factor_for_z(rtarget[Z_AXIS]);
#endif
// increment to first segment destination
@ -671,16 +662,16 @@
z_cxcy *= fade_scaling_factor; // apply fade factor to interpolated mesh height
#endif
if (--segments == 0) { // if this is last segment, use ltarget for exact
seg_rx = RAW_X_POSITION(ltarget[X_AXIS]);
seg_ry = RAW_Y_POSITION(ltarget[Y_AXIS]);
seg_rz = RAW_Z_POSITION(ltarget[Z_AXIS]);
seg_le = ltarget[E_AXIS];
if (--segments == 0) { // if this is last segment, use rtarget for exact
seg_rx = rtarget[X_AXIS];
seg_ry = rtarget[Y_AXIS];
seg_rz = rtarget[Z_AXIS];
seg_le = rtarget[E_AXIS];
}
ubl_buffer_segment_raw( seg_rx, seg_ry, seg_rz + z_cxcy, seg_le, feedrate );
ubl_buffer_segment_raw(seg_rx, seg_ry, seg_rz + z_cxcy, seg_le, feedrate);
if (segments == 0 ) // done with last segment
if (segments == 0) // done with last segment
return false; // did not set_current_from_destination()
seg_rx += seg_dx;