Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding to #23814: correct backlash applied steps when config changes #23826

Merged
merged 23 commits into from
Mar 1, 2022
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6270df9
🐛 Fix Emder-3 V2 Enhanced SetFlow (#23016)
mriscoc Oct 25, 2021
f41c78d
🐛 Fix børken E_DUAL_STEPPER_DRIVERS (#23017)
ellensp Oct 25, 2021
2b19dc3
✨ Octopus Pro V1.0 with STM32F429ZGT6 (#23008)
thisiskeithb Oct 25, 2021
845faf2
Merge branch 'MarlinFirmware:bugfix-2.0.x' into bugfix-2.0.x
tombrazier Oct 26, 2021
19784bd
Merge branch 'MarlinFirmware:bugfix-2.0.x' into bugfix-2.0.x
tombrazier Oct 30, 2021
f90aec8
Merge branch 'MarlinFirmware:bugfix-2.0.x' into bugfix-2.0.x
tombrazier Nov 2, 2021
3c2eaab
Merge branch 'MarlinFirmware:bugfix-2.0.x' into bugfix-2.0.x
tombrazier Dec 24, 2021
a01056b
Merge branch 'MarlinFirmware:bugfix-2.0.x' into bugfix-2.0.x
tombrazier Feb 14, 2022
71cce1d
Merge branch 'MarlinFirmware:bugfix-2.0.x' into bugfix-2.0.x
tombrazier Feb 19, 2022
d664ff1
Merge branch 'MarlinFirmware:bugfix-2.0.x' into bugfix-2.0.x
tombrazier Feb 23, 2022
593839c
Merge branch 'MarlinFirmware:bugfix-2.0.x' into bugfix-2.0.x
tombrazier Feb 26, 2022
15c9e4c
Moved all_on and all_off constants into class Backlash.
tombrazier Feb 27, 2022
a5d4979
Moved all_on and all_off constants into class Backlash.
tombrazier Feb 27, 2022
8f1d76a
Made Backlash parameters private and added accessor functions. This w…
tombrazier Feb 28, 2022
7f2509b
Method rename to be more in line with the new accessor methods
tombrazier Feb 28, 2022
3f96f54
Applied #23814 effects when backlash compensation configuration changes
tombrazier Feb 28, 2022
e6da6fe
Added explanatory comment
tombrazier Feb 28, 2022
3e4e0e5
Fix build error for ftdi_eve_touch_ui
tombrazier Feb 28, 2022
36dc96e
simplify 'nothing to do'
thinkyhead Feb 28, 2022
0d2c9ec
style tweaks
thinkyhead Feb 28, 2022
f47f794
maybe this is the intent?
thinkyhead Feb 28, 2022
ea2a774
…as described
thinkyhead Feb 28, 2022
14adc71
xyz types have a bool operator
thinkyhead Feb 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 45 additions & 26 deletions Marlin/src/feature/backlash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@
#include "../module/planner.h"

axis_bits_t Backlash::last_direction_bits;
#ifdef BACKLASH_SMOOTHING_MM
xyz_long_t Backlash::residual_error{0};
#endif
xyz_long_t Backlash::residual_error{0};

#ifdef BACKLASH_DISTANCE_MM
#if ENABLED(BACKLASH_GCODE)
Expand All @@ -43,7 +41,7 @@ axis_bits_t Backlash::last_direction_bits;
#endif

#if ENABLED(BACKLASH_GCODE)
uint8_t Backlash::correction = (BACKLASH_CORRECTION) * 0xFF;
uint8_t Backlash::correction = (BACKLASH_CORRECTION) * all_on;
#ifdef BACKLASH_SMOOTHING_MM
float Backlash::smoothing_mm = BACKLASH_SMOOTHING_MM;
#endif
Expand Down Expand Up @@ -87,22 +85,20 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const
#endif
last_direction_bits ^= changed_dir;

if (correction == 0) return;
bool nothing_to_do = !correction;
for (uint8_t axis = 0; nothing_to_do && axis < LINEAR_AXES; axis++)
thinkyhead marked this conversation as resolved.
Show resolved Hide resolved
nothing_to_do = !residual_error[axis];
if (nothing_to_do) return;

#ifdef BACKLASH_SMOOTHING_MM
// The segment proportion is a value greater than 0.0 indicating how much residual_error
// is corrected for in this segment. The contribution is based on segment length and the
// smoothing distance. Since the computation of this proportion involves a floating point
// division, defer computation until needed.
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

const float f_corr = float(correction) / 255.0f;
const float f_corr = float(correction) / all_on;

LOOP_LINEAR_AXES(axis) {
if (distance_mm[axis]) {
Expand All @@ -114,16 +110,14 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const

// Decide how much of the residual error to correct in this segment
int32_t error_correction = residual_error[axis];
if (reversing != (error_correction < 0))
error_correction = 0; // Don't take up any backlash in this segment, as it would subtract steps

#ifdef BACKLASH_SMOOTHING_MM
if (error_correction && smoothing_mm != 0) {
// Take up a portion of the residual_error in this segment, but only when
// the current segment travels in the same direction as the correction
if (reversing == (error_correction < 0)) {
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
// Take up a portion of the residual_error in this segment
if (segment_proportion == 0) segment_proportion = _MIN(1.0f, block->millimeters / smoothing_mm);
error_correction = CEIL(segment_proportion * error_correction);
}
#endif

Expand Down Expand Up @@ -153,27 +147,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;

const bool reversing = TEST(last_direction_bits, axis);

#ifdef BACKLASH_SMOOTHING_MM
const int32_t residual_error_axis = residual_error[axis];
#else
constexpr int32_t residual_error_axis = 0;
#endif
const int32_t residual_error_axis = residual_error[axis];

// At startup it is assumed the last move was forwards. So the applied
// steps will always be a non-positive number.

if (!reversing) 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];
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)

#include "../module/probe.h"
Expand Down
46 changes: 29 additions & 17 deletions Marlin/src/feature/backlash.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,41 +24,36 @@
#include "../inc/MarlinConfigPre.h"
#include "../module/planner.h"

constexpr uint8_t all_on = 0xFF, all_off = 0x00;

class Backlash {
public:
static constexpr uint8_t all_on = 0xFF, all_off = 0x00;

private:
static axis_bits_t last_direction_bits;
#ifdef BACKLASH_SMOOTHING_MM
static xyz_long_t residual_error;
#endif
static xyz_long_t residual_error;

public:
#if ENABLED(BACKLASH_GCODE)
static xyz_float_t distance_mm;
static uint8_t correction;
static xyz_float_t distance_mm;
#ifdef BACKLASH_SMOOTHING_MM
static float smoothing_mm;
#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
static constexpr uint8_t correction = (BACKLASH_CORRECTION) * 0xFF;
static constexpr uint8_t correction = (BACKLASH_CORRECTION) * all_on;
static const xyz_float_t distance_mm;
#ifdef BACKLASH_SMOOTHING_MM
static constexpr float smoothing_mm = BACKLASH_SMOOTHING_MM;
#endif
#endif

#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
private:
static xyz_float_t measured_mm;
static xyz_uint8_t measured_count;
public:
static void measure_with_probe();
static xyz_float_t measured_mm;
static xyz_uint8_t measured_count;
#endif

class StepAdjuster;

public:
static float get_measurement(const AxisEnum a) {
UNUSED(a);
// Return the measurement averaged over all readings
Expand All @@ -78,7 +73,24 @@ class Backlash {
}

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;
60 changes: 37 additions & 23 deletions Marlin/src/gcode/calibrate/G425.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,27 @@ struct measurements_t {
};

#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
#define TEMPORARY_BACKLASH_CORRECTION(value)
#endif

#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
#define TEMPORARY_BACKLASH_SMOOTHING(value)
#endif
Expand Down Expand Up @@ -524,53 +538,53 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {

{
// New scope for TEMPORARY_BACKLASH_CORRECTION
TEMPORARY_BACKLASH_CORRECTION(all_off);
TEMPORARY_BACKLASH_CORRECTION(backlash.all_off);
TEMPORARY_BACKLASH_SMOOTHING(0.0f);

probe_sides(m, uncertainty);

#if ENABLED(BACKLASH_GCODE)

#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)
backlash.distance_mm.x = m.backlash[LEFT];
backlash.set_distance_mm(X_AXIS, m.backlash[LEFT]);
#elif ENABLED(CALIBRATION_MEASURE_RIGHT)
backlash.distance_mm.x = m.backlash[RIGHT];
backlash.set_distance_mm(X_AXIS, m.backlash[RIGHT]);
#endif

#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)
backlash.distance_mm.y = m.backlash[FRONT];
backlash.set_distance_mm(Y_AXIS, m.backlash[FRONT]);
#elif ENABLED(CALIBRATION_MEASURE_BACK)
backlash.distance_mm.y = m.backlash[BACK];
backlash.set_distance_mm(Y_AXIS, m.backlash[BACK]);
#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
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)
backlash.distance_mm.i = m.backlash[IMINIMUM];
backlash.set_distance_mm(I_AXIS, m.backlash[IMINIMUM]);
#elif ENABLED(CALIBRATION_MEASURE_IMAX)
backlash.distance_mm.i = m.backlash[IMAXIMUM];
backlash.set_distance_mm(I_AXIS, m.backlash[IMAXIMUM]);
#endif

#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)
backlash.distance_mm.j = m.backlash[JMINIMUM];
backlash.set_distance_mm(J_AXIS, m.backlash[JMINIMUM]);
#elif ENABLED(CALIBRATION_MEASURE_JMAX)
backlash.distance_mm.j = m.backlash[JMAXIMUM];
backlash.set_distance_mm(J_AXIS, m.backlash[JMAXIMUM]);
#endif

#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)
backlash.distance_mm.k = m.backlash[KMINIMUM];
backlash.set_distance_mm(K_AXIS, m.backlash[KMINIMUM]);
#elif ENABLED(CALIBRATION_MEASURE_KMAX)
backlash.distance_mm.k = m.backlash[KMAXIMUM];
backlash.set_distance_mm(K_AXIS, m.backlash[KMAXIMUM]);
#endif

#endif // BACKLASH_GCODE
Expand All @@ -581,7 +595,7 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
// allowed directions to take up any backlash
{
// New scope for TEMPORARY_BACKLASH_CORRECTION
TEMPORARY_BACKLASH_CORRECTION(all_on);
TEMPORARY_BACKLASH_CORRECTION(backlash.all_on);
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
const xyz_float_t move = LINEAR_AXIS_ARRAY(
AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3,
Expand Down Expand Up @@ -611,7 +625,7 @@ inline void update_measurements(measurements_t &m, const AxisEnum axis) {
* - Call calibrate_backlash() beforehand for best accuracy
*/
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);

TERN(HAS_MULTI_HOTEND, set_nozzle(m, extruder), UNUSED(extruder));
Expand Down Expand Up @@ -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
*/
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);

HOTEND_LOOP() calibrate_toolhead(m, uncertainty, e);
Expand All @@ -674,7 +688,7 @@ inline void calibrate_all() {

TERN_(HAS_HOTEND_OFFSET, reset_hotend_offsets());

TEMPORARY_BACKLASH_CORRECTION(all_on);
TEMPORARY_BACKLASH_CORRECTION(backlash.all_on);
TEMPORARY_BACKLASH_SMOOTHING(0.0f);

// Do a fast and rough calibration of the toolheads
Expand Down
Loading