-
-
Notifications
You must be signed in to change notification settings - Fork 19.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Advance extrusion algorithm – LIN_ADVANCE #3676
Advance extrusion algorithm – LIN_ADVANCE #3676
Conversation
|
||
#if ENABLED(LIN_ADVANCE) | ||
|
||
for (int i = 0; i < EXTRUDERS; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that in the near future, a single extruder might have multiple steppers. So e_steps
will not depend on EXTRUDERS
but probably something named E_MOTORS
or similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thinkyhead shouldn't we clean up the "old" ADVANCE
feature ? Having two advance features using two different methods but when only one has active support and is known to work.. I would cull the other one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jbrazio in order to fix the advance feature, it needs a lot of discussion. You could create a wiki collaboration page on this. I have spent the last week a lot of thinking of this feature and looked the implementations across github like Sailfish (JNK) and Smoothieboard.
The lessons learnt by me are worth discussing on a wiki page. For example, to give you a small taste: the XY motion is calculated by the planner which is the old Grbl planner written a long time ago. It was written for CNC machines. The extruder was added later and needs to be incorporated into the planner in a smarter and more logical way. The priming and de-priming of the hot-end need to be ahead of the xy planned motion in terms of time/steps. Lots of ideas around that in terms of implementation like a third pass of the planning cycle to fill the buffer with the extruder values and using boost/Lapack libraries to simplify calculations etc.
Basically I suggest to take a structured approach in collaboration on a wiki page for this JNK feature rather than discussing via a issue thread (you lose the thinking and conclusions and new comers has to scroll through large threads whilst differentiating between opinions/rubbish and real facts) and throwing in the implementations from members which I don't understand. What do you think?
On 5 May 2016 at 09:28, João Brázio [email protected] wrote:
In Marlin/stepper.cpp
#3676 (comment):@@ -601,14 +639,28 @@ void Stepper::init() {
TCNT1 = 0;
ENABLE_STEPPER_DRIVER_INTERRUPT();
- #if ENABLED(ADVANCE)
- #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
- #if ENABLED(LIN_ADVANCE)
for (int i = 0; i < EXTRUDERS; i++) {
@thinkyhead https://github.com/thinkyhead shouldn't we clean up the
"old" ADVANCE feature ? Having two advance features using two different
methods but when only one has active support and is known to work.. I would
cull the other one.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
https://github.com/MarlinFirmware/Marlin/pull/3676/files/b497db094e421700112ec5a07e32a20bb9deaf6c#r62131409
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jbrazio I didn't want to completely drop the old ADVANCE
feature because someone out there might find it charming and want to make it work better. I think it's probably a Good Thing™ to incorporate all the extant advance algorithms, because it makes a great reference to have the code in-situ and where they can be compared and refined over time. In the longer run, we will probably end up with a nice unified algorithm.
If the old ADVANCE
feature is irredeemably broken, then we may as well drop it, but I would like to understand it better (and what the original developer was thinking) before excising it completely.
@paulusjacobus A wiki page is good to work on the feature documentation, but for figuring things out, it's fine to just keep discussing it in a Marlin issue. Everything I've been reading indicates that using a separate ISR for the E steppers produces nicer results, so I'm very enthusiastic about these algorithms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to completely drop the old ADVANCE feature because someone out there might find it charming and want to make it work better
Yes, that's me!
Everything I've been reading indicates that using a separate ISR for the E steppers produces nicer results, so >I'm very enthusiastic about these algorithms.
Actually you need to understand in detail how the planner works in order to spot the weaknesses, shortcomings so you can collaborate and understand how to fix it. For me, this means I require pictures to explain current issues with definitions so collaborators speak the same language. For example the velocity model: trapezoid and the relationship between velocity, acceleration and jerk.
Researchers from universities are now writing papers about the best strategies like maximise jerk and greedy feeding algorithms. Currently I cannot optimise the feeding buffersize or change the trapezoid profile. Ideally I would like play with these and observe the quality of the print and enhance the planner maths/model. I believe there is a lot of improvement here to be made since nobody has improved the Grbl planner. See http://maxwellsci.com/print/rjaset/v5-3543-3548.pdf
At this moment of speaking @jbrazio is closing the issues with information (I must say, in most cases it is justified). That means for me, some research or learning is lost. Conclusions and learnings need to be captured in a wiki so that can be the spec for designing and building the overhaul for a complex item (not a bug fix or simple additional feature). Anyway that is just my opinion based on my way of learning and designing.
@thinkyhead thanks for updating the PR and streamlining the code! @jbrazio @thinkyhead : There might still be a reason for keeping another advance method like the original one. My approach leads to better print results as it is closer to reality, but it requires very fast extruder movements which may not be possible at every printer. At last it should fail on flexible filaments - think about how much compression they would need to get a propper extrusion pressure when you start from 0.. |
@Sebastianv650 I am very curious about the missing lines. When I go through the code I cannot find the actual maths being carried out. Just the block is filled with advance steps initial rate and advance rate. I am currently looking at the sailfish code which has a lot more code: lead-prime and de-prime routines. The porting is not that straight forward despite the Grbl planner being nearly identical. Sailfish does some multiplication/square root operations in assembler and the acceleration variable is already quadratic (a*a) and used as such in the other calculations to save on multiplication tasks. What is missing in the overall approach is that the advance priming and depriming of the hotend needs to be ahead of the xy motion planner. I think a separate ring buffer would be required with sync between the two buffers. In that way you can adjust the priming timing of the hotend and the xy motion. What do you think? Sent from my iPad
|
Closed issues/PRs are not lost. You just have to include them in your search. |
@paulusjacobus lets see if I have all the bugs in my mind..:
which is wrong because it's assuming there is always at last one step todo. It's like truncating a comma. It will run with higher k values, but do nothing with smaller ones. This code fixes that:
Simmilar code has to be used for deceleration. Don't become confused by the sailfish code. They do a lot more than only "normal" advance. lead-prime and de-prime are disabled by default as far as I found out. This functions are an addon to the JKN advance, meaning it's releasing the pressure completely after the last print move and restoring it before the next one. You can think about that like a replacement for usual retracts. The math of sailfish is another one that can burn your (at last my) brain. They use fancy fixed comma calculations to speed up the code, which makes it realy hard to read. But that's not important as we only have to understand how the thing works in general, we don't want to copy and paste. No you don't want to prime the nozzle in advance. If you execute the advance esteps prior to the print move start, you will have a blob where nothing should be printed. Each extra step leads to an instant pressure change, you can't say I'm doing 5 steps now to have the pressure 10 ISR loops later. It's true that the sync of X,Y, Z and extruder is broken with advance. But not along time, only the speed / acceleration is not synchron anymore. |
But ok let's not kill it, your advices have been heard. |
@jbrazio I'm sorry but I don't get the meaning of what you want to say. I guess my english isn't good enough this time.. |
Or mine was a piece of poop. Let me try again, I was insisting to remove the existing My opinion to remove the existing feature is based in the rumors I have been reading around that the existing feature does not work properly and/or people do not know how to tune it. |
@Sebastianv650 that explanation makes fully sense now after I went through the code again in the last two hours. Indeed I can see the missing links and logical errors. However I think We should or at least I will definitely give it a try to improve it. Also had a look at smoothieboard which does a similar thing. Shouldn't the xy motion and extruder be in sync through their spot in the buffer when properly calculated and inserted (together in critical section)? Code in Sailfish is indeed hard to read but once you get it, it very similar to Marlin's code. Except the code has a better description of the maths behind the planner and the advance algorithm. In Marlin, the planner description is very succinct. Note: Smoothie board has a good description of the planner for those interested and want to get a basic understanding about what the Planner algorithm. Sent from my iPad
|
@paulusjacobus do you already know my small presentation? If not you might have a look at it.
Can you explain this a bit more? @jbrazio Got it! Regarding the calibration, this will be the hard part. I think it should be quite clear for someone who's understanding all the details that are happening in the printer, but a detailed step by step guide with pictures will be necessary for the normal user.. @ALL The blobs at line starts are solved :-) The extruder doesn't like more than one step at once. This changes to the advance isr fix that: Sebastianv650@0661d08 The commit is based on my RC4 version, I don't know how to append that to this PR. The changes will basicaly work in both versions. |
@Sebastianv650 Basically what I failed to express was: In other words: delta velocity is not equal in each ISR step! Your presentation is an excellent way to express what is happening than a
This is caused by the friction and heat loss in the nozzle which is I seriously start to reconsider my thought about keeping the current On 6 May 2016 at 00:11, Sebastianv650 [email protected] wrote:
|
Once again, I am pressed for time. I will read through tonight and comment tomorrow! |
No problem @thinkyhead things will take some time to discuss and absorb, we On 6 May 2016 at 13:52, Scott Lahteine [email protected] wrote:
|
The issue with k not beeing constant for different layer height is only true for the original marlin advance and the sailfish JKN implementation. This is due to the fact described in slide 4: All fomulas are based on extrusion speed. But for whatever reason, both implementations are calculating with the speed of the master axis, which most likely is never the e axis speed. |
Thanks @Sebastianv650 is your Fork working with a print speed of 40mm/s? I On 6 May 2016 at 16:53, Sebastianv650 [email protected] wrote:
|
The RC4 thing is working well for me: https://github.com/Sebastianv650/MarlinRC_LIN_ADVANCE |
@paulusjacobus You said it well, if broken should be fixed for next release. But if the feature is broken we should at least SanityCheck it with and |
@Sebastianv650 I am trying your RC4 version and will post my findings here. @jbrazio yes agreed, investigation from @Sebastianv650 shows it cannot On 6 May 2016 at 18:26, João Brázio [email protected] wrote:
|
@Sebastianv650 the tests are very promising so far. I found a K=125 for my direct drive extruder with a printing speed of 60mm/s. Since RC6 I print with 40mm/s so it seems that RC4 is smoother and allows higher printing speeds? Also less communication errors (just 1 vs. 5 error line numbers). Wonder if anyone else noticed a degradation of speed? I blamed it on my configuration plus wear and tear. I also saw that with a K=150, the ghosting disappears further at the start of the trapezoid but the extrusion at the end of the trapezoid leaves an open corner. Wonder if we can break the K into two parts: K1 for the start and K2 for the end of the block? Last observation is that the corners of the cube have rounder profile/finish which I actually don't mind. Well done! |
So you tested both the RC6 and RC4 with advance? Personaly I would say your k value is too high, the corners should get rounded. But of course in the end it's up to you what looks best in your opinion! You can also use the JKN documentation how to find the best value, in the end it's the same as my description above: The open corner you are seeing is another proof that k is too high. No, it's basicaly not possible to make a different k for accel. and deceleration. Think about it with this example: I guess your next question will be that JKN does something (but the opposite) from what you asked: K2. K2 is subtracting more steps on deceleration that where never added before or after that. A negativ K2 value would lead to what you asked. I don't like K2 because it makes steps to disapear and it's also not necessary. I guess if they would use the absolute e speed for their calculations as I did in Marlin, they would recognise K2 is no longer needed.. |
Sounds like things are working out. I will take the latest changes and integrate them ASAP. @paulusjacobus |
@Sebastianv650 I was just making the commit with your new changes, which look pretty good. One thing I noticed is that the variable interrupt rate has an interesting behavior as Perhaps it would be better to get I also noticed that, regarding the counter for |
a006df6
to
fa7a232
Compare
I started to implement the concept. But in the process, I realized why you can't set the timer rate in advance. At the same time, I can see that the divider of 17 could compound to create a larger timing issue, because 52 ÷ 17 is just a tiny bit larger than 3 (3.08 is 102.67% of 3). Meanwhile, 52 ÷ 18 = 2.88, 96% of 3. Some Bresenham-like method could smooth these out. |
@Sebastianv650 I am more then happy to review it. Just let me know when it is ready for review. Maybe an explanation of the implementation as a separate reference would be interesting for the more experience users. Sent from my iPad
|
What do you think about that: Purpose of the LIN_ADVANCE feature Let's take the common test cube as an example: You may have noticed that the corners are not sharp, they are bleeding out. Also the top solid infill has some roughness where it comes to print direction changes on the perimeters. These problems are minor at very low print speeds and become much more noticeable when you try to print fast. The root cause of this print quality issues is an improper pressure inside the nozzle. In a nutshell, LIN_ADVANCE enables a pressure control feature which sets the pressure inside the nozzle to the needed one according to the print speed. This way, bleeding edges and rough solid infill can be nearly eleminated. Advantages with enabled LIN_ADVANCE:
Important notes before you use the LIN_ADVANCE feature Please consider the following points before you enable pressure control or you may end up with strange and hard to trace back issues:
How to calibrate the K factor For a gregs wade extruder you can use K=75 as a start point for PLA and K=150 for nGen. K is a unique value for an extruder with one filament material. If you are using different filament materials like PLA and ABS, you will have one K value per material. The value will be higher for more flexible filaments. Use a test cube with the dimensions 25x25x2mm for testing. Set the acceleration of your printer to a low value like 500mm/s² to eleminate other effects like overshooting fluid filament on direction changes. Set all print speeds for the cube to the same high value, 70mm/s for 0.2mm layer height for example - but be sure to not exceed the flow rate your hotend can handle! Ensure your slicers cooling settings will not slow down the print speed. If it would do this, disable the cooling feature or increase the length and width of the test cube. Print some test cubes, each with another K value. You can set the value with "M905 K.." before you start the print, where .. is the value you want it to be. Start with K0 to disable the pressure control, which will give you a reference print how your cube would look like without the feature enabled. The best value is the one where you have no bleeding edges (bleeding edges = K too low) and no inward rounded edges (K too high). Check by holding a metal ruler on each of the 4 sides of the test prints. You will also see and even more feel the difference in the quality of the top infill, where it changes print direction at the perimeters. But top infill alone is no sufficient calibration criterion as it is also influenced by the infill overlap % that's between 15-20% in most slicers. When you have found a good value, there are two ways to make them permanent in your firmware. If you are using only one filament material, the best way is to set the K value inside Configuration_adv.h and reflash the firmware. If you are using different materials, you might want to insert a "M905 K.." line into the start code inside your slicer profile used for the corresponding material. Details about the feature for interested ones and programmers The force needed to move the filament through the nozzle depends on the speed you are trying to push it through. If you push it fast (=printing fast), the filament will be compressed in a first step before the pressure inside the nozzle is high enough to extruder the required amount of material. The LIN_ADVANCE pressure control handles this free filament length as a spring, where K is a spring constant. When the nozzle starts to print a line, it takes the extrusion speed as a reference. Additional to the needed extrusion length for a line segment, which is defined by the slicer, it calculates the needed extra compression of the filament to reach the needed nozzle pressure so that the extrusion length defined by the slicer is realy extruded. This is done in every loop of the stepper ISR. The basic formula (advance_steps = delta_extrusion_speed * K) is the same as in the famous JKN pressure control, but with one important difference: JKN is calculating the sum of all needed advance extruder steps inside the planner loop and distrubutes them equaly over every acceleration and deceleration stepper ISR loop. This leads to a wrong distribution of the advance steps, resulting in a not perfect print result. LIN_ADVANCE is calculating the needed extra steps on the fly in every stepper ISR loop, therefore executing the needed steps precisely where needed. Inside the Marlin code, stepper and planner files are the ones where the work is done. Inside the planner loop, LIN_ADVANCE checks if a move needs pressure control. This is true for a print move, but false for travel moves and extruder only moves like retract and prime events. At the moment, there is no check if the extruder acceleration, speed or jerk will exceed the limits set inside Configuration.h. To achieve such checks, the planner needs to be completely rewritten because a variable acceleration rate is needed to compensate too fast pressure advance movments. I'm quite sure the power of the used ATMega isn't sufficient to do this.. But up to now, I don't know about problems according to this in real world printing. |
That's a good overview of advance extrusion. I would only do a little tweaking to make the language more flowy. It may help to use some images to illustrate the concepts. |
@Sebastianv650 have a look here: http://www.marlinfw.org/articles/features/lin_advance.html |
Looks good! I will make pictures of a test cube with K= to low and K= to high for this article, and maybe I should also create a single simple graph that shows the advance step distribution during an acceleration phase compared to the JKN distribution, which will also clarify the problem for real world implementation into the FW for future developers. But my first priority is optimization at the moment. I'm absolutely not satisfied with the execution speed impact |
And how often does it need to run? It would be good to know what our margins are. Let's see… If it takes 160 steps-per-mm for a typical X axis, and you want to get a high speed of 100mm/s, then you need to be able to reach 16,000 steps per second. If we allow up to 4 steps per-stepper in each call of the ISR then the ISR needs to run at least 4000 times per second, so it has to stay under 1/4000 seconds (250µs) execution time. At 50µs to execute, only about 1/5 of the available time is being used up by the ISR. That sounds like a wide margin. But I'm sure I'm forgetting some extra complexities here. |
At 16kHz step frequency, Marlin will switch to double steps which results in 8kHz. So the stepper ISR on its own uses 8000 * 0.00005s = 0.4s per second = 40% of the time. Which isn't the whole truth, because it's now using a bit more time per loop to fire at last 1 stepper twice. With a stepper loop length of 80µs with advance, 64% of the time goes to the stepper. With a needed calculation time of about 2ms for a new line segment (planner) + all the ISR interruptions, this makes a nice diference in points per seconds that can be executed - and we have not even taken into account the time needed for serial communication here.. |
The problem might come from a combination of high K factor together with a more or less high jerk setting. If the needed prime steps have to be executed faster than the e stepper can handle, steps will be missing. I will try to find some new ideas after my holiday, if everything fails I will offer a JKN like approach with a linear advance step distribution over acceleration and deceleration phase, but this will lead to a clearly visible lower quality then with mathematicaly correct distribution. But of course, better than nothing. |
@lonelymyp |
@Sebastianv650: I tried to find an answer myself, but only found direct extruder K-values suggestions. |
You will have to find it out yourself - up to now I have no figures for bowden setup. It might even fail, for example if you need a K of 200 but your extruder can only keep up up to a K value of 100. PS I will be on holiday the next two weeks, I will answer further questions when I'm back again. |
Someday I hope we in the USA will have such a custom! |
I love this feature, it's amazing! However, I recently switched to 1/16 microstep on X & Y where before I was 1/8 on Y and 1/16 on X. This put enough load on the CPU with LIN_ADVANCE that it seems if I do 120mm/s print moves the extruder gets stalled out. This is with the E3D BigBox and E3D Titan extruder. Does the math add up that I will hit the stall rate at this print speed - and any suggestions for freeing up CPU for me to test? I am using the latest RCBugFix. |
I did several test prints and I think the 45cm Bowden is really a problem. The Lin_advance effect starts to appear from K=100 upwards. X, Y and E axis are all at 1/16. Acceleration at 1000 mm/s, inner perimeter at 70mm/s outer perimeter at 21mm/s. I guess a K of around 200 would be fine for me, but the extruder has problems to keep up. It works, but the print looks better with S3Ds coasting and additional restart distance enabled. In this case I have a uniformer outline, but small infills stay hollow because the outline perimeter nozzle pressure is far lower than it will have to be for the infill. |
I run this with a Bowden that's 600mm using nGen with K165 and prints very well but I had to follow the instructions and reduce my acceleration to 500 for print moves and 1500 for travel. Also I get better prints keeping my print speeds in a smaller range 30mm/s outer, 45mm/s inner and 55mm/s infill. I use 80% speed for first layer, solid or top fill. |
…N_ADVANCE) ・Update forgotten example configurations
It's best to test on a cube, because the main fix Advance provides is on sharp corners. Rounded objects will be about the same as always. |
you often do cubes? |
This was exactly my thought :) I did the initial calibration of Advance with a 40x40x40mm cube. The Advance effect was clearly visible, especially when switching from (slow) outer perimeter to (fast) infill. The absolute beginning of the infill grid line was exactly as wide as the end of the infill line. Without Advance the beginning is quite flimsy. So, the thing itself is working and, like @thinkyhead mentioned, great for cubes. When i was happy with the cube calibration settings i went to print my calibration gecko. I slightly modified some parameters like K and Retract and it came out quite nice, but, like i said, not really better than without advance. The Moai sculpture was printed to test if the "gecko settings" apply to any other object, but sadly they don't. |
@Kaibob2 did you print the one w/Advance with coasting & wipe turned off? Also try turning retract off as well.. |
The one with advance was printed without coasting and wipe but with 1mm retract. The 1mm retract was necessary to avoid massive stringing when printing the gecko. I selected optimize start points and only retract when crossing open space in S3D, so there where almost no retracts on the Maoi. |
I am getting much better results, but am not running Bowden so my K is only set to 50. |
Yes, @lonelymyp, when I'm trying to tune things, I most often use a small cube. Then I move on to other things and continue to tune. But, yes, a cube is a good start when it comes to advance extrusion, retraction, and other factors, and that was the point of my suggestion. |
@Kaibob2 I know the defects visible in your pictures, I had it a lot with nGen using higher K values. The problem isn't that lin_advance is only true for cubes, but that a cuved surface results in a lot of speed changes within fractions of a mm (depending on your stl resolution) due to jerk setting and acceleration. What you see here is the extruder stepper raising the white flag - it's missing steps during the try to adjust the nozzle pressure. I'm afraid with my limited programming skills, I can't provide a much better solution that is able to run on the 16MHz CPU. The big challenge is to find a way how to adjust the pressure with real time calculations and stay within the acceleration / jerk limits of the extruder stepper. At the moment, the X,Y speed isn't changed with lin_advance so the estepper may be overloaded. But I see no way how to keep track of the jerk / acceleration due to pressure adjustment and limit X,Y speed if it's too high. At the point we are calculating the pressure adjustment steps, the X,Y speed path is completed by the planner and can't be changed easily.. |
@Sebastianv650 has been working on this over on his fork. This is a patched up PR for compatibility with
stepper_indirection.h
which already handles multiple steppers for different features. This also keepsStepper::advance_isr
compatible with the upcoming Mixing Extruder feature.LIN_ADVANCE
by defaultADVANCE
andLIN_ADVANCE
ENABLED(LIN_ADVANCE)
#if ... #elif ... #endif
to groupLIN_ADVANCE
withADVANCE
advance_isr
can be simplified due to macros instepper_indirection.h
References: MarlinFirmware/MarlinDev#402 #3655