(Hope you like the creative title :wink:)
This is Marlin RCBugFix branch, git commit da1644313d38f02fc90e2bb0fc01a4511cdbda29 plus my settings (below).
I've been having a small argument with my printer and Marlin regarding actual extrusion rates and how LIN_ADVANCE interacts with my E steps/mm setting. If I enable LIN_ADVANCE, sharp corners start to get rounded off, even with a K-value as small as 5. I find this confusing because mine is a bowden setup, which the documentation says should require especially large values, or at least larger than a direct-drive/non-bowden setup.
The extruder consists of a common NEMA17 stepper, a B'Struder drive block assembly, and a generic 12mm (effective diameter) drive gear from eBay, pushing Inland white PLA down a 55 cm PTFE tube into a hotend originally made as part of a clone of Makerbot's Stepstruder assembly (effectively, I separated the motor/drive block from the hotend/heatbreak, to reduce the mass on the X carriage).
They say a picture is worth a thousand words, so below is a composite I made from several of my better print attempts. Along the vertical, my extrusion steps/mm (78.0 is deliberately too low, while 87.9 is measured-correct for my gear/motor). Along the horizontal, my LIN_ADVANCE value (where "off" means I commented out the entry in Configuration_adv.h to disable it entirely). Where a spot is empty, I just didn't bother testing that combo. The numbers written on the parts are just a reminder to myself where to put the object in the image.
All prints done at 30 mm/sec max speed. When LIN_ADVANCE is enabled, there are some skipped steps here and there even at that speed (big drive gear, low torque), but they're not enough to invalidate these tests as they're mostly in internal layers/infill, and anyway you can easily see how the setting affects the part:

