mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2026-02-18 10:25:12 -07:00
✨ NONLINEAR_EXTRUSION_DEFAULT_ON (#27819)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
parent
e8f2430dac
commit
a6bfdf351f
10 changed files with 83 additions and 55 deletions
|
|
@ -2384,6 +2384,9 @@
|
|||
* For better results also enable ADAPTIVE_STEP_SMOOTHING.
|
||||
*/
|
||||
//#define NONLINEAR_EXTRUSION
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
//#define NONLINEAR_EXTRUSION_DEFAULT_ON // Enable if NLE should be ON by default
|
||||
#endif
|
||||
|
||||
// @section leveling
|
||||
|
||||
|
|
|
|||
|
|
@ -30,11 +30,13 @@
|
|||
void GcodeSuite::M592_report(const bool forReplay/*=true*/) {
|
||||
TERN_(MARLIN_SMALL_BUILD, return);
|
||||
report_heading_etc(forReplay, F(STR_NONLINEAR_EXTRUSION));
|
||||
SERIAL_ECHOLNPGM(" M592 A", stepper.ne.A, " B", stepper.ne.B, " C", stepper.ne.C);
|
||||
const nonlinear_settings_t &sns = stepper.ne.settings;
|
||||
SERIAL_ECHOLNPGM(" M592 S", sns.enabled, " A", sns.coeff.A, " B", sns.coeff.B, " C", sns.coeff.C);
|
||||
}
|
||||
|
||||
/**
|
||||
* M592: Get or set nonlinear extrusion parameters
|
||||
* S<flag> Enable / Disable Nonlinear Extrusion
|
||||
* A<factor> Quadratic coefficient (default 0.0)
|
||||
* B<factor> Linear coefficient (default 0.0)
|
||||
* C<factor> Constant coefficient (default 1.0)
|
||||
|
|
@ -46,14 +48,18 @@ void GcodeSuite::M592_report(const bool forReplay/*=true*/) {
|
|||
void GcodeSuite::M592() {
|
||||
if (!parser.seen_any()) return M592_report();
|
||||
|
||||
if (parser.seenval('A')) stepper.ne.A = parser.value_float();
|
||||
if (parser.seenval('B')) stepper.ne.B = parser.value_float();
|
||||
if (parser.seenval('C')) stepper.ne.C = parser.value_float();
|
||||
nonlinear_t &ne = stepper.ne;
|
||||
nonlinear_settings_t &sns = ne.settings;
|
||||
|
||||
if (parser.seen('S')) sns.enabled = parser.value_bool();
|
||||
if (parser.seenval('A')) sns.coeff.A = parser.value_float();
|
||||
if (parser.seenval('B')) sns.coeff.B = parser.value_float();
|
||||
if (parser.seenval('C')) sns.coeff.C = parser.value_float();
|
||||
|
||||
#if ENABLED(SMOOTH_LIN_ADVANCE)
|
||||
stepper.ne_q30.A = _BV32(30) * (stepper.ne.A * planner.mm_per_step[E_AXIS_N(0)] * planner.mm_per_step[E_AXIS_N(0)]);
|
||||
stepper.ne_q30.B = _BV32(30) * (stepper.ne.B * planner.mm_per_step[E_AXIS_N(0)]);
|
||||
stepper.ne_q30.C = _BV32(30) * stepper.ne.C;
|
||||
ne.q30.A = _BV32(30) * (sns.coeff.A * planner.mm_per_step[E_AXIS_N(0)] * planner.mm_per_step[E_AXIS_N(0)]);
|
||||
ne.q30.B = _BV32(30) * (sns.coeff.B * planner.mm_per_step[E_AXIS_N(0)]);
|
||||
ne.q30.C = _BV32(30) * sns.coeff.C;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -509,6 +509,7 @@ namespace LanguageNarrow_en {
|
|||
LSTR MSG_ADVANCE_TAU = _UxGT("Advance Tau");
|
||||
LSTR MSG_ADVANCE_K_E = _UxGT("Advance K *");
|
||||
LSTR MSG_ADVANCE_TAU_E = _UxGT("Advance Tau *");
|
||||
LSTR MSG_NLE_ON = _UxGT("NLE enabled");
|
||||
LSTR MSG_CONTRAST = _UxGT("LCD Contrast");
|
||||
LSTR MSG_BRIGHTNESS = _UxGT("LCD Brightness");
|
||||
LSTR MSG_SCREEN_TIMEOUT = _UxGT("LCD Timeout (m)");
|
||||
|
|
|
|||
|
|
@ -138,6 +138,10 @@ void menu_backlash();
|
|||
#endif
|
||||
#endif // LIN_ADVANCE
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
EDIT_ITEM(bool, MSG_NLE_ON, &stepper.ne.settings.enabled);
|
||||
#endif
|
||||
|
||||
#if DISABLED(NO_VOLUMETRICS)
|
||||
EDIT_ITEM(bool, MSG_VOLUMETRIC_ENABLED, &parser.volumetric_enabled, planner.calculate_volumetric_multipliers);
|
||||
|
||||
|
|
|
|||
|
|
@ -237,6 +237,13 @@ void menu_tune() {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Nonlinear Extrusion state
|
||||
//
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
EDIT_ITEM(bool, MSG_NLE_ON, &stepper.ne.settings.enabled);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Babystep X:
|
||||
// Babystep Y:
|
||||
|
|
|
|||
|
|
@ -3255,8 +3255,8 @@ void Planner::refresh_positioning() {
|
|||
#if ENABLED(EDITABLE_STEPS_PER_UNIT)
|
||||
LOOP_DISTINCT_AXES(i) mm_per_step[i] = 1.0f / settings.axis_steps_per_mm[i];
|
||||
#if ALL(NONLINEAR_EXTRUSION, SMOOTH_LIN_ADVANCE)
|
||||
stepper.ne_q30.A = _BV32(30) * (stepper.ne.A * mm_per_step[E_AXIS_N(0)] * mm_per_step[E_AXIS_N(0)]);
|
||||
stepper.ne_q30.B = _BV32(30) * (stepper.ne.B * mm_per_step[E_AXIS_N(0)]);
|
||||
stepper.ne.q30.A = _BV32(30) * (stepper.ne.settings.coeff.A * mm_per_step[E_AXIS_N(0)] * mm_per_step[E_AXIS_N(0)]);
|
||||
stepper.ne.q30.B = _BV32(30) * (stepper.ne.settings.coeff.B * mm_per_step[E_AXIS_N(0)]);
|
||||
#endif
|
||||
#endif
|
||||
set_position_mm(current_position);
|
||||
|
|
|
|||
|
|
@ -685,7 +685,7 @@ typedef struct SettingsDataStruct {
|
|||
// Nonlinear Extrusion
|
||||
//
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
ne_coeff_t stepper_ne; // M592 A B C
|
||||
nonlinear_settings_t stepper_ne_settings; // M592 S A B C
|
||||
#endif
|
||||
|
||||
//
|
||||
|
|
@ -1798,7 +1798,7 @@ void MarlinSettings::postprocess() {
|
|||
// Nonlinear Extrusion
|
||||
//
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
EEPROM_WRITE(stepper.ne);
|
||||
EEPROM_WRITE(stepper.ne.settings);
|
||||
#endif
|
||||
|
||||
//
|
||||
|
|
@ -2933,7 +2933,7 @@ void MarlinSettings::postprocess() {
|
|||
// Nonlinear Extrusion
|
||||
//
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
EEPROM_READ(stepper.ne);
|
||||
EEPROM_READ(stepper.ne.settings);
|
||||
#endif
|
||||
|
||||
//
|
||||
|
|
@ -3747,7 +3747,7 @@ void MarlinSettings::reset() {
|
|||
//
|
||||
// Nonlinear Extrusion
|
||||
//
|
||||
TERN_(NONLINEAR_EXTRUSION, stepper.ne.reset());
|
||||
TERN_(NONLINEAR_EXTRUSION, stepper.ne.settings.reset());
|
||||
|
||||
//
|
||||
// Input Shaping
|
||||
|
|
|
|||
|
|
@ -256,17 +256,7 @@ uint32_t Stepper::advance_divisor = 0,
|
|||
#endif
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
ne_coeff_t Stepper::ne;
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
ne_q24_t Stepper::ne_q24;
|
||||
#else
|
||||
ne_q30_t Stepper::ne_q30;
|
||||
#endif
|
||||
// private:
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
int32_t Stepper::ne_edividend;
|
||||
uint32_t Stepper::ne_scale_q24;
|
||||
#endif
|
||||
nonlinear_t Stepper::ne; // Initialized by settings.load
|
||||
#endif
|
||||
|
||||
#if HAS_ZV_SHAPING
|
||||
|
|
@ -2247,11 +2237,11 @@ hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) {
|
|||
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
void Stepper::calc_nonlinear_e(const uint32_t step_rate) {
|
||||
const uint32_t velocity_q24 = ne_scale_q24 * step_rate; // Scale step_rate first so all intermediate values stay in range of 8.24 fixed point math
|
||||
int32_t vd_q24 = (((((int64_t)ne_q24.A * velocity_q24) >> 24) * velocity_q24) >> 24) + (((int64_t)ne_q24.B * velocity_q24) >> 24);
|
||||
const uint32_t velocity_q24 = ne.scale_q24 * step_rate; // Scale step_rate first so all intermediate values stay in range of 8.24 fixed point math
|
||||
int32_t vd_q24 = ((((int64_t(ne.q24.A) * velocity_q24) >> 24) * velocity_q24) >> 24) + ((int64_t(ne.q24.B) * velocity_q24) >> 24);
|
||||
NOLESS(vd_q24, 0);
|
||||
|
||||
advance_dividend.e = (uint64_t(ne_q24.C + vd_q24) * ne_edividend) >> 24;
|
||||
advance_dividend.e = (uint64_t(ne.q24.C + vd_q24) * ne.edividend) >> 24;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -2834,18 +2824,19 @@ hal_timer_t Stepper::block_phase_isr() {
|
|||
acc_step_rate = current_block->initial_rate;
|
||||
#endif
|
||||
|
||||
// Calculate Nonlinear Extrusion fixed-point quotients
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
ne_edividend = advance_dividend.e;
|
||||
const float scale = (float(ne_edividend) / advance_divisor) * planner.mm_per_step[E_AXIS_N(current_block->extruder)];
|
||||
ne_scale_q24 = _BV32(24) * scale;
|
||||
if (current_block->direction_bits.e && ANY_AXIS_MOVES(current_block)) {
|
||||
ne_q24.A = _BV32(24) * ne.A;
|
||||
ne_q24.B = _BV32(24) * ne.B;
|
||||
ne_q24.C = _BV32(24) * ne.C;
|
||||
ne.edividend = advance_dividend.e;
|
||||
const float scale = (float(ne.edividend) / advance_divisor) * planner.mm_per_step[E_AXIS_N(current_block->extruder)];
|
||||
ne.scale_q24 = _BV32(24) * scale;
|
||||
if (ne.settings.enabled && current_block->direction_bits.e && ANY_AXIS_MOVES(current_block)) {
|
||||
ne.q24.A = _BV32(24) * ne.settings.coeff.A;
|
||||
ne.q24.B = _BV32(24) * ne.settings.coeff.B;
|
||||
ne.q24.C = _BV32(24) * ne.settings.coeff.C;
|
||||
}
|
||||
else {
|
||||
ne_q24.A = ne_q24.B = 0;
|
||||
ne_q24.C = _BV32(24);
|
||||
ne.q24.A = ne.q24.B = 0;
|
||||
ne.q24.C = _BV32(24);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -2891,9 +2882,9 @@ hal_timer_t Stepper::block_phase_isr() {
|
|||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
if (forward_e && ANY_AXIS_MOVES(current_block)) {
|
||||
// Maximum polynomial value is just above 1, like 1.05..1.2, less than 2 anyway, so we can use 30 bits for fractional part
|
||||
int32_t vd_q30 = ne_q30.A*step_rate*step_rate + ne_q30.B*step_rate;
|
||||
int32_t vd_q30 = ne.q30.A * sq(step_rate) + ne.q30.B * step_rate;
|
||||
NOLESS(vd_q30, 0);
|
||||
step_rate = (int64_t(step_rate) * (ne_q30.C + vd_q30)) >> 30;
|
||||
step_rate = (int64_t(step_rate) * (ne.q30.C + vd_q30)) >> 30;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -283,15 +283,41 @@ constexpr ena_mask_t enable_overlap[] = {
|
|||
|
||||
#endif // HAS_ZV_SHAPING
|
||||
|
||||
//
|
||||
// NonLinear Extrusion data
|
||||
//
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
typedef struct { float A, B, C; void reset() { A = B = 0.0f; C = 1.0f; } } ne_coeff_t;
|
||||
|
||||
#if DISABLED(SMOOTH_LIN_ADVANCE)
|
||||
#define NONLINEAR_EXTRUSION_Q24 1
|
||||
typedef struct { int32_t A, B, C; } ne_q24_t;
|
||||
#else
|
||||
typedef struct { int32_t A, B, C; } ne_q30_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
bool enabled;
|
||||
struct {
|
||||
float A, B, C;
|
||||
void reset() { A = B = 0.0f; C = 1.0f; }
|
||||
} coeff;
|
||||
void reset() {
|
||||
enabled = ENABLED(NONLINEAR_EXTRUSION_DEFAULT_ON);
|
||||
coeff.reset();
|
||||
}
|
||||
} nonlinear_settings_t;
|
||||
|
||||
typedef struct {
|
||||
nonlinear_settings_t settings;
|
||||
union {
|
||||
struct { int32_t A, B, C; } q24;
|
||||
struct { int32_t A, B, C; } q30;
|
||||
};
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
protected:
|
||||
int32_t edividend;
|
||||
uint32_t scale_q24;
|
||||
#endif
|
||||
} nonlinear_t;
|
||||
|
||||
#endif // NONLINEAR_EXTRUSION
|
||||
|
||||
//
|
||||
// Stepper class definition
|
||||
|
|
@ -347,12 +373,7 @@ class Stepper {
|
|||
#endif
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
static ne_coeff_t ne;
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
static ne_q24_t ne_q24;
|
||||
#else
|
||||
static ne_q30_t ne_q30;
|
||||
#endif
|
||||
static nonlinear_t ne;
|
||||
#endif
|
||||
|
||||
#if ENABLED(ADAPTIVE_STEP_SMOOTHING_TOGGLE)
|
||||
|
|
@ -477,11 +498,6 @@ class Stepper {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
static int32_t ne_edividend;
|
||||
static uint32_t ne_scale_q24;
|
||||
#endif
|
||||
|
||||
#if ENABLED(BABYSTEPPING)
|
||||
static constexpr hal_timer_t BABYSTEP_NEVER = HAL_TIMER_TYPE_MAX;
|
||||
static hal_timer_t nextBabystepISR;
|
||||
|
|
|
|||
|
|
@ -15,5 +15,5 @@ opt_set MOTHERBOARD BOARD_BTT_SKR_MINI_E3_V1_0 SERIAL_PORT 1 SERIAL_PORT_2 -1 \
|
|||
X_CURRENT_HOME X_CURRENT/2 Y_CURRENT_HOME Y_CURRENT/2 Z_CURRENT_HOME Y_CURRENT/2
|
||||
opt_enable CR10_STOCKDISPLAY PINS_DEBUGGING Z_IDLE_HEIGHT EDITABLE_HOMING_CURRENT \
|
||||
FT_MOTION FT_MOTION_MENU BIQU_MICROPROBE_V1 PROBE_ENABLE_DISABLE Z_SAFE_HOMING AUTO_BED_LEVELING_BILINEAR \
|
||||
ADAPTIVE_STEP_SMOOTHING NONLINEAR_EXTRUSION
|
||||
ADAPTIVE_STEP_SMOOTHING LIN_ADVANCE SMOOTH_LIN_ADVANCE NONLINEAR_EXTRUSION INPUT_SHAPING_X INPUT_SHAPING_Y
|
||||
exec_test $1 $2 "BigTreeTech SKR Mini E3 1.0 - TMC2209 HW Serial, FT_MOTION" "$3"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue