Skip to content

Commit

Permalink
Improve Delta probing / calibration (#15887)
Browse files Browse the repository at this point in the history
  • Loading branch information
sjasonsmith authored and thinkyhead committed Nov 21, 2019
1 parent 4ede13e commit b904ba0
Show file tree
Hide file tree
Showing 26 changed files with 149 additions and 184 deletions.
13 changes: 2 additions & 11 deletions Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1387,17 +1387,8 @@
dx = (x_max - x_min) / (g29_grid_size - 1),
dy = (y_max - y_min) / (g29_grid_size - 1);

const vector_3 points[3] = {
#if ENABLED(HAS_FIXED_3POINT)
{ PROBE_PT_1_X, PROBE_PT_1_Y, 0 },
{ PROBE_PT_2_X, PROBE_PT_2_Y, 0 },
{ PROBE_PT_3_X, PROBE_PT_3_Y, 0 }
#else
{ x_min, y_min, 0 },
{ x_max, y_min, 0 },
{ (x_max - x_min) / 2, y_max, 0 }
#endif
};
xy_float_t points[3];
get_three_probe_points(points);

float measured_z;
bool abort_flag = false;
Expand Down
18 changes: 3 additions & 15 deletions Marlin/src/gcode/bedlevel/abl/G29.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,20 +263,8 @@ G29_TYPE GcodeSuite::G29() {
int constexpr abl_points = 3; // used to show total points
#endif

// Probe at 3 arbitrary points
const float x_min = probe_min_x(), x_max = probe_max_x(), y_min = probe_min_y(), y_max = probe_max_y();

ABL_VAR vector_3 points[3] = {
#if ENABLED(HAS_FIXED_3POINT)
{ PROBE_PT_1_X, PROBE_PT_1_Y, 0 },
{ PROBE_PT_2_X, PROBE_PT_2_Y, 0 },
{ PROBE_PT_3_X, PROBE_PT_3_Y, 0 }
#else
{ x_min, y_min, 0 },
{ x_max, y_min, 0 },
{ (x_max - x_min) / 2, y_max, 0 }
#endif
};
vector_3 points[3];
get_three_probe_points(points);

#endif // AUTO_BED_LEVELING_3POINT

Expand Down Expand Up @@ -764,7 +752,7 @@ G29_TYPE GcodeSuite::G29() {
for (uint8_t i = 0; i < 3; ++i) {
if (verbose_level) SERIAL_ECHOLNPAIR("Probing point ", int(i), "/3.");
#if HAS_DISPLAY
ui.status_printf_P(0, PSTR(S_FMT" %i/3"), GET_TEXT(MSG_PROBING_MESH)), int(i);
ui.status_printf_P(0, PSTR(S_FMT" %i/3"), GET_TEXT(MSG_PROBING_MESH), int(i));
#endif

// Retain the last probe position
Expand Down
29 changes: 16 additions & 13 deletions Marlin/src/gcode/calibrate/G33.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ static float std_dev_points(float z_pt[NPP + 1], const bool _0p_cal, const bool
*/
static float calibration_probe(const xy_pos_t &xy, const bool stow) {
#if HAS_BED_PROBE
return probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, false);
return probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, true);
#else
UNUSED(stow);
return lcd_probe_pt(xy);
Expand Down Expand Up @@ -222,6 +222,8 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi

if (!_0p_calibration) {

const float dcr = delta_calibration_radius();

if (!_7p_no_intermediates && !_7p_4_intermediates && !_7p_11_intermediates) { // probe the center
const xy_pos_t center{0};
z_pt[CEN] += calibration_probe(center, stow_after_each);
Expand All @@ -233,7 +235,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
steps = _7p_9_center ? _4P_STEP / 3.0f : _7p_6_center ? _7P_STEP : _4P_STEP;
I_LOOP_CAL_PT(rad, start, steps) {
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
r = delta_calibration_radius * 0.1;
r = dcr * 0.1;
const xy_pos_t vec = { cos(a), sin(a) };
z_pt[CEN] += calibration_probe(vec * r, stow_after_each);
if (isnan(z_pt[CEN])) return false;
Expand All @@ -257,7 +259,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
const int8_t offset = _7p_9_center ? 2 : 0;
for (int8_t circle = 0; circle <= offset; circle++) {
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
r = delta_calibration_radius * (1 - 0.1 * (zig_zag ? offset - circle : circle)),
r = dcr * (1 - 0.1 * (zig_zag ? offset - circle : circle)),
interpol = FMOD(rad, 1);
const xy_pos_t vec = { cos(a), sin(a) };
const float z_temp = calibration_probe(vec * r, stow_after_each);
Expand Down Expand Up @@ -287,17 +289,18 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_at_pt_axis[NPP + 1]) {
xyz_pos_t pos{0};

const float dcr = delta_calibration_radius();
LOOP_CAL_ALL(rad) {
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
r = (rad == CEN ? 0.0f : delta_calibration_radius);
r = (rad == CEN ? 0.0f : dcr);
pos.set(cos(a) * r, sin(a) * r, z_pt[rad]);
inverse_kinematics(pos);
mm_at_pt_axis[rad] = delta;
}
}

static void forward_kinematics_probe_points(abc_float_t mm_at_pt_axis[NPP + 1], float z_pt[NPP + 1]) {
const float r_quot = delta_calibration_radius / delta_radius;
const float r_quot = delta_calibration_radius() / delta_radius;

#define ZPP(N,I,A) (((1.0f + r_quot * (N)) / 3.0f) * mm_at_pt_axis[I].A)
#define Z00(I, A) ZPP( 0, I, A)
Expand Down Expand Up @@ -338,7 +341,7 @@ static void calc_kinematics_diff_probe_points(float z_pt[NPP + 1], abc_float_t d
}

static float auto_tune_h() {
const float r_quot = delta_calibration_radius / delta_radius;
const float r_quot = delta_calibration_radius() / delta_radius;
return RECIPROCAL(r_quot / (2.0f / 3.0f)); // (2/3)/CR
}

Expand Down Expand Up @@ -450,12 +453,13 @@ void GcodeSuite::G33() {

SERIAL_ECHOLNPGM("G33 Auto Calibrate");

const float dcr = delta_calibration_radius();

if (!_1p_calibration && !_0p_calibration) { // test if the outer radius is reachable
LOOP_CAL_RAD(axis) {
const float a = RADIANS(210 + (360 / NPP) * (axis - 1)),
r = delta_calibration_radius;
if (!position_is_reachable(cos(a) * r, sin(a) * r)) {
SERIAL_ECHOLNPGM("?(M665 B)ed radius implausible.");
const float a = RADIANS(210 + (360 / NPP) * (axis - 1));
if (!position_is_reachable(cos(a) * dcr, sin(a) * dcr)) {
SERIAL_ECHOLNPGM("?Bed calibration radius implausible.");
return;
}
}
Expand Down Expand Up @@ -522,12 +526,11 @@ void GcodeSuite::G33() {
#define Z0(I) ZP(0, I)

// calculate factors
const float cr_old = delta_calibration_radius;
if (_7p_9_center) delta_calibration_radius *= 0.9f;
if (_7p_9_center) calibration_radius_factor = 0.9f;
h_factor = auto_tune_h();
r_factor = auto_tune_r();
a_factor = auto_tune_a();
delta_calibration_radius = cr_old;
calibration_radius_factor = 1.0f;

switch (probe_points) {
case 0:
Expand Down
2 changes: 0 additions & 2 deletions Marlin/src/gcode/calibrate/M665.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
* L = diagonal rod
* R = delta radius
* S = segments per second
* B = delta calibration radius
* X = Alpha (Tower 1) angle trim
* Y = Beta (Tower 2) angle trim
* Z = Gamma (Tower 3) angle trim
Expand All @@ -47,7 +46,6 @@
if (parser.seen('L')) delta_diagonal_rod = parser.value_linear_units();
if (parser.seen('R')) delta_radius = parser.value_linear_units();
if (parser.seen('S')) delta_segments_per_second = parser.value_float();
if (parser.seen('B')) delta_calibration_radius = parser.value_float();
if (parser.seen('X')) delta_tower_angle_trim.a = parser.value_float();
if (parser.seen('Y')) delta_tower_angle_trim.b = parser.value_float();
if (parser.seen('Z')) delta_tower_angle_trim.c = parser.value_float();
Expand Down
115 changes: 35 additions & 80 deletions Marlin/src/inc/Conditionals_post.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,12 @@

/**
* SCARA cannot use SLOWDOWN and requires QUICKHOME
* Printable radius assumes joints can fully extend
*/
#if IS_SCARA
#undef SLOWDOWN
#define QUICK_HOME
#define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2)
#endif

/**
Expand Down Expand Up @@ -1434,6 +1436,7 @@
#define PLANNER_LEVELING (HAS_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL))
#define HAS_PROBING_PROCEDURE (HAS_ABL_OR_UBL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST))
#define HAS_POSITION_MODIFIERS (ENABLED(FWRETRACT) || HAS_LEVELING || ENABLED(SKEW_CORRECTION))
#define NEEDS_THREE_PROBE_POINTS EITHER(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_3POINT)

#if ENABLED(AUTO_BED_LEVELING_UBL)
#undef LCD_BED_LEVELING
Expand Down Expand Up @@ -1470,37 +1473,37 @@
#endif

/**
* Bed Probing rectangular bounds
* These can be further constrained in code for Delta and SCARA
* Bed Probing bounds
*/

#ifndef MIN_PROBE_EDGE
#define MIN_PROBE_EDGE 0
#endif
#ifndef MIN_PROBE_EDGE_LEFT
#define MIN_PROBE_EDGE_LEFT MIN_PROBE_EDGE
#endif
#ifndef MIN_PROBE_EDGE_RIGHT
#define MIN_PROBE_EDGE_RIGHT MIN_PROBE_EDGE
#endif
#ifndef MIN_PROBE_EDGE_FRONT
#define MIN_PROBE_EDGE_FRONT MIN_PROBE_EDGE
#endif
#ifndef MIN_PROBE_EDGE_BACK
#define MIN_PROBE_EDGE_BACK MIN_PROBE_EDGE

#if IS_KINEMATIC
#undef MIN_PROBE_EDGE_LEFT
#undef MIN_PROBE_EDGE_RIGHT
#undef MIN_PROBE_EDGE_FRONT
#undef MIN_PROBE_EDGE_BACK
#else
#ifndef MIN_PROBE_EDGE_LEFT
#define MIN_PROBE_EDGE_LEFT MIN_PROBE_EDGE
#endif
#ifndef MIN_PROBE_EDGE_RIGHT
#define MIN_PROBE_EDGE_RIGHT MIN_PROBE_EDGE
#endif
#ifndef MIN_PROBE_EDGE_FRONT
#define MIN_PROBE_EDGE_FRONT MIN_PROBE_EDGE
#endif
#ifndef MIN_PROBE_EDGE_BACK
#define MIN_PROBE_EDGE_BACK MIN_PROBE_EDGE
#endif
#endif

#if ENABLED(DELTA)
/**
* Delta radius/rod trimmers/angle trimmers
*/
#define _PROBE_RADIUS (DELTA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE))
#ifndef DELTA_CALIBRATION_RADIUS
#if HAS_BED_PROBE
#define DELTA_CALIBRATION_RADIUS (DELTA_PRINTABLE_RADIUS - _MAX(ABS(probe_offset.x), ABS(probe_offset.y), ABS(MIN_PROBE_EDGE)))
#else
#define DELTA_CALIBRATION_RADIUS _PROBE_RADIUS
#endif
#endif
#ifndef DELTA_ENDSTOP_ADJ
#define DELTA_ENDSTOP_ADJ { 0, 0, 0 }
#endif
Expand All @@ -1513,24 +1516,6 @@
#ifndef DELTA_DIAGONAL_ROD_TRIM_TOWER
#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0, 0, 0 }
#endif

// Probing points may be verified at compile time within the radius
// using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(DELTA_PRINTABLE_RADIUS),"bad probe point!")
// so that may be added to SanityCheck.h in the future.
#define PROBE_X_MIN (X_CENTER - (_PROBE_RADIUS))
#define PROBE_Y_MIN (Y_CENTER - (_PROBE_RADIUS))
#define PROBE_X_MAX (X_CENTER + _PROBE_RADIUS)
#define PROBE_Y_MAX (Y_CENTER + _PROBE_RADIUS)

#elif IS_SCARA

#define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2)
#define _PROBE_RADIUS (SCARA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE))
#define PROBE_X_MIN (X_CENTER - (SCARA_PRINTABLE_RADIUS) + MIN_PROBE_EDGE_LEFT)
#define PROBE_Y_MIN (Y_CENTER - (SCARA_PRINTABLE_RADIUS) + MIN_PROBE_EDGE_FRONT)
#define PROBE_X_MAX (X_CENTER + SCARA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE_RIGHT))
#define PROBE_Y_MAX (Y_CENTER + SCARA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE_BACK))

#endif

#if ENABLED(SEGMENT_LEVELED_MOVES) && !defined(LEVELED_SEGMENT_LENGTH)
Expand All @@ -1540,7 +1525,7 @@
/**
* Default mesh area is an area with an inset margin on the print area.
*/
#if HAS_LEVELING
#if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
#if IS_KINEMATIC
// Probing points may be verified at compile time within the radius
// using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(DELTA_PRINTABLE_RADIUS),"bad probe point!")
Expand All @@ -1551,17 +1536,10 @@
#define _MESH_MAX_Y (Y_MAX_BED - (MESH_INSET))
#else
// Boundaries for Cartesian probing based on set limits
#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL, PROBE_MANUALLY)
#define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS)) // UBL is careful not to probe off the bed. It does not
#define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS)) // need NOZZLE_TO_PROBE_OFFSET in the mesh dimensions
#define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS))
#define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS))
#else
#define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS + probe_offset.x))
#define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS + probe_offset.y))
#define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS + probe_offset.x))
#define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS + probe_offset.y))
#endif
#define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS)) // UBL is careful not to probe off the bed. It does not
#define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS)) // need NOZZLE_TO_PROBE_OFFSET in the mesh dimensions
#define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS))
#define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS))
#endif

// These may be overridden in Configuration.h if a smaller area is desired
Expand All @@ -1577,40 +1555,17 @@
#ifndef MESH_MAX_Y
#define MESH_MAX_Y _MESH_MAX_Y
#endif

#endif // MESH_BED_LEVELING || AUTO_BED_LEVELING_UBL
#else
#undef MESH_MIN_X
#undef MESH_MIN_Y
#undef MESH_MAX_X
#undef MESH_MAX_Y
#endif

#if (defined(PROBE_PT_1_X) && defined(PROBE_PT_2_X) && defined(PROBE_PT_3_X) && defined(PROBE_PT_1_Y) && defined(PROBE_PT_2_Y) && defined(PROBE_PT_3_Y))
#define HAS_FIXED_3POINT
#endif

#if EITHER(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_3POINT) && IS_KINEMATIC
#define HAS_FIXED_3POINT
#define SIN0 0.0
#define SIN120 0.866025
#define SIN240 -0.866025
#define COS0 1.0
#define COS120 -0.5
#define COS240 -0.5
#ifndef PROBE_PT_1_X
#define PROBE_PT_1_X (X_CENTER + (_PROBE_RADIUS) * COS0)
#endif
#ifndef PROBE_PT_1_Y
#define PROBE_PT_1_Y (Y_CENTER + (_PROBE_RADIUS) * SIN0)
#endif
#ifndef PROBE_PT_2_X
#define PROBE_PT_2_X (X_CENTER + (_PROBE_RADIUS) * COS120)
#endif
#ifndef PROBE_PT_2_Y
#define PROBE_PT_2_Y (Y_CENTER + (_PROBE_RADIUS) * SIN120)
#endif
#ifndef PROBE_PT_3_X
#define PROBE_PT_3_X (X_CENTER + (_PROBE_RADIUS) * COS240)
#endif
#ifndef PROBE_PT_3_Y
#define PROBE_PT_3_Y (Y_CENTER + (_PROBE_RADIUS) * SIN240)
#endif
#endif

/**
* Buzzer/Speaker
Expand Down
2 changes: 2 additions & 0 deletions Marlin/src/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@
#error "NEOPIXEL_RGBW_LED is now NEOPIXEL_LED. Please update your configuration."
#elif ENABLED(DELTA) && defined(DELTA_PROBEABLE_RADIUS)
#error "Remove DELTA_PROBEABLE_RADIUS and use MIN_PROBE_EDGE to inset the probe area instead."
#elif ENABLED(DELTA) && defined(DELTA_CALIBRATION_RADIUS)
#error "Remove DELTA_CALIBRATION_RADIUS and use MIN_PROBE_EDGE to inset the probe area instead."
#elif defined(UBL_MESH_INSET)
#error "UBL_MESH_INSET is now just MESH_INSET. Please update your configuration."
#elif defined(UBL_MESH_MIN_X) || defined(UBL_MESH_MIN_Y) || defined(UBL_MESH_MAX_X) || defined(UBL_MESH_MAX_Y)
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/lcd/menu/menu_delta_calibrate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void _man_probe_pt(const xy_pos_t &xy) {

void _goto_tower_a(const float &a) {
xy_pos_t tower_vec = { cos(RADIANS(a)), sin(RADIANS(a)) };
_man_probe_pt(tower_vec * delta_calibration_radius);
_man_probe_pt(tower_vec * delta_calibration_radius());
}
void _goto_tower_x() { _goto_tower_a(210); }
void _goto_tower_y() { _goto_tower_a(330); }
Expand Down
1 change: 1 addition & 0 deletions Marlin/src/libs/vector_3.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ struct vector_3 : xyz_float_t {
vector_3(const xy_float_t &in) { set(in.x, in.y); }
vector_3(const xyz_float_t &in) { set(in.x, in.y, in.z); }
vector_3(const xyze_float_t &in) { set(in.x, in.y, in.z); }
vector_3() { reset(); }

// Factory method
static vector_3 cross(const vector_3 &a, const vector_3 &b);
Expand Down
Loading

0 comments on commit b904ba0

Please sign in to comment.