(Open it in a new tab to see the full detail, it's 3500x2500)
Test object: large gear, caliper.STL.zip
(This is the "large gear" from angry_monk's dial calipers, scaled up in Slic3r's plater)
G-code output: large gear, caliper.gcode.zip
(as produced by Slic3r. This file used for all of the prints in the picture)
Configuration.h: Configuration.h.zip
Configuration_adv.h: Configuration_adv.h.zip
Configs as a git patch: 0001-my-settings.patch.zip
Slic3r config bundle, in case it's helpful: Slic3r_config_bundle_1.3.0-dev-2016-09-25.ini.zip
Note that the config files above have changed since this Issue went out, to reflect my having settled on a LIN_ADVANCE setting of 15 and E-steps of 87.9, for now.
@Sebastianv650 Can you bring some insight? I don't know enough about the behavior of Advance Extrusion or how the K value applies to comment on this issue.
@VanessaE Thank you for the very detailed explanation of your issue.
P.S. You might try the latest RCBugFix and use the MINIMUM_STEPPER_PULSE feature just to make sure the pulse duration for the E stepping is long enough. A value of 4 will add the smallest amount of delay.
Already on RCBugFix :smile:. Updated to HEAD, set that option, and did a couple test prints: one with LIN_ADVANCE disabled, one with it enabled. Top row is with M_S_P set to 0, bottom row set to 4. On the left is L_A disabled, at right is with it set to 15.
Top to bottom isn't much different, but clearly LIN_ADVANCE is producing cleaner extrusions, and leaving fewer gaps also.
Of course, you should tune your steps/mm as much as possible to the actual movement of the filament. Then you can just use flow adjustment to tweak the amount of material during print runs.
Have you also tried Cura for slicing? It does a good job of making sure lines meet up with an adjustable overlap, and has some other nice tricks. Perhaps Slic3r has caught up in recent months, but for a while I have been getting my best results from Cura.
Indeed, LIN_ADVANCE is having a positive effect on the extrusion quality.
I have not tried Cura (honestly, I wasn't sure how to even _download_ it when I went looking a while back). Slic3r's quality is normally pretty good, though, and has performed well for me in general. KISSlicer works, too, but is a pain in the tuchus to use.
I settled on the current steps/mm value by running the extruder and measuring the length that came out of the drive block (i.e. not letting it go to the hotend), and tweaking until it was correct. That said, maybe the drive gear just can't produce enough torque for the job. Doesn't explain why it seems almost over-extruded with even tiny values for LIN_ADVANCE though. I have new gears coming today (hardened steel MK8's), so I'll re-calibrate to those and re-test later.
(btw, I say "gears" and "those" because I actually have two extruders/hotends, but I'm only using one for these tests)
I like good documentations!
But looking only in your first row, I would recommend to be shure there is no other problem with your printer before enabling LIN_ADVANCE. You can see best what I mean in the 87.9 / off picture. There are areas with visible over extrusion, for example at 10 and 3 o'clock and others with heavy under extrusion (11 and 6 o'clock).
If your top layer speed was at or below 30mm/s, I wouldn't expect such a result (but I don't have a bowden system - could it be so bad?). I had a look into your Slic3r config, but there are so many profiles in there that I don't know which one you are using.
Therefore I would do a step back, printing a flat test cube to see how the top surface looks like. Maybe the first with 10mm/s infill (including the top one), and if thats perfect redo with 30mm/s. If it's clear afterwards that the variable over/under extrusion is only happening with the more complex shape of the gear, we can try to compensate that with LIN_ADVANCE.
PS: I'm using a very strong magnifier to search for gaps on test parts. If there are open issues with a printer, LIN_ADVANCE will make it worse.
Regarding the impact if LIN_ADVANCE k factor to esteps/mm: In a flawless implementation, there is none. LIN_ADVANCE is changing the distribution of the amount of filament laid down, not the absolute amount itself. So if your printer produces nice prints at "low" print speeds without enabled LIN_ADVANCE and you see over or underextrusion with L_A then that's a sign of something is wrong with the code or the timing resulting from the code.
There are areas with visible over extrusion, for example at 10 and 3 o'clock and others with heavy under extrusion (11 and 6 o'clock).
I saw this too, but the over/under was consistent and remained in the same locations in the part, from one print to the next, which tells me that the hardware is at least behaving in a consistent manner. The reason it looks inconsistent in the pictures is that I didn't rotate the parts to the same orientation for each picture. Rather, I let my desk lamp highlight the errors (e.g. the shadows), with each part rotated just right for maximum effect.
If your top layer speed was at or below 30mm/s, [...]
My top solid infill speed was set to 15 mm/sec for all of the above prints.
Regarding the Slic3r profiles, I guess I should have mentioned which ones I was using:
Print Settings: "Single Material, 30 mms, 0.2mm layers"
Filament: "Inland PLA, white"
Printer: "Prusa i3, single extruder"
Do note that except as described below, I used the same gcode file for all test prints.
Therefore I would do a step back, printing a flat test cube
I'd have done that, but I actually chose the gear because I figured it would be a good torture test of this feature, and anyway test cubes never show you what a real-world print will look like.
PS: I'm using a very strong magnifier to search for gaps on test parts
I have a 10x loupe and a 2x lighted magnifier at my disposal, so I'm covered. :smile:
LIN_ADVANCE is changing the distribution of the amount of filament laid down
In which case, the gear serves as something of an "acid test" since it has so many slow-to-fast flow transitions, all of which take place in small areas (e.g. very little time for the nozzle/extruder to "catch up" before it moves on to the next section of the layer).
NOW...
All of that said, I put those new extruder drive gears that I mentioned into service (along with new springs, just to be sure), calibrated them (EDIT: was 0.2% over nominal, re-calibrated a bit later after doing some more "real" prints), and did a 30 mm/sec test print of the gear. At this speed, it came out good - nothing I could call "over" extrusion, and only the tiniest amount of under-extrusion where I expected to find it. Far better than any of the above pictures.
I decided to try a faster speed, so I re-exported the object with my "100 mms, 0.2mm layers" profile and tried again. Perimeters came out good, solid infill was a bit under-extruded, about on par with the "82.0/5" (number 22) print, above. I was only printing at 200°C though, so maybe that's too cold for that speed. I didn't notice any skipping of steps at this speed.
No problems with excessively rounded corners/teeth and LIN_ADVANCE was turned off for those prints.
I guess all of this can be blamed on drive gears that just can't keep up without the assistance of a Wade extruder or some other way to multiply the torque.
Hope you don't mind me chipping in here. I think it is related.
The last rcbugfix that I used successfully was the one I downloaded on the 19th of September. At any point if I revert to that, I get perfect prints. Until then lin_advance has been working insanely well.
However with recent changes, lin_advance causes over extrusion and blobs. I've typically used values of 47, which I determined by printing many test cubes, but now I crank it up to 80 and still no change. I've noticed over long stretches there is a blob at the beginning followed by a thinning of the printed line over the length of the line. The biggest problem is short 1-4 mm segments. This behavior causes a buildup and over 2-3 layers it's just a huge bulbous mass of plastic with the head scraping and bouncing over it.
I'll also post pics and config as soon as I can.
Any suggestions?
So as I said before, the rcbugfix before 20th September produce flawless results, but here som pics of current results. I've tried many different settings starting with the same settings where possible from the working version. If I disable lin_advance completely it prints much better.
At Sep 21, my PR #4852 (Fix for advance extrusion algorithms) was merged.
It removed duplicated direction signal, and fixed inverted stepping signal.
It was discussed in Issues #4549 (new Advance Extrusion algorithm (LIN_ADVANCE) extruder motor not running).
@apballard
If you test a this branch, how will the result?
I'll give it a go and let u know!
@esenapaj
I've tried that build and its working brilliantly. There is still a very small excess in the short bits, but I want to run some other tests before I say its the firmware. I think i need to clean up my build plate.
But initial tests look excellent.
I'll give you more feedback as soon as I can.
@esenapaj
So I've done more testing and it is definitely working like I expect. Interestingly I've had to increase my k factor up from what I usually used. I used to use 47, but I'm now closer to 70 and that has alleviated the last few issues. I'll have to do some calibration cubes to get the best number.
I'm thankful to your tests that it takes a time and cost.
And I'm sorry but I've updated the test branch.
The contents of the change is only calm down behavior of direction signal.
Yellow: direction signal
Cyan: stepping pulse
Magenta: enable signal
| before | after |
| --- | --- |
|
|
|
@apballard
The above fixing has been merged into RCBugFix of official Marlin.
Indeed, this seems to improve things for me, also.
After much hair-pulling, headaches, and about 750g of wasted filament :stuck_out_tongue_closed_eyes: I think my printer's working reasonably well now, so I figured I should just leave this here:
I'd like to suggest updating the documentation to indicate that for bowden setups, not just some undefined "high" K-value be used, but maybe a specific number. K=275 is pretty close for my printer, which has around 62cm of distance from the hob to the nozzle tip.
Meanwhile, there's another related issue that needs addressed (if it hasn't been since 9a6c66602f43288195ce3e9a19555c6c667854d1): Z-hop during retract induces a large extra feed after the restart. Doing the same Z-hop via the slicer/g-code has no adverse effect.
Regarding your issue, you mean this happens with FW_RETRACT? What is your E and Z step/mm value and the mm setting for z-hop and retract length? I guess we have to add another rule when LIN_ADVANCE should be active. At the moment, it's enabled for segments which are NOT:
Thanks for you input regarding the K value for a bowden system. To use it as a reference, you should also mention following data because it influences K: Filament diameter, filament type (PLA, ABS, PETG, ..), steps/mm of the extruder. And of course the distance of the free filament length you wrote already :-)
I want do create a documentation / calculation that gives a good starting value for K based on the given values listed above. To validate this, K values of other users are welcome!
Oh yes, I meant to mention that my K-value suggestion applies to PLA, 1.75mm (specifically, Atomic "Bright White"). E-steps is set to 147.75 on my bot.
Regarding the extra blob, indeed it happens with FWRETRACT enabled. Here's the relevant section of the config:
#define FWRETRACT //ONLY PARTIALLY TESTED
#if ENABLED(FWRETRACT)
#define MIN_RETRACT 1 //minimum extruded mm to accept a automatic gcode retraction attempt
#define RETRACT_LENGTH 5.0 //default retract length (positive mm)
#define RETRACT_LENGTH_SWAP 10 //default swap retract length (positive mm), for extruder change
#define RETRACT_FEEDRATE 45 //default feedrate for retracting (mm/s)
#define RETRACT_ZLIFT 0 //default retract Z-lift
#define RETRACT_RECOVER_LENGTH 0 //default additional recover length (mm, added to retract length when recovering)
#define RETRACT_RECOVER_LENGTH_SWAP 0 //default additional swap recover length (mm, added to retract length when recovering from extruder change)
#define RETRACT_RECOVER_FEEDRATE 45 //default feedrate for recovering from retraction (mm/s)
#endif
Except of course I use Slic3r's Z-lift in lieu of turning it on in here (0.4mm 0.2 mm).
So you have 5_148=740 steps on E and 0.4_4000=1600 steps on Z for the retract / restore move. That's why it's not working. We have to prevent LIN_ADVANCE to be active during Z & E only moves.
Search for this line in planner.cpp:
if (!block->steps[E_AXIS] || (!block->steps[X_AXIS] && !block->steps[Y_AXIS] && !block->steps[Z_AXIS]) || stepper.get_advance_k() == 0 || (uint32_t) block->steps[E_AXIS] == block->step_event_count) {
and replace it with this one:
if (!block->steps[E_AXIS] || (!block->steps[X_AXIS] && !block->steps[Y_AXIS]) || stepper.get_advance_k() == 0 || (uint32_t) block->steps[E_AXIS] == block->step_event_count) {
Does it work now?
That change seems to work:

Note that I bumped the Z-lift to 0.4mm (for all tests) because the glitch wasn't showing up well at 0.2mm lift when I tried to photograph it.
Nice to hear, than I will remember the change for the next update PR.
I guess this change isn't solving your problem with #4980?
I brought my copy up-to-date to grab an unrelated bug-fix (now at 3fcf91580872bf0c7a415a8ff539e5f0cf01a244), and decided to try LIN_ADVANCE again. I'm posting my results in this Issue to avoid cluttering the list.
Using the suggested formula that was added with commit 599649e45d997099cc19a10e53a31bd044e977a1 (which I assume was influenced by my previous K=275 comment), with Atomic "Deep Black" PLA, and a free filament length of 60 cm, I get K=282, but that's way too high - prints are under-extruded and generally look bad, and the extruder was really noisy. Torque/lost steps shouldn't be a concern, as I've since gone with a Greg's Wade-type geared extruder.
Then, I thought of Slic3r's Pressure Advance feature. When using that, a value of 0.4 is reasonable for my machine, out of a suggested range of 1.0 to 10.0. I figured if Slic3r had to be set so low, then Marlin probably needs a proportionally-lower value also, so on a hunch, I tried Marlin's default of K=75 and got a pretty decent result. I have not yet settled on the "perfect" value for this filament, but 75 is fairly close. I took care to enable only one Advance implementation at a time.
All that said, I'm not so sure the added noise and wear is acceptable, though. Is there any real reason to use such aggressive back-and-forth extruder movement when drawing short segments with little angle/direction change and little change in flow rate between them (as with drawing a small circle around a screw hole)? I mean, LIN_ADVANCE is supposed to help create sharp, accurate corners, but isn't that the last thing you'd want when going around a curve?
The formula is only meant to give an idea where a good value might be. In the end you have to do calibration prints and see what value gives the best results.
Related to the wear, I'm using LIN_ADVANCE since I have a working code and I see no increased wear on the printed gears with it enabled. Also have in mind that the noise is not due to a hughe load on the stepper or the gears but due to the small direction changes done in a short time.
The algorithm LIN_ADVANCE uses has also nothing todo with sharp corners. It's movement depends on extruder speed changes only. On a 3D printer, one of the highest extruder speed changes happen at the corners of a cube - that's why it's mostly visible there, but the same is true for smaller speed changes during the points along a circle.
So the answer is simple: If you want to have a pressure control, it will act at any speed change or it will not work. If you don't want it, you will also have the drawbacks on corners.
If you want to make the movement around circles more smooth, you might play with acceleration and jerk settings. Maybe we could even discuss if there is a way to calculate more smooth direction changes with the planner (but I guess there is no way). But for LIN_ADVANCE, physics is dictating the way how it has to be done.
Related to the wear, I'm using LIN_ADVANCE since I have a working code and I see no increased wear on the printed gears with it enabled
I don't wish to be contrary, but the documentation explicitly cautions the user:
On the extruder side, the needed extra movements may lead to an increased wear on the printed gears of a gregs wade extruder
As I happen to be using this class of extruder now, this line has been on my mind. Were I still using a direct-drive extruder, I wouldn't be as concerned with wear. That said, other parts of the system will still wear out or work loose faster regardless of the type of drive, i.e. screws, bowden fittings and tubes, and the hobbed gear itself.
The algorithm LIN_ADVANCE uses has also nothing todo with sharp corners. It's movement depends on extruder speed changes only.
The first line of the documentation says:
Let’s take the common test cube as an example: You may have noticed that the corners are not sharp, they are bleeding out.
"Bleeding edges" (corners) are mentioned several more times after that, and always ahead of infill quality. So it kinda disagrees with you. :smiley:
I do understand what you're saying, though, but what I'm suggesting is that the places least likely to benefit from linear advance are the same places where the algorithm adds the most extruder noise. The algorithm needs to look ahead a few segments and take into account the lengths of any two adjacent segments, and/or the angle between them.
I am not sure which has more effect on extruder noise in practice, or what default threshold(s) to suggest, but to give a practical example, the test model has a cylindrical object with a spherical depression in the center, 8 mm outer diameter, with 256 segments around it. Not accounting for the slightly smaller diameter the slicer would naturally use for the outermost perimeter, that corresponds to segments barely 0.098 mm in length, angled ~1.406 degrees apart.
At 30 mm/sec, you can figure the nozzle will skim around that outermost perimeter in about a second, with each vertex inducing two small, opposing advance movements on top of the regular flow. That's a LOT of activity in just one second; the poor thing sounds like it wants to fly apart going around that unassuming circle. I can only imagine the noise it would make at higher print speeds.
The test object, if I haven't already linked to it, is at http://www.thingiverse.com/thing:1363023.
If you want to make the movement around circles more smooth, you might play with acceleration and jerk settings
I was talking specifically about movements of the extruder itself, not movement along the X/Y plane.
@Sebastianv650 Is the extra noise due to an excessively slow E stepper movement rate, or due to the fact that the advance extrusion is adopting the acceleration trapezoid from the linear code instead of generating its own?
@thinkyhead it's due to the advance extrusion adopting the acceleration trapezoid from the linear acceleration to a non-linear one.
@VanessaE : Yes, there "may" be increased wear. In fact the estepper is moving more LIN_ADVANCE than without, so there must be something to a small degree. I just wanted to see that the extra-wear is not visible on my printer up to now. At last for me, that means the extra wear is negligible.
I wrote the documentation in the intention that hopefuly every one can easily understand what's basicaly going on and how LIN_ADVANCE will affect a print. If I would use extruder-speed changes instead of corners in the text, I would have to explain the whole planner and jerk thing first which is everything but trivial.
I think in one sentence you are talking about implementing a max. allowed deviation between actual nozzle pressure and needed one especialy if the adopted pressure will only be needed for a short amount of steps.
Even if I would like that idea, it will not work on the current hardware used by Marlin. All these calculations are done inside the stepper ISR, and there is no big calculation time left anymore. If Marlin runs at a faster system one day and I own such a board, we may come back to this idea.
(I dont't like the idea because it's leaving the exact pressure adaptation - it may end up with what the old ADVANCE is already doing)
Nevertheless I will interrupt my current speed up investigations to try to get some plots of XY velocity and E velocity over time, especialy to have a look what happens at block junctions. There is a small chance that the way I calculate the E velocity is not correct. If it is something off, that will be a source of increased rattle of the E stepper.
I think in one sentence you are talking about implementing a max. allowed deviation between actual nozzle pressure and needed one especialy if the adopted pressure will only be needed for a short amount of steps.
Yes, that's more or less the idea - below that cutoff, little or no advance would be used until the next significant vertex.
All these calculations are done inside the stepper ISR, and there is no big calculation time left anymore
Coming from a background of 6502 assembly on the Commodore 64, I understand all too well that every cycle counts. I had this big long post written up detailing my idea and the math behind it, but to summarize, I think you're overestimating the speed impact. My estimate says 2.5 to 70 µS to do the work, all of it outside the stepper ISR. I'll "show my work" if you like - not actual code mind you, but general ideas. :smiley:
(I dont't like the idea because it's leaving the exact pressure adaptation - it may end up with what the old ADVANCE is already doing)
I don't know how the old ADVANCE feature behaves, but the current level of extruder precision is surely excessive when the printer's trying to swing around a curve quickly.
Coming from a background of 6502 assembly on the Commodore 64
6502 on the Atari 800 plus 680x0 on the Amiga here…
I suppose @Sebastianv650 grew up with Apple :smiley:
I did this port back in the day. And this original.
Impressive indeed.
I never had an apple or something starting with "i" ;-). My first own pc was something with a 220mhz Pentium with mmx inside.
Yes, write down your idea. Meanwhile i will work on #5092, the extruder should become much more quiet when the planner junction speeds are clean. Speed jumps are critical for LIN_ADVANCE, I wasn't sleeping well this night because I was thinking about a concept - I think I have one now..
Ok, here it is. Since I took a few mins to look at #5092, Let me preface the following with an additional "I probably don't quite know wtf I'm talking about here, but maybe this is useful to someone." :grin:
———
I can't imagine there being a "big" calculation needed at all, let alone inside the stepper ISR. This is the sort of thing that ought be worked out while the lines are being read from the host or SD card (is this the so-called "planner" routine?).
Take the following with a grain of salt, since the 2560's assembly dialect is different from the 6502 (it is similar though). I'm not especially good at math, so I had to do a number of web searches to refresh my memory, and I simply don't know Marlin's architecture beyond what little I've read here, but let's give this method some air - maybe it'll help elsewhere:
A line's length on the X/Y plane (we don't care about Z) is Pythagoras' domain, so...
len = sqrt( (x2-x1)² + (y2-y1)² )
If I'm reading this reference correctly, the 2560's ALU can do a 16x16 multiply in 2 cycles, and a 16-bit add or subtract takes 2 cycles also. A sqrt() should be doable in 2-4 cycles if you skip using the math library and instead truncate the input value to 8 "useful" bits, and pass it through a lookup table, since we only want a gross estimate. So with two subtracts, one add, two multiplies, and a table lookup, I get 12-14 cycles.
Get the slope of the line:
m = ( (y2-y1) / (x2-x1) )
So that's another divide and two subtracts, 6 cycles.
To get the angle between that line and the previous, I guess there are several ways. Looks like the most CPU-friendly is to do an arctangent on the lines' two slopes:
angle = arctan( (m1-m2) / (m1*m2 + 1) )
One each of add, subtract, multiply and divide (2 cycles apiece), and 4-6 cycles to get the arctan() via a lookup table. So I get 12-14 cycles for that step.
That gives me 30 to 34 cycles. Toss in a few misc. instructions to sling bytes and registers around as needed, and I get around 40 cycles, and 512 bytes used for the lookup tables. That's only 2.5 µS. Even if you used Arduino's math library for sqrt() and atan(), as I read these posts, that would put the total time somewhere in the neighborhood of 1000 cycles/60-70 µS.
From there, I guess it's just a few more cycles to do the necessary comparisons and alter the number of steps being scheduled accordingly, all outside the ISR.
The sqrt function isn't used anyplace in the stepper (ISR) code. However, in the planner (which creates the blocks that are passed to the stepper ISR) it's used potentially several times per line segment. It's used to calculate block->millimeters and then it's used by max_allowable_speed, which is called by the reverse- and forward-pass when figuring out the acceleration curve. On delta sqrt is used again three times for every line segment.
So optimizing sqrt would really speed things up a lot.
A lookup table for arbitrarily long line lengths would be quite huge. However, on a Mega2560 we have at least 100K of free space with most configurations, and sometimes twice that. For smaller values the table could contain a 16-bit fixed-point representation. For values above a certain threshold, 32-bit fixed-point. Or, it might just be stored as float since we have enough storage space.
For the acceleration code an approximation should do fine, whether by table or by algorithm. But for the delta tower positions, it should be as accurate as possible. At least within a few stepper steps.
It's also possible to just use a custom sqrt function. Since it's an iterative function, we can just drop iterations when we don't need as much accuracy.
@VanessaE Maybe I don't understand what you want to say, but the values you are calculating are not helpful for LIN_ADVANCE. You have to calculate speed differences, not angles. For example if you want to say "don't use advance while the speed delta is < x steps/s", then you would have to go through all buffered blocks and check the min and nominal speed of the trapezoid until you find a block that violates the criterion.
And you will have the drawback then, that as soon as the criterion enables advance again, the jerk for the extruder will be even bigger. So it's questionable if this approach will work better than how it is today.
Well like I said, it's just a suggestion. You guys surely know better than me how it should work.
I'm now quite sure the rattle during arcs happens due to a wrong extruder speed calculation. it seems I did a wrong assumption.
So it should be possible to get the stepper much more quiet, I'm thinking about a solution. .
I'm sure we're on the verge of figuring out a good number of optimizations and smoothing out the movement overall. Every time we look carefully, some new opportunity seems to jump out.
Heh, and here I just wanted to calm the rattling a bit, I didn't realize I was actually pointing out a bug AND a possible optimization. :smiley:
I didn't realize I was actually pointing out a bug
@VanessaE Abe: "Leaks?" Aaron: "There are always leaks."
Never seen that movie (?). Do I need to hand in my geek card now? :smiley:
"Bad" news: the way I calculate E_speed is correct. Nevertheless, the junction speeds are not identical as they should be. Here are some numbers of initial and final extruder speed (steps/s) during a circle. I calculated them in float for this test to eleminate possible precision loss with my integer bitshift calculation, but with original calc it's the same:
Block 1:
329.48
329.48
Block 2:
328.57 <= OK, less than 1step/s deviation to last exit speed
328.57
Block 3:
273.05 <= 55 steps/s difference with no time between! Will rattle!
273.05
Block 4:
332.31 <= 59 Steps delta, like above
332.31
Block 5:
324.57 <= 8 steps/s delta, not good but I could live with that.
324.57
Block 6:
332.59 <= 8 again
332.59
Block 7:
331.07 <= 1 step/s delta, good!
331.07
So some values are OK, others are very bad. Even in this short test, I see deviations beyond 60 steps/s between exit end entry speed.
At the moment I can say that's the cause of extruder rattle, but I don't know what's causing the numbers to be off. Maybe the calculation of inital and final_rate with entry and exit factor from nominal_rate isn't precise enough. (checked) Maybe the stepper ISR starts the execution of a new block while a reverse/forward pass and trapezoid recalculation isn't finished so the executed block and the prevous block doesn't share the same entry speeds any more. Maybe it's something else.
I will continue to do tests to find the reason, if somebody has a good idea or even an answer - let me know!
I checked:
inital_rate and final_rate with entry and exit factor is very precise.Finaly, having no real idea, I had a look into the gcode from the circle. I calculated the travel length and extrusion length in mm and steps from line to line. Given the fact that there are only whole steps and no fractions (lround is used), I can calculate an error of 5.8% which will be present on the extrusion speed calculation. If the rounding for the last line was going down and for the next it's rounding upward, the error will double.
The values fit to the errors shown in the post above.
Error increases significantly with lower estep/mm values - I have 801steps/mm, which is much higher than the one @VanessaE is using as far as stated in the first post here. So your error will be much, much bigger, therefore my extruder is only slightly rattling while yours may seem to fall apart.
I have to find a way to increase the precision of the ratio between extrusion speed and the speed of the leading axis :expressionless:
Actually, I'm at 760 steps/mm (I upgraded a few days ago, Greg's-Wade-class extruder).
You're right that that it rattled a lot without the gearing, however the motor now has to turn more for the same extruded volume, plus I have the extruder is screwed to the frame of my printer (via two of the motor's screws). The printer is, itself, bolted solidly to the table to keep the frame aligned properly. There isn't any kind of damping material in place in either instance (yet).
I'm probably getting about the same actual rattle as you do, maybe I just notice it more because the frame and table amplify it or something.
Also I noticed today that the under-extrusion issue has returned, and this time it was just an ordinary test cube, but only if I use linear advance. If I turn it off and use Slic3r's Pressure Advance, extruded volume is generally good, so linear advance is causing the extruder to lose steps, or maybe the filament is slipping (I doubt it).
Never seen that movie (?). Do I need to hand in my geek card now? 😃
See "Primer" and then you can have your geek card back.
@Sebastianv650 I noticed in the Prusa MK2 branch they have an additional trick, which doubles the values given to the Bresenham algorithm. This is done just ahead of the jerk calculation.
#if 1
// Oversample diagonal movements by a power of 2 up to 8x
// to achieve more accurate diagonal movements.
uint8_t bresenham_oversample = 1;
for (uint8_t i = X_AXIS; i <= Z_AXIS; ++ i) {
if (block->nominal_rate >= 5000) break; // 5kHz
block->nominal_rate << 1;
bresenham_oversample << 1;
block->step_event_count << 1;
}
if (bresenham_oversample > 1)
// Lower the acceleration steps/sec^2 to account for the oversampling.
block->acceleration_steps_per_s2 = (block->acceleration_steps_per_s2 + (bresenham_oversample >> 1)) / bresenham_oversample;
#endif
I wonder if this approach helps with the issue at hand.
I now have some damping in place. Helps with the rattling noise a bit, but not as much as I'd like.
Meanwhile, regarding the under-extrusion comment I made, it seems that linear advance doesn't play well with "normal" amounts of acceleration. I remembered that I had turned X/Y accel up to 2000 (from 500) after solving a ringing problem. That's when the under-extrusion started - when I turned acceleration back down, the under-extrusion went away. The extruder's "max" accel is set to 10'000 (the default), and I'm not sure if the "default" accel for it ever gets altered during a print.
Surely my extruder, with 5.22:1 gearing, isn't skipping steps due to excessive torque? And I quite sure now that the hob has a good grip on the filament. I can sit there and pull quite hard (enough to hurt my fingers) without any evidence of slipping or skipping, or any effect on the print.
@thinkyhead is this acceleration glitch connected to your preceding comment?
@VanessaE as long as the ratio between extrusion speed and master axis speed is only valid to around 10-20% there is the possibility of lost steps. For the E-stepper on a block junction, this is like shifting into the reverse gear at the highway - your cars engine also will have "skipped steps" after that :smile:
The intention with the ratio between extrusion speed and master axis speed calculated in the planner was to keep track of variable extrusion rates, especialy when using Slic3rs variable gap fill. Now I know this isn't working with small segments, in fact for printers with small esteps/mm value the segment length has to be quite long (several mm).
Therefore I plan to implement parameters into M905 to set extrusion width, layer height and filament diameter at the start of the print. This parameters should be available on most slicers, so they can be created automaticaly in the start gcode. Given this values, Marlin can calculate a fixed ratio that will be used for all blocks of the print.
This means if there are variable width elements in the print, the LIN_ADVANCE correction will be a little bit of. But it's a lot better to have a not-perfect result in a few places that usualy are placed even inside the printed part than to have no pressure control for the hole part or a LIN_ADVANCE that is not working in circles (=short segments).
@thinkyhead intresting approach, but when I understand it right it will not help in this case. The resultion of the nozzle position isn't increased. What makes the problem is the following:
Let's take a short segment. It may have 55 steps to move in XY plane, but only one step for E (always rounded to full steps as the planner does). A longer move with 90 XY steps has also 1 E step. The ratio for the extruder speed is calculated from (Esteps / XY steps). So the block with 55 steps has another ratio the one with 90 steps, but only due to the numerical rounding of the Estep, which might be 0.6 in the first case and 1,4 in the second case.
For normal printing that's always corrected in the next step, if the first is rounded upward, the E position is higher on the start of the next block so it will be rounded down. But it breaks the neck of LIN_ADVANCE.
your cars engine also will have "skipped steps" after that
Not to mention lost teeth in the transmission gears :smiley:
Therefore I plan to implement parameters into M905 to set extrusion width, layer height and filament diameter at the start of the print
This won't work for Slic3r, as there is no custom start g-code to go with either print/style/speed profiles or with filament profiles, at least not at present (the only custom g-code that _is_ offered is attached to the printer hardware profile, and can't adapt to the print/style/speed settings).
This means if there are variable width elements in the print, the LIN_ADVANCE correction will be a little bit of.
There indeed will be, as Slic3r has several extrusion widths it chooses from during the print, most of which aren't anywhere close to the nozzle diameter, in addition to variable gap fill. Not sure if your idea will work in practice, at least with Slic3r feeding gcode to it.
It's working with Slic3r regarding start gcode, try this one:
M905 K75 H[layer_height] W[extrusion_width] D[filament_diameter]
Only the K value has to be set according to the chosen material, thats true.
In theory you are right about Slic3rs ability to use different extrusion widths for nearly anything. But according to my experience, it's best to stick to a fixed extrusion width (expect gap fill). Very different widths (say 0.5 for perimeters and 0.8 for infill) will increase pressure changes in the nozzle which can lead to less print quality also without LIN_ADVANCE.
But don't wory, at the moment it's all in a draft state. I have one last idea how it could work with variable widths: Work with the original float X, Y and E positions. It will require some extra variables to track them, but the error might be small enough. <= Works! No need for the extended M905 thing.
I just got it to report constant extruder speeds at the junctions! Not ready to print with it yet, but now I can see some light at the end of the tunnel :)
@VanessaE thanks for being that persistent about your rattling extruder. I guess without that I would have never checked the junctions speeds and found this error.. Nice side effect is, I can now say I finally understand nearly 100% of the planner code due to all that research.
Very different widths (say 0.5 for perimeters and 0.8 for infill) will increase pressure changes in the nozzle which can lead to less print quality also without LIN_ADVANCE
Indeed it does. For some time now, I've explicitly set external and internal perimeters to 0.4mm (my nozzle diameter), because having thicker internal perimeters always leads to a blobby seam. At that point, whatever blob I'd get from an infill-to-internal-perimeters transition is small enough that it hides within that area's infill anyway.
@VanessaE thanks for being that persistent about your rattling extruder.
Heh. I actually didn't intend to be especially persistent about it at all, I just wanted to make sure I didn't leave out some important detail. Let's hope that light at the end of the tunnel isn't the headlight of an oncoming train: :stuck_out_tongue_winking_eye:
Nope, it's finished and quality is noticeable better. I will do some test prints and then there will be a PR on Monday or Tuesday. As long as the buffer isn't running dry it should be smooth.
Sounds great!
@Sebastianv650 Looking forward to your PR. I will hold off on releasing RC8 till it's ready.
@thinkyhead I'm preparing it at the moment - it's a fight with git every time for me.
You might be also interested in my solution for the buffer underruns I mentioned in #5092. I can now print circles with small segments and full speed without a jerking printer due to a dry buffer. But it might be not a desirable solution for everyone: It blocks lcd_update if the executed block is a very short one, which means the chance is high that the buffer runs dry as soon as we try to call lcd_update.
it's a fight with git every time for me.
@Sebastianv650 Want to play a game? http://learngitbranching.js.org/
You might be also interested in my solution for the buffer underruns
I definitely am. I can check it out later on this evening or tomorrow.
Here they are, #5124 to fix the jerky extruder movements (as long as the buffer isn't draining) and #5125 that prevents the block buffer from running dry very good.
@VanessaE looking forward to hear if it works for you :-)
@thinkyhead I know the "git simulator", but the problem is I'm not using it regulary so I always forget the commands from one time to the next..
I've updated and applied both of those PR's. The extruder is much quieter now. The under-extrusion problem from before has also been solved. It is NOT a Marlin problem (mostly it was the small/drive gear slipping, and oddly I was printing too cold, AND my E-steps were still a bit low. All of these have been fixed.)
However, I've found a new problem (say it ain't so!), or rather an old problem with a new twist...
Remember those blobs that would occur when using firmware retract? It would seem I've found another way to trigger them: In Slic3r, turn off "firmware retract" but leave it enabled in Marlin (actually, it doesn't matter), configure Slic3r for the same retract speed/length/Z-hop, turn on Slic3r's "wipe while retracting" feature, disable Marlin's auto-retract feature by way of M209 S0, and print something appropriate.
In the past, I had found this wipe feature to be useful for avoiding those little dots that get left on the print from the nozzle standing in one place while the retract is performed.
Yes, that's why I wrote in the documentation:
I also strongly recommend to disable further features like wipe while retract.
I never used wipe while retracting, I have to see which movements it does and maybe we can add another rule in the planner that recognises a wipe move and therefore don't trigger advance movements.
I think wipe shouldn't make a big difference when LIN_ADVANCE is enabled as the nozzle will not ooze that much in short stops.
Try this one. In planner.cpp search this line:
if (!block->steps[E_AXIS] || (!block->steps[X_AXIS] && !block->steps[Y_AXIS]) || extruder_advance_k == 0.0 || (uint32_t) block->steps[E_AXIS] == block->step_event_count) {
and replace it by:
if (!block->steps[E_AXIS] || (!block->steps[X_AXIS] && !block->steps[Y_AXIS]) || extruder_advance_k == 0.0 || (uint32_t) block->steps[E_AXIS] == block->step_event_count || de_float <= 0.0) {
It checks if the extruder is running in reverse, and if yes set block->use_advance_lead to false.
It's not so much that ooze is a problem, but rather if your hardware just can't handle high amounts of linear advance, you can't do short retracts, so the end of the just-printed line is kept hot and melty by the nozzle while the retract is done. It's just as well, Slic3r does wipes/coasted paths so quickly as to re-introduce my old nemesis, ringing, in certain cases, so I can't use it anyway. Go figure.
That aside, I don't find that exact line anywhere in the source, but it looks like planner.cpp line 1259 (in my copy) is what you're referring to:
if (!esteps || (!block->steps[X_AXIS] && !block->steps[Y_AXIS]) || extruder_advance_k == 0.0 || (uint32_t)esteps == block->step_event_count) {
I changed it thus:
if (!esteps || (!block->steps[X_AXIS] && !block->steps[Y_AXIS]) || extruder_advance_k == 0.0 || (uint32_t)esteps == block->step_event_count || de_float <= 0.0) {
This seems to fix the blobbing and makes wipe behave as expected. Note that I didn't do a thorough test.
OK, I will create a small PR to update the rules. I hope we have filtered out all bad situations then.
I believe that's the last of it, yeah.