Skip to content

Smooth Linear Advance with extruder synchronisation #27710

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

Merged

Conversation

dbuezas
Copy link
Contributor

@dbuezas dbuezas commented Feb 24, 2025

Description

Introduces a new smooth linear advance method that decouples extrusion from motion constraints, improving print speed and quality without acceleration limits. (comparable to Klipper's approach).

  • Smooth linear advance is managed by a new ISR that runs at a constant interval.
  • Smoothing is calculated from planned extrusion rate instead of acceleration. This improves nozzle pressure control by making the algorithm aware of XY jerk and line width changes, and results in higher print quality compared to 'classic LA'.
  • Instead of using moving window averaging (like Klipper) or instantaneous speed changes (like "classic" marlin linear advance), this PR uses an efficient approximation of gaussian filtering. The approximation consists of higher order (5) exponential smoothing corrected for delay.
  • Delay correction is achieved by looking ahead in the block (even into future blocks). The smoothing factors are automatically calculated from the lookahead offset (TAU) to ensure delay compensation is precise and requires no calibration.
  • TAU is somewhat analogous to Klipper's pressure_advance_smooth_time and can be configured in the LCD or via GCODE. The lower the better, as long as the extruder stepper doesn't skip steps.

Enabling SMOOTH_LIN_ADV results in faster and higher quality prints in 32 bit MCUs

The new ISR allows for a second second feature, INPUT_SHAPING_E_SYNCH, which synchronises the extruder with the input shaped x and y axes. This results in very accurate extrusion during acceleration phases. Synchronizing E to input shaping improves seams and top surfaces significantly, even at high accelerations (e.g nice seams and top surfaces at 15k mm/s^2).

Requirements

32 bit MCU

Benefits

Enables higher acceleration without extrusion artifacts

  • Improves top surfaces and seam quality
  • Reduces pressure variations in high-speed printing

Configurations

  #define SMOOTH_LIN_ADV          // Removes motion acceleration limitation by allowing to gradual ramp up of nozzle pressure
  #if ENABLED(SMOOTH_LIN_ADV)
    #define ADVANCE_TAU 0.01      // (secs) Smoothing time to reduce extruder acceleration due to linear advance.
                                  // It is also the time ahead the smoother needs to look in the planner
                                  // so the planner needs to have enough blocks loaded.
                                  // for k=0.04 at 10k acceleration and an orbiter 2, it can be as low as 0.0075.
                                  // The lower the better until stepper skipps
                                  // Higher k and higher print accelerations may require larger tau to avoid skipping steps
    #define SMOOTH_LIN_ADV_HZ 5000   // How often to update extruder speed
    #define INPUT_SHAPING_E_SYNCH    // Synchronize the extruder shaped xy axes (increrses precision)
  #endif

Related Issues

This is a further evolution of- and closes #27352. Now with more solid mathematical foundations and improved precision.

Misc

I have a fast 32 bit MCU with FPU so I made liberal use of floats. Further optimisations (e.g. fixed-point arithmetic, planner pre-computations) are possible. However, given the significant speed and quality improvements, I propose addressing those in a follow-up PR after merging this foundational implementation. I'm getting the speed and quality of a Voron or bambulab in my Ultimaker 2 with a direct drive extruder.

@tombrazier mentioned that, at least in theory, extrusion synchronisation could be done at step level. If implemented, it would replace my version of INPUT_SHAPING_E_SYNCH.

Validation of this approach

Analysed stepper control signals with a logic analyzer and performed extensive testing (>1kg of prints)

Thanks @oliof and @tombrazier for the early feedback and discussions in discord.

(cherry picked from commit 28300f8)
@tombrazier
Copy link
Contributor

First thought: what about a name change at this point? "Linear advance" isn't as good name as "pressure advance" and everyone knows "smooth pressure advance" from Klipper, so just the name would communicate a lot if we changed "linear" to "pressure". @thinkyhead

(cherry picked from commit 0f10d91)
(cherry picked from commit 2d74be5)
(cherry picked from commit 3722520)
@vovodroid
Copy link
Contributor

Hi, @dbuezas I tried to calibrate extruder steps per mm, extruding specific filament length without nozzle and found, that SMOOTH_LIN_ADVANCE introduces some extrusion length error, depending on extrusion speed, it could several percents, e.g. 5%.

I also use S_CURVE.

Anyway, should be condition ANY_AXIS_MOVES(current_block) checked for all this mechanism to prevent interaction with rectract/unretract?

@vovodroid
Copy link
Contributor

Something like this:

    void Stepper::set_la_interval(int32_t step_rate) {
      if (step_rate == 0 || !ANY_AXIS_MOVES(current_block)) {
        la_interval = LA_ADV_NEVER;
      }

@dbuezas
Copy link
Contributor Author

dbuezas commented Jun 18, 2025

Smooth linear advance could still be applying corrections after the other axes stopped, the smoothing makes it start accelerating tau seconds before planned, and stop (roughly) tau seconds after. This is by design to avoid discontinuities is rate.

Also set_la_interval actually covers all extrusion, not only the linear advance part.

Regarding the error you observe, it may be numerical error since it works on rates and not positions, but 5% is too high to be explained by that. Do you also get that kind of variance with NLE disabled?

@vovodroid
Copy link
Contributor

Do you also get that kind of variance with NLE disabled?

Yes. First, NLE is applied only if axes are moving (ANY_AXIS_MOVES(current_block)), also during investigation I found that this switch is not in use for smooth LA so I fixed this in Check NLE enabled flag for SMOOTH_LIN_ADVANCE #27926, but it doesn't matter in this case either.

Also I set LA to zero, also didn't change a thing.

Could high extrusion speed (w/o the nozzle, 20-30 mm/sec, 50-77mm^3) be related to this?

@dbuezas
Copy link
Contributor Author

dbuezas commented Jun 18, 2025

Mmm maybe, hard to say. A very low tau would make it act like the old LA

@vovodroid
Copy link
Contributor

Even with zero LA?

@dbuezas
Copy link
Contributor Author

dbuezas commented Jun 18, 2025

Oh good point, with zero LA it should be the same thing as not having anything.
The difference is that smooth LA changes the extruder speed 1000 times a second, instead of exactly in synch with the planner execution

@vovodroid
Copy link
Contributor

The difference is that smooth LA changes the extruder speed 1000 times a second, instead of exactly in synch with the planner execution

Should it apply correction when extrusion speed is constant?

@dbuezas
Copy link
Contributor Author

dbuezas commented Jun 20, 2025

A slight drift may happen since pulses aren't counted. smoothLA just assumes distance traveled from previous time and rate. I don't expect the drift to be so large though, so this may not be the reason of what you are measuring. You are sure this error is not present without smooth LA, right?

@vovodroid
Copy link
Contributor

vovodroid commented Jun 21, 2025

Well, I build with following config without NLE:

#define LIN_ADVANCE
#define ADVANCE_K 0.22        // (mm) Compression length applying to all extruders
#define SMOOTH_LIN_ADVANCE    // Remove limits on acceleration by gradual increase of nozzle pressure
#define ADVANCE_TAU 0.02       // (s) Smoothing time to reduce extruder acceleration
#define SMOOTH_LIN_ADV_HZ 1000   // (Hz) How often to update extruder speed
#define INPUT_SHAPING_E_SYNC     // Synchronize the extruder-shaped XY axes (to increase precision)
//#define NONLINEAR_EXTRUSION

Here is underextrusion table for speed (mm/s):

3	0.929
6	0.926
18	0.985
30	0.968
39	0.944

Here is a graph:

image

No LA/Tau change affect this. As I mention I have fast 500MHz SKR-3 board.

@dbuezas
Copy link
Contributor Author

dbuezas commented Jun 21, 2025

Can you add a trace without smooth LA?

@vovodroid
Copy link
Contributor

Just enable LA_DEBUG?

@dbuezas
Copy link
Contributor Author

dbuezas commented Jun 21, 2025

I mean without #define SMOOTH_LIN_ADVANCE

@vovodroid
Copy link
Contributor

Do you mean COM-port dump? How to enable needed tracing?

@dbuezas
Copy link
Contributor Author

dbuezas commented Jun 21, 2025

I just mean a trace in the plot, an extra curve

@vovodroid
Copy link
Contributor

Ahh, I checked it - without SMOOTH_LIN_ADVANCE it's always the same correct length.

@dbuezas
Copy link
Contributor Author

dbuezas commented Jun 21, 2025

Ok that's super weird. With so much under extrusion it would really show

@vovodroid
Copy link
Contributor

vovodroid commented Jun 21, 2025 via email

@dbuezas
Copy link
Contributor Author

dbuezas commented Jun 21, 2025

But quite noticeable onTm top surfaces

@vovodroid
Copy link
Contributor

vovodroid commented Jun 21, 2025 via email

@dbuezas
Copy link
Contributor Author

dbuezas commented Jun 21, 2025

Maybe it would then be best to either track actual steps done, or to leave the non LA term be handled directly by the block interrupt as before

@vovodroid
Copy link
Contributor

track actual steps done

Sorry?

leave the non LA term be handled directly by the block interrupt as before

Use smoothing only for acceleration/deceleration phase?

@dbuezas
Copy link
Contributor Author

dbuezas commented Jun 21, 2025

track actual steps done
Sorry?

Currently it calculated rates and uses them, but it doesn't count the steps done for the motor, it just "assumes" them through velocity * time

Use smoothing only for acceleration/deceleration phase?

That won't work, smoothing discontinuities involves starting earlier to be able to ramp up the speed incrementally and the same on at the end of that phase.

Linear advance demands to start a block with the extruder jumping from 0 to accel*k instantly, smooth LA ramps up instead. This ramp up means error, and the error is spread in time by starting earlier.

During most of the cruise phase, the extruder should go at the exact same speed than it used to, except for maybe some rounding error.

ThomasToka added a commit to ThomasToka/Marlin that referenced this pull request Jul 10, 2025
v034 - "The refactor update"

- included all Marlin upstream commits till 29.06.2025
- Smooth Linear Advance enabled with a default TAU of 0.020 in mainboard and screen firmware. read more about Smooth Linear Advance here: MarlinFirmware#27710
- introduced DYNAMIC_LEVELING and DYNAMIC_TRAMMING variables to conditionally enable or disable both on compile time

- starting autoleveling ALWAYS triggers a G28 Homing, even if you just entered the autoleveling site and the printer is homed
- more "changeable" text fields in blue on the screen
- reverted old non working "probe error 203 on point 1" fix
- rewritten both UBL and ABL to be conditionally dynamic
- removed old debug functions in stable code parts (so all, haha)
- rewritten the complete E3S1PRO_RTS implementation

- the "probe error 203 but finish autoleveling on point 1" bug was fixed by a earlier variable update of max_points
ThomasToka added a commit to ThomasToka/Marlin that referenced this pull request Jul 12, 2025
v034 - "The refactor update"

- included all Marlin upstream commits till 29.06.2025
- Smooth Linear Advance enabled with a default TAU of 0.020 in mainboard and screen firmware. read more about Smooth Linear Advance here: MarlinFirmware#27710
- introduced DYNAMIC_LEVELING and DYNAMIC_TRAMMING variables to conditionally enable or disable both on compile time

- starting autoleveling ALWAYS triggers a G28 Homing, even if you just entered the autoleveling site and the printer is homed
- more "changeable" text fields in blue on the screen
- reverted old non working "probe error 203 on point 1" fix
- rewritten both UBL and ABL to be conditionally dynamic
- removed old debug functions in stable code parts (so all, haha)
- rewritten the complete E3S1PRO_RTS implementation

- the "probe error 203 but finish autoleveling on point 1" bug was fixed by a earlier variable update of max_points
- hotfixed MarlinCore.cpp to fix cardreader timing
ThomasToka added a commit to ThomasToka/Marlin that referenced this pull request Jul 13, 2025
v034 - "The refactor update"

- included all Marlin upstream commits till 29.06.2025
- Smooth Linear Advance enabled with a default TAU of 0.020 in mainboard and screen firmware. read more about Smooth Linear Advance here: MarlinFirmware#27710
- starting autoleveling ALWAYS triggers a G28 Homing, even if you just entered the autoleveling site and the printer is homed
- more "changeable" text fields in blue on the screen
- reverted old non working "probe error 203 on point 1" fix
- removed old debug functions in stable code parts (so all, haha)
- the "probe error 203 but finish autoleveling on point 1" bug was fixed by a earlier variable update of max_points
ThomasToka added a commit to ThomasToka/Marlin that referenced this pull request Jul 13, 2025
v034 - "The refactor update"

- included all Marlin upstream commits till 29.06.2025
- Smooth Linear Advance enabled with a default TAU of 0.020 in mainboard and screen firmware. read more about Smooth Linear Advance here: MarlinFirmware#27710
- starting autoleveling ALWAYS triggers a G28 Homing, even if you just entered the autoleveling site and the printer is homed
- more "changeable" text fields in blue on the screen
- reverted old non working "probe error 203 on point 1" fix
- removed old debug functions in stable code parts (so all, haha)
- the "probe error 203 but finish autoleveling on point 1" bug was fixed by a earlier variable update of max_points

Update stm32f1.ini
ThomasToka added a commit to ThomasToka/Marlin that referenced this pull request Jul 18, 2025
v034 - "The refactor update"

- included all Marlin upstream commits till 29.06.2025
- Smooth Linear Advance enabled with a default TAU of 0.020 in mainboard and screen firmware. read more about Smooth Linear Advance here: MarlinFirmware#27710
- introduced DYNAMIC_LEVELING and DYNAMIC_TRAMMING variables to conditionally enable or disable both on compile time

- starting autoleveling ALWAYS triggers a G28 Homing, even if you just entered the autoleveling site and the printer is homed
- more "changeable" text fields in blue on the screen
- reverted old non working "probe error 203 on point 1" fix
- rewritten both UBL and ABL to be conditionally dynamic
- removed old debug functions in stable code parts (so all, haha)
- rewritten the complete E3S1PRO_RTS implementation

- the "probe error 203 but finish autoleveling on point 1" bug was fixed by a earlier variable update of max_points
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants