Modification of Pressure Advance for high speed Bowden printers

I’m on the The 100 discord and we have been discussing how extremely fast Bowden printers have optimal PA values that vary with print speed (and even acceleration), unlike direct drive machines that have pretty much constant PA values.

For example, here is Pressure Advance data from the PA tower test printed on voidfoo’s The 100 with a 0.4mm volcano CHT nozzle at 10k mm/s^2 acceleration, 0.04 second smoothing time, with 1mm/s square corner velocity.

For Bowden, it seems like the linear model of “flowrate proportional to filament compression” doesn’t hold true, at least in this speed regime.

At these accelerations, the PA value is pretty irrelevant for slow speeds. But at high speeds, the compression of the filament needed to respond promptly to extrusion speed changes actually seems to be relatively constant across requested extrusion speeds.

I suspect this roughly 2.4mm of compression corresponds to the amount of “slack” there is to take up in the Bowden tube before the extruder’s force reaches the hotend (which itself behaves fairly linearly).

One thing of note: it does seem to vary with acceleration too. When voidfoo tried 300 mm/s with 20k mm/s^2 acceleration, the optimal PA value was 0.36, and thus the amount of filament advance was actually 3.6mm, significantly higher. I suspect this is an interaction between the time it takes to reach peak speed and the smoothing time. We don’t have more data yet but we will be gathering more info… I want to know whether the initial slope is the same and it just tops out at different offsets, or whether the slope is different and different accelerations top out at the same printhead speed.


What I propose is an alternate Pressure Advance strategy for high speed Bowden printers which stops increasing the advance distance above a certain threshold.

Depending on further test results, it may be useful to have this threshold vary with acceleration—more data to come, hopefully.

I took a look at the code and while at first I thought it would be a trivial change it seems more difficult than that because the integration is performed analytically and this would be chopping the PA offset up into piecewise defined functions.

To implement this, pa_move_integrate needs to check each move for whether or not it crosses the offset threshold or not, and perform two separate integrations if it does.

1 Like

More data gathered by voidfoo… 20k accels for 100 through 300 mm/s.

Nothing conclusive yet. The higher accelerations demand slightly higher PA across the board, it seems, by a factor ranging from 1.1 to 1.3. We’re going to gather data at 5000 and 500 mm/s^2 as well, in order to check how that behaves in the other direction.

I’m also hoping to have other people gather the same data points with slightly (or maybe significantly) different setups.

If you want to help and have a fast Bowden printer, run PA tuning towers with 0.4mm line width, 0.2mm layer height, 1mm/s square corner velocity, at the following speeds [100 150 200 250 300 mm/s] and accelerations [500, 5000, 10000, 20000 mm/s^2]. EDIT: note that you can’t achieve higher than 150 mm/s at 500 mm/s^2, so don’t test those.

If you can’t achieve the highest values together in combination, that’s okay too. More data more better.

Direct drive printers too would benefit from different PA values depending on speeds/accel !
It is the reason why I stick with Cura + Klipper plugin : allows for various accel and PA for various lines types.

Such a feature in Klipper would be great !

Did some Elli’s calibration tests for the speeds/accel I use for outer/inner walls, top botttom, ; with eSun ABS+ on the Voron 0.2, Revo HF, PAs from 0.04 to 0.028 ; the difference is not negligible.

1 Like

More data from voidfoo:

Very high accelerations demand very high pressure advance, it seems, but at the same time, that severely stresses the extruder. voidfoo said that the filament was slipping in the extruder gears.

That said, the pressure advance offset distance nonetheless does seem fairly constant.


My hope is that we can figure out common patterns so that users won’t have to do THIS many tuning towers to build a LUT…

Interesting. Thanks for sharing your tests.

The linear model for pressure advance was thought to be a good general guide. As you’ve shown, it’s definitely not a perfect model.

Just as reference, from the data you provided in the above graphs, I’d generally recommend a pressure_advance: 0.3 setting. That is, choose the lowest PA value that works for the range of speeds one will be using. As, hopefully, that value will improve overall print quality (that is, it may not be the “perfect” setting for all speeds, but should be a good improvement over not using any pressure advance).

As you have indicated, it is possible to change the code to use a new math model for the extruder. It can be challenging to do that, however. In particular, it’s difficult to handle “initial preload distances” as that can result in “infinite velocities” that often stress the system. It is also a challenge to construct a calibration test that users can meaningfully run (an enhanced model will only improve user prints if many users can calibrate it successfully).

FYI, some users have attempted to tune pressure_advance_smooth_time as an alternative mechanism to improve responsiveness. I’m not sure if you’ve looked at that.

Also, @dmbutyugin has looked at this area as well a few times.

Let us know if you come up with further test results or code changes.

Cheers,
-Kevin

I need more people with very fast printers to capture data, but from what I can tell, at low speeds pressure advance is fine, and then it would be okay to cap out at an “initial preload distance” per acceleration.

If other printers behave similarly, they wouldn’t need too much tuning, maybe a tuning tower at 150 mm/s for each acceleration level.

The tough part about modifying the firmware is that everything it does uses analytic integrals and I don’t know how to chop the motions apart when the proportional PA crosses the threshold… do you have any advice there?


Additionally, we’re also looking at ahead-of-time computation of PA using a slicer postprocessing script, by simulating what the printer motion would be and segmenting the g-code movements into smaller ones that have the desired amount of flow.

voidfoo is working on this and the resulting segmented speed visualizations are nice, though with a few bugs still:

There are limitations on what g-code can express though, since the standard motions have has proportional flowrate and xyz motion afaik.

The integrals are just to calculate the “weighted average position” of the extruder. It helps smooth out the extruder motion. It is also needed to avoid infinite velocity requests that could occur if the extruder makes an instantaneous velocity change (due to instantaneous_corner_velocity).

The current PA formula is: pa_position(t) = (nominal_position(t) + pressure_advance * nominal_velocity(t)) . The code then calculates a weighted average of that.

If you know your new math formula, then it should be possible to calculate a weighted average for it (or some other smoothing if you don’t want a weighted average).

The math can get tricky - it certainly took me many hours working through the formulas when I initially wrote the code (and I was able to reference some examples from Dmitry). I don’t know of a “short cut” to get the math correct.

-Kevin

Yes, I have also had an experience that different pressure advance values are optimal at different velocities, though on direct drive extruders. I have a PA test in one of my branches that makes transitions between different velocities


so that a user can see which PA values are optimal. And more often than not, I get different optimal PA values at different velocity transitions.

So, I’ve also implemented a non-linear PA calculation by factoring out the PA velocity term calculation, so that then this velocity can be passed to a function that calculates a non-linear PA values. The non-linear PA models I’ve added are not particularly scientific, they just give a smooth transition between different alpha1 and alpha2 coefficients with PA(velocity==0) == alpha1 and PA(velocity → infinity) == alpha2 (the actual parameters to configure the PA models are slightly different though). You can give it a try if you want to. In fact, one can easily define their own non-linear PA model, which should be rather straightforward using the sample code in Python and C (of course, the number of parameters for PA model can be increased as one sees fit).

A couple of other thoughts:

  • I don’t have a strong evidence, but I suspect that the fact that you see PA change with acceleration may mean that you have too high smooth_time parameter for pressure advance. By default, it is 0.04 seconds, which is too generous, in my opinion, at least for typical direct drive extruders nowadays. More appropriate values are within 0.02 - 0.01, in my experience. Reducing that parameter increases the stress on extruder, but at the same time, in my experience, the PA value initially decreases with reducing the smooth_time. So, say, with smooth_time = 0.04 you may get PA = 0.05, and with smooth_time = 0.02 you’d get PA = 0.03. The moment PA stops decreasing may indicate a good optimal value for smooth_time. Separately, one could use smooth_time parameter to achieve better synchronization of PA with input shaping on vanilla Klipper - basically, by setting it equal to the input shaper largest duration, or something like an average of the durations of the two, but that value would still typically be within 0.01 - 0.03 seconds. That said, reducing smooth_time on a bowden extruder may be less than ideal, because the extruder is already under a lot of strain with PA enabled, and that will push it even further. Still, it is worth trying to reduce it just to either confirm this or that acceleration indeed has an effect on PA, even if that means reducing maximum accelerations (which is something that one would likely have to do with bowden extruders anyways if they wish to achieve high accuracy of the filament flow control).
  • I find that plateau on the PA distance vs speed chart surprising (if I read the chart correctly, of course). If it were true, it would mean that there is a range of velocities where PA control is not necessary. I think it contradicts the actual experiences. However, if that’s true, then you, arguably, could print in that velocity range without enabling PA, by just tuning retractions instead.
2 Likes

The whole thing started when people observed that the bowden extruders struggle to keep up with PA at high print speeds, and that the motors can’t keep up when the optimum 100mm/s PA is used at 300 or 400mm/s.

If you shorten the PA smoothing time, won’t the requested extruder speeds be equally unmanageable even with a lower PA value?

PA control is not necessary as long as the print head doesn’t slow down below 100mm/s ever, which isn’t the case for normal prints.

Retraction as implemented in slicers right now only occurs at the beginning and ends of travel… if it applied to every speed change, then that’s just PA all over again.

But we are looking at seeing if the PA can be implemented in (or immediately after) the slicer as an alternative to a change to the firmware.

voidfoo did get the speed working correctly considering the sharp corner velocity and all:

As I mentioned, at first, it seems that the required PA value also gets smaller as smooth_time is decreased. So, for some time the strain on extruder, arguably, does not increase all that much. Though I can only speak about direct drive extruders, I didn’t test that on bowden ones. And then again, if you have to increase the PA at larger accelerations, that may also push the extruder too much, right?

Fair enough. However, I still find your results surprising and counterintuitive, and I’d personally recommend to validate them on the PA test print that I mentioned earlier. You could easily set, say, slow_v = 50, medium_v = 150, fast_v = 250, and check how PA behaves. The main benefit of that print is that speficially tests accelerations and decelerations of the toolhead along straight lines, and does not combine different effects such as input shaping smoothing and pressure advance together (as what happens if you look at corners).

And anyways, as I mentioned, you could put your model, whatever it is, into the aforementioned code, and see how this works for the real-life prints.

And then again, if you have to increase the PA at larger accelerations, that may also push the extruder too much, right?

To me, it seems you’re both alluding to the same issue. Lowering smooth time practically reduces the window of time the extruder has to perform the Pressure Advance movements within. That’s to say, it has to move the same amount of volume but quicker. It can’t go slower, because then it would overrun its “advantage” (lookahead buffer).

Hence, while a lower PA smoothing value might require less PA overall (akin to how faster retracts usually work better at reducing pressure), it also requires proportionally more acceleration.

At some point, that acceleration gets too steep and starts acting like an instantaneous movement rather than an accelerated movement. And as we know, such movements (jerk) can only be performed in a limited scope and quantity.

Cura currently implements a function or method of applying this logic on the other variable of the equation. Instead of changing the movement of the filament in response to pressure changes, it changes the pressure changes to correspond more to what the natural drop-off and ramp-on would be (according to the settings you give it). Cura calls it Gradual Flow, under Material settings.

The fact Cura can do it with one of the two values/variables in the equation implies the math already exists in there to estimate or predict the behaviour and respond to it. Would that mean, in turn, it isn’t nearly as hard to implement the counterpart in the fashion you suggested?

Something to keep in mind, I suppose.

An addendum:

It seems logical to me that the acceleration of the printhead going up would also cause the PA to raise. What you’re doing, is brute force compensating for the timeline compression faster printhead direction changes cause. Adding more PA therefor compensates for it a little steeper (less curved in a peak, more curved in a plateau), which in effect also shifts the start of the PA movements a tiny bit earlier in the timeline. It shifts the virtual dead zone due to extruder limits away from that zone not by moving out of it, but by accepting it’s there and adding more before it.

Interesting. One possible explanation for this is that moving the extruder early, due to pressure_advance_smooth_time, causes some filament to leave the nozzle (blobbing) that should have otherwise been used to build pressure. Thus during pressure advance calibration, a higher pressure_advance value is found, because it is ultimately finding a value that is both the “blobbed amount” and the “pressure amount”.

That is, at a high-level the pressure advance system is designed to command the extruder to push extra filament to build pressure in the nozzle. Ideally that extra filament does not leave the nozzle - it’s just filament under tension between the extruder and the nozzle. However, if some of that “extra filament” intended to “build pressure” actually exits the nozzle during initial pressure buildup, then we wont have all the filament we wanted under tension during cruising.

A smaller pressure_advance_smooth_time could thus reduce the amount of filament lost due to “early blobbing”.

If this is the case, it could itself introduce a non-linearity to the pressure_advance value as extrusion speeds increase. For example, if hypothetically one lost 0.1mm of filament to “early blobbing” during the process of ramping up to 100mm/s, then ramping up to 200mm/s would be unlikely to lose 0.2mm - as the amount of “early blobbing” (if real) may be exponentially decreasing with speed…

-Kevin

All I’m suggesting is to try lowering smooth_time. This may give more accurate filament flow with similar strain on extruder, and may eliminate PA dependency on acceleration - one less variable to worry about, which would be a win. So, at least it’s worth a try.

Yes, I believe that’s what’s happening when smooth_time is too large. In that case, some of the extra movement goes to waste - it affects the filament flow too early - and so extruder has to do more movements to compensate for that.

Perhaps that could contribute to non-linearity effects, but it seems this cannot explain the effect completely. Say, when input shaping is enabled, the toolhead acceleration also starts earlier and finishes later than commanded. If smooth_time gets much smaller than the shaper duration, then, essentially, the toolhead can already start executing acceleration, but pressure advance will be lagging behind and not acting just yet. So, there’s a certain threshold value for smooth_time that one should not go below, and which likely explains why ideal PA value stops to reduce at a certain smooth_time value. And it so happens that non-linearities in PA vs speed can still be observed even in those conditions.

In general, one could argue that still PA can be out of sync with the actual toolhead motion. So, it goes like this: there’s a certain ‘ideal’ toolhead motion (computed in a look-ahead queue), then there’s a commanded trajectory from input shaping, and there’s actual motion (toolhead response), which is a third thing. Notably, even if input shaping is not enabled, and commanded motion == ‘ideal’ motion, then the actual motion still differs from commanded. Just with input shaping the actual motion is less hectic and may be a bit easier to predict. And it also better matches the ideal motion, but only spatially, not time-wise. So, arguably, Pressure Advance should target the actual toolhead motion, rather than the input shaped or the ‘ideal’ motion (which is the case today). I looked into it as a part of my efforts to improve PA synchronization with input shaped motion. My conclusion there was that one could pick specific smoother functions (and of specific durations) for extruder motion in order to at least approximate the expected response of the toolhead. Then applying PA to that motion would produce PA motion that follows the expected toolhead motion after input shaping to a certain extent, improving the extruder synchronization with the toolhead. FWIW, I concluded that the current extruder smoothing in Klipper can be seen as a first-order approximation of a toolhead response for simple shapers like (M)ZV, so that’s why I recommend setting smooth_time to a largest or an average of shaper durations for X and Y, at least for direct drive extruders. That said, in my branch I have smooth functions for the extruder generated for each shaper supported there to give better approximations of the toolhead responses. And for smooth input shapers that that branch has, due to their smooth nature and the fact that they are 0 at their ends, I believe the PA does not have that leakage problem. That is, there is no parasitic pressure built-up that results in filament leakage from the nozzle that you talked about. Basically, the extruder does not have to build-up pressure in advance, and it builds up the pressure as the toolhead also smoothly starts to accelerate. And even there I observe that for different velocity transitions the PA value is different. For example (an actual case for one of the filaments and extruders I tested for), 25->60 mm/sec transition requires PA = 0.038, 25->130 requires PA=0.034, and 60->130 requires PA=0.028.

Now, other sources of non-linearity can probably be seen as follows. The extra required filament push for PA dl can be calculated as
F = k(dl) * dl = gamma(v) * v
and dl = alpha * v. Then alpha = gamma(v) / k(dl), which is a PA coefficient. So, the higher the resistance of the filament flow gamma(v), or lower the rigidity of the system k(dl) is, the higher the PA coefficient alpha is. The fact that alpha is observed to be larger at smaller velocities could mean two things. Either higher flow resistance at lower velocities, which is counter-intuitive, but perhaps is possible due to viscosity and stickiness of the filament? Or that rigidity k(dl) is smaller at lower displacements, which would be not all that surprising, since even the stepper motor produces higher the torque the larger its offset from the equilibrium position is. And on bowden extruders there are even more sources to have low rigidity until all plays between connecting parts are eliminated.

I ran some simulations and I think that pressure_advance_smooth_time may have a notable effect on pressure_advance calibration (and a non-linear impact). However, it seems to be for different reasons than I originally described. I don’t want to derail this thread, so I started another thread at Pressure_advance_smooth_time skews pressure_advance .

I agree that pressure_advance can have a complex reaction with input_shaper. And I agree that modelling that interaction may be an interesting approach to improving quality.

Cheers,
-Kevin

Still working on my The 100, but I have another result with my KLP1 (a direct drive printer).

Recently I got a CHT nozzle for it which allows me to print at 28mm^3/s, and so I retuned the PA.

Seeing the other thread, I tried reducing the smoothing time to 0.01 seconds, in hopes of reducing thinned walls on the approach to corners, but I’m finding that when slowing from high speeds, the wall begins thinning as soon as the deceleration begins, and the corner still blobs out.

This indicates to me that the pressure advance offset definitely should not be linear with extrusion rate at high speeds, even with direct drive.

…now I need to figure out how to recompile and install klippy on the printer itself…
…probably should back up the emmc…

As an example…

This is with the lowest Pressure Advance value that avoided corner blobbing, and it has significant thinning on one side and thickening on the other side of the corner.

I am running PA of 0.022 and a smoothing time of 0.01 seconds (I tried making it shorter to see if it would help, and it didn’t).

Clearly, I need to have a lower PA but only apply it at the end of decelerations and beginning of accelerations.

I find using integrals to calculate a weighted average like this rather strange and excessively complicated. A far simpler and more standard way of smoothing in control systems is a simple low-pass filter (AKA exponentially decaying weighted average), which has known and easy to analyse characteristics (including lag).

A more advanced approach to compensate for lag would include a second low-pass velocity filter to get a smoothed velocity, and use that as a “trend” to compensate for the position-lag. This is sometimes called “double exponential smoothing”, and is basically a simplistic system model, a more advanced version of which would be a kalman-filter.

I note in the PA docs at klipper | Klipper is a 3d-printer firmware that one of the assumptions is that flow rate as a function of pressure follows Poiseuille’s law. This assumes the flow rate is linearly proportional to the pressure.

However, in the case of a “short pipe” nozzle being pushed hard with a reduction from 1.74mm to 0.4mm diameter I think the flow is more likely to follow Bernoulli’s principle. This gives the flow rate as a function of the square-root of the pressure. This means to get 2x the flow rate you need 4x the pressure.

This would explain why higher velocities appear to need higher PA values, and why even the best PA value still has flow-rate artefacts; it cannot get it right at all velocities.

Assuming this is correct, a better formula for pressure advance would be;

pa_position(t) = nominal_position(t) + pressure_advance * nominal_velocity(t)^2

Note the pressure is linearly proportional to the advance due to hook’s law, which IMHO seems like a reasonable assumption, and you could even roughly calculate it from the length of filament from extruder to nozzle and the filament material’s youngs modulus.

Of course there are other factors that would contribute, like different velocities requiring different heat intput to the nozzle to melt to the same viscosity, and nozzle temp PID lag/overshoot behaviour interacting with acceleration causing transient viscosity changes affecting flowrate. Or backlash/tension/friction in the bowden tube affecting the linearity of advance->pressure.

It would be great if all of this could be modelled in one big kalman filter, so that everything interacted and reacted together. The nozzle heater power could react preemptively to acceleration changes to maintain a more consistent melt, extruder advance could preemptively adjust nozzle pressure to match flow-rates to head velocity, etc.

It would be interesting to have a branch with the modified formula to compare the results, and to check whether a single calibration would bring accurate enough results.

No pics to prove the improvement, likely no commit.

Is a new uC code needed, or is it host-only? In the latter case I could test it too. Or @igiannakas since he already did a great job documenting the adaptive PA model he implemented in Orca :smiley:

Even better, nowadays it’s simple to perform multiple PA calibration at once (I tested it yesterday, it’s working fine)

and to compare old vs new.

Interestingly, this statement goes against my experience, I pretty much always observed that higher velocities require lower (linear) PA values, which is pretty evident on this test:

The only thing is, I tested this only on direct drive extruders and not on bowdens. FWIW, these results seems counter-intuitive and I do not have a good explanation for them.

That said, if you manage to implement your proposal and it will give good results, that would be very interesting indeed.