🔧 Allow FTM + Nonlinear Extrusion (#28250)
Some checks failed
CI - Build Tests / Build Test (push) Waiting to run
CI - Unit Tests / Unit Test (push) Waiting to run
CI - Validate Source Files / Validate Source Files (push) Waiting to run
CI - Validate Pins Files / Validate Pins Files (push) Has been cancelled

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
Vovodroid 2026-01-23 05:14:42 +02:00 committed by GitHub
parent 2e456cea8f
commit 91a91562c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 41 additions and 20 deletions

View file

@ -870,8 +870,8 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
#if ENABLED(NONLINEAR_EXTRUSION)
#if HAS_MULTI_EXTRUDER
#error "NONLINEAR_EXTRUSION doesn't currently support multi-extruder setups."
#elif DISABLED(CPU_32_BIT)
#error "NONLINEAR_EXTRUSION requires a 32-bit CPU."
#elif NONE(CPU_32_BIT, NO_STANDARD_MOTION)
#error "NONLINEAR_EXTRUSION requires a 32-bit CPU or NO_STANDARD_MOTION."
#endif
#endif
@ -4515,9 +4515,7 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive."
#error "EMERGENCY_PARSER is required with FTM_RESONANCE_TEST (to cancel the test)."
#endif
#if !HAS_STANDARD_MOTION
#if ENABLED(NONLINEAR_EXTRUSION)
#error "NONLINEAR_EXTRUSION is not yet available in FT_MOTION. Disable NO_STANDARD_MOTION if you require it."
#elif ENABLED(SMOOTH_LIN_ADVANCE)
#if ENABLED(SMOOTH_LIN_ADVANCE)
#error "SMOOTH_LIN_ADVANCE is not yet available in FT_MOTION. Disable NO_STANDARD_MOTION if you require it."
#elif ENABLED(MIXING_EXTRUDER)
#error "MIXING_EXTRUDER is not yet available in FT_MOTION. Disable NO_STANDARD_MOTION if you require it."

View file

@ -941,9 +941,6 @@
#if ENABLED(I2S_STEPPER_STREAM)
#warning "FT_MOTION has not been tested with I2S_STEPPER_STREAM."
#endif
#if ENABLED(NONLINEAR_EXTRUSION)
#warning "NONLINEAR_EXTRUSION does not (currently) operate when FT_MOTION is the active motion system."
#endif
#if ENABLED(LIN_ADVANCE)
#warning "Be aware that FT_MOTION K factor is now set with M900 K (same as LIN_ADVANCE)."
#if DISABLED(FTM_SMOOTHING)

View file

@ -478,21 +478,42 @@ xyze_float_t FTMotion::calc_traj_point(const float dist) {
LOGICAL_AXIS_MAP_LC(_SET_TRAJ);
#if FTM_HAS_LIN_ADVANCE
const float advK = planner.get_advance_k();
if (advK) {
const float traj_e = traj_coords.e;
if (use_advance_lead) {
// Don't apply LA to retract/unretract blocks
const float e_rate = (traj_e - prev_traj_e) * (FTM_FS);
// Apply LA/NLE only to printing (not retract/unretract) blocks
if (use_advance_lead) {
const float advK = planner.get_advance_k();
if (advK || TERN0(NONLINEAR_EXTRUSION, stepper.ne.settings.enabled)) {
float traj_e = traj_coords.e;
const float traj_e_delta = traj_e - prev_traj_e; // extruder delta in mm, always positive for use_advance_lead (printing moves)
const float e_rate = traj_e_delta * FTM_FS; // extruder velocity in mm/s
traj_coords.e += e_rate * advK;
#if ENABLED(NONLINEAR_EXTRUSION)
if (stepper.ne.settings.enabled) {
const nonlinear_coeff_t &coeff = stepper.ne.settings.coeff;
const float multiplier = max(coeff.C, coeff.A * sq(e_rate) + coeff.B * e_rate + coeff.C),
nle_term = traj_e_delta * (multiplier - 1);
traj_coords.e += nle_term;
traj_e += nle_term;
startPos.e += nle_term;
endPos_prevBlock.e += nle_term;
}
#endif
prev_traj_e = traj_e;
}
prev_traj_e = traj_e;
}
#endif
#endif // FTM_HAS_LIN_ADVANCE
// Update shaping parameters if needed.
switch (cfg.dynFreqMode) {
#if HAS_DYNAMIC_FREQ_MM
case dynFreqMode_Z_BASED: {
static float oldz = 0.0f;
const float z = traj_coords.z;
@ -509,9 +530,11 @@ xyze_float_t FTMotion::calc_traj_point(const float dist) {
shaping.refresh_largest_delay_samples();
}
} break;
#endif
#if HAS_DYNAMIC_FREQ_G
case dynFreqMode_MASS_BASED:
// Update constantly. The optimization done for Z value makes
// less sense for E, as E is expected to constantly change.
@ -523,6 +546,7 @@ xyze_float_t FTMotion::calc_traj_point(const float dist) {
#endif
shaping.refresh_largest_delay_samples();
break;
#endif
default: break;

View file

@ -292,12 +292,14 @@ constexpr ena_mask_t enable_overlap[] = {
#define NONLINEAR_EXTRUSION_Q24 1
#endif
typedef struct {
float A, B, C;
void reset() { A = B = 0.0f; C = 1.0f; }
} nonlinear_coeff_t;
typedef struct {
bool enabled;
struct {
float A, B, C;
void reset() { A = B = 0.0f; C = 1.0f; }
} coeff;
nonlinear_coeff_t coeff;
void reset() {
enabled = ENABLED(NONLINEAR_EXTRUSION_DEFAULT_ON);
coeff.reset();