Klipper: Gap fill and PA -> Problems

Created on 24 Jun 2019  Â·  25Comments  Â·  Source: KevinOConnor/klipper

I have had strange noise from my extruder for a long time and haven't really tracked them down until I switched to a bigger nozzle.

Gap fill and PA don't play nice twogether..
image

When I print short lines with decreasing or increasing line volume.. the color full extrusions in picture... my extruder goes backwards a small amount and ruining the next line..

image

If I slow down a lot or run without PA it works.. sort of..

Klippers Path planner see a difference in volumetric flow and assumes that the line is supposed to end. Therefor it activates pressure advance, both in the start and end of these small segments (over a distans of ~2mm there is 10 segments in decreasing length from 0.3 to less than 0.1mm long) this gains lots of direction changes for the stepper motor. And the motor, due to rotating inertia, only makes moves in one direction (skips step?)

My specs
Mega 2560
Raspberry pi 3
Tmc 2130 36v on extruder 24v on a, b and c spreadcycle and interpolation on
A really stiff bowden of a total of 470mm between melt zon and hobbed gears
BMG clone 3:1 tested with 8 16 and 32 microsteps with or without interpolation
PA ~0.2
0.6mm nozzle right now.... but normally 0.4
Slicer PE
Prusaslicer

In cura the same model looks like this, in my opinion, same but different.. I haven't printed with this slicer... and see that there might be some other problems atreas with this file and PA..
image

As I don't use Cura there might be some settings that could be altered, but I can't find any in this conglomeration of settings in Cura...

I have seen similar behavior around bridging, but that was solved by deactivate "detect bridging" i slic3r and set the line width to "1" for bridges. I think that Klipper would benefit to make this bridge moves to work as well.. but that's another issue I believe..

The only setting i Slicer regarding Gapfill is a speed setting
image

I don't have a log over this particular event.

My suggestion to solve this particular problem could be to include this small segments in the look ahead.

enhancement

Most helpful comment

FYI, here's my rough plan to enhance Klipper so that it can perform extruder lookahead across moves:

1 - Update pressure advance to use the average extruder velocity over a small time window instead of using the extruder's nominal "instantaneous" velocity. This would replace the pressure_advance_lookahead_time with a pressure_advance_smooth_time setting. I suspect a default of around 20ms should be sufficient.
2 - Add an extrude_corner_velocity setting which would configure the maximum instantaneous velocity change of the extruder stepper during cornering. I suspect a good default would be 1mm/s. This setting would be analogous to "jerk" on other firmware. Basically, if the next move's extruder velocity is notably different than the current move's extruder velocity, then the lookahead processing would ensure that the cornering speed was slow enough that the extruder velocity doesn't make any massive instantaneous velocity changes. The toolhead wouldn't need to slow all the way to zero velocity, however, as it does today.

Alas, I have no time-frame for the above. The second item is trivial to implement. The first is significant work.

The main hurdle to implementing the first item is the fact that Klipper currently generates all the steps for one g-code move at a time. (As do all common firmware, to my knowledge.) Unfortunately, to accurately calculate the average extruder velocity over a time window requires generating steps with knowledge of where the toolhead was in the near past as well as where it will be in the near future, even if that spans multiple g-code moves. In particular, we want to make sure pressure advance works well even for arcs that the slicer has turned into many tiny move segments.

The Klipper code, in general, is in a good position to implement this functionality, as all the information is available within its lookahead queue. It does need updates to make sure the step generation code has access to that info, however. Roughly the work involves something like:

A - Update the lookahead code and "iterative solver" step generation code to build a linked list of moves. When generating moves, update the "iterative solver" so that it can work across g-code move boundaries. (Basically, when calculating the next step time, allow the code to traverse the list of g-code moves to be able to find that step.) Be sure to handle the case where a stepper nominally hits zero velocity (and thus isn't moving for an extended time). Update the lookahead queue so that if the queue ever needs to be fully flushed, a brief delay is added before restarting movement (so that the code can reliably calculate step times during the flush). Handle list memory management so moves are eventually free'd from the linked list.

B - Once the iterative solver has reliable access to a minimum time window of movement (eg, +-100ms), then calculating an average extruder velocity should be straight forward. At any given time t, the code can calculate the extruder position at time t along with the extruder position at time t+pressure_advance_smooth_time. The average velocity is then (pos2-pos1)/pressure_advance_smooth_time.

The big advantage to implementing item A above is that it is also useful in several other advanced areas. I suspect it would generally improve pressure advance, as it should reduce some of the extreme extruder velocity changes and generally allow for more time to build/release pressure. It should provide a fix for issue #865. It should make it easy to provide a fix to issue #1460 (eg, the code wouldn't have to generate all the steps for an extremely long g-code move in advance - it could generate movement ~1s at a time). It provides a possible mechanism for filtering out troublesome step+dir+step events on the tmc2208 (aka issue #196). And, it provides a path to possible stepper resonance filters (as in https://github.com/KevinOConnor/klipper/issues/57#issuecomment-479549783).

Again, no time-frame for the above.
-Kevin

All 25 comments

I agree that Klipper could have done better here. It looks like the slicer is producing moves with different extrusion width. Klipper does not currently implement look-ahead between these moves (as documented in docs/Kinematics.md). Without look-ahead, the software will perform full deceleration and then acceleration between moves. The pressure advance system will also respond accordingly (it will perform a full pressure release followed by pressure buildup between moves).

Unfortunately, it is not simple to address this. In order to avoid a full deceleration, it would require a nominal instantaneous extruder velocity change. Unfortunately, the pressure advance system can not cope with that (a nominal instantaneous velocity change would result in an "infinite pressure" calculation).

As a short term solution, disabling "gap fill" may improve performance.

-Kevin

I fully understand. But the bigger gap fill will then also be turned off..
and that is not really en option..

If this is possible to identify in the gcode, a script that turned off PA
or removed the small gap fill could be an option..

I use a 0.4 mm nozzle and this render less problematic moves.. and less E
movements if the small moves is there..

On Mon, 24 Jun 2019, 15:32 KevinOConnor, notifications@github.com wrote:

I agree that Klipper could have done better here. It looks like the slicer
is producing moves with different extrusion width. Klipper does not
currently implement look-ahead between these moves (as documented in
docs/Kinematics.md). Without look-ahead, the software will perform full
deceleration and then acceleration between moves. The pressure advance
system will also respond accordingly (it will perform a full pressure
release followed by pressure buildup between moves).

Unfortunately, it is not simple to address this. In order to avoid a full
deceleration, it would require a nominal instantaneous extruder velocity
change. Unfortunately, the pressure advance system can not cope with that
(a nominal instantaneous velocity change would result in an "infinite
pressure" calculation).

As a short term solution, disabling "gap fill" may improve performance.

-Kevin

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/KevinOConnor/klipper/issues/1758?email_source=notifications&email_token=AIBHAJTEL6QLFPD6XWENTPTP4DEGNA5CNFSM4H23VOLKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYM5YEI#issuecomment-505011217,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AIBHAJULBGAXAMGJHIFED4TP4DEGNANCNFSM4H23VOLA
.

"Klipper implements look-ahead between moves that have similar extruder flow rates." What would happen if this restriction was lifted, and what prevents this restriction from being lifted?

Oh this is interesting I’ve had some very similar issues myself. I’ve
noticed certain infill patterns don’t work as well, the triangular infill
pattern sometimes doesn’t connect to its self or will be completely missing
segments depending on the model. I think we’ve discussed this before, but I

forgot.

Philip Mally
3D Printing & Rapid Prototyping Services
530-205-3210
[email protected]

Unfortunately, the pressure advance system can not cope with that (a nominal instantaneous velocity change would result in an "infinite pressure" calculation).

Is this really true though? I think it actually leads to an instantaneous change in the extruder position.
After all, the extruder pressure behaves like a first order low pass filter on the extruder velocity. PA is an attempt to invert this low pass which inherently includes a derivative of the desired velocity. This part actually gets infinite which leads to the instantaneous change in position.

The good news is that it's not all that bad. Simply trying to move to this new position as fast as possible solves the problem, although it probably requires another filter or acceleration limitation to prevent skipped steps.

Best,
Marius

What would happen if this restriction was lifted, and what prevents this restriction from being lifted?

See https://github.com/KevinOConnor/klipper/issues/1758#issuecomment-505011217 .

-Kevin

I think it actually leads to an instantaneous change in the extruder position.

Yes, that's a more precise description.

Simply trying to move to this new position as fast as possible solves the problem

No, that wont work - an attempt to move multiple steps instantaneous would cause internal errors (and likely lead to lost steps).

it probably requires another filter or acceleration limitation to prevent skipped steps.

My current rough plan is to change pressure advance to calculate an average velocity over a time window and use that instead of the nominal instantaneous velocity. I think doing that would make it easier to implement look-ahead across extrusion changes and I think it would improve pressure advance in general. Unfortunately it is a bit of work and is likely several months before I'd be able to get to it.

-Kevin

I see, I was mainly looking at it from the dynamical system perspective.
I don't know how hard it would be to implement filters like I mentioned into Klipper. I can try to come up with a basic implementation if I get the time.

Best,
Marius

My take on the small increasing/decreasing extrusions is that they are an ruff estimate of a continues decreasing/increasing extrusion. Like a wedge..

I don't have any clue on how difficult it would be to combine them and gradually alter the extrusion..

I found, by the way, a settings that makes the problem less..
Accel_to_Decell<800
But that slows down the infill a lot...

Unless I'm reading the code wrong, removing the extrude ratio check simply causes the position change to occur during an acceleration or deceleration phase. While this clearly isn't a very good solution, I don't think it will cause any huge problems with anything resembling "normal" gcode. Here's a simple patch that removes the check if anyone wants to try it (but don't be too surprised if it causes bad behavior):

````
diff --git a/klippy/kinematics/extruder.py b/klippy/kinematics/extruder.py
index 11d0070..b82dea5 100644
--- a/klippy/kinematics/extruder.py
+++ b/klippy/kinematics/extruder.py
@@ -6,8 +6,6 @@
import math, logging
import stepper, homing, chelper

-EXTRUDE_DIFF_IGNORE = 1.02
-
class PrinterExtruder:
def __init__(self, config, extruder_num):
self.printer = config.get_printer()
@@ -122,12 +120,6 @@ class PrinterExtruder:
if not extrude or not prev_extrude:
# Extrude move to non-extrude move - disable lookahead
return 0.

  • if ((move.extrude_r > prev_move.extrude_r * EXTRUDE_DIFF_IGNORE
  • or prev_move.extrude_r > move.extrude_r * EXTRUDE_DIFF_IGNORE)
  • and abs(move.move_d * prev_move.extrude_r - extrude) >= .001):
  • # Extrude ratio between moves is too different
  • return 0.
  • move.extrude_r = prev_move.extrude_r
    return move.max_cruise_v2
    def lookahead(self, moves, flush_count, lazy):
    lookahead_t = self.pressure_advance_lookahead_time
    ````

removing the extrude ratio check simply causes the position change to occur during an acceleration or deceleration phase

I'd assume that an attempted instantaneous extruder position change (whether in an acceleration phase or not) would cause skipped steps which would lead to bigger problems.
That's why I said it should try to move to the new position as fast as possible (while preventing skipped steps).

If I interpret this correctly:

No, that wont work - an attempt to move multiple steps instantaneous would cause internal errors (and likely lead to lost steps).

Then there is no way to directly output a trajectory (instead of the desired position for the next time step) from the extruder kinematics method.

It would therefore require a state variable in the extruder kinematics to be able to create a dynamic filter. That would be the control-theoretic way to do it :-)

I'd assume that an attempted instantaneous extruder position change (whether in an acceleration phase or not) would cause skipped steps which would lead to bigger problems.

It would, but that's not what actually happens. The way the code is written, the position change happens over the whole accel or decel phase of the move. The relevant code is in calc_junction() and move() in klippy/kinematics/extruder.py.

Unless I'm reading the code wrong, removing the extrude ratio check simply causes the position change to occur during an acceleration or deceleration phase. While this clearly isn't a very good solution, I don't think it will cause any huge problems with anything resembling "normal" gcode.

I suspect it would cause errors with pressure advance enabled.

-Kevin

Ah, this is the issue I noticed in my recent prints. I changed to a BMG extruder that as a 3 to 1 gear ration, meaning it has to move three times faster than the old extruder, and it makes a horrible sound when doing these and basically means the maximum PA I can use is around 0.5, while the bowden system really would like to be at 0.8-0.9 for crisp corners.

FYI, here's my rough plan to enhance Klipper so that it can perform extruder lookahead across moves:

1 - Update pressure advance to use the average extruder velocity over a small time window instead of using the extruder's nominal "instantaneous" velocity. This would replace the pressure_advance_lookahead_time with a pressure_advance_smooth_time setting. I suspect a default of around 20ms should be sufficient.
2 - Add an extrude_corner_velocity setting which would configure the maximum instantaneous velocity change of the extruder stepper during cornering. I suspect a good default would be 1mm/s. This setting would be analogous to "jerk" on other firmware. Basically, if the next move's extruder velocity is notably different than the current move's extruder velocity, then the lookahead processing would ensure that the cornering speed was slow enough that the extruder velocity doesn't make any massive instantaneous velocity changes. The toolhead wouldn't need to slow all the way to zero velocity, however, as it does today.

Alas, I have no time-frame for the above. The second item is trivial to implement. The first is significant work.

The main hurdle to implementing the first item is the fact that Klipper currently generates all the steps for one g-code move at a time. (As do all common firmware, to my knowledge.) Unfortunately, to accurately calculate the average extruder velocity over a time window requires generating steps with knowledge of where the toolhead was in the near past as well as where it will be in the near future, even if that spans multiple g-code moves. In particular, we want to make sure pressure advance works well even for arcs that the slicer has turned into many tiny move segments.

The Klipper code, in general, is in a good position to implement this functionality, as all the information is available within its lookahead queue. It does need updates to make sure the step generation code has access to that info, however. Roughly the work involves something like:

A - Update the lookahead code and "iterative solver" step generation code to build a linked list of moves. When generating moves, update the "iterative solver" so that it can work across g-code move boundaries. (Basically, when calculating the next step time, allow the code to traverse the list of g-code moves to be able to find that step.) Be sure to handle the case where a stepper nominally hits zero velocity (and thus isn't moving for an extended time). Update the lookahead queue so that if the queue ever needs to be fully flushed, a brief delay is added before restarting movement (so that the code can reliably calculate step times during the flush). Handle list memory management so moves are eventually free'd from the linked list.

B - Once the iterative solver has reliable access to a minimum time window of movement (eg, +-100ms), then calculating an average extruder velocity should be straight forward. At any given time t, the code can calculate the extruder position at time t along with the extruder position at time t+pressure_advance_smooth_time. The average velocity is then (pos2-pos1)/pressure_advance_smooth_time.

The big advantage to implementing item A above is that it is also useful in several other advanced areas. I suspect it would generally improve pressure advance, as it should reduce some of the extreme extruder velocity changes and generally allow for more time to build/release pressure. It should provide a fix for issue #865. It should make it easy to provide a fix to issue #1460 (eg, the code wouldn't have to generate all the steps for an extremely long g-code move in advance - it could generate movement ~1s at a time). It provides a possible mechanism for filtering out troublesome step+dir+step events on the tmc2208 (aka issue #196). And, it provides a path to possible stepper resonance filters (as in https://github.com/KevinOConnor/klipper/issues/57#issuecomment-479549783).

Again, no time-frame for the above.
-Kevin

I've got a test file that demonstrates this for the case I posted. The STL in the ZIP is just a portion of the boots of Astronaut Phil. It's set to 0 bottom layers and 0 top layers in the gcode file (so only the 3 perimeters) and causes the skipping issue on the 2 full speed perimeters and not on the 75% speed outer layer.

APAM_Accel_Test.zip

Thanks @KevinOConnor for working on this.

One quick question:

With your linked-list architecture, would it be possible to add a static time offset to shift/stagger the relationship of the now-decoupled extrude and move stepper command sets while printing? While tuning pressure advance, particularly on long Bowden extruders, I've often looked at my prints and thought that they would have been pretty much perfect if the extruder could have been leading the X/Y movements by just a few milliseconds. "Anticipation" might be a good term for the parameter.

Basically, a static time offset would compensate for _some_ of the Bowden-induced delays globally, instead of forcing the extrusion effects of them all to be corrected on each tiny move. The beginning of extrusions would get a free priming, and the end of the extrusions would get a result very similar to coasting, without requiring wild pressure swings by the extruder to achieve.

It would be experimental of course, but I have a hunch it would perform well if used in small amounts, in conjunction with a low to moderate amount of the normal pressure advance. And since this wouldn't require any motion slowdowns or additional extruder movements (in contrast to high values of pressure advance), I think it would scale well for high print speeds.

Just a thought, unproven until tested of course. I'd be happy to do that validation if the capability was possible with Klipper.

@dstulken - see issue #1260.

-Kevin

@dstulken i can recommend you to stiffen up the bowden tube. there are some significant elongation/compression going on during printing(they worsen with Capricorn tubes)..
I used PET-mesh(at first I used shielding for cables but it was difficult to use) and gluing heat shrink and was able to lower PA a fair bit as well as retractions..

photo1

photo2

FYI, I have some (very preliminary) code available at PR #1997 for those that would like to test. This new code should (hopefully) perform better with changing extrusion rates and should therefore (hopefully) avoid issues with gap-fill.

-Kevin

I will test in the week..
Anything special except the notes in the PR.. That you want included in testing?

Tested #1997

Success, so I have no doubt that it is solved

Lets leave this open until PR #1997 gets merged. My rough plan is to merge near end of October.

-Kevin

With the merge of #1997 I believe this issue is now fixed.

-Kevin

Fixed
Super duper thanks...

Closing

Was this page helpful?
0 / 5 - 0 ratings

Related issues

speendo picture speendo  Â·  3Comments

Hywelmartin picture Hywelmartin  Â·  6Comments

superg3 picture superg3  Â·  6Comments

Michael-Bell picture Michael-Bell  Â·  5Comments

TronskiFPV picture TronskiFPV  Â·  5Comments