MarlinFirmware / Marlin

Marlin is an optimized firmware for RepRap 3D printers based on the Arduino platform. Many commercial 3D printers come with Marlin installed. Check with your vendor if you need source code for your specific machine.
https://marlinfw.org
GNU General Public License v3.0
16.34k stars 19.26k forks source link

Extrusion confusion: LIN_ADVANCE is leaving me behind #4896

Closed VanessaE closed 8 years ago

VanessaE commented 8 years ago

(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:

untitled (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.

thinkyhead commented 8 years ago

@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.

thinkyhead commented 8 years ago

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.

VanessaE commented 8 years ago

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.

p1160632

thinkyhead commented 8 years ago

Top to bottom isn't much different, but clearly LIN_ADVANCE is producing cleaner extrusions, and leaving fewer gaps also.

thinkyhead commented 8 years ago

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.

thinkyhead commented 8 years ago

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.

VanessaE commented 8 years ago

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.

VanessaE commented 8 years ago

(btw, I say "gears" and "those" because I actually have two extruders/hotends, but I'm only using one for these tests)

Sebastianv650 commented 8 years ago

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.

VanessaE commented 8 years ago

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.

apballard commented 8 years ago

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?

apballard commented 8 years ago

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.

img_8966 img_8967

ghost commented 8 years ago

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).

ghost commented 8 years ago

@apballard If you test a this branch, how will the result?

apballard commented 8 years ago

I'll give it a go and let u know!

apballard commented 8 years ago

@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.

apballard commented 8 years ago

@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.

ghost commented 8 years ago

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
ds1z_quickprint1 2 ds1z_quickprint2 2
ghost commented 8 years ago

@apballard The above fixing has been merged into RCBugFix of official Marlin.

VanessaE commented 8 years ago

Indeed, this seems to improve things for me, also.

VanessaE commented 8 years ago

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.

Sebastianv650 commented 8 years ago

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!

VanessaE commented 8 years ago

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).

Sebastianv650 commented 8 years ago

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?

VanessaE commented 8 years ago

That change seems to work:

p1160703

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.

Sebastianv650 commented 8 years ago

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?

VanessaE commented 8 years ago

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?

Sebastianv650 commented 8 years ago

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.

VanessaE commented 8 years ago

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.

thinkyhead commented 8 years ago

@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?

Sebastianv650 commented 8 years ago

@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.

VanessaE commented 8 years ago

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.

thinkyhead commented 8 years ago

Coming from a background of 6502 assembly on the Commodore 64

6502 on the Atari 800 plus 680x0 on the Amiga here…

VanessaE commented 8 years ago

I suppose @Sebastianv650 grew up with Apple :smiley:

thinkyhead commented 8 years ago

I did this port back in the day. And this original.

VanessaE commented 8 years ago

Impressive indeed.

Sebastianv650 commented 8 years ago

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..

VanessaE commented 8 years ago

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.

thinkyhead commented 8 years ago

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.

Sebastianv650 commented 8 years ago

@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.

VanessaE commented 8 years ago

Well like I said, it's just a suggestion. You guys surely know better than me how it should work.

Sebastianv650 commented 8 years ago

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. .

thinkyhead commented 8 years ago

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.

VanessaE commented 8 years ago

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:

thinkyhead commented 8 years ago

I didn't realize I was actually pointing out a bug

@VanessaE Abe: "Leaks?" Aaron: "There are always leaks."

VanessaE commented 8 years ago

Never seen that movie (?). Do I need to hand in my geek card now? :smiley:

Sebastianv650 commented 8 years ago

"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!

Sebastianv650 commented 8 years ago

I checked:

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:

VanessaE commented 8 years ago

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).

thinkyhead commented 8 years ago

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.