Marlin icon indicating copy to clipboard operation
Marlin copied to clipboard

[BUG] Smooth Linear Advance results in underextrusion curve

Open vovodroid opened this issue 6 months ago • 28 comments

Did you test the latest bugfix-2.1.x code?

Yes, and the problem still exists.

Bug Description

Smooth Linear Advance with extruder synchronisation #27710 introduces underextusion, depending on extrusion speed. Extrusion length is measure with long (500mm) cold extrusion without nozzle.

Configuration used:

#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

image

No LA/Tau change affect this. Fast 500MHz SKR-3 board with TMC2209 is used.

Electronics

SKR-3, TMC2209

Marlin.zip

vovodroid avatar Jun 21 '25 16:06 vovodroid

With such a long extrusion, the accel/decel phases should be irrelevant, and therefore the linear advance part shouldn't be significant. The only other source I see is the fact that smooth LA makes all extrusion without bresenham and it is therefore subject to rounding errors.

Namely inside set_la_interval:

la_interval = calc_timer_interval(uint32_t(ABS(step_rate)));

where calc_timer_interval returns

 uint32_t(STEPPER_TIMER_RATE) / step_rate;

in the skr3, STEPPER_TIMER_RATE=2_000_000

So at an extrussion rate of 18mm/s with steps_per_mm = 43.125*16 (microsteps), gives us


`la_interval = 2000000/18*43.125*16 = 76666666.66666667`

but then the rounding error is 100*(1-76666666/76666666.66666667) = 0.00000087%.


This can't be it

dbuezas avatar Jun 22 '25 15:06 dbuezas

It could also be e-synch. Can you confirm none of your input shaping frequencies are below the smallest one set at build time (i.e the default IS frequencies)?

dbuezas avatar Jun 22 '25 17:06 dbuezas

I just flushed build with smoothing and skipped config initialization, so default values were used for test.

#define SHAPING_FREQ_X  58
#define SHAPING_FREQ_Y  28
#define SHAPING_MIN_FREQ  20.0

vovodroid avatar Jun 22 '25 17:06 vovodroid

I assume with the same results? Did you try disabling e_synch?

dbuezas avatar Jun 22 '25 18:06 dbuezas

Did you try disabling e_synch?

