Enhancements to G425 (#13159)
- Turn off bed leveling prior to calibrating. - This prevents lateral probes from having a Z component that triggers the Z endstop and causes the motion to be aborted. - Got rid of static const float arrays "dimension" and "true_center" - Frees up 24 bytes of SRAM - Changed incorrect use of "bool" for float in backlash macros. - Replaced arguments with 0.0f and 1.0f for clarity. - Now only disables soft endstops (since calibration cube is outside of bed) - Not necessary to disable global endstops
This commit is contained in:
parent
84fc400aba
commit
31c240a8db
1 changed files with 61 additions and 44 deletions
|
@ -30,6 +30,8 @@
|
||||||
#include "../../module/planner.h"
|
#include "../../module/planner.h"
|
||||||
#include "../../module/tool_change.h"
|
#include "../../module/tool_change.h"
|
||||||
#include "../../module/endstops.h"
|
#include "../../module/endstops.h"
|
||||||
|
#include "../../feature/bedlevel/bedlevel.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* G425 backs away from the calibration object by various distances
|
* G425 backs away from the calibration object by various distances
|
||||||
|
@ -60,8 +62,9 @@
|
||||||
enum side_t : uint8_t { TOP, RIGHT, FRONT, LEFT, BACK, NUM_SIDES };
|
enum side_t : uint8_t { TOP, RIGHT, FRONT, LEFT, BACK, NUM_SIDES };
|
||||||
|
|
||||||
struct measurements_t {
|
struct measurements_t {
|
||||||
static const float dimensions[XYZ];
|
static constexpr float dimensions[XYZ] = CALIBRATION_OBJECT_DIMENSIONS;
|
||||||
static const float true_center[XYZ]; // This cannot be constexpr since it is accessed by index in probe_side
|
static constexpr float true_center[XYZ] = CALIBRATION_OBJECT_CENTER;
|
||||||
|
|
||||||
float obj_center[XYZ] = CALIBRATION_OBJECT_CENTER;
|
float obj_center[XYZ] = CALIBRATION_OBJECT_CENTER;
|
||||||
float obj_side[NUM_SIDES];
|
float obj_side[NUM_SIDES];
|
||||||
|
|
||||||
|
@ -71,16 +74,13 @@ struct measurements_t {
|
||||||
float nozzle_outer_dimension[2] = {CALIBRATION_NOZZLE_OUTER_DIAMETER, CALIBRATION_NOZZLE_OUTER_DIAMETER};
|
float nozzle_outer_dimension[2] = {CALIBRATION_NOZZLE_OUTER_DIAMETER, CALIBRATION_NOZZLE_OUTER_DIAMETER};
|
||||||
};
|
};
|
||||||
|
|
||||||
const float measurements_t::true_center[XYZ] = CALIBRATION_OBJECT_CENTER;
|
#define TEMPORARY_BED_LEVELING_STATE(enable) TemporaryBedLevelingState tbls(enable)
|
||||||
|
#define TEMPORARY_SOFT_ENDSTOP_STATE(enable) REMEMBER(tes, soft_endstops_enabled, enable);
|
||||||
const float measurements_t::dimensions[] = CALIBRATION_OBJECT_DIMENSIONS;
|
|
||||||
|
|
||||||
#define TEMPORARY_ENDSTOP_STATE(enable) REMEMBER(tes, soft_endstops_enabled, enable); TemporaryGlobalEndstopsState tges(enable)
|
|
||||||
|
|
||||||
#if ENABLED(BACKLASH_GCODE)
|
#if ENABLED(BACKLASH_GCODE)
|
||||||
#define TEMPORARY_BACKLASH_STATE(enable) REMEMBER(tbst, backlash_correction, enable)
|
#define TEMPORARY_BACKLASH_CORRECTION(value) REMEMBER(tbst, backlash_correction, value)
|
||||||
#else
|
#else
|
||||||
#define TEMPORARY_BACKLASH_STATE(enable)
|
#define TEMPORARY_BACKLASH_CORRECTION(value)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
|
#if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
|
||||||
|
@ -89,6 +89,20 @@ const float measurements_t::dimensions[] = CALIBRATION_OBJECT_DIMENSIONS;
|
||||||
#define TEMPORARY_BACKLASH_SMOOTHING(value)
|
#define TEMPORARY_BACKLASH_SMOOTHING(value)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to save and change the bed leveling state,
|
||||||
|
* then restore it when it goes out of scope.
|
||||||
|
*/
|
||||||
|
class TemporaryBedLevelingState {
|
||||||
|
bool saved;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TemporaryBedLevelingState(const bool enable) : saved(planner.leveling_active) {
|
||||||
|
set_bed_leveling_enabled(enable);
|
||||||
|
}
|
||||||
|
~TemporaryBedLevelingState() { set_bed_leveling_enabled(saved); }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move to a particular location. Up to three individual axes
|
* Move to a particular location. Up to three individual axes
|
||||||
* and their destinations can be specified, in any order.
|
* and their destinations can be specified, in any order.
|
||||||
|
@ -121,10 +135,10 @@ inline void move_to(
|
||||||
* uncertainty in - How far away from the object top to park
|
* uncertainty in - How far away from the object top to park
|
||||||
*/
|
*/
|
||||||
inline void park_above_object(measurements_t &m, const float uncertainty) {
|
inline void park_above_object(measurements_t &m, const float uncertainty) {
|
||||||
/* Move to safe distance above calibration object */
|
// Move to safe distance above calibration object
|
||||||
move_to(Z_AXIS, m.obj_center[Z_AXIS] + m.dimensions[Z_AXIS] / 2 + uncertainty);
|
move_to(Z_AXIS, m.obj_center[Z_AXIS] + m.dimensions[Z_AXIS] / 2 + uncertainty);
|
||||||
|
|
||||||
/* Move to center of calibration object in XY */
|
// Move to center of calibration object in XY
|
||||||
move_to(X_AXIS, m.obj_center[X_AXIS], Y_AXIS, m.obj_center[Y_AXIS]);
|
move_to(X_AXIS, m.obj_center[X_AXIS], Y_AXIS, m.obj_center[Y_AXIS]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,6 +242,7 @@ inline float measure(const AxisEnum axis, const int dir, const bool stop_state,
|
||||||
* to find out height of edge
|
* to find out height of edge
|
||||||
*/
|
*/
|
||||||
inline void probe_side(measurements_t &m, const float uncertainty, const side_t side, const bool probe_top_at_edge=false) {
|
inline void probe_side(measurements_t &m, const float uncertainty, const side_t side, const bool probe_top_at_edge=false) {
|
||||||
|
const float dimensions[] = CALIBRATION_OBJECT_DIMENSIONS;
|
||||||
AxisEnum axis;
|
AxisEnum axis;
|
||||||
float dir;
|
float dir;
|
||||||
|
|
||||||
|
@ -236,7 +251,7 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
|
||||||
switch(side) {
|
switch(side) {
|
||||||
case TOP: {
|
case TOP: {
|
||||||
const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
|
const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
|
||||||
m.obj_center[Z_AXIS] = measurement - m.dimensions[Z_AXIS] / 2;
|
m.obj_center[Z_AXIS] = measurement - dimensions[Z_AXIS] / 2;
|
||||||
m.obj_side[TOP] = measurement;
|
m.obj_side[TOP] = measurement;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -250,18 +265,18 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
|
||||||
|
|
||||||
if (probe_top_at_edge) {
|
if (probe_top_at_edge) {
|
||||||
// Probe top nearest the side we are probing
|
// Probe top nearest the side we are probing
|
||||||
move_to(axis, m.obj_center[axis] + (-dir) * (m.dimensions[axis] / 2 - m.nozzle_outer_dimension[axis]));
|
move_to(axis, m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 - m.nozzle_outer_dimension[axis]));
|
||||||
m.obj_side[TOP] = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
|
m.obj_side[TOP] = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
|
||||||
m.obj_center[Z_AXIS] = m.obj_side[TOP] - m.dimensions[Z_AXIS] / 2;
|
m.obj_center[Z_AXIS] = m.obj_side[TOP] - dimensions[Z_AXIS] / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move to safe distance to the side of the calibration object
|
// Move to safe distance to the side of the calibration object
|
||||||
move_to(axis, m.obj_center[axis] + (-dir) * (m.dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2 + uncertainty));
|
move_to(axis, m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2 + uncertainty));
|
||||||
|
|
||||||
// Plunge below the side of the calibration object and measure
|
// Plunge below the side of the calibration object and measure
|
||||||
move_to(Z_AXIS, m.obj_side[TOP] - CALIBRATION_NOZZLE_TIP_HEIGHT * 0.7);
|
move_to(Z_AXIS, m.obj_side[TOP] - CALIBRATION_NOZZLE_TIP_HEIGHT * 0.7);
|
||||||
const float measurement = measure(axis, dir, true, &m.backlash[side], uncertainty);
|
const float measurement = measure(axis, dir, true, &m.backlash[side], uncertainty);
|
||||||
m.obj_center[axis] = measurement + dir * (m.dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2);
|
m.obj_center[axis] = measurement + dir * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2);
|
||||||
m.obj_side[side] = measurement;
|
m.obj_side[side] = measurement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,14 +287,11 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
|
||||||
* uncertainty in - How far away from the calibration object to begin probing
|
* uncertainty in - How far away from the calibration object to begin probing
|
||||||
*/
|
*/
|
||||||
inline void probe_sides(measurements_t &m, const float uncertainty) {
|
inline void probe_sides(measurements_t &m, const float uncertainty) {
|
||||||
TEMPORARY_ENDSTOP_STATE(false);
|
|
||||||
|
|
||||||
#ifdef CALIBRATION_MEASURE_AT_TOP_EDGES
|
#ifdef CALIBRATION_MEASURE_AT_TOP_EDGES
|
||||||
constexpr bool probe_top_at_edge = true;
|
constexpr bool probe_top_at_edge = true;
|
||||||
#else
|
#else
|
||||||
/* Probing at the exact center only works if the center is flat. Probing on a washer
|
// Probing at the exact center only works if the center is flat. Probing on a washer
|
||||||
* or bolt will require probing the top near the side edges, away from the center.
|
// or bolt will require probing the top near the side edges, away from the center.
|
||||||
*/
|
|
||||||
constexpr bool probe_top_at_edge = false;
|
constexpr bool probe_top_at_edge = false;
|
||||||
probe_side(m, uncertainty, TOP);
|
probe_side(m, uncertainty, TOP);
|
||||||
#endif
|
#endif
|
||||||
|
@ -287,9 +299,11 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
||||||
#ifdef CALIBRATION_MEASURE_RIGHT
|
#ifdef CALIBRATION_MEASURE_RIGHT
|
||||||
probe_side(m, uncertainty, RIGHT, probe_top_at_edge);
|
probe_side(m, uncertainty, RIGHT, probe_top_at_edge);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CALIBRATION_MEASURE_FRONT
|
#ifdef CALIBRATION_MEASURE_FRONT
|
||||||
probe_side(m, uncertainty, FRONT, probe_top_at_edge);
|
probe_side(m, uncertainty, FRONT, probe_top_at_edge);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CALIBRATION_MEASURE_LEFT
|
#ifdef CALIBRATION_MEASURE_LEFT
|
||||||
probe_side(m, uncertainty, LEFT, probe_top_at_edge);
|
probe_side(m, uncertainty, LEFT, probe_top_at_edge);
|
||||||
#endif
|
#endif
|
||||||
|
@ -297,7 +311,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
||||||
probe_side(m, uncertainty, BACK, probe_top_at_edge);
|
probe_side(m, uncertainty, BACK, probe_top_at_edge);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Compute the measured center of the calibration object. */
|
// Compute the measured center of the calibration object.
|
||||||
#if HAS_X_CENTER
|
#if HAS_X_CENTER
|
||||||
m.obj_center[X_AXIS] = (m.obj_side[LEFT] + m.obj_side[RIGHT]) / 2;
|
m.obj_center[X_AXIS] = (m.obj_side[LEFT] + m.obj_side[RIGHT]) / 2;
|
||||||
#endif
|
#endif
|
||||||
|
@ -305,8 +319,8 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
||||||
m.obj_center[Y_AXIS] = (m.obj_side[FRONT] + m.obj_side[BACK]) / 2;
|
m.obj_center[Y_AXIS] = (m.obj_side[FRONT] + m.obj_side[BACK]) / 2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Compute the outside diameter of the nozzle at the height
|
// Compute the outside diameter of the nozzle at the height
|
||||||
* at which it makes contact with the calibration object */
|
// at which it makes contact with the calibration object
|
||||||
#if HAS_X_CENTER
|
#if HAS_X_CENTER
|
||||||
m.nozzle_outer_dimension[X_AXIS] = m.obj_side[RIGHT] - m.obj_side[LEFT] - m.dimensions[X_AXIS];
|
m.nozzle_outer_dimension[X_AXIS] = m.obj_side[RIGHT] - m.obj_side[LEFT] - m.dimensions[X_AXIS];
|
||||||
#endif
|
#endif
|
||||||
|
@ -316,8 +330,8 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
||||||
|
|
||||||
park_above_object(m, uncertainty);
|
park_above_object(m, uncertainty);
|
||||||
|
|
||||||
/* The positional error is the difference between the known calibration
|
// The difference between the known and the measured location
|
||||||
* object location and the measured calibration object location */
|
// of the calibration object is the positional error
|
||||||
m.pos_error[X_AXIS] =
|
m.pos_error[X_AXIS] =
|
||||||
#if HAS_X_CENTER
|
#if HAS_X_CENTER
|
||||||
m.true_center[X_AXIS] - m.obj_center[X_AXIS];
|
m.true_center[X_AXIS] - m.obj_center[X_AXIS];
|
||||||
|
@ -434,9 +448,9 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
|
||||||
// Backlash compensation should be off while measuring backlash
|
// Backlash compensation should be off while measuring backlash
|
||||||
|
|
||||||
{
|
{
|
||||||
// New scope for TEMPORARY_BACKLASH_STATE
|
// New scope for TEMPORARY_BACKLASH_CORRECTION
|
||||||
TEMPORARY_BACKLASH_STATE(false);
|
TEMPORARY_BACKLASH_CORRECTION(0.0f);
|
||||||
TEMPORARY_BACKLASH_SMOOTHING(0);
|
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
||||||
|
|
||||||
probe_sides(m, uncertainty);
|
probe_sides(m, uncertainty);
|
||||||
|
|
||||||
|
@ -466,9 +480,9 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
|
||||||
// directions to take up any backlash
|
// directions to take up any backlash
|
||||||
|
|
||||||
{
|
{
|
||||||
// New scope for TEMPORARY_BACKLASH_STATE
|
// New scope for TEMPORARY_BACKLASH_CORRECTION
|
||||||
TEMPORARY_BACKLASH_STATE(true);
|
TEMPORARY_BACKLASH_CORRECTION(1.0f);
|
||||||
TEMPORARY_BACKLASH_SMOOTHING(0);
|
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
||||||
move_to(
|
move_to(
|
||||||
X_AXIS, current_position[X_AXIS] + 3,
|
X_AXIS, current_position[X_AXIS] + 3,
|
||||||
Y_AXIS, current_position[Y_AXIS] + 3,
|
Y_AXIS, current_position[Y_AXIS] + 3,
|
||||||
|
@ -484,8 +498,9 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void update_measurements(measurements_t &m, const AxisEnum axis) {
|
inline void update_measurements(measurements_t &m, const AxisEnum axis) {
|
||||||
|
const float true_center[XYZ] = CALIBRATION_OBJECT_CENTER;
|
||||||
current_position[axis] += m.pos_error[axis];
|
current_position[axis] += m.pos_error[axis];
|
||||||
m.obj_center[axis] = m.true_center[axis];
|
m.obj_center[axis] = true_center[axis];
|
||||||
m.pos_error[axis] = 0;
|
m.pos_error[axis] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,8 +516,8 @@ inline void update_measurements(measurements_t &m, const AxisEnum axis) {
|
||||||
* - Call calibrate_backlash() beforehand for best accuracy
|
* - Call calibrate_backlash() beforehand for best accuracy
|
||||||
*/
|
*/
|
||||||
inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const uint8_t extruder) {
|
inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const uint8_t extruder) {
|
||||||
TEMPORARY_BACKLASH_STATE(true);
|
TEMPORARY_BACKLASH_CORRECTION(1.0f);
|
||||||
TEMPORARY_BACKLASH_SMOOTHING(0);
|
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
||||||
|
|
||||||
#if HOTENDS > 1
|
#if HOTENDS > 1
|
||||||
set_nozzle(m, extruder);
|
set_nozzle(m, extruder);
|
||||||
|
@ -510,7 +525,7 @@ inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const
|
||||||
|
|
||||||
probe_sides(m, uncertainty);
|
probe_sides(m, uncertainty);
|
||||||
|
|
||||||
/* Adjust the hotend offset */
|
// Adjust the hotend offset
|
||||||
#if HOTENDS > 1
|
#if HOTENDS > 1
|
||||||
#if HAS_X_CENTER
|
#if HAS_X_CENTER
|
||||||
hotend_offset[X_AXIS][extruder] += m.pos_error[X_AXIS];
|
hotend_offset[X_AXIS][extruder] += m.pos_error[X_AXIS];
|
||||||
|
@ -545,8 +560,8 @@ inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const
|
||||||
* uncertainty in - How far away from the object to begin probing
|
* uncertainty in - How far away from the object to begin probing
|
||||||
*/
|
*/
|
||||||
inline void calibrate_all_toolheads(measurements_t &m, const float uncertainty) {
|
inline void calibrate_all_toolheads(measurements_t &m, const float uncertainty) {
|
||||||
TEMPORARY_BACKLASH_STATE(true);
|
TEMPORARY_BACKLASH_CORRECTION(1.0f);
|
||||||
TEMPORARY_BACKLASH_SMOOTHING(0);
|
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
||||||
|
|
||||||
HOTEND_LOOP() calibrate_toolhead(m, uncertainty, e);
|
HOTEND_LOOP() calibrate_toolhead(m, uncertainty, e);
|
||||||
|
|
||||||
|
@ -574,23 +589,22 @@ inline void calibrate_all() {
|
||||||
reset_nozzle_offsets();
|
reset_nozzle_offsets();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEMPORARY_BACKLASH_STATE(true);
|
TEMPORARY_BACKLASH_CORRECTION(1.0f);
|
||||||
TEMPORARY_BACKLASH_SMOOTHING(0);
|
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
||||||
|
|
||||||
|
// Do a fast and rough calibration of the toolheads
|
||||||
/* Do a fast and rough calibration of the toolheads */
|
|
||||||
calibrate_all_toolheads(m, CALIBRATION_MEASUREMENT_UNKNOWN);
|
calibrate_all_toolheads(m, CALIBRATION_MEASUREMENT_UNKNOWN);
|
||||||
|
|
||||||
#if ENABLED(BACKLASH_GCODE)
|
#if ENABLED(BACKLASH_GCODE)
|
||||||
calibrate_backlash(m, CALIBRATION_MEASUREMENT_UNCERTAIN);
|
calibrate_backlash(m, CALIBRATION_MEASUREMENT_UNCERTAIN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Cycle the toolheads so the servos settle into their "natural" positions */
|
// Cycle the toolheads so the servos settle into their "natural" positions
|
||||||
#if HOTENDS > 1
|
#if HOTENDS > 1
|
||||||
HOTEND_LOOP() set_nozzle(m, e);
|
HOTEND_LOOP() set_nozzle(m, e);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Do a slow and precise calibration of the toolheads */
|
// Do a slow and precise calibration of the toolheads
|
||||||
calibrate_all_toolheads(m, CALIBRATION_MEASUREMENT_UNCERTAIN);
|
calibrate_all_toolheads(m, CALIBRATION_MEASUREMENT_UNCERTAIN);
|
||||||
|
|
||||||
move_to(X_AXIS, 150); // Park nozzle away from calibration object
|
move_to(X_AXIS, 150); // Park nozzle away from calibration object
|
||||||
|
@ -607,6 +621,9 @@ inline void calibrate_all() {
|
||||||
* no args - Perform entire calibration sequence (backlash + position on all toolheads)
|
* no args - Perform entire calibration sequence (backlash + position on all toolheads)
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::G425() {
|
void GcodeSuite::G425() {
|
||||||
|
TEMPORARY_SOFT_ENDSTOP_STATE(false);
|
||||||
|
TEMPORARY_BED_LEVELING_STATE(false);
|
||||||
|
|
||||||
if (axis_unhomed_error()) return;
|
if (axis_unhomed_error()) return;
|
||||||
|
|
||||||
measurements_t m;
|
measurements_t m;
|
||||||
|
|
Reference in a new issue