Extruder PA synchronization with input shaping

Klipper has an implementation of a pressure advance algorithm that synchronizes filament extrusion with the toolhead motion and eliminates many artifacts. Input shaping alters toolhead motion in an attempt to reduce vibration and ringing. However, the problem is that pressure advance today is not synchronized with input shaping.

FWIW, the problem isn’t too bad because Klipper has pressure advance smoothing. While it’s not really the same as input shaping, it still introduces changes to extruder motion that exhibit similar behavior as input shaping. So, PA smoothing synchronizes extruder with input shaping to some degree, though this synchronization is mostly accidental and is not perfect. It can be especially noticeable if X and Y have very different resonance frequencies, and/or if the PA smooth time deviates significantly from the input shaper duration. So, I attempted to implement PA synchronization with input shaping.

The implementation is available in this branch. In a nutshell, it calculates the toolhead motion over X, Y and Z axes, applies input shaping to X and Y, and uses linearization to project the motion of individual axes onto E. If the input shaper is the same for X and Y axis (e.g. some 2hump_ei or 3hump_ei input shaper), then the result is precise for XY motion. Otherwise, it is a linear approximation over X/Y deviations, but still, hopefully, better than the current state. Here’s a demonstration of the extruder kinematics with the baseline and my implementation:

This shows some extrusion moves followed by a wipe. Left is the current extruder PA code, right is the PA with the input shaping enabled. On the top graphs, the blue line is the extruder velocity from its move queue, and the orange line is the extruder stepper velocity. The charts also show the velocity of X and Y steppers for the reference (after input shaping, which is ei@45 Hz for X and mzv@41Hz in this case). Pressure advance in both cases is set to smooth_time = 0.01 s and advance=0.04.

One could observe from the charts a bit less erratic behavior of PA during extrusion moves for extruder input shaping branch - fewer retractions and deretractions during decelerations/accelerations. The extruder velocity is also more stable and changes less - apparently because the actual toolhead velocity (looking at the steppers velocities) changes less with time due to input shaping. As a result, there is less pressure on the extruder to maintain the extrusion. The behavior of the wipe (first, larger retraction when the toolhead is at still, followed by a toolhead move combined with some retraction, followed by a small retraction when the toolhead isn’t moving) is also better, in my opinion, as the extruder maintains more stable retraction velocity throughout the wipe. Note that I generated the charts from the code based on my improved stepcompress code, but that’s because the stepper velocity charts aren’t particularly legible otherwise, but I didn’t observe any noticeable change in the extruder code performance when based on the improved stepcompress code vs the regular Klipper mainline.

So far, I have been testing this branch for over a couple of months, and overall I think it offers small improvements in quality of the real prints. Overall, I’d expect it to have most of the effect on the direct drive extruders with a relatively short filament paths, where PA smooth time might be desirable to reduce (more on PA tuning for it in the next post). I wouldn’t expect noticeable improvements on bowden extruders (though likely there shouldn’t be degradation in quality either). If you want to give it a try, please do and report back your experience (whether the changes in prints are positive, negative or neutral). If you happen to be using my stepcompress branch, you may continue to do so by using this branch for extruder input shaping instead of the regular one, so that you don’t have to reflash the MCU back. Things to keep an eye on (where the quality may improve or degrade) are when the toolhead velocity changes: corners of the model, starts and ends of the bridges, infill connecting to perimeters, etc.

Note that you should really change/retune PA for this branch. I’ll make a follow-up post with more details, but at the very least, you should try to reduce the pressure_advance_smooth_time from the default 0.04 to 0.02 or even better 0.01 (assuming direct drive extruder and non-flex filaments). That will likely result in a different (smaller) choice of PA value, especially if you’ve been using the Klipper PA tuning tower to choose the PA advance value.

Overall, the current Klipper PA tuning process is a bit of a hit and miss. In my experience, after comparing the results with a different approach, I think the default PA tuning process often gives too large PA values. I suspect this is primarily due to the following reasons:

  1. It is difficult to inspect corners for quality to find the good point.
  2. Using low acceleration value means that PA acts less and over longer distance (it takes 10 mm to decelerate from 100 mm/sec at 500 mm/sec^2 acceleration), so PA values that are already too aggressive may be difficult to identify as such.
  3. Using too low square corner velocity setting means that the toolhead must decelerate very much, and it is likely that PA isn’t working great at this velocity (1 mm/sec), so the corners bulge too much, giving a false sense that PA value “isn’t yet large enough”, when it actually already is.

These reasons, especially (3) combined with (2), make a user likely to select a PA value that is actually too large for the given printer, filament and printing parameters. A better test model could be something like this:

Basically, a 1-2 walls tower with a velocity change from fast to slow and back. Notice that

  • A user can print it with a regular acceleration, making a test more representative of the real prints.
  • Velocity change happens not at the corners (at them too, but one shouldn’t inspect them), but when the toolhead moves in a straight line. This isolates PA effects from everything else (e.g. input shaping, square corner velocity, etc.).
  • It is actually quite easy to inspect the lines where velocity changes to find the best PA value.

My experience is that I get a PA value of 0.044 for the baseline Klipper (and smooth_time=0.04) for some PLA using the default test, and a value of 0.02 - for exactly the same filament for this different tower test. Incidentally, the improved test shows that 0.044 PA value would really be too much for the real prints and could create gaps in the model (a mark on the model, printed with TUNING_TOWER COMMAND=SET_PRESSURE_ADVANCE PARAMETER=ADVANCE START=0 STEP_DELTA=0.002 STEP_HEIGHT=2, the total model height is 50 mm):

I suspect this defect doesn’t happen in practice often because near corners, the toolhead decelerates a lot more and moves slowly around a corner, and so perhaps some extra material can flow from the nozzle and compensate for the defect a bit; it can be observed that the corner of the model isn’t that bad here too. However, when decelerating from 100 to 20 mm/sec, the toolhead still moves sufficiently fast and the defect appears. This kind of defect can appear in real prints near bridges, because the toolhead may experience a similar pattern of deceleration and subsequent acceleration.

Then, using this improved test, I observed that if I reduce the smooth_time to 0.02, the ideal PA value reduces to 0.012 (from 0.02), and then reducing it further to 0.01 does not change PA value further (so the ideal value stays around 0.012).

Now, with the extruder input shaping branch and smooth_time 0.01 sec, I get the same PA value of 0.012. However, with the extruder shaping enabled, I think I can now choose a more optimal point such that the defects during acceleration and deceleration are minimal, in contrast with the mainline Klipper, where some defects are still present at the same height - during acceleration, deceleration or both:

Here left to right are baseline smooth_time = 0.04, baseline smooth_time = 0.02, baseline smooth_time = 0.01 and extruder shaping smooth_time = 0.01.

And one more test, 30x30 mm square printed with those smooth_time(s) and the optimal PA values as described above:

Here, counter-clockwise, starting from the bottom-left corner are baseline smooth_time = 0.04, baseline smooth_time = 0.02, baseline smooth_time = 0.01 and extruder shaping smooth_time = 0.01 (so extruder shaping test is at the top left). I put together the same corner from all 4 test models by rotating them appropriately. Overall this confirms that the choice of PA values is good (and PA values are smaller than from the default Klipper PA test - so those values would be actually excessive). Then, the individual differences between the corners are admittedly not large. I find the corner from the extruder shaping code a bit more crisp and geometrically accurate, but that may be subjective and you can judge for yourself from the picture.

So, if you will be testing my extruder input shaping branch, please make sure to reduce the pressure_advance_smooth_time in the config and tune the PA value appropriately.

Sadly, it is not possible to generate the desired PA tuning tower test in PrusaSlicer/Superslicer using model modifiers (it is a known bug that’s unfixed):

And unfortunately, the GCode generator that I have used to generate a test GCode has some bugs, so I cannot really link it here, and required some code/gcode fixes. If you have some good ideas how to generate a test model/gcode like that - please share them, I’d be happy to hear. Maybe there’s some good generator out there. For the reference, the GCode that I ended up using is this one (for 0.4 mm nozzle):
KF_0.28mm_50mm.zip (15.7 KB)

And one more thing: the code is experimental and may not work in multi-extruder or multi-extruder-stepper setups. So, be advised about this potential limitation (for now).

Regardless if I use the dmbutyugin/extr-is-stepcompr or dmbutyugin/extruder-input-shaping branch, when performing the PA tuning I end up with

Error on ‘SET_PRESSURE_ADVANCE ADVANCE=’: unable to parse

Am I missing something?

klippy.log (917.8 KB)

Tripped over the M900 in the new tuning tower gcode. PEBCAK

Thank for your work on klipper!

It looks interesting and the motion traces certainly seem more sensible. However, I might be missing something, as I don’t understand the need for synchronization in the first place.

By reducing vibrations, IS is supposed to improve the system response to follow more closely the input command (minus smoothing). The acceleration pulses duplicated by IS are meant to cancel out and yield a zero delay response.
At least that is my understanding. And with this, I fail to see why the extruder should be re-synchronized to the input shaped motion.

Please enlighten me :smiley:

Could this be described as a way for the extruder to piggyback the IS smoothing on X/Y?

Yeah, it is a way to synchronize an extruder with input shaping smoothing. The smoothing not only causes the toolhead to deviate from the requested trajectory around corners, it, more importantly for extruder and PA, alters toolhead velocity. As a result, PA may be using a wrong velocity for adjusting the filament position. And then shaper pulses and PA smoothing may kick in at different points in time in general, causing small artifacts near the points of velocity changes either due to slight under- or over-extrusion.

Tested a print using the extr-is-stepcompr branch. Came out nicely.
New PA tuning (PETG) came down from 0.14 to 0.10. The new tuning tower is really nice. The transition between bad - good - bad is pretty evident.
Printed a case, where the bottom was on Klipper main and the top with the a.m. branch. I have the impression that the top came out slightly underextruded. I mean, not really under-extruded but “less” extruded.

Anyway, thanks a lot for keeping up such kind of work. This is a lot more valuable than supporting chocolate printers and obscure LCDs and one of the main reasons why I really like Klipper. Its about printing and not messing with “decoration” :+1:

Thanks! The part about under-extrusion is strange though; technically, the new code should extrude the same amount of plastic as the mainline Klipper. It’s just how exactly the filament is deposited around corners and acceleration/deceleration part could differ vs the mainline branch, but the regular extrusion lines shouldn’t really be affected. Unless, of course, there are bugs :slight_smile: The case part was fairly large, I assume, not like 20x20 mm cube?

Not too large 112x90 mm

The bottom part has a nearly closed 1st layer surface and also not the slight gaps around the hole. Looks like I now need to increase my Z-Offset by at least 0.05 to 0.1

Looks like a Z offset being a bit off, by like 0.075 maybe. It couldn’t have changed naturally, could it? I guess a top surface could be more telling if there’s any extrusion problem. Or is it already a top surface?

Agree, as state above. Typically my offset is pretty stable and I only slightly modify it when I change material and / or bed temps drastically. Between two prints with the identical material I do not experience such a drift.

It’s bottom first layer. This is top:

Actually quite happy with the quality

Wouldn’t it be better to synchronize the extruder against the output of a damped spring-mass model tuned to the IS frequency and fed with the input shaped signal? This could more closely follow the real velocity of the toolhead and would be less erratic than the raw input shaped command.

I haven’t looked into the code in details, but I guess that the PA smoothing take care of the roughness of input shaped X/Y that is projected back on E?

I’ll try this branch next week end. I think I have a good test case.

Well, one would have to integrate that damped spring-mass model numerically within Klipper, which we don’t currently do. Plus, TBH, I have doubts that it would be possible to robustly extract and use the frequency response from the measurements for all types of prints. Keep in mind that a single resonance peak is a rare occasion rather than a norm (at least that’s my impression from the charts people post on Discord). So, that model would have to be potentially complex and account for multiple resonances and for how different parts of the motion system may be connected to each other. Hence my reservations.

I agree that the proposed change is still an approximation. Just, perhaps, a bit better approximation than just using PA with larger smooth_time window.

Then, input shaping actually always makes the toolhead motion smoother than the original motion (assuming all IS coefficients are positive). So, the motion profile to PA after IS will be less erratic than the original toolhead motion. But yes, PA still applies smoothing with IS (I just suggest to use quite a bit smaller smooth_time window), so the velocity and acceleration jumps will still be smoothed so that PA does not have to make large jumps, if that was the question.

Edit: and yes, if you have a good test case, it would be awesome to give that a try.

Thanks, this clarifies a lot! I wasn’t totally aware of this. After all, IS merges delayed versions of the input, resulting in more discontinuities, but indeed, more spread out over time. (without negative coefficients that would otherwise swing the velocity the other direction)
I was speaking hypothetically, first to understand whether you use the input shaped signal or some sort of system response. Furthermore, I was kinda hoping there would be an easy way to compute the smoothed response in the same way that one can derive % resonance and smoothing factor.

I reproduced a similar tower than yours, with my unusual extrusion setup: BMG bowden and 0.2 mm nozzle. This usually give me quite high pressure advance, original tower tells me to use a pressure advance of ~1.5 s. I subsequently reduced it empirically to 0.9 s by incremental improvements.

Test specification:

  • 100x50mm footprint, single wall,
  • The extrusion sections are lw×lh = 0.22×0.12 mm (E moves at 1.01% of toolhead velocity),
  • Toolhead velocity is oscillating between 200mm/s and 40 mm/s at 4000 mm/s² and scv = 6.5 mm/s (Input shapers both at 46 Hz, mzv on X, 2hump_ei on Y),
  • PA ranges from 0.2 to 1.75 s and is kept constant for a succession of 5 layers (0.6 mm bands), smoothing time is 10 ms,
  • Three PA implementations, from top to bottom: upstream, extruder-input-shaping, and upstream but excluding the base position from smoothing (à la Rich Felker).

Long 200 mm/s side (tool head moves from left to right, slow, fast, slo):

Long 40 mm/s side (fast, slow, layer change, slow, fast):

Edit: gcode.zip (for reference only, generator code is WIP) Also added IS parameters above.

I ended up with a pressure advance of 0.63 s. So that’s already a win. I target the layer where opacity is similar on both sides of the acceleration.
However there is little differences between the PA versions. Maybe yours has less of a flow rate dip when transitioning from low to high velocity. I guess I should try with longer smooth time in order to get a more pronounced effect. Do you have another suggestion?

Yeah, more discontinuities, but smaller in magnitude. So, that might actually be helpful for PA, as it means proportionally less filament to push for a single ‘step’.

Maybe I’m just now aware of it. But on the other hand, I somewhat doubt it. Anyways, the resonance %% and smoothing factor reported by a script are also mere approximations or scores and not the actual precise values.

FWIW, your setup is rather unusual indeed. A bowden setup is already a challenge, and such a small nozzle will make matters even worse. TBH, I’m unsure if this setup can push enough filament at 200 mm/sec without underextrusion, especially with the PA enabled (e.g. due to filament slipping on the gears in the extruder). Either way, I think there wouldn’t be a significant impact of my changes on bowden extruders, as I suspect they have larger reactivity and require larger smooth_time values to operate properly. You may give smooth_time = 0.02 and smooth_time = 0.04 a try and see how that impacts your setup (also for the mainline Klipper). On the other hand, at least your experiments confirm my changes aren’t making things worse for your setup :slight_smile:

I’m sorry, I didn’t fully understand which effect you are describing here.

I understand this is a result of just the test and applies also to the mainline Klipper? And you were targeting these areas, right?

TBH, I almost never print at 200 mm/s, I cranked it up to get higher contrast between the slow/fast extrusions of the tuning test.
At the most extreme, I print at 150-180 mm/s with a smooth time of 0.03s, or 80-130 mm/s with a smooth_time of 0.02 s, and only use a smooth <= 0.01 s when slowing down to 50-80 mm/s.

The high PA value in combination with high printing speeds is not as unsound as it first looks. When halving the nozzle diameter, the “natural” extrusion section is divided by 4. So, at identical toolhead velocity, the flow rate is again divided by 4 (q ~ 1/r²). The theoretical Poiseuille pressure[1] is multiplied by 4 ( p ~ q / r⁴ ~ 1 / r² ) and so is the compressed length of filament. In the end, the pressure advance coefficient should be 8 times the original while the PA offset position only sees a 4 folds increase.

I’m planning a direct drive conversion, but before I commit to it, I want to finalize some experiments characterizing extreme bowden setups (notably testing the idea that anistropic acceleration could be bad for bowden printers). I’ll probably go back to .4 for repeatable results, but for now, .2 suits what I print and waste less material per test.

The question is if and how can I get you interesting data points with this? I think I’ll transition to the test case I had in mind.
With higher accelerations and SCV the gaps widen where the lines meet at obtuse angles, as expected from IS smoothing. Interestingly, the position of the under-extrusions are direction dependent. This makes me think that this artifact could be related to the interaction between PA and IS.

If I don’t see any differences, I would concede that my extrusion system doesn’t have enough reactivity to show the effect of your patch.

On the left side of the first picture, there is a thin brighter vertical line under the 20->200 mm/s transition that persists at all PA values. It can also be found on the right side of the second picture, but less pronounced.
While it is not very clear in the photo, I do believe that it is less pronounced on your PA implementation (middle row).

Yes, I targeted these areas. Pretty much the same result for each PA implementation/

  1. Poiseuille is likely the wrong model, but the exponents should be good enough for a rough demonstration. ↩︎

Seems to fit into this discussion

First row is mainline PA, second is @dmbutyugin’s implementation.

  • Left column is 80 mm/s 6000 mm/s² scv=9 mm/s (my medium fast profile, with scv increased to 125% of my usual value)
  • Right column is 40 mm/s 2000 mm/s² scv=4.6 mm/s (slow profile for detailed prints)

Each printed at lw×lh = 0.22×0.12 mm extrusions, PLA @ 230°C, PA = 0.7 s, smooth_time = 0.01 s.

motan traces
So yes, not much to see here. You must be right, the bowden is blurring any potential improvement. At least there is no visible degradation.
Sorry for the noise :slightly_frowning_face:

No worries, thanks for testing it! Even if the result is neutral, it is still a result, and we’d need that too - confirm that the new code does not make things worse on bowden setups. The real question is, does it improve print quality even if a bit on sufficiently many setups?

Thank you for sharing it here. I looked briefly through the article, and my impression was that they built a model of how the filament flow in the absence of PA. And in general, their data and model matched my expectations, though not all parts of their model matched what I would expect from the filament flow based on a PA model. However, they may have just fitted real data to a slightly different model. As it is though, I’m not sure if there is a lot to be [re-]used from there - I did not notice any obvious areas that wouldn’t be covered by the PA model.

Did some more prints. All works well. Calibrated PLA and it went down from 0.058 to 0.048
Quality wise I cannot really tell any difference. It might be that my extruder stepper gets less hot but this is kind of subjective to me touching it. Before it was so hot that touching it was almost hurting and it seems less so.