Merge pull request #8229 from thinkyhead/bf1_native_operation

[1.1.x] Operate in Native Machine Space
master
Scott Lahteine 7 years ago committed by GitHub
commit 309890cb8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -279,7 +279,7 @@
// If this mesh location is outside the printable_radius, skip it. // 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 xi = location.x_index; // Just to shrink the next few lines and make them easier to understand
yi = location.y_index; yi = location.y_index;
@ -328,16 +328,16 @@
if (tmp_div_30 < 0) tmp_div_30 += 360 / 30; if (tmp_div_30 < 0) tmp_div_30 += 360 / 30;
if (tmp_div_30 > 11) 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 float rx = circle_x + cos_table[tmp_div_30], // for speed, these are now a lookup table entry
y = circle_y + sin_table[tmp_div_30], ry = circle_y + sin_table[tmp_div_30],
xe = circle_x + cos_table[tmp_div_30 + 1], xe = circle_x + cos_table[tmp_div_30 + 1],
ye = circle_y + sin_table[tmp_div_30 + 1]; ye = circle_y + sin_table[tmp_div_30 + 1];
#if IS_KINEMATIC #if IS_KINEMATIC
// Check to make sure this segment is entirely on the bed, skip if not. // 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 #else // not, we need to skip
x = constrain(x, X_MIN_POS + 1, X_MAX_POS - 1); // This keeps us from bumping the endstops rx = constrain(rx, 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); ry = constrain(ry, Y_MIN_POS + 1, Y_MAX_POS - 1);
xe = constrain(xe, X_MIN_POS + 1, X_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); ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
#endif #endif
@ -353,7 +353,7 @@
// debug_current_and_destination(seg_msg); // 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()) if (look_for_lines_to_connect())
@ -459,7 +459,7 @@
sy = ey = constrain(mesh_index_to_ypos(j), Y_MIN_POS + 1, Y_MAX_POS - 1); 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); 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) { if (g26_debug_flag) {
SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx); SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx);
@ -470,8 +470,7 @@
SERIAL_EOL(); SERIAL_EOL();
//debug_current_and_destination(PSTR("Connecting horizontal line.")); //debug_current_and_destination(PSTR("Connecting horizontal line."));
} }
print_line_from_here_to_there(sx, sy, g26_layer_height, ex, ey, g26_layer_height);
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);
} }
bit_set(horizontal_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if we skipped it bit_set(horizontal_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if we skipped it
} }
@ -493,7 +492,7 @@
sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1); sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
ey = constrain(ey, 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) { if (g26_debug_flag) {
SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx); SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx);
@ -504,7 +503,7 @@
SERIAL_EOL(); SERIAL_EOL();
debug_current_and_destination(PSTR("Connecting vertical line.")); 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 bit_set(vertical_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if skipped
} }
@ -596,9 +595,8 @@
// If the end point of the line is closer to the nozzle, flip the direction, // If the end point of the line is closer to the nozzle, flip the direction,
// moving from the end to the start. On very small lines the optimization isn't worth it. // moving from the end to the start. On very small lines the optimization isn't worth it.
if (dist_end < dist_start && (SIZE_OF_INTERSECTION_CIRCLES) < FABS(line_length)) { if (dist_end < dist_start && (SIZE_OF_INTERSECTION_CIRCLES) < FABS(line_length))
return print_line_from_here_to_there(ex, ey, ez, sx, sy, sz); return print_line_from_here_to_there(ex, ey, ez, sx, sy, sz);
}
// Decide whether to retract & bump // Decide whether to retract & bump
@ -737,9 +735,9 @@
return UBL_ERR; return UBL_ERR;
} }
g26_x_pos = parser.linearval('X', current_position[X_AXIS]); g26_x_pos = parser.seenval('X') ? RAW_X_POSITION(parser.value_linear_units()) : current_position[X_AXIS];
g26_y_pos = parser.linearval('Y', current_position[Y_AXIS]); g26_y_pos = parser.seenval('Y') ? RAW_X_POSITION(parser.value_linear_units()) : current_position[Y_AXIS];
if (!position_is_reachable_xy(g26_x_pos, g26_y_pos)) { if (!position_is_reachable(g26_x_pos, g26_y_pos)) {
SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds."); SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
return UBL_ERR; return UBL_ERR;
} }

