Recently I started looking on pressure advance and how it works and I'm a bit confused about where it is usually implemented.

My Idea of 3D printer was that its firmware is fairly dumb and only replays GCode, not knowing anything about the object being printed, material used, or even the printer itself.

But with pressure advance this whole thing changes and now the firmware needs to know the linear advance factor which combines information about the filament and filament path used. In addition the E axis is no longer controlled directly by the GCode, but it's motion is almost independently determined by the firmware.

Why is this? Is there a reason that slicer (or a post-processor) can't compute all this and directly store the needed extruder axis movements in the GCode? Does the printer have some additional information that the slicer is missing?

  • $\begingroup$ hort answer: G-code can alter variables in the firmware, if needed. $\endgroup$ – Trish Dec 9 '20 at 10:50

In addition the E axis is no longer controlled directly by the GCode, but it's motion is almost independently determined by the firmware.

This is the case even without linear advance. G-code does not directly control the movement of any of the axes. G-code only specifies the path the axes should travel, but not the acceleration and deceleration associated with following that path. If you are printing a cube, then the G-code might specify that the extruder has to extrude a square. It will specify that the 4 sides of the square should be printed, but it does not specify how the transition from one side to the next should be handled.

The printer cannot instantly transition from extruding one side of the square to extruding the next side, because the direction of the extruder cannot change instantaneously. It needs to smoothly decelerate and accelerate. This is handled by the firmware, which translates the straight line commands from G-code to smooth acceleration and deceleration of the extruder.

This is exactly where linear advance comes in. It is coupled to the acceleration and deceleration. There is no way to "implement" linear advance in G-code, because G-code does not even have any notion of acceleration and deceleration. The G-code (and slicer) has no idea how the firmware is handling the acceleration and deceleration, so therefore it is impossible for the slicer to know what linear advance is required to match.

Then you might ask: "why is acceleration and deceleration not implemented in G-code (rather than in firmware)?" This is simply a design choice. G-code is meant to be a very simple file format, and it simply allows you to specify straight line move commands. Representing smooth acceleration curves would either require breaking them down into many discrete, small steps, but this would greatly increase the file size. You could suggest a more complex G-code specification that would allow a more "compact" representation of acceleration and deceleration curves but then you're just shifting the computation back to the firmware (albeit with a more explicit specification in the G-code).


This is a really good question that sheds a lot of light on 3D printer software/firmware architecture, and Tom already said a lot of the things I wanted to say before getting a chance to write an answer. The basic problem is that, to do pressure advance accurately (and in a way that doesn't get it horribly wrong when inaccurate), you need to know the actual feedrate of the extruder at all times, and that's not available until applying the acceleration profile, which by convention happens in the printer firmware.

With that said, there were primitive and even somewhat advanced attempts to do pressure advance in the slicer. The first seems to have been "coasting", which, along with extra-priming after coast, is pretty much just "pressure advance, assuming a constant feedrate". It gets things horribly wrong if you mix different extruder feedrates (different print speeds or line widths, etc.) or if you have slow acceleration, but if your acceleration is so fast (relative to max speed) that it's approximately instantaneous, it might work okay.

Modern Cura also has Flow Rate Compensation, which is something like pressure advance. It's rate-sensitive, so in theory it can give accurate results with varying line width and print speed as long as acceleration is close enough to instantaneous. Since it appeared after Marlin added linear advance, I never bothered trying to play with it, so I can't speak to whether it actually works decently. There are still a lot of subtleties to when the advance is performed that it could get wrong, and I think you'd want to do some test cases just to read the gcode output and evaluate whether what it's doing is sufficiently close to reasonable.

If you wanted to do full pressure advance in the slicer, you'd need to let the slicer handle acceleration profile, breaking lines up into small segments each with nominal feedrate matching the rate they should end at, and sufficiently close to the rate they should start at, with the firmware acceleration limits set to accommodate the change. Then, knowing a very good approximation of the actual toolhead and thus extruder feedrate for each segment, you'd know the advance to apply, and could apply it as an additional subdivision at the end of the previous print move. And then in theory, it all works out. But this would make the gcode a lot larger/bulkier, and more demanding on the serial link speed and microcontroller's ability to keep up with parsing/planning. So it's almost surely a bad idea.

The Klipper firmware does this differently. It does the gcode parsing and planning (including pressure advance) in Python software (with some C for critical paths) running on a much more capable computer, and sends the precise generated stepper motor timings over the serial link to the microcontroller operating the printer hardware.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.