Just now - exactly the same results (axes don't move during the test anyway).

vovodroid avatar Jun 23 '25 06:06 vovodroid

I finally got around testing it myself, the issue is not affecting my machine. I used the same speeds as you. There's only underextrussion at 39mm/s, which is anyway an extreme speed.

mm/s mm/min Flow (mm³/s) mm1 mm2
39 2340 93.80 99.50 99.85
30 1800 72.15 101.73 101.43
18 1080 43.29 101.60 101.10
6 360 14.43 101.15 101.70
3 180 7.22 101.74 101.50

dbuezas avatar Jul 09 '25 19:07 dbuezas

Any difference in our configuration could lead to such results?

vovodroid avatar Jul 10 '25 08:07 vovodroid

I see you have S_CURVE_FACTOR enabled so I suppose you are using #27101. That's the only thing I see that could affect it. SmoothLA uses specific code to integrate with "normal" S_CURVE, so maybe something went wrong there. I suggest you to make a test from latest bugfix branch to be sure

dbuezas avatar Jul 10 '25 09:07 dbuezas

Ok, I retested without S_CURVE (any type), INPUT_SHAPING and NONLINEAR_EXTRUSION. The same result - 3-4% underextrusion an 3mm/s speed.

vovodroid avatar Jul 14 '25 10:07 vovodroid

I assume you u are testing directly from bugfix, right? Also with NLE disabled during build. I don't know what could be the issue, I can't reproduce it :/

dbuezas avatar Jul 14 '25 13:07 dbuezas

I assume you u are testing directly from bugfix, right?

Yes, no NLE enabled in config, with only filament encoder counter added. On 15 mm^3/sec (6.2 mm/sec) it extrudes (cold extrusion) 192 encoder impulses instead of 200.

Could it be related to high speed board? What else do you suggest to check? Comment out some code parts?

vovodroid avatar Jul 14 '25 15:07 vovodroid

I use an skr3, I do have SCurve enabled (but not the special one in an open MR) The only thing I can think of is trying higher micro stepping to check if some fractional error could yve related to it

dbuezas avatar Jul 14 '25 15:07 dbuezas

I reduced extruder microsteps to 8. Do you think it could be related?

vovodroid avatar Jul 14 '25 16:07 vovodroid

Anyway with 8 microsteps final steps per mm is 200. Isn't it enough?

vovodroid avatar Jul 14 '25 20:07 vovodroid

It is just a guess, if the problem goes away at higher microsteps it would be a good clue

dbuezas avatar Jul 14 '25 21:07 dbuezas

I tried with 32 microsteps and 806 steps/mm. The same.

vovodroid avatar Jul 15 '25 06:07 vovodroid

Greetings from the Marlin AutoBot! This issue has had no activity for the last 90 days. Do you still see this issue with the latest bugfix-2.1.x code? Please add a reply within 14 days or this issue will be automatically closed. To keep a confirmed issue open we can also add a "Bug: Confirmed" tag.

Disclaimer: This is an open community project with lots of activity and limited resources. The main project contributors will do a bug sweep ahead of the next release, but any skilled member of the community may jump in at any time to fix this issue. That can take a while depending on our busy lives so please be patient, and take advantage of other resources such as the MarlinFirmware Discord to help solve the issue.

github-actions[bot] avatar Oct 14 '25 01:10 github-actions[bot]

Bump

vovodroid avatar Oct 14 '25 06:10 vovodroid

Hello, It looks like I have a related issue. I have updated my SKR3 to Marlin 2.1.3 beta 3 and with SMOOTH_LIN_ADVANCE enabled I get severe under extrusion when printing small features at lower layer heights (extruder feedrates below about 0,5mm/s). If I drop ADVANCE_TAU to 0 the situation improves somewhat - minimum feedrate is 0,4mm/s - 0,3mm/s or so. if I disable SMOOTH_LIN_ADVANCE I am getting perfect extrusion as low as 0,15mm/s. Another thing with SMOOTH_LIN_ADVANCE, is it seems to stop applying LA below approximately E feedrate of 3,5mm/s (printing at 0,2mm layer at ~100mm/s, 3K accel). However, when printing at higher speeds and accelerations the corners are much better than without SMOOTH_LIN_ADVANCE.

Soft-Brick avatar Dec 07 '25 13:12 Soft-Brick

Have you tried bugfix? Release is half year old at this point...

Nuck-TH avatar Dec 07 '25 13:12 Nuck-TH

Have you tried bugfix? Release is half year old at this point...

Thanks for the suggestion. I've just tried latest bugfix. SMOOTH_LIN_ADVANCE still causes underextrusion on low flowrates. ADVANCE_TAU at 0 gives best results, but still not perfect. With S-Curve enabled LA gives bad corner quality. With S-Curve disabled LA seems to work perfectly over wide range of speeds and accelerations. I had hopes that S-Curve and LA compatibility was fixed, but apparently not. Not sure what to make of this.

Soft-Brick avatar Dec 07 '25 14:12 Soft-Brick

Time to jump to ftmotion, that's the best option at the moment

dbuezas avatar Dec 07 '25 16:12 dbuezas

Time to jump to ftmotion, that's the best option at the moment

ftmotion fixed all my problems, thanks.

Soft-Brick avatar Dec 07 '25 19:12 Soft-Brick

ftmotion fixed all my problems, thanks.

Happy to hear! Make sure to update once #28192 merges, otherwise long prints start torturing the extruder

dbuezas avatar Dec 08 '25 07:12 dbuezas

Time to jump to ftmotion, that's the best option at the moment

#warning "NONLINEAR_EXTRUSION does not (currently) operate when FT_MOTION is the active motion system."

vovodroid avatar Dec 08 '25 08:12 vovodroid

@vovodroid It is super easy to implement in ftmotion, I would do it but I don't use the feature so I'd probably not test it well enough.

I think this is all there is to do in FTMotion::calc_traj_point:

if (use_advance_lead) {
  // Don't apply LA or NLE to retract/unretract blocks
  const float e_rate = (traj_e - prev_traj_e) * (FTM_FS);
  
  #if ENABLED(NONLINEAR_EXTRUSION)
    const float v = abs(e_rate); // extruder velocity in mm/s
    const float multiplier = max(C, stepper.ne.settings.coeff.A * sq(v) + stepper.ne.settings.coeff.B * v + stepper.ne.settings.coeff.C);
    
    traj_coords.e += e_rate * advK * multiplier;
  #else
    traj_coords.e += e_rate * advK;
  #endif
}

Since ftmotion works on position and not rates, there can be no drift/accumulation of error.

dbuezas avatar Dec 08 '25 08:12 dbuezas

@dbuezas , is if (use_advance_lead) { block runs for retract/unretract only?

vovodroid avatar Dec 08 '25 10:12 vovodroid

Image In short: the opposite.

dbuezas avatar Dec 08 '25 11:12 dbuezas

Why we need abs here: const float v = abs(e_rate); // extruder velocity in mm/s?

Could const float e_rate = (traj_e - prev_traj_e) * (FTM_FS); be negative for printing extrusion?

vovodroid avatar Dec 12 '25 12:12 vovodroid

It shouldn't. I didn't put much thought in the code hehe

dbuezas avatar Dec 12 '25 15:12 dbuezas