@ -252,14 +252,14 @@ extern float current_position[NUM_AXIS];
#define WORKSPACE_OFFSET(AXIS) 0 #define WORKSPACE_OFFSET(AXIS) 0
#endif #endif
#define LOGICAL_POSITION(POS, AXIS) ((POS) + WORKSPACE_OFFSET(AXIS)) #define NATIVE_TO_LOGICAL(POS, AXIS) ((POS) + WORKSPACE_OFFSET(AXIS))
#define RAW_POSITION(POS, AXIS) ((POS) - WORKSPACE_OFFSET(AXIS)) #define LOGICAL_TO_NATIVE(POS, AXIS) ((POS) - WORKSPACE_OFFSET(AXIS))
#if HAS_POSITION_SHIFT || DISABLED(DELTA) #if HAS_POSITION_SHIFT || DISABLED(DELTA)
#define LOGICAL_X_POSITION(POS) LOGICAL_POSITION(POS, X_AXIS) #define LOGICAL_X_POSITION(POS) NATIVE_TO_LOGICAL(POS, X_AXIS)
#define LOGICAL_Y_POSITION(POS) LOGICAL_POSITION(POS, Y_AXIS) #define LOGICAL_Y_POSITION(POS) NATIVE_TO_LOGICAL(POS, Y_AXIS)
#define RAW_X_POSITION(POS) RAW_POSITION(POS, X_AXIS) #define RAW_X_POSITION(POS) LOGICAL_TO_NATIVE(POS, X_AXIS)
#define RAW_Y_POSITION(POS) RAW_POSITION(POS, Y_AXIS) #define RAW_Y_POSITION(POS) LOGICAL_TO_NATIVE(POS, Y_AXIS)
#else #else
#define LOGICAL_X_POSITION(POS) (POS) #define LOGICAL_X_POSITION(POS) (POS)
#define LOGICAL_Y_POSITION(POS) (POS) #define LOGICAL_Y_POSITION(POS) (POS)
@ -267,9 +267,8 @@ extern float current_position[NUM_AXIS];
#define RAW_Y_POSITION(POS) (POS) #define RAW_Y_POSITION(POS) (POS)
#endif #endif
#define LOGICAL_Z_POSITION(POS) LOGICAL_POSITION(POS, Z_AXIS) #define LOGICAL_Z_POSITION(POS) NATIVE_TO_LOGICAL(POS, Z_AXIS)
#define RAW_Z_POSITION(POS) RAW_POSITION(POS, Z_AXIS) #define RAW_Z_POSITION(POS) LOGICAL_TO_NATIVE(POS, Z_AXIS)
#define RAW_CURRENT_POSITION(A) RAW_##A##_POSITION(current_position[A##_AXIS])
// Hotend Offsets // Hotend Offsets
#if HOTENDS > 1 #if HOTENDS > 1
@ -293,7 +292,7 @@ extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ];
#if IS_KINEMATIC #if IS_KINEMATIC
extern float delta[ABC]; extern float delta[ABC];
void inverse_kinematics(const float logical[XYZ]); void inverse_kinematics(const float raw[XYZ]);
#endif #endif
#if ENABLED(DELTA) #if ENABLED(DELTA)
@ -313,7 +312,7 @@ extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ];
extern int bilinear_grid_spacing[2], bilinear_start[2]; extern int bilinear_grid_spacing[2], bilinear_start[2];
extern float bilinear_grid_factor[2], extern float bilinear_grid_factor[2],
z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; 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]);
#endif #endif
#if ENABLED(AUTO_BED_LEVELING_UBL) #if ENABLED(AUTO_BED_LEVELING_UBL)
@ -455,7 +454,7 @@ void do_blocking_move_to_xy(const float &x, const float &y, const float &fr_mm_s
extern const float L1, L2; extern const float L1, L2;
#endif #endif
inline bool position_is_reachable_raw_xy(const float &rx, const float &ry) { inline bool position_is_reachable(const float &rx, const float &ry) {
#if ENABLED(DELTA) #if ENABLED(DELTA)
return HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS); return HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS);
#elif IS_SCARA #elif IS_SCARA
@ -470,24 +469,24 @@ void do_blocking_move_to_xy(const float &x, const float &y, const float &fr_mm_s
#endif #endif
} }
inline bool position_is_reachable_by_probe_raw_xy(const float &rx, const float &ry) { inline bool position_is_reachable_by_probe(const float &rx, const float &ry) {
// Both the nozzle and the probe must be able to reach the point. // Both the nozzle and the probe must be able to reach the point.
// This won't work on SCARA since the probe offset rotates with the arm. // This won't work on SCARA since the probe offset rotates with the arm.
return position_is_reachable_raw_xy(rx, ry) return position_is_reachable(rx, ry)
&& position_is_reachable_raw_xy(rx - X_PROBE_OFFSET_FROM_EXTRUDER, ry - Y_PROBE_OFFSET_FROM_EXTRUDER); && position_is_reachable(rx - X_PROBE_OFFSET_FROM_EXTRUDER, ry - Y_PROBE_OFFSET_FROM_EXTRUDER);
} }
#else // CARTESIAN #else // CARTESIAN
inline bool position_is_reachable_raw_xy(const float &rx, const float &ry) { inline bool position_is_reachable(const float &rx, const float &ry) {
// Add 0.001 margin to deal with float imprecision // Add 0.001 margin to deal with float imprecision
return WITHIN(rx, X_MIN_POS - 0.001, X_MAX_POS + 0.001) return WITHIN(rx, X_MIN_POS - 0.001, X_MAX_POS + 0.001)
&& WITHIN(ry, Y_MIN_POS - 0.001, Y_MAX_POS + 0.001); && WITHIN(ry, Y_MIN_POS - 0.001, Y_MAX_POS + 0.001);
} }
inline bool position_is_reachable_by_probe_raw_xy(const float &rx, const float &ry) { inline bool position_is_reachable_by_probe(const float &rx, const float &ry) {
// Add 0.001 margin to deal with float imprecision // Add 0.001 margin to deal with float imprecision
return WITHIN(rx, MIN_PROBE_X - 0.001, MAX_PROBE_X + 0.001) return WITHIN(rx, MIN_PROBE_X - 0.001, MAX_PROBE_X + 0.001)
&& WITHIN(ry, MIN_PROBE_Y - 0.001, MAX_PROBE_Y + 0.001); && WITHIN(ry, MIN_PROBE_Y - 0.001, MAX_PROBE_Y + 0.001);
@ -495,12 +494,4 @@ void do_blocking_move_to_xy(const float &x, const float &y, const float &fr_mm_s
#endif // CARTESIAN #endif // CARTESIAN
FORCE_INLINE bool position_is_reachable_by_probe_xy(const float &lx, const float &ly) {
return position_is_reachable_by_probe_raw_xy(RAW_X_POSITION(lx), RAW_Y_POSITION(ly));
}
FORCE_INLINE bool position_is_reachable_xy(const float &lx, const float &ly) {
return position_is_reachable_raw_xy(RAW_X_POSITION(lx), RAW_Y_POSITION(ly));
}
#endif // MARLIN_H #endif // MARLIN_H

@ -370,7 +370,7 @@ uint8_t marlin_debug_flags = DEBUG_NONE;
/** /**
* Cartesian Current Position * Cartesian Current Position
* Used to track the logical position as moves are queued. * Used to track the native machine position as moves are queued.
* Used by 'line_to_current_position' to do a move after changing it. * Used by 'line_to_current_position' to do a move after changing it.
* Used by 'SYNC_PLAN_POSITION_KINEMATIC' to update 'planner.position'. * Used by 'SYNC_PLAN_POSITION_KINEMATIC' to update 'planner.position'.
*/ */
@ -1367,7 +1367,7 @@ bool get_target_extruder_from_command(const uint16_t code) {
static float x_home_pos(const int extruder) { static float x_home_pos(const int extruder) {
if (extruder == 0) if (extruder == 0)
return LOGICAL_X_POSITION(base_home_pos(X_AXIS)); return base_home_pos(X_AXIS);
else else
/** /**
* In dual carriage mode the extruder offset provides an override of the * In dual carriage mode the extruder offset provides an override of the
@ -1375,7 +1375,7 @@ bool get_target_extruder_from_command(const uint16_t code) {
* This allows soft recalibration of the second extruder home position * This allows soft recalibration of the second extruder home position
* without firmware reflash (through the M218 command). * without firmware reflash (through the M218 command).
*/ */
return LOGICAL_X_POSITION(hotend_offset[X_AXIS][1] > 0 ? hotend_offset[X_AXIS][1] : X2_HOME_POS); return hotend_offset[X_AXIS][1] > 0 ? hotend_offset[X_AXIS][1] : X2_HOME_POS;
} }
static int x_home_dir(const int extruder) { return extruder ? X2_HOME_DIR : X_HOME_DIR; } static int x_home_dir(const int extruder) { return extruder ? X2_HOME_DIR : X_HOME_DIR; }
@ -1437,12 +1437,6 @@ bool get_target_extruder_from_command(const uint16_t code) {
soft_endstop_max[axis] = base_max_pos(axis) + offs; soft_endstop_max[axis] = base_max_pos(axis) + offs;
} }
} }
#elif ENABLED(DELTA)
soft_endstop_min[axis] = base_min_pos(axis) + (axis == Z_AXIS ? 0 : offs);
soft_endstop_max[axis] = base_max_pos(axis) + offs;
#else
soft_endstop_min[axis] = base_min_pos(axis) + offs;
soft_endstop_max[axis] = base_max_pos(axis) + offs;
#endif #endif
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
@ -1486,7 +1480,6 @@ bool get_target_extruder_from_command(const uint16_t code) {
* call sync_plan_position soon after this. * call sync_plan_position soon after this.
*/ */
static void set_home_offset(const AxisEnum axis, const float v) { static void set_home_offset(const AxisEnum axis, const float v) {
current_position[axis] += v - home_offset[axis];
home_offset[axis] = v; home_offset[axis] = v;
update_software_endstops(axis); update_software_endstops(axis);
} }
@ -1540,8 +1533,11 @@ static void set_axis_is_at_home(const AxisEnum axis) {
*/ */
if (axis == X_AXIS || axis == Y_AXIS) { if (axis == X_AXIS || axis == Y_AXIS) {
float homeposition[XYZ]; float homeposition[XYZ] = {
LOOP_XYZ(i) homeposition[i] = LOGICAL_POSITION(base_home_pos((AxisEnum)i), i); base_home_pos(X_AXIS),
base_home_pos(Y_AXIS),
base_home_pos(Z_AXIS)
};
// SERIAL_ECHOPAIR("homeposition X:", homeposition[X_AXIS]); // SERIAL_ECHOPAIR("homeposition X:", homeposition[X_AXIS]);
// SERIAL_ECHOLNPAIR(" Y:", homeposition[Y_AXIS]); // SERIAL_ECHOLNPAIR(" Y:", homeposition[Y_AXIS]);
@ -1556,7 +1552,7 @@ static void set_axis_is_at_home(const AxisEnum axis) {
// SERIAL_ECHOPAIR("Cartesian X:", cartes[X_AXIS]); // SERIAL_ECHOPAIR("Cartesian X:", cartes[X_AXIS]);
// SERIAL_ECHOLNPAIR(" Y:", cartes[Y_AXIS]); // SERIAL_ECHOLNPAIR(" Y:", cartes[Y_AXIS]);
current_position[axis] = LOGICAL_POSITION(cartes[axis], axis); current_position[axis] = cartes[axis];
/** /**
* SCARA home positions are based on configuration since the actual * SCARA home positions are based on configuration since the actual
@ -1568,7 +1564,7 @@ static void set_axis_is_at_home(const AxisEnum axis) {
else else
#endif #endif
{ {
current_position[axis] = LOGICAL_POSITION(base_home_pos(axis), axis); current_position[axis] = base_home_pos(axis);
} }
/** /**
@ -1679,16 +1675,16 @@ inline void set_destination_from_current() { COPY(destination, current_position)
* Plan a move to (X, Y, Z) and set the current_position * Plan a move to (X, Y, Z) and set the current_position
* The final current_position may not be the one that was requested * The final current_position may not be the one that was requested
*/ */
void do_blocking_move_to(const float &lx, const float &ly, const float &lz, const float &fr_mm_s/*=0.0*/) { void do_blocking_move_to(const float &rx, const float &ry, const float &rz, const float &fr_mm_s/*=0.0*/) {
const float old_feedrate_mm_s = feedrate_mm_s; const float old_feedrate_mm_s = feedrate_mm_s;
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) print_xyz(PSTR(">>> do_blocking_move_to"), NULL, lx, ly, lz); if (DEBUGGING(LEVELING)) print_xyz(PSTR(">>> do_blocking_move_to"), NULL, LOGICAL_X_POSITION(rx), LOGICAL_Y_POSITION(ry), LOGICAL_Z_POSITION(rz));
#endif #endif
#if ENABLED(DELTA) #if ENABLED(DELTA)
if (!position_is_reachable_xy(lx, ly)) return; if (!position_is_reachable(rx, ry)) return;
feedrate_mm_s = fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S; feedrate_mm_s = fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S;
@ -1700,10 +1696,10 @@ void do_blocking_move_to(const float &lx, const float &ly, const float &lz, cons
// when in the danger zone // when in the danger zone
if (current_position[Z_AXIS] > delta_clip_start_height) { if (current_position[Z_AXIS] > delta_clip_start_height) {
if (lz > delta_clip_start_height) { // staying in the danger zone if (rz > delta_clip_start_height) { // staying in the danger zone
destination[X_AXIS] = lx; // move directly (uninterpolated) destination[X_AXIS] = rx; // move directly (uninterpolated)
destination[Y_AXIS] = ly; destination[Y_AXIS] = ry;
destination[Z_AXIS] = lz; destination[Z_AXIS] = rz;
prepare_uninterpolated_move_to_destination(); // set_current_from_destination prepare_uninterpolated_move_to_destination(); // set_current_from_destination
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("danger zone move", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("danger zone move", current_position);
@ -1719,23 +1715,23 @@ void do_blocking_move_to(const float &lx, const float &ly, const float &lz, cons
} }
} }
if (lz > current_position[Z_AXIS]) { // raising? if (rz > current_position[Z_AXIS]) { // raising?
destination[Z_AXIS] = lz; destination[Z_AXIS] = rz;
prepare_uninterpolated_move_to_destination(); // set_current_from_destination prepare_uninterpolated_move_to_destination(); // set_current_from_destination
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("z raise move", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("z raise move", current_position);
#endif #endif
} }
destination[X_AXIS] = lx; destination[X_AXIS] = rx;
destination[Y_AXIS] = ly; destination[Y_AXIS] = ry;
prepare_move_to_destination(); // set_current_from_destination prepare_move_to_destination(); // set_current_from_destination
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("xy move", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("xy move", current_position);
#endif #endif
if (lz < current_position[Z_AXIS]) { // lowering? if (rz < current_position[Z_AXIS]) { // lowering?
destination[Z_AXIS] = lz; destination[Z_AXIS] = rz;
prepare_uninterpolated_move_to_destination(); // set_current_from_destination prepare_uninterpolated_move_to_destination(); // set_current_from_destination
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("z lower move", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("z lower move", current_position);
@ -1744,44 +1740,44 @@ void do_blocking_move_to(const float &lx, const float &ly, const float &lz, cons
#elif IS_SCARA #elif IS_SCARA
if (!position_is_reachable_xy(lx, ly)) return; if (!position_is_reachable(rx, ry)) return;
set_destination_from_current(); set_destination_from_current();
// If Z needs to raise, do it before moving XY // If Z needs to raise, do it before moving XY
if (destination[Z_AXIS] < lz) { if (destination[Z_AXIS] < rz) {
destination[Z_AXIS] = lz; destination[Z_AXIS] = rz;
prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS)); prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS));
} }
destination[X_AXIS] = lx; destination[X_AXIS] = rx;
destination[Y_AXIS] = ly; destination[Y_AXIS] = ry;
prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S); prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S);
// If Z needs to lower, do it after moving XY // If Z needs to lower, do it after moving XY
if (destination[Z_AXIS] > lz) { if (destination[Z_AXIS] > rz) {
destination[Z_AXIS] = lz; destination[Z_AXIS] = rz;
prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS)); prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS));
} }
#else #else
// If Z needs to raise, do it before moving XY // If Z needs to raise, do it before moving XY
if (current_position[Z_AXIS] < lz) { if (current_position[Z_AXIS] < rz) {
feedrate_mm_s = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS); feedrate_mm_s = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS);
current_position[Z_AXIS] = lz; current_position[Z_AXIS] = rz;
line_to_current_position(); line_to_current_position();
} }
feedrate_mm_s = fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S; feedrate_mm_s = fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S;
current_position[X_AXIS] = lx; current_position[X_AXIS] = rx;
current_position[Y_AXIS] = ly; current_position[Y_AXIS] = ry;
line_to_current_position(); line_to_current_position();
// If Z needs to lower, do it after moving XY // If Z needs to lower, do it after moving XY
if (current_position[Z_AXIS] > lz) { if (current_position[Z_AXIS] > rz) {
feedrate_mm_s = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS); feedrate_mm_s = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS);
current_position[Z_AXIS] = lz; current_position[Z_AXIS] = rz;
line_to_current_position(); line_to_current_position();
} }
@ -1795,14 +1791,14 @@ void do_blocking_move_to(const float &lx, const float &ly, const float &lz, cons
if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< do_blocking_move_to"); if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< do_blocking_move_to");
#endif #endif
} }
void do_blocking_move_to_x(const float &lx, const float &fr_mm_s/*=0.0*/) { void do_blocking_move_to_x(const float &rx, const float &fr_mm_s/*=0.0*/) {
do_blocking_move_to(lx, current_position[Y_AXIS], current_position[Z_AXIS], fr_mm_s); do_blocking_move_to(rx, current_position[Y_AXIS], current_position[Z_AXIS], fr_mm_s);
} }
void do_blocking_move_to_z(const float &lz, const float &fr_mm_s/*=0.0*/) { void do_blocking_move_to_z(const float &rz, const float &fr_mm_s/*=0.0*/) {
do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], lz, fr_mm_s); do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], rz, fr_mm_s);
} }
void do_blocking_move_to_xy(const float &lx, const float &ly, const float &fr_mm_s/*=0.0*/) { void do_blocking_move_to_xy(const float &rx, const float &ry, const float &fr_mm_s/*=0.0*/) {
do_blocking_move_to(lx, ly, current_position[Z_AXIS], fr_mm_s); do_blocking_move_to(rx, ry, current_position[Z_AXIS], fr_mm_s);
} }
// //
@ -1916,8 +1912,8 @@ static void clean_up_after_endstop_or_probe_move() {
#elif ENABLED(Z_PROBE_ALLEN_KEY) #elif ENABLED(Z_PROBE_ALLEN_KEY)
FORCE_INLINE void do_blocking_move_to(const float logical[XYZ], const float &fr_mm_s) { FORCE_INLINE void do_blocking_move_to(const float raw[XYZ], const float &fr_mm_s) {
do_blocking_move_to(logical[X_AXIS], logical[Y_AXIS], logical[Z_AXIS], fr_mm_s); do_blocking_move_to(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], fr_mm_s);
} }
void run_deploy_moves_script() { void run_deploy_moves_script() {
@ -2376,7 +2372,7 @@ static void clean_up_after_endstop_or_probe_move() {
} }
#endif #endif
return RAW_CURRENT_POSITION(Z) + zprobe_zoffset return current_position[Z_AXIS] + zprobe_zoffset
#if ENABLED(DELTA) #if ENABLED(DELTA)
+ home_offset[Z_AXIS] // Account for delta height adjustment + home_offset[Z_AXIS] // Account for delta height adjustment
#endif #endif
@ -2392,22 +2388,22 @@ static void clean_up_after_endstop_or_probe_move() {
* - Raise to the BETWEEN height * - Raise to the BETWEEN height
* - Return the probed Z position * - Return the probed Z position
*/ */
float probe_pt(const float &lx, const float &ly, const bool stow, const uint8_t verbose_level, const bool printable=true) { float probe_pt(const float &rx, const float &ry, const bool stow, const uint8_t verbose_level, const bool printable=true) {
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) { if (DEBUGGING(LEVELING)) {
SERIAL_ECHOPAIR(">>> probe_pt(", lx); SERIAL_ECHOPAIR(">>> probe_pt(", LOGICAL_X_POSITION(rx));
SERIAL_ECHOPAIR(", ", ly); SERIAL_ECHOPAIR(", ", LOGICAL_Y_POSITION(ry));
SERIAL_ECHOPAIR(", ", stow ? "" : "no "); SERIAL_ECHOPAIR(", ", stow ? "" : "no ");
SERIAL_ECHOLNPGM("stow)"); SERIAL_ECHOLNPGM("stow)");
DEBUG_POS("", current_position); DEBUG_POS("", current_position);
} }
#endif #endif
const float nx = lx - (X_PROBE_OFFSET_FROM_EXTRUDER), ny = ly - (Y_PROBE_OFFSET_FROM_EXTRUDER); const float nx = rx - (X_PROBE_OFFSET_FROM_EXTRUDER), ny = ry - (Y_PROBE_OFFSET_FROM_EXTRUDER);
if (printable if (printable
? !position_is_reachable_xy(nx, ny) ? !position_is_reachable(nx, ny)
: !position_is_reachable_by_probe_xy(lx, ly) : !position_is_reachable_by_probe(rx, ry)
) return NAN; ) return NAN;
@ -2446,9 +2442,9 @@ static void clean_up_after_endstop_or_probe_move() {
if (verbose_level > 2) { if (verbose_level > 2) {
SERIAL_PROTOCOLPGM("Bed X: "); SERIAL_PROTOCOLPGM("Bed X: ");
SERIAL_PROTOCOL_F(lx, 3); SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(rx), 3);
SERIAL_PROTOCOLPGM(" Y: "); SERIAL_PROTOCOLPGM(" Y: ");
SERIAL_PROTOCOL_F(ly, 3); SERIAL_PROTOCOL_F(LOGICAL_Y_POSITION(ry), 3);
SERIAL_PROTOCOLPGM(" Z: "); SERIAL_PROTOCOLPGM(" Z: ");
SERIAL_PROTOCOL_F(measured_z, 3); SERIAL_PROTOCOL_F(measured_z, 3);
SERIAL_EOL(); SERIAL_EOL();
@ -3351,7 +3347,7 @@ static void homeaxis(const AxisEnum axis) {
void gcode_get_destination() { void gcode_get_destination() {
LOOP_XYZE(i) { LOOP_XYZE(i) {
if (parser.seen(axis_codes[i])) if (parser.seen(axis_codes[i]))
destination[i] = parser.value_axis_units((AxisEnum)i) + (axis_relative_modes[i] || relative_mode ? current_position[i] : 0); destination[i] = LOGICAL_TO_NATIVE(parser.value_axis_units((AxisEnum)i) + (axis_relative_modes[i] || relative_mode ? current_position[i] : 0), i);
else else
destination[i] = current_position[i]; destination[i] = current_position[i];
} }
@ -3476,7 +3472,7 @@ inline void gcode_G0_G1(
*/ */
#if ENABLED(ARC_SUPPORT) #if ENABLED(ARC_SUPPORT)
inline void gcode_G2_G3(bool clockwise) { inline void gcode_G2_G3(const bool clockwise) {
#if ENABLED(NO_MOTION_BEFORE_HOMING) #if ENABLED(NO_MOTION_BEFORE_HOMING)
if (axis_unhomed_error()) return; if (axis_unhomed_error()) return;
#endif #endif
@ -3650,10 +3646,19 @@ inline void gcode_G4() {
#if ENABLED(CNC_WORKSPACE_PLANES) #if ENABLED(CNC_WORKSPACE_PLANES)
void report_workspace_plane() { inline void report_workspace_plane() {
SERIAL_ECHO_START(); SERIAL_ECHO_START();
SERIAL_ECHOPGM("Workspace Plane "); SERIAL_ECHOPGM("Workspace Plane ");
serialprintPGM(workspace_plane == PLANE_YZ ? PSTR("YZ\n") : workspace_plane == PLANE_ZX ? PSTR("ZX\n") : PSTR("XY\n")); serialprintPGM(
workspace_plane == PLANE_YZ ? PSTR("YZ\n") :
workspace_plane == PLANE_ZX ? PSTR("ZX\n") :
PSTR("XY\n")
);
}
inline void set_workspace_plane(const WorkspacePlane plane) {
workspace_plane = plane;
if (DEBUGGING(INFO)) report_workspace_plane();
} }
/** /**
@ -3661,9 +3666,9 @@ inline void gcode_G4() {
* G18: Select Plane ZX * G18: Select Plane ZX
* G19: Select Plane YZ * G19: Select Plane YZ
*/ */
inline void gcode_G17() { workspace_plane = PLANE_XY; } inline void gcode_G17() { set_workspace_plane(PLANE_XY); }
inline void gcode_G18() { workspace_plane = PLANE_ZX; } inline void gcode_G18() { set_workspace_plane(PLANE_ZX); }
inline void gcode_G19() { workspace_plane = PLANE_YZ; } inline void gcode_G19() { set_workspace_plane(PLANE_YZ); }
#endif // CNC_WORKSPACE_PLANES #endif // CNC_WORKSPACE_PLANES
@ -3821,10 +3826,10 @@ inline void gcode_G4() {
SERIAL_ECHOPGM("Mesh Bed Leveling"); SERIAL_ECHOPGM("Mesh Bed Leveling");
if (planner.leveling_active) { if (planner.leveling_active) {
float lz = current_position[Z_AXIS]; float rz = current_position[Z_AXIS];
planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], lz); planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], rz);
SERIAL_ECHOLNPGM(" (enabled)"); SERIAL_ECHOLNPGM(" (enabled)");
SERIAL_ECHOPAIR("MBL Adjustment Z", lz); SERIAL_ECHOPAIR("MBL Adjustment Z", rz);
} }
else else
SERIAL_ECHOPGM(" (disabled)"); SERIAL_ECHOPGM(" (disabled)");
@ -3912,8 +3917,8 @@ inline void gcode_G4() {
/** /**
* Move the Z probe (or just the nozzle) to the safe homing point * Move the Z probe (or just the nozzle) to the safe homing point
*/ */
destination[X_AXIS] = LOGICAL_X_POSITION(Z_SAFE_HOMING_X_POINT); destination[X_AXIS] = Z_SAFE_HOMING_X_POINT;
destination[Y_AXIS] = LOGICAL_Y_POSITION(Z_SAFE_HOMING_Y_POINT); destination[Y_AXIS] = Z_SAFE_HOMING_Y_POINT;
destination[Z_AXIS] = current_position[Z_AXIS]; // Z is already at the right height destination[Z_AXIS] = current_position[Z_AXIS]; // Z is already at the right height
#if HOMING_Z_WITH_PROBE #if HOMING_Z_WITH_PROBE
@ -3921,7 +3926,7 @@ inline void gcode_G4() {
destination[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER; destination[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER;
#endif #endif
if (position_is_reachable_xy(destination[X_AXIS], destination[Y_AXIS])) { if (position_is_reachable(destination[X_AXIS], destination[Y_AXIS])) {
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("Z_SAFE_HOMING", destination); if (DEBUGGING(LEVELING)) DEBUG_POS("Z_SAFE_HOMING", destination);
@ -4041,7 +4046,7 @@ inline void gcode_G28(const bool always_home_all) {
if (home_all || homeX || homeY) { if (home_all || homeX || homeY) {
// Raise Z before homing any other axes and z is not already high enough (never lower z) // Raise Z before homing any other axes and z is not already high enough (never lower z)
destination[Z_AXIS] = LOGICAL_Z_POSITION(Z_HOMING_HEIGHT); destination[Z_AXIS] = Z_HOMING_HEIGHT;
if (destination[Z_AXIS] > current_position[Z_AXIS]) { if (destination[Z_AXIS] > current_position[Z_AXIS]) {
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
@ -4083,7 +4088,7 @@ inline void gcode_G28(const bool always_home_all) {
HOMEAXIS(X); HOMEAXIS(X);
// Remember this extruder's position for later tool change // Remember this extruder's position for later tool change
inactive_extruder_x_pos = RAW_X_POSITION(current_position[X_AXIS]); inactive_extruder_x_pos = current_position[X_AXIS];
// Home the 1st (left) extruder // Home the 1st (left) extruder
active_extruder = 0; active_extruder = 0;
@ -4184,18 +4189,18 @@ void home_all_axes() { gcode_G28(true); }
extern bool lcd_wait_for_move; extern bool lcd_wait_for_move;
#endif #endif
inline void _manual_goto_xy(const float &x, const float &y) { inline void _manual_goto_xy(const float &rx, const float &ry) {
const float old_feedrate_mm_s = feedrate_mm_s; const float old_feedrate_mm_s = feedrate_mm_s;
#if MANUAL_PROBE_HEIGHT > 0 #if MANUAL_PROBE_HEIGHT > 0
const float prev_z = current_position[Z_AXIS]; const float prev_z = current_position[Z_AXIS];
feedrate_mm_s = homing_feedrate(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(); line_to_current_position();
#endif #endif
feedrate_mm_s = MMM_TO_MMS(XY_PROBE_SPEED); feedrate_mm_s = MMM_TO_MMS(XY_PROBE_SPEED);
current_position[X_AXIS] = LOGICAL_X_POSITION(x); current_position[X_AXIS] = rx;
current_position[Y_AXIS] = LOGICAL_Y_POSITION(y); current_position[Y_AXIS] = ry;
line_to_current_position(); line_to_current_position();
#if MANUAL_PROBE_HEIGHT > 0 #if MANUAL_PROBE_HEIGHT > 0
@ -4233,7 +4238,7 @@ void home_all_axes() { gcode_G28(true); }
home_all_axes(); home_all_axes();
set_bed_leveling_enabled(true); set_bed_leveling_enabled(true);
#if ENABLED(MESH_G28_REST_ORIGIN) #if ENABLED(MESH_G28_REST_ORIGIN)
current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS); current_position[Z_AXIS] = Z_MIN_POS;
set_destination_from_current(); set_destination_from_current();
line_to_destination(homing_feedrate(Z_AXIS)); line_to_destination(homing_feedrate(Z_AXIS));
stepper.synchronize(); stepper.synchronize();
@ -4326,7 +4331,7 @@ void home_all_axes() { gcode_G28(true); }
} }
else { else {
// One last "return to the bed" (as originally coded) at completion // One last "return to the bed" (as originally coded) at completion
current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT; current_position[Z_AXIS] = Z_MIN_POS + MANUAL_PROBE_HEIGHT;
line_to_current_position(); line_to_current_position();
stepper.synchronize(); stepper.synchronize();
@ -4609,28 +4614,28 @@ void home_all_axes() { gcode_G28(true); }
return; return;
} }
const float z = parser.floatval('Z', RAW_CURRENT_POSITION(Z)); const float rz = parser.seenval('Z') ? RAW_Z_POSITION(parser.value_linear_units()) : current_position[Z_AXIS];
if (!WITHIN(z, -10, 10)) { if (!WITHIN(rz, -10, 10)) {
SERIAL_ERROR_START(); SERIAL_ERROR_START();
SERIAL_ERRORLNPGM("Bad Z value"); SERIAL_ERRORLNPGM("Bad Z value");
return; return;
} }
const float x = parser.floatval('X', NAN), const float rx = RAW_X_POSITION(parser.linearval('X', NAN)),
y = parser.floatval('Y', NAN); ry = RAW_Y_POSITION(parser.linearval('Y', NAN));
int8_t i = parser.byteval('I', -1), int8_t i = parser.byteval('I', -1),
j = parser.byteval('J', -1); j = parser.byteval('J', -1);
if (!isnan(x) && !isnan(y)) { if (!isnan(rx) && !isnan(ry)) {
// Get nearest i / j from x / y // Get nearest i / j from x / y
i = (x - LOGICAL_X_POSITION(bilinear_start[X_AXIS]) + 0.5 * xGridSpacing) / xGridSpacing; i = (rx - bilinear_start[X_AXIS] + 0.5 * xGridSpacing) / xGridSpacing;
j = (y - LOGICAL_Y_POSITION(bilinear_start[Y_AXIS]) + 0.5 * yGridSpacing) / yGridSpacing; j = (ry - bilinear_start[Y_AXIS] + 0.5 * yGridSpacing) / yGridSpacing;
i = constrain(i, 0, GRID_MAX_POINTS_X - 1); i = constrain(i, 0, GRID_MAX_POINTS_X - 1);
j = constrain(j, 0, GRID_MAX_POINTS_Y - 1); j = constrain(j, 0, GRID_MAX_POINTS_Y - 1);
} }
if (WITHIN(i, 0, GRID_MAX_POINTS_X - 1) && WITHIN(j, 0, GRID_MAX_POINTS_Y)) { if (WITHIN(i, 0, GRID_MAX_POINTS_X - 1) && WITHIN(j, 0, GRID_MAX_POINTS_Y)) {
set_bed_leveling_enabled(false); set_bed_leveling_enabled(false);
z_values[i][j] = z; z_values[i][j] = rz;
#if ENABLED(ABL_BILINEAR_SUBDIVISION) #if ENABLED(ABL_BILINEAR_SUBDIVISION)
bed_level_virt_interpolate(); bed_level_virt_interpolate();
#endif #endif
@ -4690,36 +4695,36 @@ void home_all_axes() { gcode_G28(true); }
xy_probe_feedrate_mm_s = MMM_TO_MMS(parser.linearval('S', XY_PROBE_SPEED)); xy_probe_feedrate_mm_s = MMM_TO_MMS(parser.linearval('S', XY_PROBE_SPEED));
left_probe_bed_position = (int)parser.linearval('L', LOGICAL_X_POSITION(LEFT_PROBE_BED_POSITION)); left_probe_bed_position = parser.seenval('L') ? (int)RAW_X_POSITION(parser.value_linear_units()) : LEFT_PROBE_BED_POSITION;
right_probe_bed_position = (int)parser.linearval('R', LOGICAL_X_POSITION(RIGHT_PROBE_BED_POSITION)); right_probe_bed_position = parser.seenval('R') ? (int)RAW_X_POSITION(parser.value_linear_units()) : RIGHT_PROBE_BED_POSITION;
front_probe_bed_position = (int)parser.linearval('F', LOGICAL_Y_POSITION(FRONT_PROBE_BED_POSITION)); front_probe_bed_position = parser.seenval('F') ? (int)RAW_Y_POSITION(parser.value_linear_units()) : FRONT_PROBE_BED_POSITION;
back_probe_bed_position = (int)parser.linearval('B', LOGICAL_Y_POSITION(BACK_PROBE_BED_POSITION)); back_probe_bed_position = parser.seenval('B') ? (int)RAW_Y_POSITION(parser.value_linear_units()) : BACK_PROBE_BED_POSITION;
const bool left_out_l = left_probe_bed_position < LOGICAL_X_POSITION(MIN_PROBE_X), const bool left_out_l = left_probe_bed_position < MIN_PROBE_X,
left_out = left_out_l || left_probe_bed_position > right_probe_bed_position - (MIN_PROBE_EDGE), left_out = left_out_l || left_probe_bed_position > right_probe_bed_position - (MIN_PROBE_EDGE),
right_out_r = right_probe_bed_position > LOGICAL_X_POSITION(MAX_PROBE_X), right_out_r = right_probe_bed_position > MAX_PROBE_X,
right_out = right_out_r || right_probe_bed_position < left_probe_bed_position + MIN_PROBE_EDGE, right_out = right_out_r || right_probe_bed_position < left_probe_bed_position + MIN_PROBE_EDGE,
front_out_f = front_probe_bed_position < LOGICAL_Y_POSITION(MIN_PROBE_Y), front_out_f = front_probe_bed_position < MIN_PROBE_Y,
front_out = front_out_f || front_probe_bed_position > back_probe_bed_position - (MIN_PROBE_EDGE), front_out = front_out_f || front_probe_bed_position > back_probe_bed_position - (MIN_PROBE_EDGE),
back_out_b = back_probe_bed_position > LOGICAL_Y_POSITION(MAX_PROBE_Y), back_out_b = back_probe_bed_position > MAX_PROBE_Y,
back_out = back_out_b || back_probe_bed_position < front_probe_bed_position + MIN_PROBE_EDGE; back_out = back_out_b || back_probe_bed_position < front_probe_bed_position + MIN_PROBE_EDGE;
if (left_out || right_out || front_out || back_out) { if (left_out || right_out || front_out || back_out) {
if (left_out) { if (left_out) {
out_of_range_error(PSTR("(L)eft")); out_of_range_error(PSTR("(L)eft"));
left_probe_bed_position = left_out_l ? LOGICAL_X_POSITION(MIN_PROBE_X) : right_probe_bed_position - (MIN_PROBE_EDGE); left_probe_bed_position = left_out_l ? MIN_PROBE_X : right_probe_bed_position - (MIN_PROBE_EDGE);
} }
if (right_out) { if (right_out) {
out_of_range_error(PSTR("(R)ight")); out_of_range_error(PSTR("(R)ight"));
right_probe_bed_position = right_out_r ? LOGICAL_Y_POSITION(MAX_PROBE_X) : left_probe_bed_position + MIN_PROBE_EDGE; right_probe_bed_position = right_out_r ? MAX_PROBE_X : left_probe_bed_position + MIN_PROBE_EDGE;
} }
if (front_out) { if (front_out) {
out_of_range_error(PSTR("(F)ront")); out_of_range_error(PSTR("(F)ront"));
front_probe_bed_position = front_out_f ? LOGICAL_Y_POSITION(MIN_PROBE_Y) : back_probe_bed_position - (MIN_PROBE_EDGE); front_probe_bed_position = front_out_f ? MIN_PROBE_Y : back_probe_bed_position - (MIN_PROBE_EDGE);
} }
if (back_out) { if (back_out) {
out_of_range_error(PSTR("(B)ack")); out_of_range_error(PSTR("(B)ack"));
back_probe_bed_position = back_out_b ? LOGICAL_Y_POSITION(MAX_PROBE_Y) : front_probe_bed_position + MIN_PROBE_EDGE; back_probe_bed_position = back_out_b ? MAX_PROBE_Y : front_probe_bed_position + MIN_PROBE_EDGE;
} }
return; return;
} }
@ -4766,8 +4771,8 @@ void home_all_axes() { gcode_G28(true); }
#endif #endif
if ( xGridSpacing != bilinear_grid_spacing[X_AXIS] if ( xGridSpacing != bilinear_grid_spacing[X_AXIS]
|| yGridSpacing != bilinear_grid_spacing[Y_AXIS] || yGridSpacing != bilinear_grid_spacing[Y_AXIS]
|| left_probe_bed_position != LOGICAL_X_POSITION(bilinear_start[X_AXIS]) || left_probe_bed_position != bilinear_start[X_AXIS]
|| front_probe_bed_position != LOGICAL_Y_POSITION(bilinear_start[Y_AXIS]) || front_probe_bed_position != bilinear_start[Y_AXIS]
) { ) {
if (dryrun) { if (dryrun) {
// Before reset bed level, re-enable to correct the position // Before reset bed level, re-enable to correct the position
@ -4779,8 +4784,8 @@ void home_all_axes() { gcode_G28(true); }
// Initialize a grid with the given dimensions // Initialize a grid with the given dimensions
bilinear_grid_spacing[X_AXIS] = xGridSpacing; bilinear_grid_spacing[X_AXIS] = xGridSpacing;
bilinear_grid_spacing[Y_AXIS] = yGridSpacing; bilinear_grid_spacing[Y_AXIS] = yGridSpacing;
bilinear_start[X_AXIS] = RAW_X_POSITION(left_probe_bed_position); bilinear_start[X_AXIS] = left_probe_bed_position;
bilinear_start[Y_AXIS] = RAW_Y_POSITION(front_probe_bed_position); bilinear_start[Y_AXIS] = front_probe_bed_position;
// Can't re-enable (on error) until the new grid is written // Can't re-enable (on error) until the new grid is written
abl_should_enable = false; abl_should_enable = false;
@ -4905,7 +4910,7 @@ void home_all_axes() { gcode_G28(true); }
#endif #endif
// Keep looping till a reachable point is found // Keep looping till a reachable point is found
if (position_is_reachable_xy(xProbe, yProbe)) break; if (position_is_reachable(xProbe, yProbe)) break;
++abl_probe_index; ++abl_probe_index;
} }
@ -4935,8 +4940,8 @@ void home_all_axes() { gcode_G28(true); }
// Probe at 3 arbitrary points // Probe at 3 arbitrary points
if (abl_probe_index < 3) { if (abl_probe_index < 3) {
xProbe = LOGICAL_X_POSITION(points[abl_probe_index].x); xProbe = points[abl_probe_index].x;
yProbe = LOGICAL_Y_POSITION(points[abl_probe_index].y); yProbe = points[abl_probe_index].y;
#if HAS_SOFTWARE_ENDSTOPS #if HAS_SOFTWARE_ENDSTOPS
// Disable software endstops to allow manual adjustment // Disable software endstops to allow manual adjustment
// If G29 is not completed, they will not be re-enabled // If G29 is not completed, they will not be re-enabled
@ -5011,7 +5016,7 @@ void home_all_axes() { gcode_G28(true); }
#if IS_KINEMATIC #if IS_KINEMATIC
// Avoid probing outside the round or hexagonal area // Avoid probing outside the round or hexagonal area
if (!position_is_reachable_by_probe_xy(xProbe, yProbe)) continue; if (!position_is_reachable_by_probe(xProbe, yProbe)) continue;
#endif #endif
measured_z = faux ? 0.001 * random(-100, 101) : probe_pt(xProbe, yProbe, stow_probe_after_each, verbose_level); measured_z = faux ? 0.001 * random(-100, 101) : probe_pt(xProbe, yProbe, stow_probe_after_each, verbose_level);
@ -5049,8 +5054,8 @@ void home_all_axes() { gcode_G28(true); }
for (uint8_t i = 0; i < 3; ++i) { for (uint8_t i = 0; i < 3; ++i) {
// Retain the last probe position // Retain the last probe position
xProbe = LOGICAL_X_POSITION(points[i].x); xProbe = points[i].x;
yProbe = LOGICAL_Y_POSITION(points[i].y); yProbe = points[i].y;
measured_z = faux ? 0.001 * random(-100, 101) : probe_pt(xProbe, yProbe, stow_probe_after_each, verbose_level); measured_z = faux ? 0.001 * random(-100, 101) : probe_pt(xProbe, yProbe, stow_probe_after_each, verbose_level);
if (isnan(measured_z)) { if (isnan(measured_z)) {
planner.leveling_active = abl_should_enable; planner.leveling_active = abl_should_enable;
@ -5333,7 +5338,7 @@ void home_all_axes() { gcode_G28(true); }
const float xpos = parser.linearval('X', current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER), const float xpos = parser.linearval('X', current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER),
ypos = parser.linearval('Y', current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER); ypos = parser.linearval('Y', current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER);
if (!position_is_reachable_by_probe_xy(xpos, ypos)) return; if (!position_is_reachable_by_probe(xpos, ypos)) return;
// Disable leveling so the planner won't mess with us // Disable leveling so the planner won't mess with us
#if HAS_LEVELING #if HAS_LEVELING
@ -5797,7 +5802,7 @@ void home_all_axes() { gcode_G28(true); }
LOOP_CAL_RAD(axis) { LOOP_CAL_RAD(axis) {
const float a = RADIANS(210 + (360 / NPP) * (axis - 1)), const float a = RADIANS(210 + (360 / NPP) * (axis - 1)),
r = delta_calibration_radius * (1 + (_7p_9_centre ? 0.1 : 0.0)); r = delta_calibration_radius * (1 + (_7p_9_centre ? 0.1 : 0.0));
if (!position_is_reachable_xy(cos(a) * r, sin(a) * r)) { if (!position_is_reachable(cos(a) * r, sin(a) * r)) {
SERIAL_PROTOCOLLNPGM("?(M665 B)ed radius is implausible."); SERIAL_PROTOCOLLNPGM("?(M665 B)ed radius is implausible.");
return; return;
} }
@ -6148,9 +6153,9 @@ void home_all_axes() { gcode_G28(true); }
if (IsRunning()) { if (IsRunning()) {
const bool hasI = parser.seenval('I'); const bool hasI = parser.seenval('I');
const int8_t ix = hasI ? parser.value_int() : 0; const int8_t ix = RAW_X_POSITION(hasI ? parser.value_linear_units() : 0);
const bool hasJ = parser.seenval('J'); const bool hasJ = parser.seenval('J');
const int8_t iy = hasJ ? parser.value_int() : 0; const int8_t iy = RAW_Y_POSITION(hasJ ? parser.value_linear_units() : 0);
if ((hasI && !WITHIN(ix, 0, GRID_MAX_POINTS_X - 1)) || (hasJ && !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1))) { if ((hasI && !WITHIN(ix, 0, GRID_MAX_POINTS_X - 1)) || (hasJ && !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1))) {
SERIAL_ECHOLNPGM(MSG_ERR_MESH_XY); SERIAL_ECHOLNPGM(MSG_ERR_MESH_XY);
@ -6169,8 +6174,8 @@ void home_all_axes() { gcode_G28(true); }
#endif #endif
set_destination_from_current(); set_destination_from_current();
if (hasI) destination[X_AXIS] = LOGICAL_X_POSITION(_GET_MESH_X(ix)); if (hasI) destination[X_AXIS] = _GET_MESH_X(ix);
if (hasJ) destination[Y_AXIS] = LOGICAL_Y_POSITION(_GET_MESH_Y(iy)); if (hasJ) destination[Y_AXIS] = _GET_MESH_Y(iy);
if (parser.boolval('P')) { if (parser.boolval('P')) {
if (hasI) destination[X_AXIS] -= X_PROBE_OFFSET_FROM_EXTRUDER; if (hasI) destination[X_AXIS] -= X_PROBE_OFFSET_FROM_EXTRUDER;
if (hasJ) destination[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER; if (hasJ) destination[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER;
@ -6202,7 +6207,6 @@ inline void gcode_G92() {
LOOP_XYZE(i) { LOOP_XYZE(i) {
if (parser.seenval(axis_codes[i])) { if (parser.seenval(axis_codes[i])) {
#if IS_SCARA #if IS_SCARA
current_position[i] = parser.value_axis_units((AxisEnum)i);
if (i != E_AXIS) didXYZ = true; if (i != E_AXIS) didXYZ = true;
#else #else
#if HAS_POSITION_SHIFT #if HAS_POSITION_SHIFT
@ -6210,8 +6214,6 @@ inline void gcode_G92() {
#endif #endif
const float v = parser.value_axis_units((AxisEnum)i); const float v = parser.value_axis_units((AxisEnum)i);
current_position[i] = v;
if (i != E_AXIS) { if (i != E_AXIS) {
didXYZ = true; didXYZ = true;
#if HAS_POSITION_SHIFT #if HAS_POSITION_SHIFT
@ -7289,16 +7291,16 @@ inline void gcode_M42() {
Y_probe_location = parser.linearval('Y', Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER); Y_probe_location = parser.linearval('Y', Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER);
#if DISABLED(DELTA) #if DISABLED(DELTA)
if (!WITHIN(X_probe_location, LOGICAL_X_POSITION(MIN_PROBE_X), LOGICAL_X_POSITION(MAX_PROBE_X))) { if (!WITHIN(X_probe_location, MIN_PROBE_X, MAX_PROBE_X)) {
out_of_range_error(PSTR("X")); out_of_range_error(PSTR("X"));
return; return;
} }
if (!WITHIN(Y_probe_location, LOGICAL_Y_POSITION(MIN_PROBE_Y), LOGICAL_Y_POSITION(MAX_PROBE_Y))) { if (!WITHIN(Y_probe_location, MIN_PROBE_Y, MAX_PROBE_Y)) {
out_of_range_error(PSTR("Y")); out_of_range_error(PSTR("Y"));
return; return;
} }
#else #else
if (!position_is_reachable_by_probe_xy(X_probe_location, Y_probe_location)) { if (!position_is_reachable_by_probe(X_probe_location, Y_probe_location)) {
SERIAL_PROTOCOLLNPGM("? (X,Y) location outside of probeable radius."); SERIAL_PROTOCOLLNPGM("? (X,Y) location outside of probeable radius.");
return; return;
} }
@ -7391,7 +7393,7 @@ inline void gcode_M42() {
#else #else
// If we have gone out too far, we can do a simple fix and scale the numbers // If we have gone out too far, we can do a simple fix and scale the numbers
// back in closer to the origin. // back in closer to the origin.
while (!position_is_reachable_by_probe_xy(X_current, Y_current)) { while (!position_is_reachable_by_probe(X_current, Y_current)) {
X_current *= 0.8; X_current *= 0.8;
Y_current *= 0.8; Y_current *= 0.8;
if (verbose_level > 3) { if (verbose_level > 3) {
@ -8403,11 +8405,11 @@ inline void gcode_M92() {
*/ */
void report_current_position() { void report_current_position() {
SERIAL_PROTOCOLPGM("X:"); SERIAL_PROTOCOLPGM("X:");
SERIAL_PROTOCOL(current_position[X_AXIS]); SERIAL_PROTOCOL(LOGICAL_X_POSITION(current_position[X_AXIS]));
SERIAL_PROTOCOLPGM(" Y:"); SERIAL_PROTOCOLPGM(" Y:");
SERIAL_PROTOCOL(current_position[Y_AXIS]); SERIAL_PROTOCOL(LOGICAL_X_POSITION(current_position[Y_AXIS]));
SERIAL_PROTOCOLPGM(" Z:"); SERIAL_PROTOCOLPGM(" Z:");
SERIAL_PROTOCOL(current_position[Z_AXIS]); SERIAL_PROTOCOL(LOGICAL_Z_POSITION(current_position[Z_AXIS]));
SERIAL_PROTOCOLPGM(" E:"); SERIAL_PROTOCOLPGM(" E:");
SERIAL_PROTOCOL(current_position[E_AXIS]); SERIAL_PROTOCOL(current_position[E_AXIS]);
@ -8440,11 +8442,15 @@ void report_current_position() {
stepper.synchronize(); stepper.synchronize();
SERIAL_PROTOCOLPGM("\nLogical:"); SERIAL_PROTOCOLPGM("\nLogical:");
report_xyze(current_position); const float logical[XYZ] = {
LOGICAL_X_POSITION(current_position[X_AXIS]),
LOGICAL_Y_POSITION(current_position[Y_AXIS]),
LOGICAL_Z_POSITION(current_position[Z_AXIS])
};
report_xyze(logical);
SERIAL_PROTOCOLPGM("Raw: "); SERIAL_PROTOCOLPGM("Raw: ");
const float raw[XYZ] = { RAW_X_POSITION(current_position[X_AXIS]), RAW_Y_POSITION(current_position[Y_AXIS]), RAW_Z_POSITION(current_position[Z_AXIS]) }; report_xyz(current_position);
report_xyz(raw);
SERIAL_PROTOCOLPGM("Leveled:"); SERIAL_PROTOCOLPGM("Leveled:");
float leveled[XYZ] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] }; float leveled[XYZ] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] };
@ -8871,7 +8877,6 @@ inline void gcode_M205() {
if (parser.seen('P')) set_home_offset(B_AXIS, parser.value_linear_units()); // Psi if (parser.seen('P')) set_home_offset(B_AXIS, parser.value_linear_units()); // Psi
#endif #endif
SYNC_PLAN_POSITION_KINEMATIC();
report_current_position(); report_current_position();
} }
@ -9477,11 +9482,11 @@ inline void gcode_M303() {
#if ENABLED(MORGAN_SCARA) #if ENABLED(MORGAN_SCARA)
bool SCARA_move_to_cal(uint8_t delta_a, uint8_t delta_b) { bool SCARA_move_to_cal(const uint8_t delta_a, const uint8_t delta_b) {
if (IsRunning()) { if (IsRunning()) {
forward_kinematics_SCARA(delta_a, delta_b); forward_kinematics_SCARA(delta_a, delta_b);
destination[X_AXIS] = LOGICAL_X_POSITION(cartes[X_AXIS]); destination[X_AXIS] = cartes[X_AXIS];
destination[Y_AXIS] = LOGICAL_Y_POSITION(cartes[Y_AXIS]); destination[Y_AXIS] = cartes[Y_AXIS];
destination[Z_AXIS] = current_position[Z_AXIS]; destination[Z_AXIS] = current_position[Z_AXIS];
prepare_move_to_destination(); prepare_move_to_destination();
return true; return true;
@ -9797,9 +9802,9 @@ void quickstop_stepper() {
*/ */
inline void gcode_M421() { inline void gcode_M421() {
const bool hasX = parser.seen('X'), hasI = parser.seen('I'); const bool hasX = parser.seen('X'), hasI = parser.seen('I');
const int8_t ix = hasI ? parser.value_int() : hasX ? mbl.probe_index_x(RAW_X_POSITION(parser.value_linear_units())) : -1; const int8_t ix = hasI ? parser.value_int() : hasX ? mbl.probe_index_x(parser.value_linear_units()) : -1;
const bool hasY = parser.seen('Y'), hasJ = parser.seen('J'); const bool hasY = parser.seen('Y'), hasJ = parser.seen('J');
const int8_t iy = hasJ ? parser.value_int() : hasY ? mbl.probe_index_y(RAW_Y_POSITION(parser.value_linear_units())) : -1; const int8_t iy = hasJ ? parser.value_int() : hasY ? mbl.probe_index_y(parser.value_linear_units()) : -1;
const bool hasZ = parser.seen('Z'), hasQ = !hasZ && parser.seen('Q'); const bool hasZ = parser.seen('Z'), hasQ = !hasZ && parser.seen('Q');
if (int(hasI && hasJ) + int(hasX && hasY) != 1 || !(hasZ || hasQ)) { if (int(hasI && hasJ) + int(hasX && hasY) != 1 || !(hasZ || hasQ)) {
@ -9903,7 +9908,7 @@ void quickstop_stepper() {
LOOP_XYZ(i) { LOOP_XYZ(i) {
if (axis_homed[i]) { if (axis_homed[i]) {
const float base = (current_position[i] > (soft_endstop_min[i] + soft_endstop_max[i]) * 0.5) ? base_home_pos((AxisEnum)i) : 0, const float base = (current_position[i] > (soft_endstop_min[i] + soft_endstop_max[i]) * 0.5) ? base_home_pos((AxisEnum)i) : 0,
diff = base - RAW_POSITION(current_position[i], i); diff = base - current_position[i];
if (WITHIN(diff, -20, 20)) { if (WITHIN(diff, -20, 20)) {
set_home_offset((AxisEnum)i, diff); set_home_offset((AxisEnum)i, diff);
} }
@ -9919,7 +9924,6 @@ void quickstop_stepper() {
} }
if (!err) { if (!err) {
SYNC_PLAN_POSITION_KINEMATIC();
report_current_position(); report_current_position();
LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED); LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED);
BUZZ(100, 659); BUZZ(100, 659);
@ -10820,9 +10824,9 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
switch (dual_x_carriage_mode) { switch (dual_x_carriage_mode) {
case DXC_FULL_CONTROL_MODE: case DXC_FULL_CONTROL_MODE:
// New current position is the position of the activated extruder // New current position is the position of the activated extruder
current_position[X_AXIS] = LOGICAL_X_POSITION(inactive_extruder_x_pos); current_position[X_AXIS] = inactive_extruder_x_pos;
// Save the inactive extruder's position (from the old current_position) // Save the inactive extruder's position (from the old current_position)
inactive_extruder_x_pos = RAW_X_POSITION(destination[X_AXIS]); inactive_extruder_x_pos = destination[X_AXIS];
break; break;
case DXC_AUTO_PARK_MODE: case DXC_AUTO_PARK_MODE:
// record raised toolhead position for use by unpark // record raised toolhead position for use by unpark
@ -10840,10 +10844,10 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
active_extruder_parked = (active_extruder == 0); active_extruder_parked = (active_extruder == 0);
if (active_extruder_parked) if (active_extruder_parked)
current_position[X_AXIS] = LOGICAL_X_POSITION(inactive_extruder_x_pos); current_position[X_AXIS] = inactive_extruder_x_pos;
else else
current_position[X_AXIS] = destination[X_AXIS] + duplicate_extruder_x_offset; current_position[X_AXIS] = destination[X_AXIS] + duplicate_extruder_x_offset;
inactive_extruder_x_pos = RAW_X_POSITION(destination[X_AXIS]); inactive_extruder_x_pos = destination[X_AXIS];
extruder_duplication_enabled = false; extruder_duplication_enabled = false;
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) { if (DEBUGGING(LEVELING)) {
@ -12154,7 +12158,7 @@ void ok_to_send() {
#endif #endif
// Get the Z adjustment for non-linear bed leveling // 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, static float z1, d2, z3, d4, L, D, ratio_x, ratio_y,
last_x = -999.999, last_y = -999.999; last_x = -999.999, last_y = -999.999;
@ -12164,8 +12168,8 @@ void ok_to_send() {
last_gridx = -99, last_gridy = -99; last_gridx = -99, last_gridy = -99;
// XY relative to the probed area // XY relative to the probed area
const float x = RAW_X_POSITION(logical[X_AXIS]) - bilinear_start[X_AXIS], const float rx = raw[X_AXIS] - bilinear_start[X_AXIS],
y = RAW_Y_POSITION(logical[Y_AXIS]) - bilinear_start[Y_AXIS]; ry = raw[Y_AXIS] - bilinear_start[Y_AXIS];
#if ENABLED(EXTRAPOLATE_BEYOND_GRID) #if ENABLED(EXTRAPOLATE_BEYOND_GRID)
// Keep using the last grid box // Keep using the last grid box
@ -12175,9 +12179,9 @@ void ok_to_send() {
#define FAR_EDGE_OR_BOX 1 #define FAR_EDGE_OR_BOX 1
#endif #endif
if (last_x != x) { if (last_x != rx) {
last_x = x; last_x = rx;
ratio_x = x * ABL_BG_FACTOR(X_AXIS); ratio_x = rx * ABL_BG_FACTOR(X_AXIS);
const float gx = constrain(FLOOR(ratio_x), 0, ABL_BG_POINTS_X - FAR_EDGE_OR_BOX); 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 ratio_x -= gx; // Subtract whole to get the ratio within the grid box
@ -12190,11 +12194,11 @@ void ok_to_send() {
nextx = min(gridx + 1, ABL_BG_POINTS_X - 1); 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) { if (last_y != ry) {
last_y = y; last_y = ry;
ratio_y = y * ABL_BG_FACTOR(Y_AXIS); ratio_y = ry * ABL_BG_FACTOR(Y_AXIS);
const float gy = constrain(FLOOR(ratio_y), 0, ABL_BG_POINTS_Y - FAR_EDGE_OR_BOX); const float gy = constrain(FLOOR(ratio_y), 0, ABL_BG_POINTS_Y - FAR_EDGE_OR_BOX);
ratio_y -= gy; ratio_y -= gy;
@ -12217,7 +12221,7 @@ void ok_to_send() {
d4 = ABL_BG_GRID(nextx, nexty) - z3; // right-back (delta) 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 L = z1 + d2 * ratio_y; // Linear interp. LF -> LB
const float R = z3 + d4 * ratio_y; // Linear interp. RF -> RB const float R = z3 + d4 * ratio_y; // Linear interp. RF -> RB
@ -12230,10 +12234,10 @@ void ok_to_send() {
static float last_offset = 0; static float last_offset = 0;
if (FABS(last_offset - offset) > 0.2) { if (FABS(last_offset - offset) > 0.2) {
SERIAL_ECHOPGM("Sudden Shift at "); SERIAL_ECHOPGM("Sudden Shift at ");
SERIAL_ECHOPAIR("x=", x); SERIAL_ECHOPAIR("x=", rx);
SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[X_AXIS]); SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[X_AXIS]);
SERIAL_ECHOLNPAIR(" -> gridx=", gridx); SERIAL_ECHOLNPAIR(" -> gridx=", gridx);
SERIAL_ECHOPAIR(" y=", y); SERIAL_ECHOPAIR(" y=", ry);
SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[Y_AXIS]); SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[Y_AXIS]);
SERIAL_ECHOLNPAIR(" -> gridy=", gridy); SERIAL_ECHOLNPAIR(" -> gridy=", gridy);
SERIAL_ECHOPAIR(" ratio_x=", ratio_x); SERIAL_ECHOPAIR(" ratio_x=", ratio_x);
@ -12304,7 +12308,7 @@ void ok_to_send() {
/** /**
* Delta Inverse Kinematics * Delta Inverse Kinematics
* *
* Calculate the tower positions for a given logical * Calculate the tower positions for a given machine
* position, storing the result in the delta[] array. * position, storing the result in the delta[] array.
* *
* This is an expensive calculation, requiring 3 square * This is an expensive calculation, requiring 3 square
@ -12334,15 +12338,6 @@ void ok_to_send() {
delta[C_AXIS] = DELTA_Z(C_AXIS); \ delta[C_AXIS] = DELTA_Z(C_AXIS); \
}while(0) }while(0)
#define DELTA_LOGICAL_IK() do { \
const float raw[XYZ] = { \
RAW_X_POSITION(logical[X_AXIS]), \
RAW_Y_POSITION(logical[Y_AXIS]), \
RAW_Z_POSITION(logical[Z_AXIS]) \
}; \
DELTA_RAW_IK(); \
}while(0)
#define DELTA_DEBUG() do { \ #define DELTA_DEBUG() do { \
SERIAL_ECHOPAIR("cartesian X:", raw[X_AXIS]); \ SERIAL_ECHOPAIR("cartesian X:", raw[X_AXIS]); \
SERIAL_ECHOPAIR(" Y:", raw[Y_AXIS]); \ SERIAL_ECHOPAIR(" Y:", raw[Y_AXIS]); \
@ -12352,8 +12347,8 @@ void ok_to_send() {
SERIAL_ECHOLNPAIR(" C:", delta[C_AXIS]); \ SERIAL_ECHOLNPAIR(" C:", delta[C_AXIS]); \
}while(0) }while(0)
void inverse_kinematics(const float logical[XYZ]) { void inverse_kinematics(const float raw[XYZ]) {
DELTA_LOGICAL_IK(); DELTA_RAW_IK();
// DELTA_DEBUG(); // DELTA_DEBUG();
} }
@ -12362,11 +12357,7 @@ void ok_to_send() {
* effector has the full range of XY motion. * effector has the full range of XY motion.
*/ */
float delta_safe_distance_from_top() { float delta_safe_distance_from_top() {
float cartesian[XYZ] = { float cartesian[XYZ] = { 0, 0, 0 };
LOGICAL_X_POSITION(0),
LOGICAL_Y_POSITION(0),
LOGICAL_Z_POSITION(0)
};
inverse_kinematics(cartesian); inverse_kinematics(cartesian);
float distance = delta[A_AXIS]; float distance = delta[A_AXIS];
cartesian[Y_AXIS] = LOGICAL_Y_POSITION(DELTA_PRINTABLE_RADIUS); cartesian[Y_AXIS] = LOGICAL_Y_POSITION(DELTA_PRINTABLE_RADIUS);
@ -12462,8 +12453,8 @@ void ok_to_send() {
* *
* The result is in the current coordinate space with * The result is in the current coordinate space with
* leveling applied. The coordinates need to be run through * leveling applied. The coordinates need to be run through
* unapply_leveling to obtain the "ideal" coordinates * unapply_leveling to obtain machine coordinates suitable
* suitable for current_position, etc. * for current_position, etc.
*/ */
void get_cartesian_from_steppers() { void get_cartesian_from_steppers() {
#if ENABLED(DELTA) #if ENABLED(DELTA)
@ -12472,20 +12463,16 @@ void get_cartesian_from_steppers() {
stepper.get_axis_position_mm(B_AXIS), stepper.get_axis_position_mm(B_AXIS),
stepper.get_axis_position_mm(C_AXIS) stepper.get_axis_position_mm(C_AXIS)
); );
cartes[X_AXIS] += LOGICAL_X_POSITION(0); #else
cartes[Y_AXIS] += LOGICAL_Y_POSITION(0); #if IS_SCARA
cartes[Z_AXIS] += LOGICAL_Z_POSITION(0);
#elif IS_SCARA
forward_kinematics_SCARA( forward_kinematics_SCARA(
stepper.get_axis_position_degrees(A_AXIS), stepper.get_axis_position_degrees(A_AXIS),
stepper.get_axis_position_degrees(B_AXIS) stepper.get_axis_position_degrees(B_AXIS)
); );
cartes[X_AXIS] += LOGICAL_X_POSITION(0);
cartes[Y_AXIS] += LOGICAL_Y_POSITION(0);
cartes[Z_AXIS] = stepper.get_axis_position_mm(Z_AXIS);
#else #else
cartes[X_AXIS] = stepper.get_axis_position_mm(X_AXIS); cartes[X_AXIS] = stepper.get_axis_position_mm(X_AXIS);
cartes[Y_AXIS] = stepper.get_axis_position_mm(Y_AXIS); cartes[Y_AXIS] = stepper.get_axis_position_mm(Y_AXIS);
#endif
cartes[Z_AXIS] = stepper.get_axis_position_mm(Z_AXIS); cartes[Z_AXIS] = stepper.get_axis_position_mm(Z_AXIS);
#endif #endif
} }
@ -12513,10 +12500,10 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
* splitting the move where it crosses mesh borders. * splitting the move where it crosses mesh borders.
*/ */
void mesh_line_to_destination(float fr_mm_s, uint8_t x_splits = 0xFF, uint8_t y_splits = 0xFF) { void mesh_line_to_destination(float fr_mm_s, uint8_t x_splits = 0xFF, uint8_t y_splits = 0xFF) {
int cx1 = mbl.cell_index_x(RAW_CURRENT_POSITION(X)), int cx1 = mbl.cell_index_x(current_position[X_AXIS]),
cy1 = mbl.cell_index_y(RAW_CURRENT_POSITION(Y)), cy1 = mbl.cell_index_y(current_position[Y_AXIS]),
cx2 = mbl.cell_index_x(RAW_X_POSITION(destination[X_AXIS])), cx2 = mbl.cell_index_x(destination[X_AXIS]),
cy2 = mbl.cell_index_y(RAW_Y_POSITION(destination[Y_AXIS])); cy2 = mbl.cell_index_y(destination[Y_AXIS]);
NOMORE(cx1, GRID_MAX_POINTS_X - 2); NOMORE(cx1, GRID_MAX_POINTS_X - 2);
NOMORE(cy1, GRID_MAX_POINTS_Y - 2); NOMORE(cy1, GRID_MAX_POINTS_Y - 2);
NOMORE(cx2, GRID_MAX_POINTS_X - 2); NOMORE(cx2, GRID_MAX_POINTS_X - 2);
@ -12537,14 +12524,14 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2); const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
if (cx2 != cx1 && TEST(x_splits, gcx)) { if (cx2 != cx1 && TEST(x_splits, gcx)) {
COPY(end, destination); 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]); normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]);
destination[Y_AXIS] = MBL_SEGMENT_END(Y); destination[Y_AXIS] = MBL_SEGMENT_END(Y);
CBI(x_splits, gcx); CBI(x_splits, gcx);
} }
else if (cy2 != cy1 && TEST(y_splits, gcy)) { else if (cy2 != cy1 && TEST(y_splits, gcy)) {
COPY(end, destination); 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]); normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]);
destination[X_AXIS] = MBL_SEGMENT_END(X); destination[X_AXIS] = MBL_SEGMENT_END(X);
CBI(y_splits, gcy); CBI(y_splits, gcy);
@ -12600,14 +12587,14 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2); const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
if (cx2 != cx1 && TEST(x_splits, gcx)) { if (cx2 != cx1 && TEST(x_splits, gcx)) {
COPY(end, destination); 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]); normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]);
destination[Y_AXIS] = LINE_SEGMENT_END(Y); destination[Y_AXIS] = LINE_SEGMENT_END(Y);
CBI(x_splits, gcx); CBI(x_splits, gcx);
} }
else if (cy2 != cy1 && TEST(y_splits, gcy)) { else if (cy2 != cy1 && TEST(y_splits, gcy)) {
COPY(end, destination); 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]); normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]);
destination[X_AXIS] = LINE_SEGMENT_END(X); destination[X_AXIS] = LINE_SEGMENT_END(X);
CBI(y_splits, gcy); CBI(y_splits, gcy);
@ -12640,26 +12627,26 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
* This calls planner.buffer_line several times, adding * This calls planner.buffer_line several times, adding
* small incremental moves for DELTA or SCARA. * small incremental moves for DELTA or SCARA.
*/ */
inline bool prepare_kinematic_move_to(float ltarget[XYZE]) { inline bool prepare_kinematic_move_to(float rtarget[XYZE]) {
// Get the top feedrate of the move in the XY plane // Get the top feedrate of the move in the XY plane
const float _feedrate_mm_s = MMS_SCALED(feedrate_mm_s); const float _feedrate_mm_s = MMS_SCALED(feedrate_mm_s);
// If the move is only in Z/E don't split up the move // If the move is only in Z/E don't split up the move
if (ltarget[X_AXIS] == current_position[X_AXIS] && ltarget[Y_AXIS] == current_position[Y_AXIS]) { if (rtarget[X_AXIS] == current_position[X_AXIS] && rtarget[Y_AXIS] == current_position[Y_AXIS]) {
planner.buffer_line_kinematic(ltarget, _feedrate_mm_s, active_extruder); planner.buffer_line_kinematic(rtarget, _feedrate_mm_s, active_extruder);
return false; return false;
} }
// Fail if attempting move outside printable radius // Fail if attempting move outside printable radius
if (!position_is_reachable_xy(ltarget[X_AXIS], ltarget[Y_AXIS])) return true; if (!position_is_reachable(rtarget[X_AXIS], rtarget[Y_AXIS])) return true;
// Get the cartesian distances moved in XYZE // Get the cartesian distances moved in XYZE
const float difference[XYZE] = { const float difference[XYZE] = {
ltarget[X_AXIS] - current_position[X_AXIS], rtarget[X_AXIS] - current_position[X_AXIS],
ltarget[Y_AXIS] - current_position[Y_AXIS], rtarget[Y_AXIS] - current_position[Y_AXIS],
ltarget[Z_AXIS] - current_position[Z_AXIS], rtarget[Z_AXIS] - current_position[Z_AXIS],
ltarget[E_AXIS] - current_position[E_AXIS] rtarget[E_AXIS] - current_position[E_AXIS]
}; };
// Get the linear distance in XYZ // Get the linear distance in XYZ
@ -12707,9 +12694,9 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
oldB = stepper.get_axis_position_degrees(B_AXIS); oldB = stepper.get_axis_position_degrees(B_AXIS);
#endif #endif
// Get the logical current position as starting point // Get the raw current position as starting point
float logical[XYZE]; float raw[XYZE];
COPY(logical, current_position); COPY(raw, current_position);
// Drop one segment so the last move is to the exact target. // Drop one segment so the last move is to the exact target.
// If there's only 1 segment, loops will be skipped entirely. // If there's only 1 segment, loops will be skipped entirely.
@ -12717,25 +12704,25 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
// Calculate and execute the segments // Calculate and execute the segments
for (uint16_t s = segments + 1; --s;) { for (uint16_t s = segments + 1; --s;) {
LOOP_XYZE(i) logical[i] += segment_distance[i]; LOOP_XYZE(i) raw[i] += segment_distance[i];
#if ENABLED(DELTA) #if ENABLED(DELTA)
DELTA_LOGICAL_IK(); // Delta can inline its kinematics DELTA_RAW_IK(); // Delta can inline its kinematics
#else #else
inverse_kinematics(logical); inverse_kinematics(raw);
#endif #endif
ADJUST_DELTA(logical); // Adjust Z if bed leveling is enabled ADJUST_DELTA(raw); // Adjust Z if bed leveling is enabled
#if IS_SCARA && ENABLED(SCARA_FEEDRATE_SCALING) #if IS_SCARA && ENABLED(SCARA_FEEDRATE_SCALING)
// For SCARA scale the feed rate from mm/s to degrees/s // For SCARA scale the feed rate from mm/s to degrees/s
// Use ratio between the length of the move and the larger angle change // Use ratio between the length of the move and the larger angle change
const float adiff = abs(delta[A_AXIS] - oldA), const float adiff = abs(delta[A_AXIS] - oldA),
bdiff = abs(delta[B_AXIS] - oldB); bdiff = abs(delta[B_AXIS] - oldB);
planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], logical[E_AXIS], max(adiff, bdiff) * feed_factor, active_extruder); planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], max(adiff, bdiff) * feed_factor, active_extruder);
oldA = delta[A_AXIS]; oldA = delta[A_AXIS];
oldB = delta[B_AXIS]; oldB = delta[B_AXIS];
#else #else
planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], logical[E_AXIS], _feedrate_mm_s, active_extruder); planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], _feedrate_mm_s, active_extruder);
#endif #endif
} }
@ -12745,13 +12732,13 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
#if IS_SCARA && ENABLED(SCARA_FEEDRATE_SCALING) #if IS_SCARA && ENABLED(SCARA_FEEDRATE_SCALING)
// For SCARA scale the feed rate from mm/s to degrees/s // For SCARA scale the feed rate from mm/s to degrees/s
// With segments > 1 length is 1 segment, otherwise total length // With segments > 1 length is 1 segment, otherwise total length
inverse_kinematics(ltarget); inverse_kinematics(rtarget);
ADJUST_DELTA(ltarget); ADJUST_DELTA(rtarget);
const float adiff = abs(delta[A_AXIS] - oldA), const float adiff = abs(delta[A_AXIS] - oldA),
bdiff = abs(delta[B_AXIS] - oldB); bdiff = abs(delta[B_AXIS] - oldB);
planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], logical[E_AXIS], max(adiff, bdiff) * feed_factor, active_extruder); planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], max(adiff, bdiff) * feed_factor, active_extruder);
#else #else
planner.buffer_line_kinematic(ltarget, _feedrate_mm_s, active_extruder); planner.buffer_line_kinematic(rtarget, _feedrate_mm_s, active_extruder);
#endif #endif
return false; return false;
@ -12832,13 +12819,13 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
if (active_extruder == 0) { if (active_extruder == 0) {
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) { if (DEBUGGING(LEVELING)) {
SERIAL_ECHOPAIR("Set planner X", LOGICAL_X_POSITION(inactive_extruder_x_pos)); SERIAL_ECHOPAIR("Set planner X", inactive_extruder_x_pos);
SERIAL_ECHOLNPAIR(" ... Line to X", current_position[X_AXIS] + duplicate_extruder_x_offset); SERIAL_ECHOLNPAIR(" ... Line to X", current_position[X_AXIS] + duplicate_extruder_x_offset);
} }
#endif #endif
// move duplicate extruder into correct duplication position. // move duplicate extruder into correct duplication position.
planner.set_position_mm( planner.set_position_mm(
LOGICAL_X_POSITION(inactive_extruder_x_pos), inactive_extruder_x_pos,
current_position[Y_AXIS], current_position[Y_AXIS],
current_position[Z_AXIS], current_position[Z_AXIS],
current_position[E_AXIS] current_position[E_AXIS]
@ -12932,7 +12919,7 @@ void prepare_move_to_destination() {
* options for G2/G3 arc generation. In future these options may be GCode tunable. * options for G2/G3 arc generation. In future these options may be GCode tunable.
*/ */
void plan_arc( void plan_arc(
float logical[XYZE], // Destination position float raw[XYZE], // Destination position
float *offset, // Center of rotation relative to current_position float *offset, // Center of rotation relative to current_position
uint8_t clockwise // Clockwise? uint8_t clockwise // Clockwise?
) { ) {
@ -12953,10 +12940,10 @@ void prepare_move_to_destination() {
const float radius = HYPOT(r_P, r_Q), const float radius = HYPOT(r_P, r_Q),
center_P = current_position[p_axis] - r_P, center_P = current_position[p_axis] - r_P,
center_Q = current_position[q_axis] - r_Q, center_Q = current_position[q_axis] - r_Q,
rt_X = logical[p_axis] - center_P, rt_X = raw[p_axis] - center_P,
rt_Y = logical[q_axis] - center_Q, rt_Y = raw[q_axis] - center_Q,
linear_travel = logical[l_axis] - current_position[l_axis], linear_travel = raw[l_axis] - current_position[l_axis],
extruder_travel = logical[E_AXIS] - current_position[E_AXIS]; extruder_travel = raw[E_AXIS] - current_position[E_AXIS];
// CCW angle of rotation between position and target from the circle center. Only one atan2() trig computation required. // CCW angle of rotation between position and target from the circle center. Only one atan2() trig computation required.
float angular_travel = ATAN2(r_P * rt_Y - r_Q * rt_X, r_P * rt_X + r_Q * rt_Y); float angular_travel = ATAN2(r_P * rt_Y - r_Q * rt_X, r_P * rt_X + r_Q * rt_Y);
@ -12964,7 +12951,7 @@ void prepare_move_to_destination() {
if (clockwise) angular_travel -= RADIANS(360); if (clockwise) angular_travel -= RADIANS(360);
// Make a circle if the angular rotation is 0 and the target is current position // Make a circle if the angular rotation is 0 and the target is current position
if (angular_travel == 0 && current_position[p_axis] == logical[p_axis] && current_position[q_axis] == logical[q_axis]) if (angular_travel == 0 && current_position[p_axis] == raw[p_axis] && current_position[q_axis] == raw[q_axis])
angular_travel = RADIANS(360); angular_travel = RADIANS(360);
const float mm_of_travel = HYPOT(angular_travel * radius, FABS(linear_travel)); const float mm_of_travel = HYPOT(angular_travel * radius, FABS(linear_travel));
@ -13064,7 +13051,7 @@ void prepare_move_to_destination() {
} }
// Ensure last segment arrives at target location. // Ensure last segment arrives at target location.
planner.buffer_line_kinematic(logical, fr_mm_s, active_extruder); planner.buffer_line_kinematic(raw, fr_mm_s, active_extruder);
// As far as the parser is concerned, the position is now == target. In reality the // As far as the parser is concerned, the position is now == target. In reality the
// motion control system might still be processing the action and the real tool position // motion control system might still be processing the action and the real tool position
@ -13164,12 +13151,12 @@ void prepare_move_to_destination() {
* Maths and first version by QHARLEY. * Maths and first version by QHARLEY.
* Integrated into Marlin and slightly restructured by Joachim Cerny. * Integrated into Marlin and slightly restructured by Joachim Cerny.
*/ */
void inverse_kinematics(const float logical[XYZ]) { void inverse_kinematics(const float raw[XYZ]) {
static float C2, S2, SK1, SK2, THETA, PSI; static float C2, S2, SK1, SK2, THETA, PSI;
float sx = RAW_X_POSITION(logical[X_AXIS]) - SCARA_OFFSET_X, // Translate SCARA to standard X Y float sx = raw[X_AXIS] - SCARA_OFFSET_X, // Translate SCARA to standard X Y
sy = RAW_Y_POSITION(logical[Y_AXIS]) - SCARA_OFFSET_Y; // With scaling factor. sy = raw[Y_AXIS] - SCARA_OFFSET_Y; // With scaling factor.
if (L1 == L2) if (L1 == L2)
C2 = HYPOT2(sx, sy) / L1_2_2 - 1; C2 = HYPOT2(sx, sy) / L1_2_2 - 1;
@ -13192,10 +13179,10 @@ void prepare_move_to_destination() {
delta[A_AXIS] = DEGREES(THETA); // theta is support arm angle delta[A_AXIS] = DEGREES(THETA); // theta is support arm angle
delta[B_AXIS] = DEGREES(THETA + PSI); // equal to sub arm angle (inverted motor) delta[B_AXIS] = DEGREES(THETA + PSI); // equal to sub arm angle (inverted motor)
delta[C_AXIS] = logical[Z_AXIS]; delta[C_AXIS] = raw[Z_AXIS];
/* /*
DEBUG_POS("SCARA IK", logical); DEBUG_POS("SCARA IK", raw);
DEBUG_POS("SCARA IK", delta); DEBUG_POS("SCARA IK", delta);
SERIAL_ECHOPAIR(" SCARA (x,y) ", sx); SERIAL_ECHOPAIR(" SCARA (x,y) ", sx);
SERIAL_ECHOPAIR(",", sy); SERIAL_ECHOPAIR(",", sy);

@ -112,7 +112,7 @@ float Planner::min_feedrate_mm_s,
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
float Planner::z_fade_height, // Initialized by settings.load() float Planner::z_fade_height, // Initialized by settings.load()
Planner::inverse_z_fade_height, Planner::inverse_z_fade_height,
Planner::last_raw_lz; Planner::last_fade_z;
#endif #endif
#endif #endif
@ -523,14 +523,14 @@ void Planner::check_axes_activity() {
#if PLANNER_LEVELING #if PLANNER_LEVELING
/** /**
* lx, ly, lz - logical (cartesian, not delta) positions in mm * rx, ry, rz - cartesian position in mm
*/ */
void Planner::apply_leveling(float &lx, float &ly, float &lz) { void Planner::apply_leveling(float &rx, float &ry, float &rz) {
if (!leveling_active) return; if (!leveling_active) return;
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
const float fade_scaling_factor = fade_scaling_factor_for_z(lz); const float fade_scaling_factor = fade_scaling_factor_for_z(rz);
if (!fade_scaling_factor) return; if (!fade_scaling_factor) return;
#else #else
constexpr float fade_scaling_factor = 1.0; constexpr float fade_scaling_factor = 1.0;
@ -538,11 +538,11 @@ void Planner::check_axes_activity() {
#if ENABLED(AUTO_BED_LEVELING_UBL) #if ENABLED(AUTO_BED_LEVELING_UBL)
lz += ubl.get_z_correction(lx, ly) * fade_scaling_factor; rz += ubl.get_z_correction(rx, ry) * fade_scaling_factor;
#elif ENABLED(MESH_BED_LEVELING) #elif ENABLED(MESH_BED_LEVELING)
lz += mbl.get_z(RAW_X_POSITION(lx), RAW_Y_POSITION(ly) rz += mbl.get_z(rx, ry
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
, fade_scaling_factor , fade_scaling_factor
#endif #endif
@ -552,40 +552,38 @@ void Planner::check_axes_activity() {
UNUSED(fade_scaling_factor); UNUSED(fade_scaling_factor);
float dx = RAW_X_POSITION(lx) - (X_TILT_FULCRUM), float dx = rx - (X_TILT_FULCRUM),
dy = RAW_Y_POSITION(ly) - (Y_TILT_FULCRUM), dy = ry - (Y_TILT_FULCRUM);
dz = RAW_Z_POSITION(lz);
apply_rotation_xyz(bed_level_matrix, dx, dy, dz); apply_rotation_xyz(bed_level_matrix, dx, dy, rz);
lx = LOGICAL_X_POSITION(dx + X_TILT_FULCRUM); rx = dx + X_TILT_FULCRUM;
ly = LOGICAL_Y_POSITION(dy + Y_TILT_FULCRUM); ry = dy + Y_TILT_FULCRUM;
lz = LOGICAL_Z_POSITION(dz);
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR) #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
float tmp[XYZ] = { lx, ly, 0 }; float tmp[XYZ] = { rx, ry, 0 };
lz += bilinear_z_offset(tmp) * fade_scaling_factor; rz += bilinear_z_offset(tmp) * fade_scaling_factor;
#endif #endif
} }
void Planner::unapply_leveling(float logical[XYZ]) { void Planner::unapply_leveling(float raw[XYZ]) {
#if HAS_LEVELING #if HAS_LEVELING
if (!leveling_active) return; if (!leveling_active) return;
#endif #endif
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
if (!leveling_active_at_z(logical[Z_AXIS])) return; if (!leveling_active_at_z(raw[Z_AXIS])) return;
#endif #endif
#if ENABLED(AUTO_BED_LEVELING_UBL) #if ENABLED(AUTO_BED_LEVELING_UBL)
const float z_physical = RAW_Z_POSITION(logical[Z_AXIS]), const float z_physical = raw[Z_AXIS],
z_correct = ubl.get_z_correction(logical[X_AXIS], logical[Y_AXIS]), z_correct = ubl.get_z_correction(raw[X_AXIS], raw[Y_AXIS]),
z_virtual = z_physical - z_correct; z_virtual = z_physical - z_correct;
float z_logical = LOGICAL_Z_POSITION(z_virtual); float z_raw = z_virtual;
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
@ -598,15 +596,15 @@ void Planner::check_axes_activity() {
// so L=(P-M)/(1-M/H) for L<H // so L=(P-M)/(1-M/H) for L<H
if (planner.z_fade_height) { if (planner.z_fade_height) {
if (z_logical >= planner.z_fade_height) if (z_raw >= planner.z_fade_height)
z_logical = LOGICAL_Z_POSITION(z_physical); z_raw = z_physical;
else else
z_logical /= 1.0 - z_correct * planner.inverse_z_fade_height; z_raw /= 1.0 - z_correct * planner.inverse_z_fade_height;
} }
#endif // ENABLE_LEVELING_FADE_HEIGHT #endif // ENABLE_LEVELING_FADE_HEIGHT
logical[Z_AXIS] = z_logical; raw[Z_AXIS] = z_raw;
return; // don't fall thru to other ENABLE_LEVELING_FADE_HEIGHT logic return; // don't fall thru to other ENABLE_LEVELING_FADE_HEIGHT logic
@ -616,10 +614,10 @@ void Planner::check_axes_activity() {
if (leveling_active) { if (leveling_active) {
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
const float c = mbl.get_z(RAW_X_POSITION(logical[X_AXIS]), RAW_Y_POSITION(logical[Y_AXIS]), 1.0); const float c = mbl.get_z(raw[X_AXIS], raw[Y_AXIS], 1.0);
logical[Z_AXIS] = (z_fade_height * (RAW_Z_POSITION(logical[Z_AXIS]) - c)) / (z_fade_height - c); raw[Z_AXIS] = (z_fade_height * (raw[Z_AXIS]) - c) / (z_fade_height - c);
#else #else
logical[Z_AXIS] -= mbl.get_z(RAW_X_POSITION(logical[X_AXIS]), RAW_Y_POSITION(logical[Y_AXIS])); raw[Z_AXIS] -= mbl.get_z(raw[X_AXIS], raw[Y_AXIS]);
#endif #endif
} }
@ -627,23 +625,21 @@ void Planner::check_axes_activity() {
matrix_3x3 inverse = matrix_3x3::transpose(bed_level_matrix); matrix_3x3 inverse = matrix_3x3::transpose(bed_level_matrix);
float dx = RAW_X_POSITION(logical[X_AXIS]) - (X_TILT_FULCRUM), float dx = raw[X_AXIS] - (X_TILT_FULCRUM),
dy = RAW_Y_POSITION(logical[Y_AXIS]) - (Y_TILT_FULCRUM), dy = raw[Y_AXIS] - (Y_TILT_FULCRUM);
dz = RAW_Z_POSITION(logical[Z_AXIS]);
apply_rotation_xyz(inverse, dx, dy, dz); apply_rotation_xyz(inverse, dx, dy, raw[Z_AXIS]);
logical[X_AXIS] = LOGICAL_X_POSITION(dx + X_TILT_FULCRUM); raw[X_AXIS] = dx + X_TILT_FULCRUM;
logical[Y_AXIS] = LOGICAL_Y_POSITION(dy + Y_TILT_FULCRUM); raw[Y_AXIS] = dy + Y_TILT_FULCRUM;
logical[Z_AXIS] = LOGICAL_Z_POSITION(dz);
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR) #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
const float c = bilinear_z_offset(logical); const float c = bilinear_z_offset(raw);
logical[Z_AXIS] = (z_fade_height * (RAW_Z_POSITION(logical[Z_AXIS]) - c)) / (z_fade_height - c); raw[Z_AXIS] = (z_fade_height * (raw[Z_AXIS]) - c) / (z_fade_height - c);
#else #else
logical[Z_AXIS] -= bilinear_z_offset(logical); raw[Z_AXIS] -= bilinear_z_offset(raw);
#endif #endif
#endif #endif

@ -192,7 +192,7 @@ class Planner {
static uint32_t cutoff_long; static uint32_t cutoff_long;
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
static float last_raw_lz; static float last_fade_z;
#endif #endif
#if ENABLED(DISABLE_INACTIVE_EXTRUDER) #if ENABLED(DISABLE_INACTIVE_EXTRUDER)
@ -255,21 +255,20 @@ class Planner {
* Returns 1.0 if planner.z_fade_height is 0.0. * Returns 1.0 if planner.z_fade_height is 0.0.
* Returns 0.0 if Z is past the specified 'Fade Height'. * Returns 0.0 if Z is past the specified 'Fade Height'.
*/ */
inline static float fade_scaling_factor_for_z(const float &lz) { inline static float fade_scaling_factor_for_z(const float &rz) {
static float z_fade_factor = 1.0; static float z_fade_factor = 1.0;
if (z_fade_height) { if (z_fade_height) {
const float raw_lz = RAW_Z_POSITION(lz); if (rz >= z_fade_height) return 0.0;
if (raw_lz >= z_fade_height) return 0.0; if (last_fade_z != rz) {
if (last_raw_lz != raw_lz) { last_fade_z = rz;
last_raw_lz = raw_lz; z_fade_factor = 1.0 - rz * inverse_z_fade_height;
z_fade_factor = 1.0 - raw_lz * inverse_z_fade_height;
} }
return z_fade_factor; return z_fade_factor;
} }
return 1.0; return 1.0;
} }
FORCE_INLINE static void force_fade_recalc() { last_raw_lz = -999.999; } FORCE_INLINE static void force_fade_recalc() { last_fade_z = -999.999; }
FORCE_INLINE static void set_z_fade_height(const float &zfh) { FORCE_INLINE static void set_z_fade_height(const float &zfh) {
z_fade_height = zfh > 0 ? zfh : 0; z_fade_height = zfh > 0 ? zfh : 0;
@ -277,40 +276,40 @@ class Planner {
force_fade_recalc(); force_fade_recalc();
} }
FORCE_INLINE static bool leveling_active_at_z(const float &lz) { FORCE_INLINE static bool leveling_active_at_z(const float &rz) {
return !z_fade_height || RAW_Z_POSITION(lz) < z_fade_height; return !z_fade_height || rz < z_fade_height;
} }
#else #else
FORCE_INLINE static float fade_scaling_factor_for_z(const float &lz) { FORCE_INLINE static float fade_scaling_factor_for_z(const float &rz) {
UNUSED(lz); UNUSED(rz);
return 1.0; return 1.0;
} }
FORCE_INLINE static bool leveling_active_at_z(const float &lz) { UNUSED(lz); return true; } FORCE_INLINE static bool leveling_active_at_z(const float &rz) { UNUSED(rz); return true; }
#endif #endif
#if PLANNER_LEVELING #if PLANNER_LEVELING
#define ARG_X float lx #define ARG_X float rx
#define ARG_Y float ly #define ARG_Y float ry
#define ARG_Z float lz #define ARG_Z float rz
/** /**
* Apply leveling to transform a cartesian position * Apply leveling to transform a cartesian position
* as it will be given to the planner and steppers. * as it will be given to the planner and steppers.
*/ */
static void apply_leveling(float &lx, float &ly, float &lz); static void apply_leveling(float &rx, float &ry, float &rz);
static void apply_leveling(float logical[XYZ]) { apply_leveling(logical[X_AXIS], logical[Y_AXIS], logical[Z_AXIS]); } static void apply_leveling(float raw[XYZ]) { apply_leveling(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
static void unapply_leveling(float logical[XYZ]); static void unapply_leveling(float raw[XYZ]);
#else #else
#define ARG_X const float &lx #define ARG_X const float &rx
#define ARG_Y const float &ly #define ARG_Y const float &ry
#define ARG_Z const float &lz #define ARG_Z const float &rz
#endif #endif
@ -337,15 +336,15 @@ class Planner {
* Kinematic machines should call buffer_line_kinematic (for leveled moves). * Kinematic machines should call buffer_line_kinematic (for leveled moves).
* (Cartesians may also call buffer_line_kinematic.) * (Cartesians may also call buffer_line_kinematic.)
* *
* lx,ly,lz,e - target position in mm or degrees * rx,ry,rz,e - target position in mm or degrees
* fr_mm_s - (target) speed of the move (mm/s) * fr_mm_s - (target) speed of the move (mm/s)
* extruder - target extruder * extruder - target extruder
*/ */
static FORCE_INLINE void buffer_line(ARG_X, ARG_Y, ARG_Z, const float &e, const float &fr_mm_s, const uint8_t extruder) { static FORCE_INLINE void buffer_line(ARG_X, ARG_Y, ARG_Z, const float &e, const float &fr_mm_s, const uint8_t extruder) {
#if PLANNER_LEVELING && IS_CARTESIAN #if PLANNER_LEVELING && IS_CARTESIAN
apply_leveling(lx, ly, lz); apply_leveling(rx, ry, rz);
#endif #endif
_buffer_line(lx, ly, lz, e, fr_mm_s, extruder); _buffer_line(rx, ry, rz, e, fr_mm_s, extruder);
} }
/** /**
@ -353,22 +352,22 @@ class Planner {
* The target is cartesian, it's translated to delta/scara if * The target is cartesian, it's translated to delta/scara if
* needed. * needed.
* *
* ltarget - x,y,z,e CARTESIAN target in mm * rtarget - x,y,z,e CARTESIAN target in mm
* fr_mm_s - (target) speed of the move (mm/s) * fr_mm_s - (target) speed of the move (mm/s)
* extruder - target extruder * extruder - target extruder
*/ */
static FORCE_INLINE void buffer_line_kinematic(const float ltarget[XYZE], const float &fr_mm_s, const uint8_t extruder) { static FORCE_INLINE void buffer_line_kinematic(const float rtarget[XYZE], const float &fr_mm_s, const uint8_t extruder) {
#if PLANNER_LEVELING #if PLANNER_LEVELING
float lpos[XYZ] = { ltarget[X_AXIS], ltarget[Y_AXIS], ltarget[Z_AXIS] }; float lpos[XYZ] = { rtarget[X_AXIS], rtarget[Y_AXIS], rtarget[Z_AXIS] };
apply_leveling(lpos); apply_leveling(lpos);
#else #else
const float * const lpos = ltarget; const float * const lpos = rtarget;
#endif #endif
#if IS_KINEMATIC #if IS_KINEMATIC
inverse_kinematics(lpos); inverse_kinematics(lpos);
_buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], ltarget[E_AXIS], fr_mm_s, extruder); _buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], rtarget[E_AXIS], fr_mm_s, extruder);
#else #else
_buffer_line(lpos[X_AXIS], lpos[Y_AXIS], lpos[Z_AXIS], ltarget[E_AXIS], fr_mm_s, extruder); _buffer_line(lpos[X_AXIS], lpos[Y_AXIS], lpos[Z_AXIS], rtarget[E_AXIS], fr_mm_s, extruder);
#endif #endif
} }
@ -383,9 +382,9 @@ class Planner {
*/ */
static FORCE_INLINE void set_position_mm(ARG_X, ARG_Y, ARG_Z, const float &e) { static FORCE_INLINE void set_position_mm(ARG_X, ARG_Y, ARG_Z, const float &e) {
#if PLANNER_LEVELING && IS_CARTESIAN #if PLANNER_LEVELING && IS_CARTESIAN
apply_leveling(lx, ly, lz); apply_leveling(rx, ry, rz);
#endif #endif
_set_position_mm(lx, ly, lz, e); _set_position_mm(rx, ry, rz, e);
} }
static void set_position_mm_kinematic(const float position[NUM_AXIS]); static void set_position_mm_kinematic(const float position[NUM_AXIS]);
static void set_position_mm(const AxisEnum axis, const float &v); static void set_position_mm(const AxisEnum axis, const float &v);

@ -114,14 +114,14 @@
static bool g29_parameter_parsing(); static bool g29_parameter_parsing();
static void find_mean_mesh_height(); static void find_mean_mesh_height();
static void shift_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 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_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 tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map);
static void g29_what_command(); static void g29_what_command();
static void g29_eeprom_dump(); static void g29_eeprom_dump();
static void g29_compare_current_mesh_to_stored_mesh(); 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 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(); static void smart_fill_mesh();
@ -244,10 +244,10 @@
* z_correction_for_x_on_horizontal_mesh_line is an optimization for * 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. * 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 (!WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 2) || !WITHIN(yi, 0, GRID_MAX_POINTS_Y - 1)) {
serialprintPGM( !WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) ? PSTR("x1l_i") : PSTR("yi") ); 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(",x1_i=", x1_i);
SERIAL_ECHOPAIR(",yi=", yi); SERIAL_ECHOPAIR(",yi=", yi);
SERIAL_CHAR(')'); SERIAL_CHAR(')');
@ -255,7 +255,7 @@
return NAN; 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]; z1 = z_values[x1_i][yi];
return z1 + xratio * (z_values[x1_i + 1][yi] - z1); return z1 + xratio * (z_values[x1_i + 1][yi] - z1);
@ -264,10 +264,10 @@
// //
// See comments above for z_correction_for_x_on_horizontal_mesh_line // 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 (!WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(y1_i, 0, GRID_MAX_POINTS_Y - 2)) {
serialprintPGM( !WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) ? PSTR("xi") : PSTR("yl_i") ); 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(", xi=", xi);
SERIAL_ECHOPAIR(", y1_i=", y1_i); SERIAL_ECHOPAIR(", y1_i=", y1_i);
SERIAL_CHAR(')'); SERIAL_CHAR(')');
@ -275,7 +275,7 @@
return NAN; 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]; z1 = z_values[xi][y1_i];
return z1 + yratio * (z_values[xi][y1_i + 1] - z1); return z1 + yratio * (z_values[xi][y1_i + 1] - z1);
@ -287,14 +287,14 @@
* Z-Height at both ends. Then it does a linear interpolation of these heights based * Z-Height at both ends. Then it does a linear interpolation of these heights based
* on the Y position within the cell. * on the Y position within the cell.
*/ */
static float get_z_correction(const float &lx0, const float &ly0) { static float get_z_correction(const float &rx0, const float &ry0) {
const int8_t cx = get_cell_index_x(RAW_X_POSITION(lx0)), const int8_t cx = get_cell_index_x(rx0),
cy = get_cell_index_y(RAW_Y_POSITION(ly0)); cy = get_cell_index_y(ry0);
if (!WITHIN(cx, 0, GRID_MAX_POINTS_X - 2) || !WITHIN(cy, 0, GRID_MAX_POINTS_Y - 2)) { 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("? in get_z_correction(rx0=", rx0);
SERIAL_ECHOPAIR(", ly0=", ly0); SERIAL_ECHOPAIR(", ry0=", ry0);
SERIAL_CHAR(')'); SERIAL_CHAR(')');
SERIAL_EOL(); SERIAL_EOL();
@ -305,23 +305,23 @@
return NAN; 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), z_values[cx][cy],
mesh_index_to_xpos(cx + 1), z_values[cx + 1][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), z_values[cx][cy + 1],
mesh_index_to_xpos(cx + 1), z_values[cx + 1][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), z1,
mesh_index_to_ypos(cy + 1), z2); mesh_index_to_ypos(cy + 1), z2);
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(MESH_ADJUST)) { if (DEBUGGING(MESH_ADJUST)) {
SERIAL_ECHOPAIR(" raw get_z_correction(", lx0); SERIAL_ECHOPAIR(" raw get_z_correction(", rx0);
SERIAL_CHAR(','); SERIAL_CHAR(',');
SERIAL_ECHO(ly0); SERIAL_ECHO(ry0);
SERIAL_ECHOPGM(") = "); SERIAL_ECHOPGM(") = ");
SERIAL_ECHO_F(z0, 6); SERIAL_ECHO_F(z0, 6);
} }
@ -343,9 +343,9 @@
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(MESH_ADJUST)) { 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_CHAR(',');
SERIAL_ECHO(ly0); SERIAL_ECHO(ry0);
SERIAL_CHAR(')'); SERIAL_CHAR(')');
SERIAL_EOL(); SERIAL_EOL();
} }
@ -362,7 +362,7 @@
return i < GRID_MAX_POINTS_Y ? pgm_read_float(&_mesh_index_to_ypos[i]) : MESH_MIN_Y + i * (MESH_Y_DIST); 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); static void line_to_destination_cartesian(const float &fr, uint8_t e);
}; // class unified_bed_leveling }; // class unified_bed_leveling

@ -51,7 +51,7 @@
extern float meshedit_done; extern float meshedit_done;
extern long babysteps_done; extern long babysteps_done;
extern float probe_pt(const float &lx, const float &ly, const bool, const uint8_t, const bool=true); extern float probe_pt(const float &rx, const float &ry, const bool, const uint8_t, const bool=true);
extern bool set_probe_deployed(bool); extern bool set_probe_deployed(bool);
extern void set_bed_leveling_enabled(bool); extern void set_bed_leveling_enabled(bool);
typedef void (*screenFunc_t)(); typedef void (*screenFunc_t)();
@ -392,11 +392,11 @@
restore_ubl_active_state_and_leave(); restore_ubl_active_state_and_leave();
} }
else { // grid_size == 0 : A 3-Point leveling has been requested 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)) { 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)) 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 if (isnan(z1) || isnan(z2) || isnan(z3)) { // probe_pt will return NAN if unreachable
@ -410,9 +410,9 @@
// its height is.) // its height is.)
save_ubl_active_state_and_disable(); 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 */ ; z1 -= get_z_correction(UBL_PROBE_PT_1_X, 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 */ ; z2 -= get_z_correction(UBL_PROBE_PT_2_X, 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 */ ; 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))); 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); tilt_mesh_based_on_3pts(z1, z2, z3);
@ -496,7 +496,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."); SERIAL_PROTOCOLLNPGM("XY outside printable radius.");
return; return;
} }
@ -640,8 +640,8 @@
SERIAL_ECHOPAIR(" J ", y); SERIAL_ECHOPAIR(" J ", y);
SERIAL_ECHOPGM(" Z "); SERIAL_ECHOPGM(" Z ");
SERIAL_ECHO_F(z_values[x][y], 6); SERIAL_ECHO_F(z_values[x][y], 6);
SERIAL_ECHOPAIR(" ; X ", LOGICAL_X_POSITION(mesh_index_to_xpos(x))); SERIAL_ECHOPAIR(" ; X ", mesh_index_to_xpos(x));
SERIAL_ECHOPAIR(", Y ", LOGICAL_Y_POSITION(mesh_index_to_ypos(y))); SERIAL_ECHOPAIR(", Y ", mesh_index_to_ypos(y));
SERIAL_EOL(); SERIAL_EOL();
} }
return; return;
@ -732,7 +732,7 @@
* Probe all invalidated locations of the mesh that can be reached by the 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. * 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; mesh_index_pair location;
has_control_of_lcd_panel = true; has_control_of_lcd_panel = true;
@ -755,13 +755,13 @@
} }
#endif #endif
location = find_closest_mesh_point_of_type(INVALID, lx, ly, USE_PROBE_AS_REFERENCE, NULL, close_or_far); location = find_closest_mesh_point_of_type(INVALID, rx, ry, USE_PROBE_AS_REFERENCE, NULL, close_or_far);
if (location.x_index >= 0) { // mesh point found and is reachable by probe if (location.x_index >= 0) { // mesh point found and is reachable by probe
const float rawx = mesh_index_to_xpos(location.x_index), const float rawx = mesh_index_to_xpos(location.x_index),
rawy = mesh_index_to_ypos(location.y_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; z_values[location.x_index][location.y_index] = measured_z;
} }
@ -773,8 +773,8 @@
restore_ubl_active_state_and_leave(); restore_ubl_active_state_and_leave();
do_blocking_move_to_xy( do_blocking_move_to_xy(
constrain(lx - (X_PROBE_OFFSET_FROM_EXTRUDER), MESH_MIN_X, MESH_MAX_X), constrain(rx - (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(ry - (Y_PROBE_OFFSET_FROM_EXTRUDER), MESH_MIN_Y, MESH_MAX_Y)
); );
} }
@ -946,28 +946,26 @@
return thickness; 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; 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 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_z(Z_CLEARANCE_BETWEEN_PROBES);
do_blocking_move_to_xy(lx, ly); do_blocking_move_to_xy(rx, ry);
lcd_return_to_status(); lcd_return_to_status();
mesh_index_pair location; mesh_index_pair location;
do { do {
location = find_closest_mesh_point_of_type(INVALID, lx, ly, USE_NOZZLE_AS_REFERENCE, NULL, false); location = find_closest_mesh_point_of_type(INVALID, rx, ry, USE_NOZZLE_AS_REFERENCE, NULL, false);
// It doesn't matter if the probe can't reach the NAN location. This is a manual probe. // 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; if (location.x_index < 0 && location.y_index < 0) continue;
const float rawx = mesh_index_to_xpos(location.x_index), const float xProbe = mesh_index_to_xpos(location.x_index),
rawy = mesh_index_to_ypos(location.y_index), yProbe = mesh_index_to_ypos(location.y_index);
xProbe = LOGICAL_X_POSITION(rawx),
yProbe = LOGICAL_Y_POSITION(rawy);
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); do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
@ -1031,7 +1029,7 @@
restore_ubl_active_state_and_leave(); restore_ubl_active_state_and_leave();
KEEPALIVE_STATE(IN_HANDLER); KEEPALIVE_STATE(IN_HANDLER);
do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); 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 #endif // NEWPANEL
@ -1103,8 +1101,8 @@
} }
// If X or Y are not valid, use center of the bed values // 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(g29_x_pos, X_MIN_BED, X_MAX_BED)) g29_x_pos = 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_y_pos, Y_MIN_BED, Y_MAX_BED)) g29_y_pos = Y_CENTER;
if (err_flag) return UBL_ERR; if (err_flag) return UBL_ERR;
@ -1230,7 +1228,7 @@
SERIAL_PROTOCOLPGM("X-Axis Mesh Points at: "); SERIAL_PROTOCOLPGM("X-Axis Mesh Points at: ");
for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(mesh_index_to_xpos(i)), 3); SERIAL_PROTOCOL_F(mesh_index_to_xpos(i), 3);
SERIAL_PROTOCOLPGM(" "); SERIAL_PROTOCOLPGM(" ");
safe_delay(25); safe_delay(25);
} }
@ -1238,7 +1236,7 @@
SERIAL_PROTOCOLPGM("Y-Axis Mesh Points at: "); SERIAL_PROTOCOLPGM("Y-Axis Mesh Points at: ");
for (uint8_t i = 0; i < GRID_MAX_POINTS_Y; i++) { for (uint8_t i = 0; i < GRID_MAX_POINTS_Y; i++) {
SERIAL_PROTOCOL_F(LOGICAL_Y_POSITION(mesh_index_to_ypos(i)), 3); SERIAL_PROTOCOL_F(mesh_index_to_ypos(i), 3);
SERIAL_PROTOCOLPGM(" "); SERIAL_PROTOCOLPGM(" ");
safe_delay(25); safe_delay(25);
} }
@ -1342,13 +1340,13 @@
z_values[x][y] -= tmp_z_values[x][y]; z_values[x][y] -= tmp_z_values[x][y];
} }
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, unsigned int bits[16], const bool far_flag) { 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, unsigned int bits[16], const bool far_flag) {
mesh_index_pair out_mesh; mesh_index_pair out_mesh;
out_mesh.x_index = out_mesh.y_index = -1; out_mesh.x_index = out_mesh.y_index = -1;
// Get our reference position. Either the nozzle or probe location. // 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), const float px = rx - (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); py = ry - (probe_as_reference == USE_PROBE_AS_REFERENCE ? Y_PROBE_OFFSET_FROM_EXTRUDER : 0);
float best_so_far = far_flag ? -99999.99 : 99999.99; float best_so_far = far_flag ? -99999.99 : 99999.99;
@ -1361,7 +1359,6 @@
) { ) {
// We only get here if we found a Mesh Point of the specified type // 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), const float mx = mesh_index_to_xpos(i),
my = mesh_index_to_ypos(j); my = mesh_index_to_ypos(j);
@ -1369,7 +1366,7 @@
// Also for round beds, there are grid points outside the bed the nozzle can't reach. // 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). // 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; continue;
// Reachable. Check if it's the best_so_far location to the nozzle. // Reachable. Check if it's the best_so_far location to the nozzle.
@ -1397,7 +1394,7 @@
else else
// factor in the distance from the current location for the normal case // factor in the distance from the current location for the normal case
// so the nozzle isn't running all over the bed. // 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 far_flag, look for farthest point // if far_flag, look for farthest point
if (far_flag == (distance > best_so_far) && distance != best_so_far) { if (far_flag == (distance > best_so_far) && distance != best_so_far) {
@ -1415,7 +1412,7 @@
#if ENABLED(NEWPANEL) #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 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. g29_repetition_cnt = 1; // do exactly one mesh location. Otherwise use what the parser decided.
@ -1430,7 +1427,7 @@
mesh_index_pair location; mesh_index_pair location;
if (!position_is_reachable_xy(lx, ly)) { if (!position_is_reachable(rx, ry)) {
SERIAL_PROTOCOLLNPGM("(X,Y) outside printable radius."); SERIAL_PROTOCOLLNPGM("(X,Y) outside printable radius.");
return; return;
} }
@ -1440,12 +1437,12 @@
LCD_MESSAGEPGM(MSG_UBL_FINE_TUNE_MESH); LCD_MESSAGEPGM(MSG_UBL_FINE_TUNE_MESH);
do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); 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]; uint16_t not_done[16];
memset(not_done, 0xFF, sizeof(not_done)); memset(not_done, 0xFF, sizeof(not_done));
do { do {
location = find_closest_mesh_point_of_type(SET_IN_BITMAP, lx, ly, USE_NOZZLE_AS_REFERENCE, not_done, false); location = find_closest_mesh_point_of_type(SET_IN_BITMAP, rx, ry, USE_NOZZLE_AS_REFERENCE, not_done, false);
if (location.x_index < 0) break; // stop when we can't find any more reachable points. if (location.x_index < 0) break; // stop when we can't find any more reachable points.
@ -1455,7 +1452,7 @@
const float rawx = mesh_index_to_xpos(location.x_index), const float rawx = mesh_index_to_xpos(location.x_index),
rawy = mesh_index_to_ypos(location.y_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; break;
float new_z = z_values[location.x_index][location.y_index]; float new_z = z_values[location.x_index][location.y_index];
@ -1464,7 +1461,7 @@
new_z = 0.0; 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_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 new_z = FLOOR(new_z * 1000.0) * 0.001; // Chop off digits after the 1000ths place
@ -1526,7 +1523,7 @@
restore_ubl_active_state_and_leave(); restore_ubl_active_state_and_leave();
do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); 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); LCD_MESSAGEPGM(MSG_UBL_DONE_EDITING_MESH);
SERIAL_ECHOLNPGM("Done Editing Mesh"); SERIAL_ECHOLNPGM("Done Editing Mesh");
@ -1610,10 +1607,10 @@
bool zig_zag = false; bool zig_zag = false;
for (uint8_t ix = 0; ix < g29_grid_size; ix++) { 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++) { 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); const float ry = 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 float measured_z = probe_pt(rx, ry, parser.seen('E'), g29_verbose_level); // TODO: Needs error handling
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) { if (DEBUGGING(LEVELING)) {
SERIAL_CHAR('('); SERIAL_CHAR('(');
@ -1622,17 +1619,17 @@
SERIAL_PROTOCOL_F(y, 7); SERIAL_PROTOCOL_F(y, 7);
SERIAL_ECHOPGM(") logical: "); SERIAL_ECHOPGM(") logical: ");
SERIAL_CHAR('('); SERIAL_CHAR('(');
SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(x), 7); SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(rx), 7);
SERIAL_CHAR(','); SERIAL_CHAR(',');
SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(y), 7); SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(ry), 7);
SERIAL_ECHOPGM(") measured: "); SERIAL_ECHOPGM(") measured: ");
SERIAL_PROTOCOL_F(measured_z, 7); SERIAL_PROTOCOL_F(measured_z, 7);
SERIAL_ECHOPGM(" correction: "); 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 #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 ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) { if (DEBUGGING(LEVELING)) {
@ -1642,7 +1639,7 @@
} }
#endif #endif
incremental_LSF(&lsf_results, x, y, measured_z); incremental_LSF(&lsf_results, rx, ry, measured_z);
} }
zig_zag ^= true; zig_zag ^= true;

@ -125,10 +125,10 @@
destination[E_AXIS] destination[E_AXIS]
}; };
const int cell_start_xi = get_cell_index_x(RAW_X_POSITION(start[X_AXIS])), const int cell_start_xi = get_cell_index_x(start[X_AXIS]),
cell_start_yi = get_cell_index_y(RAW_Y_POSITION(start[Y_AXIS])), cell_start_yi = get_cell_index_y(start[Y_AXIS]),
cell_dest_xi = get_cell_index_x(RAW_X_POSITION(end[X_AXIS])), cell_dest_xi = get_cell_index_x(end[X_AXIS]),
cell_dest_yi = get_cell_index_y(RAW_Y_POSITION(end[Y_AXIS])); cell_dest_yi = get_cell_index_y(end[Y_AXIS]);
if (g26_debug_flag) { if (g26_debug_flag) {
SERIAL_ECHOPAIR(" ubl.line_to_destination(xe=", end[X_AXIS]); SERIAL_ECHOPAIR(" ubl.line_to_destination(xe=", end[X_AXIS]);
@ -173,7 +173,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. * 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 * 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 ]), (z_values[cell_dest_xi + 1][cell_dest_yi ] - z_values[cell_dest_xi][cell_dest_yi ]),
@ -185,7 +185,7 @@
// we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we // 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. // 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; 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;
/** /**
@ -261,7 +261,7 @@
current_yi += down_flag; // Line is heading down, we just want to go to the bottom current_yi += down_flag; // Line is heading down, we just want to go to the bottom
while (current_yi != cell_dest_yi + down_flag) { while (current_yi != cell_dest_yi + down_flag) {
current_yi += dyi; 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 * if the slope of the line is infinite, we won't do the calculations
@ -282,7 +282,7 @@
*/ */
if (isnan(z0)) z0 = 0.0; if (isnan(z0)) z0 = 0.0;
const float y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi)); const float y = mesh_index_to_ypos(current_yi);
/** /**
* Without this check, it is possible for the algorithm to generate a zero length move in the case * Without this check, it is possible for the algorithm to generate a zero length move in the case
@ -331,7 +331,7 @@
// edge of this cell for the first move. // edge of this cell for the first move.
while (current_xi != cell_dest_xi + left_flag) { while (current_xi != cell_dest_xi + left_flag) {
current_xi += dxi; current_xi += dxi;
const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi)), const float next_mesh_line_x = mesh_index_to_xpos(current_xi),
y = m * next_mesh_line_x + c; // Calculate Y at the next X mesh line y = 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(y, current_xi, current_yi)
@ -346,7 +346,7 @@
*/ */
if (isnan(z0)) z0 = 0.0; if (isnan(z0)) z0 = 0.0;
const float x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi)); const float x = mesh_index_to_xpos(current_xi);
/** /**
* Without this check, it is possible for the algorithm to generate a zero length move in the case * Without this check, it is possible for the algorithm to generate a zero length move in the case
@ -396,8 +396,8 @@
while (xi_cnt > 0 || yi_cnt > 0) { while (xi_cnt > 0 || yi_cnt > 0) {
const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi + dxi)), const float next_mesh_line_x = mesh_index_to_xpos(current_xi + dxi),
next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi + dyi)), next_mesh_line_y = mesh_index_to_ypos(current_yi + dyi),
y = m * next_mesh_line_x + c, // Calculate Y at the next X mesh line 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 x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line
// (No need to worry about m being zero. // (No need to worry about m being zero.
@ -489,7 +489,7 @@
// We don't want additional apply_leveling() performed by regular buffer_line or buffer_line_kinematic, // 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. // 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( float rx, float ry, float rz, float e, float fr ) {
#if ENABLED(DELTA) // apply delta inverse_kinematics #if ENABLED(DELTA) // apply delta inverse_kinematics
@ -505,14 +505,11 @@
- HYPOT2( delta_tower[C_AXIS][X_AXIS] - rx, - HYPOT2( delta_tower[C_AXIS][X_AXIS] - rx,
delta_tower[C_AXIS][Y_AXIS] - ry )); 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) #elif IS_SCARA // apply scara inverse_kinematics (should be changed to save raw->logical->raw)
const float lseg[XYZ] = { LOGICAL_X_POSITION(rx), const float lseg[XYZ] = { rx, ry, rz };
LOGICAL_Y_POSITION(ry),
LOGICAL_Z_POSITION(rz)
};
inverse_kinematics(lseg); // this writes delta[ABC] from lseg[XYZ] inverse_kinematics(lseg); // this writes delta[ABC] from lseg[XYZ]
// should move the feedrate scaling to scara inverse_kinematics // should move the feedrate scaling to scara inverse_kinematics
@ -523,17 +520,13 @@
scara_oldB = delta[B_AXIS]; scara_oldB = delta[B_AXIS];
float s_feedrate = max(adiff, bdiff) * scara_feed_factor; 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 #else // CARTESIAN
// Cartesian _buffer_line seems to take LOGICAL, not RAW coordinates // Cartesian _buffer_line seems to take LOGICAL, not RAW coordinates
const float lx = LOGICAL_X_POSITION(rx), planner._buffer_line(rx, ry, rz, e, fr, active_extruder);
ly = LOGICAL_Y_POSITION(ry),
lz = LOGICAL_Z_POSITION(rz);
planner._buffer_line(lx, ly, lz, le, fr, active_extruder);
#endif #endif
@ -546,15 +539,15 @@
* Returns true if did NOT move, false if moved (requires current_position update). * 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 return true; // did not move, so current_position still accurate
const float tot_dx = ltarget[X_AXIS] - current_position[X_AXIS], const float tot_dx = rtarget[X_AXIS] - current_position[X_AXIS],
tot_dy = ltarget[Y_AXIS] - current_position[Y_AXIS], tot_dy = rtarget[Y_AXIS] - current_position[Y_AXIS],
tot_dz = ltarget[Z_AXIS] - current_position[Z_AXIS], tot_dz = rtarget[Z_AXIS] - current_position[Z_AXIS],
tot_de = ltarget[E_AXIS] - current_position[E_AXIS]; tot_de = rtarget[E_AXIS] - current_position[E_AXIS];
const float cartesian_xy_mm = HYPOT(tot_dx, tot_dy); // total horizontal xy distance const float cartesian_xy_mm = HYPOT(tot_dx, tot_dy); // total horizontal xy distance
@ -584,14 +577,14 @@
// Note that E segment distance could vary slightly as z mesh height // Note that E segment distance could vary slightly as z mesh height
// changes for each segment, but small enough to ignore. // changes for each segment, but small enough to ignore.
float seg_rx = RAW_X_POSITION(current_position[X_AXIS]), float seg_rx = current_position[X_AXIS],
seg_ry = RAW_Y_POSITION(current_position[Y_AXIS]), seg_ry = current_position[Y_AXIS],
seg_rz = RAW_Z_POSITION(current_position[Z_AXIS]), seg_rz = current_position[Z_AXIS],
seg_le = current_position[E_AXIS]; seg_le = current_position[E_AXIS];
const bool above_fade_height = ( const bool above_fade_height = (
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
planner.z_fade_height != 0 && planner.z_fade_height < RAW_Z_POSITION(ltarget[Z_AXIS]) planner.z_fade_height != 0 && planner.z_fade_height < rtarget[Z_AXIS]
#else #else
false false
#endif #endif
@ -599,7 +592,7 @@
// Only compute leveling per segment if ubl active and target below z_fade_height. // 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 { do {
@ -609,13 +602,13 @@
seg_rz += seg_dz; seg_rz += seg_dz;
seg_le += seg_de; seg_le += seg_de;
} else { // last segment, use exact destination } else { // last segment, use exact destination
seg_rx = RAW_X_POSITION(ltarget[X_AXIS]); seg_rx = rtarget[X_AXIS];
seg_ry = RAW_Y_POSITION(ltarget[Y_AXIS]); seg_ry = rtarget[Y_AXIS];
seg_rz = RAW_Z_POSITION(ltarget[Z_AXIS]); seg_rz = rtarget[Z_AXIS];
seg_le = ltarget[E_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); } while (segments);
@ -625,7 +618,7 @@
// Otherwise perform per-segment leveling // Otherwise perform per-segment leveling
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #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]);
#else #else
constexpr float fade_scaling_factor = 1.0; constexpr float fade_scaling_factor = 1.0;
#endif #endif
@ -690,16 +683,16 @@
float z_cxcy = (z_cxy0 + z_cxym * cy) * fade_scaling_factor; // interpolated mesh z height along cx at cy, scaled for fade float z_cxcy = (z_cxy0 + z_cxym * cy) * fade_scaling_factor; // interpolated mesh z height along cx at cy, scaled for fade
if (--segments == 0) { // if this is last segment, use ltarget for exact if (--segments == 0) { // if this is last segment, use rtarget for exact
seg_rx = RAW_X_POSITION(ltarget[X_AXIS]); seg_rx = rtarget[X_AXIS];
seg_ry = RAW_Y_POSITION(ltarget[Y_AXIS]); seg_ry = rtarget[Y_AXIS];
seg_rz = RAW_Z_POSITION(ltarget[Z_AXIS]); seg_rz = rtarget[Z_AXIS];
seg_le = ltarget[E_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() return false; // did not set_current_from_destination()
seg_rx += seg_dx; seg_rx += seg_dx;

@ -1673,7 +1673,7 @@ void kill_screen(const char* lcd_msg) {
*/ */
static int8_t bed_corner; static int8_t bed_corner;
void _lcd_goto_next_corner() { void _lcd_goto_next_corner() {
line_to_z(LOGICAL_Z_POSITION(4.0)); line_to_z(4.0);
switch (bed_corner) { switch (bed_corner) {
case 0: case 0:
current_position[X_AXIS] = X_MIN_BED + 10; current_position[X_AXIS] = X_MIN_BED + 10;
@ -1690,7 +1690,7 @@ void kill_screen(const char* lcd_msg) {
break; break;
} }
planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[X_AXIS]), active_extruder); planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[X_AXIS]), active_extruder);
line_to_z(LOGICAL_Z_POSITION(0.0)); line_to_z(0.0);
if (++bed_corner > 3) bed_corner = 0; if (++bed_corner > 3) bed_corner = 0;
} }
@ -1736,7 +1736,7 @@ void kill_screen(const char* lcd_msg) {
// //
void _lcd_after_probing() { void _lcd_after_probing() {
#if MANUAL_PROBE_HEIGHT > 0 #if MANUAL_PROBE_HEIGHT > 0
line_to_z(LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT); line_to_z(Z_MIN_POS + MANUAL_PROBE_HEIGHT);
#endif #endif
// Display "Done" screen and wait for moves to complete // Display "Done" screen and wait for moves to complete
#if MANUAL_PROBE_HEIGHT > 0 || ENABLED(MESH_BED_LEVELING) #if MANUAL_PROBE_HEIGHT > 0 || ENABLED(MESH_BED_LEVELING)
@ -1751,13 +1751,13 @@ void kill_screen(const char* lcd_msg) {
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
// Utility to go to the next mesh point // Utility to go to the next mesh point
inline void _manual_probe_goto_xy(float x, float y) { inline void _manual_probe_goto_xy(const float rx, const float ry) {
#if MANUAL_PROBE_HEIGHT > 0 #if MANUAL_PROBE_HEIGHT > 0
const float prev_z = current_position[Z_AXIS]; const float prev_z = current_position[Z_AXIS];
line_to_z(LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT); line_to_z(Z_MIN_POS + MANUAL_PROBE_HEIGHT);
#endif #endif
current_position[X_AXIS] = LOGICAL_X_POSITION(x); current_position[X_AXIS] = rx;
current_position[Y_AXIS] = LOGICAL_Y_POSITION(y); current_position[Y_AXIS] = ry;
planner.buffer_line_kinematic(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder); planner.buffer_line_kinematic(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder);
#if MANUAL_PROBE_HEIGHT > 0 #if MANUAL_PROBE_HEIGHT > 0
line_to_z(prev_z); line_to_z(prev_z);
@ -1888,8 +1888,8 @@ void kill_screen(const char* lcd_msg) {
// Controls the loop until the move is done // Controls the loop until the move is done
_manual_probe_goto_xy( _manual_probe_goto_xy(
LOGICAL_X_POSITION(mbl.index_to_xpos[px]), mbl.index_to_xpos[px],
LOGICAL_Y_POSITION(mbl.index_to_ypos[py]) mbl.index_to_ypos[py]
); );
// After the blocking function returns, change menus // After the blocking function returns, change menus
@ -2368,8 +2368,8 @@ void kill_screen(const char* lcd_msg) {
* UBL LCD Map Movement * UBL LCD Map Movement
*/ */
void ubl_map_move_to_xy() { void ubl_map_move_to_xy() {
current_position[X_AXIS] = LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot])); current_position[X_AXIS] = pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]);
current_position[Y_AXIS] = LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot])); current_position[Y_AXIS] = pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]);
planner.buffer_line_kinematic(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder); planner.buffer_line_kinematic(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder);
} }
@ -2703,26 +2703,24 @@ void kill_screen(const char* lcd_msg) {
lcd_goto_screen(_lcd_calibrate_homing); lcd_goto_screen(_lcd_calibrate_homing);
} }
void _man_probe_pt(const float &lx, const float &ly) { void _man_probe_pt(const float rx, const float ry) {
#if HAS_LEVELING #if HAS_LEVELING
reset_bed_level(); // After calibration bed-level data is no longer valid reset_bed_level(); // After calibration bed-level data is no longer valid
#endif #endif
float z_dest = LOGICAL_Z_POSITION((Z_CLEARANCE_BETWEEN_PROBES) + (DELTA_PRINTABLE_RADIUS) / 5); line_to_z((Z_CLEARANCE_BETWEEN_PROBES) + (DELTA_PRINTABLE_RADIUS) / 5);
line_to_z(z_dest); current_position[X_AXIS] = rx;
current_position[X_AXIS] = LOGICAL_X_POSITION(lx); current_position[Y_AXIS] = ry;
current_position[Y_AXIS] = LOGICAL_Y_POSITION(ly);
line_to_current_z(); line_to_current_z();
z_dest = LOGICAL_Z_POSITION(Z_CLEARANCE_BETWEEN_PROBES); line_to_z(Z_CLEARANCE_BETWEEN_PROBES);
line_to_z(z_dest);
lcd_synchronize(); lcd_synchronize();
move_menu_scale = PROBE_MANUALLY_STEP; move_menu_scale = PROBE_MANUALLY_STEP;
lcd_goto_screen(lcd_move_z); lcd_goto_screen(lcd_move_z);
} }
float lcd_probe_pt(const float &lx, const float &ly) { float lcd_probe_pt(const float &rx, const float &ry) {
_man_probe_pt(lx, ly); _man_probe_pt(rx, ry);
KEEPALIVE_STATE(PAUSED_FOR_USER); KEEPALIVE_STATE(PAUSED_FOR_USER);
defer_return_to_status = true; defer_return_to_status = true;
wait_for_user = true; wait_for_user = true;

@ -202,7 +202,7 @@ void lcd_reset_status();
#endif #endif
#if ENABLED(DELTA_CALIBRATION_MENU) #if ENABLED(DELTA_CALIBRATION_MENU)
float lcd_probe_pt(const float &lx, const float &ly); float lcd_probe_pt(const float &rx, const float &ry);
#endif #endif
#if ENABLED(SD_REPRINT_LAST_SELECTED_FILE) #if ENABLED(SD_REPRINT_LAST_SELECTED_FILE)

@ -645,9 +645,9 @@ static void lcd_implementation_status_screen() {
// At the first page, regenerate the XYZ strings // At the first page, regenerate the XYZ strings
if (page.page == 0) { if (page.page == 0) {
strcpy(xstring, ftostr4sign(current_position[X_AXIS])); strcpy(xstring, ftostr4sign(LOGICAL_X_POSITION(current_position[X_AXIS])));
strcpy(ystring, ftostr4sign(current_position[Y_AXIS])); strcpy(ystring, ftostr4sign(LOGICAL_Y_POSITION(current_position[Y_AXIS])));
strcpy(zstring, ftostr52sp(FIXFLOAT(current_position[Z_AXIS]))); strcpy(zstring, ftostr52sp(FIXFLOAT(LOGICAL_Z_POSITION(current_position[Z_AXIS]))));
#if ENABLED(FILAMENT_LCD_DISPLAY) && DISABLED(SDSUPPORT) #if ENABLED(FILAMENT_LCD_DISPLAY) && DISABLED(SDSUPPORT)
strcpy(wstring, ftostr12ns(filament_width_meas)); strcpy(wstring, ftostr12ns(filament_width_meas));
strcpy(mstring, itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); strcpy(mstring, itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]));

@ -618,7 +618,9 @@ FORCE_INLINE void _draw_heater_status(const int8_t heater, const char prefix, co
lcd.print(itostr3(t1 + 0.5)); lcd.print(itostr3(t1 + 0.5));
lcd.write('/'); lcd.write('/');
#if HEATER_IDLE_HANDLER #if !HEATER_IDLE_HANDLER
UNUSED(blink);
#else
const bool is_idle = (!isBed ? thermalManager.is_heater_idle(heater) : const bool is_idle = (!isBed ? thermalManager.is_heater_idle(heater) :
#if HAS_TEMP_BED #if HAS_TEMP_BED
thermalManager.is_bed_idle() thermalManager.is_bed_idle()
@ -776,12 +778,12 @@ static void lcd_implementation_status_screen() {
// When everything is ok you see a constant 'X'. // When everything is ok you see a constant 'X'.
_draw_axis_label(X_AXIS, PSTR(MSG_X), blink); _draw_axis_label(X_AXIS, PSTR(MSG_X), blink);
lcd.print(ftostr4sign(current_position[X_AXIS])); lcd.print(ftostr4sign(LOGICAL_X_POSITION(current_position[X_AXIS])));
lcd.write(' '); lcd.write(' ');
_draw_axis_label(Y_AXIS, PSTR(MSG_Y), blink); _draw_axis_label(Y_AXIS, PSTR(MSG_Y), blink);
lcd.print(ftostr4sign(current_position[Y_AXIS])); lcd.print(ftostr4sign(LOGICAL_Y_POSITION(current_position[Y_AXIS])));
#endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0 #endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0

Loading…
Cancel
Save