mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2025-12-30 19:30:46 -07:00
⚡️ Fix K, improve FTMotion linear advance (#28058)
This commit is contained in:
parent
d0dc3b619f
commit
5917aa73b5
7 changed files with 42 additions and 32 deletions
|
|
@ -249,7 +249,7 @@ void GcodeSuite::M493() {
|
|||
// Pressure control (linear advance) gain parameter.
|
||||
if (parser.seenval('K')) {
|
||||
const float val = parser.value_float();
|
||||
if (val >= 0.0f) {
|
||||
if (WITHIN(val, 0.0f, 10.0f)) {
|
||||
ftMotion.cfg.linearAdvK = val;
|
||||
flag.report = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,6 +348,10 @@
|
|||
#define HAS_ROUGH_LIN_ADVANCE 1
|
||||
#endif
|
||||
|
||||
#if ALL(FT_MOTION, HAS_EXTRUDERS)
|
||||
#define HAS_FTM_LIN_ADVANCE 1
|
||||
#endif
|
||||
|
||||
// Some displays can toggle Adaptive Step Smoothing.
|
||||
// The state is saved to EEPROM.
|
||||
// In future this may be added to a G-code such as M205 A.
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ void menu_move() {
|
|||
#if HAS_EXTRUDERS
|
||||
EDIT_ITEM(bool, MSG_LINEAR_ADVANCE, &c.linearAdvEna);
|
||||
if (c.linearAdvEna || ENABLED(FT_MOTION_NO_MENU_TOGGLE))
|
||||
EDIT_ITEM(float62, MSG_ADVANCE_K, &c.linearAdvK, 0.0f, 1000.0f);
|
||||
EDIT_ITEM(float42_52, MSG_ADVANCE_K, &c.linearAdvK, 0.0f, 10.0f);
|
||||
#endif
|
||||
}
|
||||
END_MENU();
|
||||
|
|
@ -547,7 +547,7 @@ void menu_move() {
|
|||
#if HAS_EXTRUDERS
|
||||
EDIT_ITEM(bool, MSG_LINEAR_ADVANCE, &c.linearAdvEna);
|
||||
if (c.linearAdvEna || ENABLED(FT_MOTION_NO_MENU_TOGGLE))
|
||||
EDIT_ITEM(float62, MSG_ADVANCE_K, &c.linearAdvK, 0.0f, 1000.0f);
|
||||
EDIT_ITEM(float42_52, MSG_ADVANCE_K, &c.linearAdvK, 0.0f, 10.0f);
|
||||
#endif
|
||||
|
||||
END_MENU();
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ uint32_t FTMotion::interpIdx = 0; // Index of current data point b
|
|||
uint8_t FTMotion::block_extruder_axis; // Cached E Axis from last-fetched block
|
||||
#elif HAS_EXTRUDERS
|
||||
constexpr uint8_t FTMotion::block_extruder_axis;
|
||||
bool FTMotion::use_advance_lead;
|
||||
#endif
|
||||
|
||||
// Shaping variables.
|
||||
|
|
@ -103,15 +104,14 @@ uint32_t FTMotion::interpIdx = 0; // Index of current data point b
|
|||
, x:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 } // ena, d_zi[], Ai[], Ni[], max_i
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
, y:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 } // ena, d_zi[], Ai[], Ni[], max_i
|
||||
, y:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 }
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
// Linear advance variables.
|
||||
float FTMotion::e_raw_z1 = 0.0f; // (ms) Unit delay of raw extruder position.
|
||||
float FTMotion::e_advanced_z1 = 0.0f; // (ms) Unit delay of advanced extruder position.
|
||||
float FTMotion::prev_traj_e = 0.0f; // (ms) Unit delay of raw extruder position.
|
||||
#endif
|
||||
|
||||
constexpr uint32_t BATCH_SIDX_IN_WINDOW = (FTM_WINDOW_SIZE) - (FTM_BATCH_SIZE); // Batch start index in window.
|
||||
|
|
@ -388,7 +388,7 @@ void FTMotion::reset() {
|
|||
shaping.zi_idx = 0;
|
||||
#endif
|
||||
|
||||
TERN_(HAS_EXTRUDERS, e_raw_z1 = e_advanced_z1 = 0.0f); // Reset linear advance variables.
|
||||
TERN_(HAS_EXTRUDERS, prev_traj_e = 0.0f); // Reset linear advance variables.
|
||||
TERN_(DISTINCT_E_FACTORS, block_extruder_axis = E_AXIS);
|
||||
|
||||
axis_move_end_ti.reset();
|
||||
|
|
@ -539,6 +539,8 @@ void FTMotion::loadBlockData(block_t * const current_block) {
|
|||
|
||||
endPos_prevBlock += moveDist;
|
||||
|
||||
TERN_(FTM_HAS_LIN_ADVANCE, use_advance_lead = current_block->use_advance_lead);
|
||||
|
||||
// Watch endstops until the move ends
|
||||
const millis_t move_end_ti = millis() + SEC_TO_MS((FTM_TS) * float(max_intervals + num_samples_shaper_settle() + ((PROP_BATCHES) + 1) * (FTM_BATCH_SIZE)) + (float(FTM_STEPPERCMD_BUFF_SIZE) / float(FTM_STEPPER_FS)));
|
||||
|
||||
|
|
@ -557,14 +559,10 @@ void FTMotion::generateTrajectoryPointsFromBlock() {
|
|||
do {
|
||||
float tau = (traj_idx_get + 1) * (FTM_TS); // (s) Time since start of block
|
||||
float dist = 0.0f; // (mm) Distance traveled
|
||||
#if HAS_EXTRUDERS
|
||||
float accel_k = 0.0f; // (mm/s^2) Acceleration K factor
|
||||
#endif
|
||||
|
||||
if (traj_idx_get < N1) {
|
||||
// Acceleration phase
|
||||
dist = (f_s * tau) + (0.5f * accel_P * sq(tau)); // (mm) Distance traveled for acceleration phase since start of block
|
||||
TERN_(HAS_EXTRUDERS, accel_k = accel_P); // (mm/s^2) Acceleration K factor from Accel phase
|
||||
}
|
||||
else if (traj_idx_get < (N1 + N2)) {
|
||||
// Coasting phase
|
||||
|
|
@ -575,20 +573,20 @@ void FTMotion::generateTrajectoryPointsFromBlock() {
|
|||
// Deceleration phase
|
||||
tau -= (N1 + N2) * (FTM_TS); // (s) Time since start of decel phase
|
||||
dist = s_2e + F_P * tau + 0.5f * decel_P * sq(tau); // (mm) Distance traveled for deceleration phase since start of block
|
||||
TERN_(HAS_EXTRUDERS, accel_k = decel_P); // (mm/s^2) Acceleration K factor from Decel phase
|
||||
}
|
||||
|
||||
#define _SET_TRAJ(q) traj.q[traj_idx_set] = startPos.q + ratio.q * dist;
|
||||
LOGICAL_AXIS_MAP_LC(_SET_TRAJ);
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
#if FTM_HAS_LIN_ADVANCE
|
||||
if (cfg.linearAdvEna) {
|
||||
float dedt_adj = (traj.e[traj_idx_set] - e_raw_z1) * (FTM_FS);
|
||||
if (ratio.e > 0.0f) dedt_adj += accel_k * cfg.linearAdvK * 0.0001f;
|
||||
|
||||
e_raw_z1 = traj.e[traj_idx_set];
|
||||
e_advanced_z1 += dedt_adj * (FTM_TS);
|
||||
traj.e[traj_idx_set] = e_advanced_z1;
|
||||
float traj_e = traj.e[traj_idx_set];
|
||||
if (use_advance_lead) {
|
||||
// Don't apply LA to retract/unretract blocks
|
||||
float e_rate = (traj_e - prev_traj_e) * (FTM_FS);
|
||||
traj.e[traj_idx_set] += e_rate * cfg.linearAdvK;
|
||||
}
|
||||
prev_traj_e = traj_e;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ class FTMotion {
|
|||
static uint8_t block_extruder_axis; // Cached extruder axis index
|
||||
#elif HAS_EXTRUDERS
|
||||
static constexpr uint8_t block_extruder_axis = E_AXIS;
|
||||
static bool use_advance_lead;
|
||||
#endif
|
||||
|
||||
// Shaping variables.
|
||||
|
|
@ -209,7 +210,7 @@ class FTMotion {
|
|||
|
||||
// Linear advance variables.
|
||||
#if HAS_EXTRUDERS
|
||||
static float e_raw_z1, e_advanced_z1;
|
||||
static float prev_traj_e;
|
||||
#endif
|
||||
|
||||
// Private methods
|
||||
|
|
|
|||
|
|
@ -2379,7 +2379,7 @@ bool Planner::_populate_block(
|
|||
const float steps_per_mm = block->step_event_count * inverse_millimeters;
|
||||
block->steps_per_mm = steps_per_mm;
|
||||
uint32_t accel;
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
#if ANY(LIN_ADVANCE, FTM_HAS_LIN_ADVANCE)
|
||||
bool use_advance_lead = false;
|
||||
#endif
|
||||
if (!ANY_AXIS_MOVES(block)) { // Is this a retract / recover move?
|
||||
|
|
@ -2403,7 +2403,7 @@ bool Planner::_populate_block(
|
|||
// Start with print or travel acceleration
|
||||
accel = CEIL((esteps ? settings.acceleration : settings.travel_acceleration) * steps_per_mm);
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
#if ANY(LIN_ADVANCE, FTM_HAS_LIN_ADVANCE)
|
||||
// Linear advance is currently not ready for HAS_I_AXIS
|
||||
#define MAX_E_JERK(N) TERN(HAS_LINEAR_E_JERK, max_e_jerk[E_INDEX_N(N)], max_jerk.e)
|
||||
|
||||
|
|
@ -2432,16 +2432,22 @@ bool Planner::_populate_block(
|
|||
use_advance_lead = false;
|
||||
else {
|
||||
#if HAS_ROUGH_LIN_ADVANCE
|
||||
// Scale E acceleration so that it will be possible to jump to the advance speed.
|
||||
const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[E_INDEX_N(extruder)] * e_D_ratio) * steps_per_mm;
|
||||
if (accel > max_accel_steps_per_s2) {
|
||||
accel = max_accel_steps_per_s2;
|
||||
if (TERN0(LA_DEBUG, DEBUGGING(INFO))) SERIAL_ECHOLNPGM("Acceleration limited.");
|
||||
const bool limit_accel = TERN1(HAS_FTM_LIN_ADVANCE, !ftMotion.cfg.active);
|
||||
if (limit_accel) {
|
||||
// Scale E acceleration so that it will be possible to jump to the advance speed.
|
||||
const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[E_INDEX_N(extruder)] * e_D_ratio) * steps_per_mm;
|
||||
if (accel > max_accel_steps_per_s2) {
|
||||
accel = max_accel_steps_per_s2;
|
||||
if (TERN0(LA_DEBUG, DEBUGGING(INFO))) SERIAL_ECHOLNPGM("Acceleration limited.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if ANY(SMOOTH_LIN_ADVANCE, FTM_HAS_LIN_ADVANCE)
|
||||
block->use_advance_lead = use_advance_lead;
|
||||
#endif
|
||||
}
|
||||
#endif // LIN_ADVANCE
|
||||
#endif // LIN_ADVANCE || FTM_HAS_LIN_ADVANCE
|
||||
|
||||
// Limit acceleration per axis
|
||||
if (block->step_event_count <= acceleration_long_cutoff) {
|
||||
|
|
@ -2484,7 +2490,6 @@ bool Planner::_populate_block(
|
|||
SERIAL_ECHOLNPGM("eISR running at > 10kHz: ", block->la_advance_rate);
|
||||
}
|
||||
#elif ENABLED(SMOOTH_LIN_ADVANCE)
|
||||
block->use_advance_lead = use_advance_lead;
|
||||
const uint32_t ratio = (uint64_t(block->steps.e) * _BV32(30)) / block->step_event_count;
|
||||
block->e_step_ratio_q30 = block->direction_bits.e ? ratio : -ratio;
|
||||
|
||||
|
|
|
|||
|
|
@ -271,10 +271,12 @@ typedef struct PlannerBlock {
|
|||
#endif
|
||||
|
||||
// Advance extrusion
|
||||
#if ANY(SMOOTH_LIN_ADVANCE, FTM_HAS_LIN_ADVANCE)
|
||||
bool use_advance_lead;
|
||||
#endif
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
#if ENABLED(SMOOTH_LIN_ADVANCE)
|
||||
bool use_advance_lead;
|
||||
#else
|
||||
#if HAS_ROUGH_LIN_ADVANCE
|
||||
uint32_t la_advance_rate; // The rate at which steps are added whilst accelerating
|
||||
uint8_t la_scaling; // Scale ISR frequency down and step frequency up by 2 ^ la_scaling
|
||||
uint16_t max_adv_steps, // Max advance steps to get cruising speed pressure
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue