✨ ADVANCE_K per-extruder (#24821)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
		
				
					committed by
					
						
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							8481264566
						
					
				
				
					commit
					0203e32c73
				
			@@ -2061,12 +2061,16 @@
 | 
			
		||||
 */
 | 
			
		||||
//#define LIN_ADVANCE
 | 
			
		||||
#if ENABLED(LIN_ADVANCE)
 | 
			
		||||
  //#define EXTRA_LIN_ADVANCE_K // Add a second linear advance constant, configurable with M900 L.
 | 
			
		||||
  #define LIN_ADVANCE_K 0.22    // Unit: mm compression per 1mm/s extruder speed
 | 
			
		||||
  //#define LA_DEBUG            // Print debug information to serial during operation. Disable for production use.
 | 
			
		||||
  //#define EXPERIMENTAL_SCURVE // Allow S-Curve Acceleration to be used with LA.
 | 
			
		||||
  //#define ALLOW_LOW_EJERK     // Allow a DEFAULT_EJERK value of <10. Recommended for direct drive hotends.
 | 
			
		||||
  //#define EXPERIMENTAL_I2S_LA // Allow I2S_STEPPER_STREAM to be used with LA. Performance degrades as the LA step rate reaches ~20kHz.
 | 
			
		||||
  #if ENABLED(DISTINCT_E_FACTORS)
 | 
			
		||||
    #define ADVANCE_K { 0.22 }    // (mm) Compression length per 1mm/s extruder speed, per extruder
 | 
			
		||||
  #else
 | 
			
		||||
    #define ADVANCE_K 0.22        // (mm) Compression length applying to all extruders
 | 
			
		||||
  #endif
 | 
			
		||||
  //#define ADVANCE_K_EXTRA       // Add a second linear advance constant, configurable with M900 L.
 | 
			
		||||
  //#define LA_DEBUG              // Print debug information to serial during operation. Disable for production use.
 | 
			
		||||
  //#define EXPERIMENTAL_SCURVE   // Allow S-Curve Acceleration to be used with LA.
 | 
			
		||||
  //#define ALLOW_LOW_EJERK       // Allow a DEFAULT_EJERK value of <10. Recommended for direct drive hotends.
 | 
			
		||||
  //#define EXPERIMENTAL_I2S_LA   // Allow I2S_STEPPER_STREAM to be used with LA. Performance degrades as the LA step rate reaches ~20kHz.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// @section leveling
 | 
			
		||||
 
 | 
			
		||||
@@ -27,8 +27,8 @@
 | 
			
		||||
#include "../../gcode.h"
 | 
			
		||||
#include "../../../module/planner.h"
 | 
			
		||||
 | 
			
		||||
#if ENABLED(EXTRA_LIN_ADVANCE_K)
 | 
			
		||||
  float other_extruder_advance_K[EXTRUDERS];
 | 
			
		||||
#if ENABLED(ADVANCE_K_EXTRA)
 | 
			
		||||
  float other_extruder_advance_K[DISTINCT_E];
 | 
			
		||||
  uint8_t lin_adv_slot = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -36,8 +36,8 @@
 | 
			
		||||
 * M900: Get or Set Linear Advance K-factor
 | 
			
		||||
 *  T<tool>     Which tool to address
 | 
			
		||||
 *  K<factor>   Set current advance K factor (Slot 0).
 | 
			
		||||
 *  L<factor>   Set secondary advance K factor (Slot 1). Requires EXTRA_LIN_ADVANCE_K.
 | 
			
		||||
 *  S<0/1>      Activate slot 0 or 1. Requires EXTRA_LIN_ADVANCE_K.
 | 
			
		||||
 *  L<factor>   Set secondary advance K factor (Slot 1). Requires ADVANCE_K_EXTRA.
 | 
			
		||||
 *  S<0/1>      Activate slot 0 or 1. Requires ADVANCE_K_EXTRA.
 | 
			
		||||
 */
 | 
			
		||||
void GcodeSuite::M900() {
 | 
			
		||||
 | 
			
		||||
@@ -58,12 +58,12 @@ void GcodeSuite::M900() {
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  float &kref = planner.extruder_advance_K[tool_index], newK = kref;
 | 
			
		||||
  float &kref = planner.extruder_advance_K[E_INDEX_N(tool_index)], newK = kref;
 | 
			
		||||
  const float oldK = newK;
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(EXTRA_LIN_ADVANCE_K)
 | 
			
		||||
  #if ENABLED(ADVANCE_K_EXTRA)
 | 
			
		||||
 | 
			
		||||
    float &lref = other_extruder_advance_K[tool_index];
 | 
			
		||||
    float &lref = other_extruder_advance_K[E_INDEX_N(tool_index)];
 | 
			
		||||
 | 
			
		||||
    const bool old_slot = TEST(lin_adv_slot, tool_index), // The tool's current slot (0 or 1)
 | 
			
		||||
               new_slot = parser.boolval('S', old_slot);  // The passed slot (default = current)
 | 
			
		||||
@@ -111,9 +111,9 @@ void GcodeSuite::M900() {
 | 
			
		||||
 | 
			
		||||
  if (!parser.seen_any()) {
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(EXTRA_LIN_ADVANCE_K)
 | 
			
		||||
    #if ENABLED(ADVANCE_K_EXTRA)
 | 
			
		||||
 | 
			
		||||
      #if EXTRUDERS < 2
 | 
			
		||||
      #if DISTINCT_E < 2
 | 
			
		||||
        SERIAL_ECHOLNPGM("Advance S", new_slot, " K", kref, "(S", !new_slot, " K", lref, ")");
 | 
			
		||||
      #else
 | 
			
		||||
        EXTRUDER_LOOP() {
 | 
			
		||||
@@ -127,7 +127,7 @@ void GcodeSuite::M900() {
 | 
			
		||||
    #else
 | 
			
		||||
 | 
			
		||||
      SERIAL_ECHO_START();
 | 
			
		||||
      #if EXTRUDERS < 2
 | 
			
		||||
      #if DISTINCT_E < 2
 | 
			
		||||
        SERIAL_ECHOLNPGM("Advance K=", planner.extruder_advance_K[0]);
 | 
			
		||||
      #else
 | 
			
		||||
        SERIAL_ECHOPGM("Advance K");
 | 
			
		||||
@@ -145,7 +145,7 @@ void GcodeSuite::M900() {
 | 
			
		||||
 | 
			
		||||
void GcodeSuite::M900_report(const bool forReplay/*=true*/) {
 | 
			
		||||
  report_heading(forReplay, F(STR_LINEAR_ADVANCE));
 | 
			
		||||
  #if EXTRUDERS < 2
 | 
			
		||||
  #if DISTINCT_E < 2
 | 
			
		||||
    report_echo_start(forReplay);
 | 
			
		||||
    SERIAL_ECHOLNPGM("  M900 K", planner.extruder_advance_K[0]);
 | 
			
		||||
  #else
 | 
			
		||||
 
 | 
			
		||||
@@ -990,7 +990,7 @@
 | 
			
		||||
 *  with shared motion and temperature settings.
 | 
			
		||||
 *
 | 
			
		||||
 * DISTINCT_E is the number of distinguished extruders. By default this
 | 
			
		||||
 *  well be 1 which indicates all extruders share the same settings.
 | 
			
		||||
 *  will be 1 which indicates all extruders share the same settings.
 | 
			
		||||
 *
 | 
			
		||||
 * E_INDEX_N(E) should be used to get the E index of any item that might be
 | 
			
		||||
 *  distinguished.
 | 
			
		||||
 
 | 
			
		||||
@@ -652,6 +652,8 @@
 | 
			
		||||
  #error "USE_M73_REMAINING_TIME is now SET_REMAINING_TIME."
 | 
			
		||||
#elif defined(SHOW_SD_PERCENT)
 | 
			
		||||
  #error "SHOW_SD_PERCENT is now SHOW_PROGRESS_PERCENT."
 | 
			
		||||
#elif defined(EXTRA_LIN_ADVANCE_K)
 | 
			
		||||
  #error "EXTRA_LIN_ADVANCE_K is now ADVANCE_K_EXTRA."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// L64xx stepper drivers have been removed
 | 
			
		||||
@@ -1336,10 +1338,15 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
 | 
			
		||||
 * Linear Advance 1.5 - Check K value range
 | 
			
		||||
 */
 | 
			
		||||
#if ENABLED(LIN_ADVANCE)
 | 
			
		||||
  static_assert(
 | 
			
		||||
    WITHIN(LIN_ADVANCE_K, 0, 10),
 | 
			
		||||
    "LIN_ADVANCE_K must be a value from 0 to 10 (Changed in LIN_ADVANCE v1.5, Marlin 1.1.9)."
 | 
			
		||||
  );
 | 
			
		||||
  #if DISTINCT_E > 1
 | 
			
		||||
    constexpr float lak[] = ADVANCE_K;
 | 
			
		||||
    static_assert(COUNT(lak) < DISTINCT_E, "The ADVANCE_K array has too many elements (i.e., more than " STRINGIFY(DISTINCT_E) ").");
 | 
			
		||||
    #define _LIN_ASSERT(N) static_assert(N >= COUNT(lak) || WITHIN(lak[N], 0, 10), "ADVANCE_K values must be from 0 to 10 (Changed in LIN_ADVANCE v1.5, Marlin 1.1.9).");
 | 
			
		||||
    REPEAT(DISTINCT_E, _LIN_ASSERT)
 | 
			
		||||
    #undef _LIN_ASSERT
 | 
			
		||||
  #else
 | 
			
		||||
    static_assert(WITHIN(ADVANCE_K, 0, 10), "ADVANCE_K must be from 0 to 10 (Changed in LIN_ADVANCE v1.5, Marlin 1.1.9).");
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(S_CURVE_ACCELERATION) && DISABLED(EXPERIMENTAL_SCURVE)
 | 
			
		||||
    #error "LIN_ADVANCE and S_CURVE_ACCELERATION may not play well together! Enable EXPERIMENTAL_SCURVE to continue."
 | 
			
		||||
  #elif ENABLED(DIRECT_STEPPING)
 | 
			
		||||
 
 | 
			
		||||
@@ -2772,7 +2772,7 @@ void CrealityDWINClass::Menu_Item_Handler(uint8_t menu, uint8_t item, bool draw/
 | 
			
		||||
        #if ENABLED(LIN_ADVANCE)
 | 
			
		||||
          case ADVANCED_LA:
 | 
			
		||||
            if (draw) {
 | 
			
		||||
              Draw_Menu_Item(row, ICON_MaxAccelerated, F("Lin Advance Kp"));
 | 
			
		||||
              Draw_Menu_Item(row, ICON_MaxAccelerated, F("Lin Advance K"));
 | 
			
		||||
              Draw_Float(planner.extruder_advance_K[0], row, false, 100);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
 
 | 
			
		||||
@@ -712,17 +712,17 @@ namespace ExtUI {
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(POWER_LOSS_RECOVERY)
 | 
			
		||||
    bool getPowerLossRecoveryEnabled()                 { return recovery.enabled; }
 | 
			
		||||
    void setPowerLossRecoveryEnabled(const bool value) {  recovery.enable(value); }
 | 
			
		||||
    void setPowerLossRecoveryEnabled(const bool value) { recovery.enable(value); }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(LIN_ADVANCE)
 | 
			
		||||
    float getLinearAdvance_mm_mm_s(const extruder_t extruder) {
 | 
			
		||||
      return (extruder < EXTRUDERS) ? planner.extruder_advance_K[extruder - E0] : 0;
 | 
			
		||||
      return (extruder < EXTRUDERS) ? planner.extruder_advance_K[E_INDEX_N(extruder - E0)] : 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void setLinearAdvance_mm_mm_s(const_float_t value, const extruder_t extruder) {
 | 
			
		||||
      if (extruder < EXTRUDERS)
 | 
			
		||||
        planner.extruder_advance_K[extruder - E0] = constrain(value, 0, 10);
 | 
			
		||||
        planner.extruder_advance_K[E_INDEX_N(extruder - E0)] = constrain(value, 0, 10);
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -109,9 +109,9 @@ void menu_backlash();
 | 
			
		||||
    BACK_ITEM(MSG_ADVANCED_SETTINGS);
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(LIN_ADVANCE)
 | 
			
		||||
      #if EXTRUDERS == 1
 | 
			
		||||
      #if DISTINCT_E < 2
 | 
			
		||||
        EDIT_ITEM(float42_52, MSG_ADVANCE_K, &planner.extruder_advance_K[0], 0, 10);
 | 
			
		||||
      #elif HAS_MULTI_EXTRUDER
 | 
			
		||||
      #else
 | 
			
		||||
        EXTRUDER_LOOP()
 | 
			
		||||
          EDIT_ITEM_N(float42_52, e, MSG_ADVANCE_K_E, &planner.extruder_advance_K[e], 0, 10);
 | 
			
		||||
      #endif
 | 
			
		||||
@@ -687,11 +687,11 @@ void menu_advanced_settings() {
 | 
			
		||||
  #if DISABLED(NO_VOLUMETRICS) || ENABLED(ADVANCED_PAUSE_FEATURE)
 | 
			
		||||
    SUBMENU(MSG_FILAMENT, menu_advanced_filament);
 | 
			
		||||
  #elif ENABLED(LIN_ADVANCE)
 | 
			
		||||
    #if EXTRUDERS == 1
 | 
			
		||||
    #if DISTINCT_E < 2
 | 
			
		||||
      EDIT_ITEM(float42_52, MSG_ADVANCE_K, &planner.extruder_advance_K[0], 0, 10);
 | 
			
		||||
    #elif HAS_MULTI_EXTRUDER
 | 
			
		||||
      LOOP_L_N(n, E_STEPPERS)
 | 
			
		||||
        EDIT_ITEM_N(float42_52, n, MSG_ADVANCE_K_E, &planner.extruder_advance_K[n], 0, 10);
 | 
			
		||||
    #else
 | 
			
		||||
      EXTRUDER_LOOP()
 | 
			
		||||
        EDIT_ITEM_N(float42_52, n, MSG_ADVANCE_K_E, &planner.extruder_advance_K[e], 0, 10);
 | 
			
		||||
    #endif
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -210,9 +210,9 @@ void menu_tune() {
 | 
			
		||||
  // Advance K:
 | 
			
		||||
  //
 | 
			
		||||
  #if ENABLED(LIN_ADVANCE) && DISABLED(SLIM_LCD_MENUS)
 | 
			
		||||
    #if EXTRUDERS == 1
 | 
			
		||||
    #if DISTINCT_E < 2
 | 
			
		||||
      EDIT_ITEM(float42_52, MSG_ADVANCE_K, &planner.extruder_advance_K[0], 0, 10);
 | 
			
		||||
    #elif HAS_MULTI_EXTRUDER
 | 
			
		||||
    #else
 | 
			
		||||
      EXTRUDER_LOOP()
 | 
			
		||||
        EDIT_ITEM_N(float42_52, e, MSG_ADVANCE_K_E, &planner.extruder_advance_K[e], 0, 10);
 | 
			
		||||
    #endif
 | 
			
		||||
 
 | 
			
		||||
@@ -227,7 +227,7 @@ float Planner::previous_nominal_speed;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLED(LIN_ADVANCE)
 | 
			
		||||
  float Planner::extruder_advance_K[EXTRUDERS]; // Initialized by settings.load()
 | 
			
		||||
  float Planner::extruder_advance_K[DISTINCT_E]; // Initialized by settings.load()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAS_POSITION_FLOAT
 | 
			
		||||
@@ -854,7 +854,7 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(LIN_ADVANCE)
 | 
			
		||||
    if (block->la_advance_rate) {
 | 
			
		||||
      const float comp = extruder_advance_K[block->extruder] * block->steps.e / block->step_event_count;
 | 
			
		||||
      const float comp = extruder_advance_K[E_INDEX_N(block->extruder)] * block->steps.e / block->step_event_count;
 | 
			
		||||
      block->max_adv_steps = cruise_rate * comp;
 | 
			
		||||
      block->final_adv_steps = final_rate * comp;
 | 
			
		||||
    }
 | 
			
		||||
@@ -2541,7 +2541,7 @@ bool Planner::_populate_block(
 | 
			
		||||
       *
 | 
			
		||||
       * de > 0                       : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
 | 
			
		||||
       */
 | 
			
		||||
      use_advance_lead = esteps && extruder_advance_K[extruder] && de > 0;
 | 
			
		||||
      use_advance_lead = esteps && extruder_advance_K[E_INDEX_N(extruder)] && de > 0;
 | 
			
		||||
 | 
			
		||||
      if (use_advance_lead) {
 | 
			
		||||
        float e_D_ratio = (target_float.e - position_float.e) /
 | 
			
		||||
@@ -2557,7 +2557,7 @@ bool Planner::_populate_block(
 | 
			
		||||
          use_advance_lead = false;
 | 
			
		||||
        else {
 | 
			
		||||
          // 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[extruder] * e_D_ratio) * steps_per_mm;
 | 
			
		||||
          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 (TERN0(LA_DEBUG, accel > max_accel_steps_per_s2))
 | 
			
		||||
            SERIAL_ECHOLNPGM("Acceleration limited.");
 | 
			
		||||
          NOMORE(accel, max_accel_steps_per_s2);
 | 
			
		||||
@@ -2594,7 +2594,7 @@ bool Planner::_populate_block(
 | 
			
		||||
 | 
			
		||||
    if (use_advance_lead) {
 | 
			
		||||
      // the Bresenham algorithm will convert this step rate into extruder steps
 | 
			
		||||
      block->la_advance_rate = extruder_advance_K[extruder] * block->acceleration_steps_per_s2;
 | 
			
		||||
      block->la_advance_rate = extruder_advance_K[E_INDEX_N(extruder)] * block->acceleration_steps_per_s2;
 | 
			
		||||
 | 
			
		||||
      // reduce LA ISR frequency by calling it only often enough to ensure that there will
 | 
			
		||||
      // never be more than four extruder steps per call
 | 
			
		||||
 
 | 
			
		||||
@@ -459,7 +459,7 @@ class Planner {
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(LIN_ADVANCE)
 | 
			
		||||
      static float extruder_advance_K[EXTRUDERS];
 | 
			
		||||
      static float extruder_advance_K[DISTINCT_E];
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -118,8 +118,8 @@
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLED(EXTRA_LIN_ADVANCE_K)
 | 
			
		||||
  extern float other_extruder_advance_K[EXTRUDERS];
 | 
			
		||||
#if ENABLED(ADVANCE_K_EXTRA)
 | 
			
		||||
  extern float other_extruder_advance_K[DISTINCT_E];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAS_MULTI_EXTRUDER
 | 
			
		||||
@@ -442,7 +442,7 @@ typedef struct SettingsDataStruct {
 | 
			
		||||
  //
 | 
			
		||||
  // LIN_ADVANCE
 | 
			
		||||
  //
 | 
			
		||||
  float planner_extruder_advance_K[_MAX(EXTRUDERS, 1)]; // M900 K  planner.extruder_advance_K
 | 
			
		||||
  float planner_extruder_advance_K[DISTINCT_E]; // M900 K  planner.extruder_advance_K
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // HAS_MOTOR_CURRENT_PWM
 | 
			
		||||
@@ -2334,7 +2334,7 @@ void MarlinSettings::postprocess() {
 | 
			
		||||
      // Linear Advance
 | 
			
		||||
      //
 | 
			
		||||
      {
 | 
			
		||||
        float extruder_advance_K[_MAX(EXTRUDERS, 1)];
 | 
			
		||||
        float extruder_advance_K[DISTINCT_E];
 | 
			
		||||
        _FIELD_TEST(planner_extruder_advance_K);
 | 
			
		||||
        EEPROM_READ(extruder_advance_K);
 | 
			
		||||
        #if ENABLED(LIN_ADVANCE)
 | 
			
		||||
@@ -3206,12 +3206,17 @@ void MarlinSettings::reset() {
 | 
			
		||||
  //
 | 
			
		||||
  // Linear Advance
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(LIN_ADVANCE)
 | 
			
		||||
    EXTRUDER_LOOP() {
 | 
			
		||||
      planner.extruder_advance_K[e] = LIN_ADVANCE_K;
 | 
			
		||||
      TERN_(EXTRA_LIN_ADVANCE_K, other_extruder_advance_K[e] = LIN_ADVANCE_K);
 | 
			
		||||
    }
 | 
			
		||||
    #if ENABLED(DISTINCT_E_FACTORS)
 | 
			
		||||
      constexpr float linAdvanceK[] = ADVANCE_K;
 | 
			
		||||
      EXTRUDER_LOOP() {
 | 
			
		||||
        const float a = linAdvanceK[_MAX(e, COUNT(linAdvanceK) - 1)];
 | 
			
		||||
        planner.extruder_advance_K[e] = a;
 | 
			
		||||
        TERN_(ADVANCE_K_EXTRA, other_extruder_advance_K[e] = a);
 | 
			
		||||
      }
 | 
			
		||||
    #else
 | 
			
		||||
      planner.extruder_advance_K[0] = ADVANCE_K;
 | 
			
		||||
    #endif
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user