🐛 Fix backlash applied steps when config changes (#23826)
Followup to #23814
This commit is contained in:
parent
2d648e4dd9
commit
41a51e9527
8 changed files with 167 additions and 117 deletions
|
@ -30,9 +30,7 @@
|
||||||
#include "../module/planner.h"
|
#include "../module/planner.h"
|
||||||
|
|
||||||
axis_bits_t Backlash::last_direction_bits;
|
axis_bits_t Backlash::last_direction_bits;
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
xyz_long_t Backlash::residual_error{0};
|
||||||
xyz_long_t Backlash::residual_error{0};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BACKLASH_DISTANCE_MM
|
#ifdef BACKLASH_DISTANCE_MM
|
||||||
#if ENABLED(BACKLASH_GCODE)
|
#if ENABLED(BACKLASH_GCODE)
|
||||||
|
@ -43,7 +41,7 @@ axis_bits_t Backlash::last_direction_bits;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(BACKLASH_GCODE)
|
#if ENABLED(BACKLASH_GCODE)
|
||||||
uint8_t Backlash::correction = (BACKLASH_CORRECTION) * 0xFF;
|
uint8_t Backlash::correction = (BACKLASH_CORRECTION) * all_on;
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
float Backlash::smoothing_mm = BACKLASH_SMOOTHING_MM;
|
float Backlash::smoothing_mm = BACKLASH_SMOOTHING_MM;
|
||||||
#endif
|
#endif
|
||||||
|
@ -87,7 +85,7 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const
|
||||||
#endif
|
#endif
|
||||||
last_direction_bits ^= changed_dir;
|
last_direction_bits ^= changed_dir;
|
||||||
|
|
||||||
if (correction == 0) return;
|
if (!correction && !residual_error) return;
|
||||||
|
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
// The segment proportion is a value greater than 0.0 indicating how much residual_error
|
// The segment proportion is a value greater than 0.0 indicating how much residual_error
|
||||||
|
@ -95,35 +93,28 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const
|
||||||
// smoothing distance. Since the computation of this proportion involves a floating point
|
// smoothing distance. Since the computation of this proportion involves a floating point
|
||||||
// division, defer computation until needed.
|
// division, defer computation until needed.
|
||||||
float segment_proportion = 0;
|
float segment_proportion = 0;
|
||||||
#else
|
|
||||||
// No direction change, no correction.
|
|
||||||
if (!changed_dir) return;
|
|
||||||
// No leftover residual error from segment to segment
|
|
||||||
xyz_long_t residual_error{0};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const float f_corr = float(correction) / 255.0f;
|
const float f_corr = float(correction) / all_on;
|
||||||
|
|
||||||
LOOP_LINEAR_AXES(axis) {
|
LOOP_LINEAR_AXES(axis) {
|
||||||
if (distance_mm[axis]) {
|
if (distance_mm[axis]) {
|
||||||
const bool reversing = TEST(dm,axis);
|
const bool reverse = TEST(dm, axis);
|
||||||
|
|
||||||
// When an axis changes direction, add axis backlash to the residual error
|
// When an axis changes direction, add axis backlash to the residual error
|
||||||
if (TEST(changed_dir, axis))
|
if (TEST(changed_dir, axis))
|
||||||
residual_error[axis] += (reversing ? -f_corr : f_corr) * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis];
|
residual_error[axis] += (reverse ? -f_corr : f_corr) * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis];
|
||||||
|
|
||||||
// Decide how much of the residual error to correct in this segment
|
// Decide how much of the residual error to correct in this segment
|
||||||
int32_t error_correction = residual_error[axis];
|
int32_t error_correction = residual_error[axis];
|
||||||
|
if (reverse != (error_correction < 0))
|
||||||
|
error_correction = 0; // Don't take up any backlash in this segment, as it would subtract steps
|
||||||
|
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
if (error_correction && smoothing_mm != 0) {
|
if (error_correction && smoothing_mm != 0) {
|
||||||
// Take up a portion of the residual_error in this segment, but only when
|
// Take up a portion of the residual_error in this segment
|
||||||
// the current segment travels in the same direction as the correction
|
if (segment_proportion == 0) segment_proportion = _MIN(1.0f, block->millimeters / smoothing_mm);
|
||||||
if (reversing == (error_correction < 0)) {
|
error_correction = CEIL(segment_proportion * error_correction);
|
||||||
if (segment_proportion == 0) segment_proportion = _MIN(1.0f, block->millimeters / smoothing_mm);
|
|
||||||
error_correction = CEIL(segment_proportion * error_correction);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
error_correction = 0; // Don't take up any backlash in this segment, as it would subtract steps
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -153,27 +144,52 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Backlash::applied_steps(const AxisEnum axis) {
|
int32_t Backlash::get_applied_steps(const AxisEnum axis) {
|
||||||
if (axis >= LINEAR_AXES) return 0;
|
if (axis >= LINEAR_AXES) return 0;
|
||||||
|
|
||||||
const bool reversing = TEST(last_direction_bits, axis);
|
const bool reverse = TEST(last_direction_bits, axis);
|
||||||
|
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
const int32_t residual_error_axis = residual_error[axis];
|
||||||
const int32_t residual_error_axis = residual_error[axis];
|
|
||||||
#else
|
|
||||||
constexpr int32_t residual_error_axis = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// At startup it is assumed the last move was forwards. So the applied
|
// At startup it is assumed the last move was forwards. So the applied
|
||||||
// steps will always be a non-positive number.
|
// steps will always be a non-positive number.
|
||||||
|
|
||||||
if (!reversing) return -residual_error_axis;
|
if (!reverse) return -residual_error_axis;
|
||||||
|
|
||||||
const float f_corr = float(correction) / 255.0f;
|
const float f_corr = float(correction) / all_on;
|
||||||
const int32_t full_error_axis = -f_corr * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis];
|
const int32_t full_error_axis = -f_corr * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis];
|
||||||
return full_error_axis - residual_error_axis;
|
return full_error_axis - residual_error_axis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Backlash::StepAdjuster {
|
||||||
|
xyz_long_t applied_steps;
|
||||||
|
public:
|
||||||
|
StepAdjuster() {
|
||||||
|
LOOP_LINEAR_AXES(axis) applied_steps[axis] = backlash.get_applied_steps((AxisEnum)axis);
|
||||||
|
}
|
||||||
|
~StepAdjuster() {
|
||||||
|
// after backlash compensation parameter changes, ensure applied step count does not change
|
||||||
|
LOOP_LINEAR_AXES(axis) residual_error[axis] += backlash.get_applied_steps((AxisEnum)axis) - applied_steps[axis];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void Backlash::set_correction_uint8(const uint8_t v) {
|
||||||
|
StepAdjuster adjuster;
|
||||||
|
correction = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Backlash::set_distance_mm(const AxisEnum axis, const float v) {
|
||||||
|
StepAdjuster adjuster;
|
||||||
|
distance_mm[axis] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
|
void Backlash::set_smoothing_mm(const float v) {
|
||||||
|
StepAdjuster adjuster;
|
||||||
|
smoothing_mm = v;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
||||||
|
|
||||||
#include "../module/probe.h"
|
#include "../module/probe.h"
|
||||||
|
|
|
@ -24,27 +24,22 @@
|
||||||
#include "../inc/MarlinConfigPre.h"
|
#include "../inc/MarlinConfigPre.h"
|
||||||
#include "../module/planner.h"
|
#include "../module/planner.h"
|
||||||
|
|
||||||
constexpr uint8_t all_on = 0xFF, all_off = 0x00;
|
|
||||||
|
|
||||||
class Backlash {
|
class Backlash {
|
||||||
|
public:
|
||||||
|
static constexpr uint8_t all_on = 0xFF, all_off = 0x00;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static axis_bits_t last_direction_bits;
|
static axis_bits_t last_direction_bits;
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
static xyz_long_t residual_error;
|
||||||
static xyz_long_t residual_error;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
#if ENABLED(BACKLASH_GCODE)
|
#if ENABLED(BACKLASH_GCODE)
|
||||||
static xyz_float_t distance_mm;
|
|
||||||
static uint8_t correction;
|
static uint8_t correction;
|
||||||
|
static xyz_float_t distance_mm;
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
static float smoothing_mm;
|
static float smoothing_mm;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void set_correction(const_float_t v) { correction = _MAX(0, _MIN(1.0, v)) * all_on; }
|
|
||||||
static float get_correction() { return float(ui8_to_percent(correction)) / 100.0f; }
|
|
||||||
#else
|
#else
|
||||||
static constexpr uint8_t correction = (BACKLASH_CORRECTION) * 0xFF;
|
static constexpr uint8_t correction = (BACKLASH_CORRECTION) * all_on;
|
||||||
static const xyz_float_t distance_mm;
|
static const xyz_float_t distance_mm;
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
static constexpr float smoothing_mm = BACKLASH_SMOOTHING_MM;
|
static constexpr float smoothing_mm = BACKLASH_SMOOTHING_MM;
|
||||||
|
@ -52,13 +47,13 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
||||||
private:
|
static xyz_float_t measured_mm;
|
||||||
static xyz_float_t measured_mm;
|
static xyz_uint8_t measured_count;
|
||||||
static xyz_uint8_t measured_count;
|
|
||||||
public:
|
|
||||||
static void measure_with_probe();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class StepAdjuster;
|
||||||
|
|
||||||
|
public:
|
||||||
static float get_measurement(const AxisEnum a) {
|
static float get_measurement(const AxisEnum a) {
|
||||||
UNUSED(a);
|
UNUSED(a);
|
||||||
// Return the measurement averaged over all readings
|
// Return the measurement averaged over all readings
|
||||||
|
@ -78,7 +73,24 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const axis_bits_t dm, block_t * const block);
|
static void add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const axis_bits_t dm, block_t * const block);
|
||||||
static int32_t applied_steps(const AxisEnum axis);
|
static int32_t get_applied_steps(const AxisEnum axis);
|
||||||
|
|
||||||
|
#if ENABLED(BACKLASH_GCODE)
|
||||||
|
static void set_correction_uint8(const uint8_t v);
|
||||||
|
static uint8_t get_correction_uint8() { return correction; }
|
||||||
|
static void set_correction(const float v) { set_correction_uint8(_MAX(0, _MIN(1.0, v)) * all_on + 0.5f); }
|
||||||
|
static float get_correction() { return float(get_correction_uint8()) / all_on; }
|
||||||
|
static void set_distance_mm(const AxisEnum axis, const float v);
|
||||||
|
static float get_distance_mm(const AxisEnum axis) {return distance_mm[axis];}
|
||||||
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
|
static void set_smoothing_mm(const float v);
|
||||||
|
static float get_smoothing_mm() {return smoothing_mm;}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
||||||
|
static void measure_with_probe();
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Backlash backlash;
|
extern Backlash backlash;
|
||||||
|
|
|
@ -105,13 +105,27 @@ struct measurements_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
#if ENABLED(BACKLASH_GCODE)
|
#if ENABLED(BACKLASH_GCODE)
|
||||||
#define TEMPORARY_BACKLASH_CORRECTION(value) REMEMBER(tbst, backlash.correction, value)
|
class restorer_correction {
|
||||||
|
const uint8_t val_;
|
||||||
|
public:
|
||||||
|
restorer_correction(const uint8_t temp_val) : val_(backlash.get_correction_uint8()) { backlash.set_correction_uint8(temp_val); }
|
||||||
|
~restorer_correction() { backlash.set_correction_uint8(val_); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TEMPORARY_BACKLASH_CORRECTION(value) restorer_correction restorer_tbst(value)
|
||||||
#else
|
#else
|
||||||
#define TEMPORARY_BACKLASH_CORRECTION(value)
|
#define TEMPORARY_BACKLASH_CORRECTION(value)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
|
#if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
|
||||||
#define TEMPORARY_BACKLASH_SMOOTHING(value) REMEMBER(tbsm, backlash.smoothing_mm, value)
|
class restorer_smoothing {
|
||||||
|
const float val_;
|
||||||
|
public:
|
||||||
|
restorer_smoothing(const float temp_val) : val_(backlash.get_smoothing_mm()) { backlash.set_smoothing_mm(temp_val); }
|
||||||
|
~restorer_smoothing() { backlash.set_smoothing_mm(val_); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TEMPORARY_BACKLASH_SMOOTHING(value) restorer_smoothing restorer_tbsm(value)
|
||||||
#else
|
#else
|
||||||
#define TEMPORARY_BACKLASH_SMOOTHING(value)
|
#define TEMPORARY_BACKLASH_SMOOTHING(value)
|
||||||
#endif
|
#endif
|
||||||
|
@ -524,7 +538,7 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
|
||||||
|
|
||||||
{
|
{
|
||||||
// New scope for TEMPORARY_BACKLASH_CORRECTION
|
// New scope for TEMPORARY_BACKLASH_CORRECTION
|
||||||
TEMPORARY_BACKLASH_CORRECTION(all_off);
|
TEMPORARY_BACKLASH_CORRECTION(backlash.all_off);
|
||||||
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
||||||
|
|
||||||
probe_sides(m, uncertainty);
|
probe_sides(m, uncertainty);
|
||||||
|
@ -532,45 +546,45 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
|
||||||
#if ENABLED(BACKLASH_GCODE)
|
#if ENABLED(BACKLASH_GCODE)
|
||||||
|
|
||||||
#if HAS_X_CENTER
|
#if HAS_X_CENTER
|
||||||
backlash.distance_mm.x = (m.backlash[LEFT] + m.backlash[RIGHT]) / 2;
|
backlash.set_distance_mm(X_AXIS, (m.backlash[LEFT] + m.backlash[RIGHT]) / 2);
|
||||||
#elif ENABLED(CALIBRATION_MEASURE_LEFT)
|
#elif ENABLED(CALIBRATION_MEASURE_LEFT)
|
||||||
backlash.distance_mm.x = m.backlash[LEFT];
|
backlash.set_distance_mm(X_AXIS, m.backlash[LEFT]);
|
||||||
#elif ENABLED(CALIBRATION_MEASURE_RIGHT)
|
#elif ENABLED(CALIBRATION_MEASURE_RIGHT)
|
||||||
backlash.distance_mm.x = m.backlash[RIGHT];
|
backlash.set_distance_mm(X_AXIS, m.backlash[RIGHT]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_Y_CENTER
|
#if HAS_Y_CENTER
|
||||||
backlash.distance_mm.y = (m.backlash[FRONT] + m.backlash[BACK]) / 2;
|
backlash.set_distance_mm(Y_AXIS, (m.backlash[FRONT] + m.backlash[BACK]) / 2);
|
||||||
#elif ENABLED(CALIBRATION_MEASURE_FRONT)
|
#elif ENABLED(CALIBRATION_MEASURE_FRONT)
|
||||||
backlash.distance_mm.y = m.backlash[FRONT];
|
backlash.set_distance_mm(Y_AXIS, m.backlash[FRONT]);
|
||||||
#elif ENABLED(CALIBRATION_MEASURE_BACK)
|
#elif ENABLED(CALIBRATION_MEASURE_BACK)
|
||||||
backlash.distance_mm.y = m.backlash[BACK];
|
backlash.set_distance_mm(Y_AXIS, m.backlash[BACK]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TERN_(HAS_Z_AXIS, if (AXIS_CAN_CALIBRATE(Z)) backlash.distance_mm.z = m.backlash[TOP]);
|
TERN_(HAS_Z_AXIS, if (AXIS_CAN_CALIBRATE(Z)) backlash.set_distance_mm(Z_AXIS, m.backlash[TOP]));
|
||||||
|
|
||||||
#if HAS_I_CENTER
|
#if HAS_I_CENTER
|
||||||
backlash.distance_mm.i = (m.backlash[IMINIMUM] + m.backlash[IMAXIMUM]) / 2;
|
backlash.set_distance_mm(I_AXIS, (m.backlash[IMINIMUM] + m.backlash[IMAXIMUM]) / 2);
|
||||||
#elif ENABLED(CALIBRATION_MEASURE_IMIN)
|
#elif ENABLED(CALIBRATION_MEASURE_IMIN)
|
||||||
backlash.distance_mm.i = m.backlash[IMINIMUM];
|
backlash.set_distance_mm(I_AXIS, m.backlash[IMINIMUM]);
|
||||||
#elif ENABLED(CALIBRATION_MEASURE_IMAX)
|
#elif ENABLED(CALIBRATION_MEASURE_IMAX)
|
||||||
backlash.distance_mm.i = m.backlash[IMAXIMUM];
|
backlash.set_distance_mm(I_AXIS, m.backlash[IMAXIMUM]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_J_CENTER
|
#if HAS_J_CENTER
|
||||||
backlash.distance_mm.j = (m.backlash[JMINIMUM] + m.backlash[JMAXIMUM]) / 2;
|
backlash.set_distance_mm(J_AXIS, (m.backlash[JMINIMUM] + m.backlash[JMAXIMUM]) / 2);
|
||||||
#elif ENABLED(CALIBRATION_MEASURE_JMIN)
|
#elif ENABLED(CALIBRATION_MEASURE_JMIN)
|
||||||
backlash.distance_mm.j = m.backlash[JMINIMUM];
|
backlash.set_distance_mm(J_AXIS, m.backlash[JMINIMUM]);
|
||||||
#elif ENABLED(CALIBRATION_MEASURE_JMAX)
|
#elif ENABLED(CALIBRATION_MEASURE_JMAX)
|
||||||
backlash.distance_mm.j = m.backlash[JMAXIMUM];
|
backlash.set_distance_mm(J_AXIS, m.backlash[JMAXIMUM]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_K_CENTER
|
#if HAS_K_CENTER
|
||||||
backlash.distance_mm.k = (m.backlash[KMINIMUM] + m.backlash[KMAXIMUM]) / 2;
|
backlash.set_distance_mm(K_AXIS, (m.backlash[KMINIMUM] + m.backlash[KMAXIMUM]) / 2);
|
||||||
#elif ENABLED(CALIBRATION_MEASURE_KMIN)
|
#elif ENABLED(CALIBRATION_MEASURE_KMIN)
|
||||||
backlash.distance_mm.k = m.backlash[KMINIMUM];
|
backlash.set_distance_mm(K_AXIS, m.backlash[KMINIMUM]);
|
||||||
#elif ENABLED(CALIBRATION_MEASURE_KMAX)
|
#elif ENABLED(CALIBRATION_MEASURE_KMAX)
|
||||||
backlash.distance_mm.k = m.backlash[KMAXIMUM];
|
backlash.set_distance_mm(K_AXIS, m.backlash[KMAXIMUM]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // BACKLASH_GCODE
|
#endif // BACKLASH_GCODE
|
||||||
|
@ -581,7 +595,7 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
|
||||||
// allowed directions to take up any backlash
|
// allowed directions to take up any backlash
|
||||||
{
|
{
|
||||||
// New scope for TEMPORARY_BACKLASH_CORRECTION
|
// New scope for TEMPORARY_BACKLASH_CORRECTION
|
||||||
TEMPORARY_BACKLASH_CORRECTION(all_on);
|
TEMPORARY_BACKLASH_CORRECTION(backlash.all_on);
|
||||||
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
||||||
const xyz_float_t move = LINEAR_AXIS_ARRAY(
|
const xyz_float_t move = LINEAR_AXIS_ARRAY(
|
||||||
AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3,
|
AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3,
|
||||||
|
@ -611,7 +625,7 @@ 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_CORRECTION(all_on);
|
TEMPORARY_BACKLASH_CORRECTION(backlash.all_on);
|
||||||
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
||||||
|
|
||||||
TERN(HAS_MULTI_HOTEND, set_nozzle(m, extruder), UNUSED(extruder));
|
TERN(HAS_MULTI_HOTEND, set_nozzle(m, extruder), UNUSED(extruder));
|
||||||
|
@ -648,7 +662,7 @@ 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_CORRECTION(all_on);
|
TEMPORARY_BACKLASH_CORRECTION(backlash.all_on);
|
||||||
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
||||||
|
|
||||||
HOTEND_LOOP() calibrate_toolhead(m, uncertainty, e);
|
HOTEND_LOOP() calibrate_toolhead(m, uncertainty, e);
|
||||||
|
@ -674,7 +688,7 @@ inline void calibrate_all() {
|
||||||
|
|
||||||
TERN_(HAS_HOTEND_OFFSET, reset_hotend_offsets());
|
TERN_(HAS_HOTEND_OFFSET, reset_hotend_offsets());
|
||||||
|
|
||||||
TEMPORARY_BACKLASH_CORRECTION(all_on);
|
TEMPORARY_BACKLASH_CORRECTION(backlash.all_on);
|
||||||
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
||||||
|
|
||||||
// Do a fast and rough calibration of the toolheads
|
// Do a fast and rough calibration of the toolheads
|
||||||
|
|
|
@ -63,7 +63,7 @@ void GcodeSuite::M425() {
|
||||||
LOOP_LINEAR_AXES(a) {
|
LOOP_LINEAR_AXES(a) {
|
||||||
if (axis_can_calibrate(a) && parser.seen(AXIS_CHAR(a))) {
|
if (axis_can_calibrate(a) && parser.seen(AXIS_CHAR(a))) {
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
backlash.distance_mm[a] = parser.has_value() ? parser.value_linear_units() : backlash.get_measurement(AxisEnum(a));
|
backlash.set_distance_mm(AxisEnum(a), parser.has_value() ? parser.value_linear_units() : backlash.get_measurement(AxisEnum(a)));
|
||||||
noArgs = false;
|
noArgs = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,25 +77,25 @@ void GcodeSuite::M425() {
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
if (parser.seen('S')) {
|
if (parser.seen('S')) {
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
backlash.smoothing_mm = parser.value_linear_units();
|
backlash.set_smoothing_mm(parser.value_linear_units());
|
||||||
noArgs = false;
|
noArgs = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (noArgs) {
|
if (noArgs) {
|
||||||
SERIAL_ECHOPGM("Backlash Correction ");
|
SERIAL_ECHOPGM("Backlash Correction ");
|
||||||
if (!backlash.correction) SERIAL_ECHOPGM("in");
|
if (!backlash.get_correction_uint8()) SERIAL_ECHOPGM("in");
|
||||||
SERIAL_ECHOLNPGM("active:");
|
SERIAL_ECHOLNPGM("active:");
|
||||||
SERIAL_ECHOLNPGM(" Correction Amount/Fade-out: F", backlash.get_correction(), " (F1.0 = full, F0.0 = none)");
|
SERIAL_ECHOLNPGM(" Correction Amount/Fade-out: F", backlash.get_correction(), " (F1.0 = full, F0.0 = none)");
|
||||||
SERIAL_ECHOPGM(" Backlash Distance (mm): ");
|
SERIAL_ECHOPGM(" Backlash Distance (mm): ");
|
||||||
LOOP_LINEAR_AXES(a) if (axis_can_calibrate(a)) {
|
LOOP_LINEAR_AXES(a) if (axis_can_calibrate(a)) {
|
||||||
SERIAL_CHAR(' ', AXIS_CHAR(a));
|
SERIAL_CHAR(' ', AXIS_CHAR(a));
|
||||||
SERIAL_ECHO(backlash.distance_mm[a]);
|
SERIAL_ECHO(backlash.get_distance_mm(AxisEnum(a)));
|
||||||
SERIAL_EOL();
|
SERIAL_EOL();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
SERIAL_ECHOLNPGM(" Smoothing (mm): S", backlash.smoothing_mm);
|
SERIAL_ECHOLNPGM(" Smoothing (mm): S", backlash.get_smoothing_mm());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
||||||
|
@ -118,15 +118,15 @@ void GcodeSuite::M425_report(const bool forReplay/*=true*/) {
|
||||||
SERIAL_ECHOLNPGM_P(
|
SERIAL_ECHOLNPGM_P(
|
||||||
PSTR(" M425 F"), backlash.get_correction()
|
PSTR(" M425 F"), backlash.get_correction()
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
, PSTR(" S"), LINEAR_UNIT(backlash.smoothing_mm)
|
, PSTR(" S"), LINEAR_UNIT(backlash.get_smoothing_mm())
|
||||||
#endif
|
#endif
|
||||||
, LIST_N(DOUBLE(LINEAR_AXES),
|
, LIST_N(DOUBLE(LINEAR_AXES),
|
||||||
SP_X_STR, LINEAR_UNIT(backlash.distance_mm.x),
|
SP_X_STR, LINEAR_UNIT(backlash.get_distance_mm(X_AXIS)),
|
||||||
SP_Y_STR, LINEAR_UNIT(backlash.distance_mm.y),
|
SP_Y_STR, LINEAR_UNIT(backlash.get_distance_mm(Y_AXIS)),
|
||||||
SP_Z_STR, LINEAR_UNIT(backlash.distance_mm.z),
|
SP_Z_STR, LINEAR_UNIT(backlash.get_distance_mm(Z_AXIS)),
|
||||||
SP_I_STR, LINEAR_UNIT(backlash.distance_mm.i),
|
SP_I_STR, LINEAR_UNIT(backlash.get_distance_mm(I_AXIS)),
|
||||||
SP_J_STR, LINEAR_UNIT(backlash.distance_mm.j),
|
SP_J_STR, LINEAR_UNIT(backlash.get_distance_mm(J_AXIS)),
|
||||||
SP_K_STR, LINEAR_UNIT(backlash.distance_mm.k)
|
SP_K_STR, LINEAR_UNIT(backlash.get_distance_mm(K_AXIS))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -861,16 +861,16 @@ namespace ExtUI {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(BACKLASH_GCODE)
|
#if ENABLED(BACKLASH_GCODE)
|
||||||
float getAxisBacklash_mm(const axis_t axis) { return backlash.distance_mm[axis]; }
|
float getAxisBacklash_mm(const axis_t axis) { return backlash.get_distance_mm((AxisEnum)axis); }
|
||||||
void setAxisBacklash_mm(const_float_t value, const axis_t axis)
|
void setAxisBacklash_mm(const_float_t value, const axis_t axis)
|
||||||
{ backlash.distance_mm[axis] = constrain(value,0,5); }
|
{ backlash.set_distance_mm((AxisEnum)axis, constrain(value,0,5)); }
|
||||||
|
|
||||||
float getBacklashCorrection_percent() { return ui8_to_percent(backlash.correction); }
|
float getBacklashCorrection_percent() { return backlash.get_correction() * 100.0f; }
|
||||||
void setBacklashCorrection_percent(const_float_t value) { backlash.correction = map(constrain(value, 0, 100), 0, 100, 0, 255); }
|
void setBacklashCorrection_percent(const_float_t value) { backlash.set_correction(constrain(value, 0, 100) / 100.0f); }
|
||||||
|
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
float getBacklashSmoothing_mm() { return backlash.smoothing_mm; }
|
float getBacklashSmoothing_mm() { return backlash.get_smoothing_mm(); }
|
||||||
void setBacklashSmoothing_mm(const_float_t value) { backlash.smoothing_mm = constrain(value, 0, 999); }
|
void setBacklashSmoothing_mm(const_float_t value) { backlash.set_smoothing_mm(constrain(value, 0, 999)); }
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -36,14 +36,20 @@ void menu_backlash() {
|
||||||
START_MENU();
|
START_MENU();
|
||||||
BACK_ITEM(MSG_MAIN);
|
BACK_ITEM(MSG_MAIN);
|
||||||
|
|
||||||
EDIT_ITEM_FAST(percent, MSG_BACKLASH_CORRECTION, &backlash.correction, all_off, all_on);
|
editable.uint8 = backlash.get_correction_uint8();
|
||||||
|
EDIT_ITEM_FAST(percent, MSG_BACKLASH_CORRECTION, &editable.uint8, backlash.all_off, backlash.all_on, []{ backlash.set_correction_uint8(editable.uint8); });
|
||||||
|
|
||||||
#if DISABLED(CORE_BACKLASH) || EITHER(MARKFORGED_XY, MARKFORGED_YX)
|
#if DISABLED(CORE_BACKLASH) || EITHER(MARKFORGED_XY, MARKFORGED_YX)
|
||||||
#define _CAN_CALI AXIS_CAN_CALIBRATE
|
#define _CAN_CALI AXIS_CAN_CALIBRATE
|
||||||
#else
|
#else
|
||||||
#define _CAN_CALI(A) true
|
#define _CAN_CALI(A) true
|
||||||
#endif
|
#endif
|
||||||
#define EDIT_BACKLASH_DISTANCE(N) EDIT_ITEM_FAST(float43, MSG_BACKLASH_##N, &backlash.distance_mm[_AXIS(N)], 0.0f, 9.9f);
|
|
||||||
|
#define EDIT_BACKLASH_DISTANCE(N) do { \
|
||||||
|
editable.decimal = backlash.get_distance_mm(_AXIS(N)); \
|
||||||
|
EDIT_ITEM_FAST(float43, MSG_BACKLASH_##N, &editable.decimal, 0.0f, 9.9f, []{ backlash.set_distance_mm(_AXIS(N), editable.decimal); }); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
if (_CAN_CALI(A)) EDIT_BACKLASH_DISTANCE(A);
|
if (_CAN_CALI(A)) EDIT_BACKLASH_DISTANCE(A);
|
||||||
#if HAS_Y_AXIS && _CAN_CALI(B)
|
#if HAS_Y_AXIS && _CAN_CALI(B)
|
||||||
EDIT_BACKLASH_DISTANCE(B);
|
EDIT_BACKLASH_DISTANCE(B);
|
||||||
|
@ -62,7 +68,8 @@ void menu_backlash() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
EDIT_ITEM_FAST(float43, MSG_BACKLASH_SMOOTHING, &backlash.smoothing_mm, 0.0f, 9.9f);
|
editable.decimal = backlash.get_smoothing_mm();
|
||||||
|
EDIT_ITEM_FAST(float43, MSG_BACKLASH_SMOOTHING, &editable.decimal, 0.0f, 9.9f, []{ backlash.set_smoothing_mm(editable.decimal); });
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
END_MENU();
|
END_MENU();
|
||||||
|
|
|
@ -1706,7 +1706,7 @@ void Planner::endstop_triggered(const AxisEnum axis) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float Planner::triggered_position_mm(const AxisEnum axis) {
|
float Planner::triggered_position_mm(const AxisEnum axis) {
|
||||||
const float result = DIFF_TERN(BACKLASH_COMPENSATION, stepper.triggered_position(axis), backlash.applied_steps(axis));
|
const float result = DIFF_TERN(BACKLASH_COMPENSATION, stepper.triggered_position(axis), backlash.get_applied_steps(axis));
|
||||||
return result * mm_per_step[axis];
|
return result * mm_per_step[axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1729,8 +1729,8 @@ float Planner::get_axis_position_mm(const AxisEnum axis) {
|
||||||
// Protect the access to the position.
|
// Protect the access to the position.
|
||||||
const bool was_enabled = stepper.suspend();
|
const bool was_enabled = stepper.suspend();
|
||||||
|
|
||||||
const int32_t p1 = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(CORE_AXIS_1), backlash.applied_steps(CORE_AXIS_1)),
|
const int32_t p1 = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(CORE_AXIS_1), backlash.get_applied_steps(CORE_AXIS_1)),
|
||||||
p2 = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(CORE_AXIS_2), backlash.applied_steps(CORE_AXIS_2));
|
p2 = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(CORE_AXIS_2), backlash.get_applied_steps(CORE_AXIS_2));
|
||||||
|
|
||||||
if (was_enabled) stepper.wake_up();
|
if (was_enabled) stepper.wake_up();
|
||||||
|
|
||||||
|
@ -1739,7 +1739,7 @@ float Planner::get_axis_position_mm(const AxisEnum axis) {
|
||||||
axis_steps = (axis == CORE_AXIS_2 ? CORESIGN(p1 - p2) : p1 + p2) * 0.5f;
|
axis_steps = (axis == CORE_AXIS_2 ? CORESIGN(p1 - p2) : p1 + p2) * 0.5f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
axis_steps = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(axis), backlash.applied_steps(axis));
|
axis_steps = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(axis), backlash.get_applied_steps(axis));
|
||||||
|
|
||||||
#elif EITHER(MARKFORGED_XY, MARKFORGED_YX)
|
#elif EITHER(MARKFORGED_XY, MARKFORGED_YX)
|
||||||
|
|
||||||
|
@ -1756,12 +1756,12 @@ float Planner::get_axis_position_mm(const AxisEnum axis) {
|
||||||
axis_steps = ((axis == CORE_AXIS_1) ? p1 - p2 : p2);
|
axis_steps = ((axis == CORE_AXIS_1) ? p1 - p2 : p2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
axis_steps = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(axis), backlash.applied_steps(axis));
|
axis_steps = DIFF_TERN(BACKLASH_COMPENSATION, stepper.position(axis), backlash.get_applied_steps(axis));
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
axis_steps = stepper.position(axis);
|
axis_steps = stepper.position(axis);
|
||||||
TERN_(BACKLASH_COMPENSATION, axis_steps -= backlash.applied_steps(axis));
|
TERN_(BACKLASH_COMPENSATION, axis_steps -= backlash.get_applied_steps(axis));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2844,7 +2844,7 @@ void Planner::buffer_sync_block(TERN_(LASER_SYNCHRONOUS_M106_M107, uint8_t sync_
|
||||||
|
|
||||||
block->position = position;
|
block->position = position;
|
||||||
#if ENABLED(BACKLASH_COMPENSATION)
|
#if ENABLED(BACKLASH_COMPENSATION)
|
||||||
LOOP_LINEAR_AXES(axis) block->position[axis] += backlash.applied_steps((AxisEnum)axis);
|
LOOP_LINEAR_AXES(axis) block->position[axis] += backlash.get_applied_steps((AxisEnum)axis);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BOTH(HAS_FAN, LASER_SYNCHRONOUS_M106_M107)
|
#if BOTH(HAS_FAN, LASER_SYNCHRONOUS_M106_M107)
|
||||||
|
@ -3122,7 +3122,7 @@ void Planner::set_machine_position_mm(const abce_pos_t &abce) {
|
||||||
else {
|
else {
|
||||||
#if ENABLED(BACKLASH_COMPENSATION)
|
#if ENABLED(BACKLASH_COMPENSATION)
|
||||||
abce_long_t stepper_pos = position;
|
abce_long_t stepper_pos = position;
|
||||||
LOOP_LINEAR_AXES(axis) stepper_pos[axis] += backlash.applied_steps((AxisEnum)axis);
|
LOOP_LINEAR_AXES(axis) stepper_pos[axis] += backlash.get_applied_steps((AxisEnum)axis);
|
||||||
stepper.set_position(stepper_pos);
|
stepper.set_position(stepper_pos);
|
||||||
#else
|
#else
|
||||||
stepper.set_position(position);
|
stepper.set_position(position);
|
||||||
|
|
|
@ -1426,14 +1426,15 @@ void MarlinSettings::postprocess() {
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
#if ENABLED(BACKLASH_GCODE)
|
#if ENABLED(BACKLASH_GCODE)
|
||||||
const xyz_float_t &backlash_distance_mm = backlash.distance_mm;
|
xyz_float_t backlash_distance_mm;
|
||||||
const uint8_t &backlash_correction = backlash.correction;
|
LOOP_LINEAR_AXES(axis) backlash_distance_mm[axis] = backlash.get_distance_mm((AxisEnum)axis);
|
||||||
|
const uint8_t backlash_correction = backlash.get_correction_uint8();
|
||||||
#else
|
#else
|
||||||
const xyz_float_t backlash_distance_mm{0};
|
const xyz_float_t backlash_distance_mm{0};
|
||||||
const uint8_t backlash_correction = 0;
|
const uint8_t backlash_correction = 0;
|
||||||
#endif
|
#endif
|
||||||
#if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
|
#if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
|
||||||
const float &backlash_smoothing_mm = backlash.smoothing_mm;
|
const float backlash_smoothing_mm = backlash.get_smoothing_mm();
|
||||||
#else
|
#else
|
||||||
const float backlash_smoothing_mm = 3;
|
const float backlash_smoothing_mm = 3;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2364,22 +2365,22 @@ void MarlinSettings::postprocess() {
|
||||||
// Backlash Compensation
|
// Backlash Compensation
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
#if ENABLED(BACKLASH_GCODE)
|
xyz_float_t backlash_distance_mm;
|
||||||
const xyz_float_t &backlash_distance_mm = backlash.distance_mm;
|
uint8_t backlash_correction;
|
||||||
const uint8_t &backlash_correction = backlash.correction;
|
float backlash_smoothing_mm;
|
||||||
#else
|
|
||||||
xyz_float_t backlash_distance_mm;
|
|
||||||
uint8_t backlash_correction;
|
|
||||||
#endif
|
|
||||||
#if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
|
|
||||||
const float &backlash_smoothing_mm = backlash.smoothing_mm;
|
|
||||||
#else
|
|
||||||
float backlash_smoothing_mm;
|
|
||||||
#endif
|
|
||||||
_FIELD_TEST(backlash_distance_mm);
|
_FIELD_TEST(backlash_distance_mm);
|
||||||
EEPROM_READ(backlash_distance_mm);
|
EEPROM_READ(backlash_distance_mm);
|
||||||
EEPROM_READ(backlash_correction);
|
EEPROM_READ(backlash_correction);
|
||||||
EEPROM_READ(backlash_smoothing_mm);
|
EEPROM_READ(backlash_smoothing_mm);
|
||||||
|
|
||||||
|
#if ENABLED(BACKLASH_GCODE)
|
||||||
|
LOOP_LINEAR_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, backlash_distance_mm[axis]);
|
||||||
|
backlash.set_correction_uint8(backlash_correction);
|
||||||
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
|
backlash.set_smoothing_mm(backlash_smoothing_mm);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -2811,11 +2812,11 @@ void MarlinSettings::reset() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(BACKLASH_GCODE)
|
#if ENABLED(BACKLASH_GCODE)
|
||||||
backlash.correction = (BACKLASH_CORRECTION) * 255;
|
backlash.set_correction(BACKLASH_CORRECTION);
|
||||||
constexpr xyz_float_t tmp = BACKLASH_DISTANCE_MM;
|
constexpr xyz_float_t tmp = BACKLASH_DISTANCE_MM;
|
||||||
backlash.distance_mm = tmp;
|
LOOP_LINEAR_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, tmp[axis]);
|
||||||
#ifdef BACKLASH_SMOOTHING_MM
|
#ifdef BACKLASH_SMOOTHING_MM
|
||||||
backlash.smoothing_mm = BACKLASH_SMOOTHING_MM;
|
backlash.set_smoothing_mm(BACKLASH_SMOOTHING_MM);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue