-
-
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
Collecting ideas and advises for LIN_ADVANCE v2 #9048
Comments
Just wanna express support. And hope to see farther improvements in lin_advance. Its really has helped over all print quality. I think its a great improvement. |
Ok, I will by no means pretend that I have understood everything but anyway, thanks a lot for this extensive write up.
In such a system the damper force goes towards 0 for low velocity and for high velocities may even kind of block the system. Solving this is some differential equation tho. But as an analogy to the topic here, it may be a way to split the k-factor in two components. Maybe a constant one similar to the spring force (i.e. number of steps) and some portion depending on the acceleration. |
I don't think we need another factor, I don't see a damper as you described it in our extruder system.
Therefore, the spring model to calculate the needed filament compression which will result in the needed extrusion force seems to be valid. |
Any chance to have Cura's variable extrusion widths mixed in there? |
Hi everyone. I think that the spring model is simple and effective enough. I believe introducing a more complex model won't give any appreciable improvement, while it would slow down computation. I didn't understand why actually LINEAR_ADVANCE is not supported by non-cartesian printers. As far as I know, kinematics machines split every movement in many little movements which are approximately linear. We could calculate the real length of those tiny movements by applying Pythagorean theorem to their start and end positions. Am I wrong? I really would like to help, but I feel I didn't understand 100% the problem. Bye |
Guess you know this already: https://airtripper.com/1338/airtripper-extruder-filament-force-sensor-introduction/ |
@psavva well, variable extrusion widths are basicaly supported by LIN_ADVANCE so there is no need to think about Cura in special. What was a problem with Cura in the past wasn't variable extrusion widths but wrong ones, spikes at incredible magnitude that occur randomly. So that's something up to Cura developers, I guess it's already fixed as I had a Cura gcode some times ago and it was fine.
@iosonopersia in fact I wasn't thinking about that in detail. @thinkyhead made that statement a short while ago during a change we discussed for 1.1.7. As he is way better in coding and knowing the Marlin details, I just accepted it. And it makes sense due to the way I calculate the extrusion speed and how I'm checking for print moves. I also wrote about that in the long text. @Sineos yes, that's the one I was reffering to when I wrote about the extrusion force measurement :) |
Have 4 printers (mk3 on the way when they get powdered metal pei sheets in). But the cheap Chinese Delta was my first. So between delta auto calibration, unified bed leveling, linear advance and skew correction it has never printed this well. Print quality is truly amazing. (I'm afraid to install the tmc2130 drivers I bought for it because its super loud but I dont wanna mess up a good thing) Linear Advance made corners sharper and top layers better looking, less retraction necessary too. Plus i could bump up speeds. I'll have to try and figure how to disable the sanity check for delta's concerning linear advance. |
@mylife4aiurr , you simply need to find in sanitycheck.h these lines and delete them: // Linear Advance
#if ENABLED(LIN_ADVANCE) && !IS_CARTESIAN
#error "DEPENDENCY ERROR: Sorry! LIN_ADVANCE is only compatible with Cartesian."
#endif If LIN_ADVANCE V1 works well with non cartesian machines, that would be one less problem to solve... We need someone to test it on a Core machine too. |
Awesome @Sebastianv650, I'm glad to hear that you are still fired up to develop advance! I won't likely be much use in the actual coding changes, but have a solid grasp on the physics involved and can help work through conceptual stuff. In addition to testing on my well-tuned bowden printer. It sure seems like an overhaul of the actual motion planner, which did away with jerk (at least in its current form), instead using a "maximum path deviation" parameter to allow a smoother path, which did not "hit" every coordinate exactly, better leveraging linear acceleration; would solve many of the advance challenges (among others). Easier said than done! ;) Is the current version of LIN ADVANCE bounded by the E max acceleration setting, or is it operating outside of its control? Regarding the mention of dampers: I agree that there isn't a useful place for damping in the physical model of the advance engine. The linear spring model will work very well to link flow rate with head speed. But, perhaps adding a 'damping' to the addition/subtraction of advance E steps would help smooth out the advance moves. This kind of ties back in to bounding the moves with max E acceleration. It might be even better to look ahead and filter / average the inputs to the advance engine. This could help on the arc jitter situation you described. I think this could also help in the issues I see with the current LIN ADVANCE. Even with modest K values, well below what I need to truly equalize flow, the extruder is pretty spastic and starts to skip steps. For example, with simple "line" infill from Cura: I find that this gives a better printed result, compared to "zig zag" which connects passes with a print move (and inadvertently over-extrudes these direction changes). "Line" infill uses small rapid moves to move between passes. Even though each of these moves is executed in a small fraction of a second (0.002 s for one that I calculated), advance seems to look at them as extrusion rate = 0; making corrections for the start and stop of every pass. As I look closer, there is an additional move that Cura makes, which could be contributing to (some of) my issues with advance, called "infill wipe". It is just a small G1 move, without extrusion, in the same direction as the infill pass. It is meant to give better adhesion between infill and walls, which it does well. It's possible that this is what is tricking advance into becoming active where it is not needed, in this case: The same principle applies though. There is a realistic time required to change pressure at the nozzle through advance moves. Reacting to pressure changes in the code which take less than this amount of time to execute, is not productive, and contributes to issues. I understand that the implementation may not be simple. Some moves are physically very long, while others are incredibly short. So you can't just look-ahead some number of moves, but must instead look at distances and speeds to make time based decisions. |
Maybe the analogy was badly chosen and I couldn't bring over my point. As far as I understood:
The first one is already being represented by the k-factor while the second one actually might change E steps without any acceleration or deceleration being involved.
I wonder how these measurements would look like with LIN_ADVANCE |
@Sebastianv650 — I just reading the OP so here are my first random thoughts… Generally, when the slicer outputs G-code, I assume that it basically just outputs some linear motion and then a proportional amount of extrusion to fill up the line. So for each individual segment you can always calculate the extrusion-to-length ratio, and when wall widths are all the same this value shouldn't change. But if the slicer is using variable wall thickness, then this should manifest as an obvious change in the E-to-length ratio. Since this can be figured ahead of segments, perhaps this changing ratio can be utilized as part of the trapezoid generation and block-joining procedure to ensure that the linear advance flow is slightly increased or reduced ahead of the block where it changes. |
At the moment it's ignoring every limit. That's due to the fact I had no idea how to limit the esteps easily (=with acceptable calculation power) on the one side and on the other side it should never hit a limit as long as we have a smooth extrusion speed path.
Non-extrusion moves are not a problem as they don't alter the extruder pressure. @thinkyhead this might be possible and something to keep in mind. At the moment I'm stuck some steps before that.
Edit: Please ignore the stroke through part for the moment, investigation is ongoing and the error might be on my side! |
Does lin advance thus benefit from a higher step per mm on the extruder, which would artificially limit speed on it as well? E.g. im running a direct extruder at 95 steps per mm, with 1/16th microstepping, but since i have tmc2130s with up to 1/256th microstepping, could i theoretically just increase the microstepping on E to get rid of the extruder jitter caused by lin advance? Also, is the K value dependant on steps per mm? |
The K value should not have any dependence on steps/mm. It represents a physical spring rate of the combined compression of filament and elongation of the bowden tube. @Sebastianv650 would have to confirm whether lin advance would benefit in any way. My gut says no. |
Why? Who tested and found No GO? Just use a thingiverse object designed to calibrate lin_advance Disabled sanity check for Delta's working fine (higher K factor) but it works.... |
Pressure changes don't just come from rounding jitter and variable width, also there is the filament width sensor to play nice with. How does filament width correction work, just adjusting extruder step count in the segment (appears identical to slight width variation per segment), or some other way? |
@Beherith K isn't dependant to steps/mm setting, at least it shouldn't. The step amount / mm on e axis is quite unimportant for LIN_ADVANCE as it's not using block step amount for speed calculation. By the way a higher espep/mm value shouldn't slow down your maximum print speed. I'm using 801/mm and my max espeed is 40mm/s - way more than any print move will ever use. @mylife4aiurr the person in your linked issue did ;) thinkyhead also recognised it (independetly from this) in the last days. It might work to some degree, but the math behind is definitly not right for delta printers. This will be fixed in v2. @aaulick the filament sensor works by adjusting the extruder length per block. Inside the planner it is identicaly to increasing flow rate per hand, it's combined in one factor. |
@Sebastianv650 A useful invariant for debugging is that total steps extruded between retraction moves should never be different for lin_advance enabled/disabled cases. Individual segments will have wildly different step counts in order to prepare the right pressure for starting the next segment, but the total filament in one extrusion stream starting from 0 pressure before last advance and ending at 0 pressure after last retract has to be the same number of steps, extra advance cancelled by extra retract. |
That's how I tested LIN_ADVANCE and also the reason why I designed the code in stepper.cpp how it is. It makes debugging easy. But there is no "live check", you would need to add some SERIAL_ECHOs. |
@Sebastianv650, I did some math related to modeling the linear advance. This doesn't help at all with the problems of discontinuous extrusion width (still need some smoothing feature there to prevent discontinuities) but it lets us put a unit on the current K constant and suggests a couple ways to calibrate K for a given printer config. Please check my math, let me know if this is correctly modeling the current code that's there in 1.1.18, and point out any mistakes or bad assumptions. I have some more work on solving the differential equation relating extrude rate decay to feed rate when the two are out-of-sync. That might be useful for smoothing the extruder motions, not sure yet. Also possibly more coming on how to transfer K calibration to different filament or different nozzle temp. Assumptions and definitions:
Given these assumptions, we can know:
Calibrate K with a filament force sensor using equation (5):
Estimate K by weighing ooze using equation (5):This way of estimating is only good if gravity does not cause your filament to ooze out of your hotend even at 0 pressure. Maybe OK for small nozzles, but if you have a volcano nozzle that oozes until the melt chamber is empty, you will only be measuring your melt chamber volume.
|
You wanted to write something even longer than my first text, isn't it? :-D
But I also found a not jet tested way to determine K. I will write it down as it fits to the topic:
|
Hi, This speaks of preload in kisslicer slicer but may possibly be giving ideas : Yoann |
@BillyQuiet maybe you can give me a short hint what they are talking about. While I understand it's about preloading, which is nothing else than LIN_ADVANCE does, I have no clue how Kisslicer wants to do this in gcode. The gcode as defined in Marlin only allowes synchronised moves, meaning a linear movement between all 4 axis. With this basic moves, there is no way of incorporating a smooth preload. |
@Sebastianv650 |
@Sebastianv650 @BillyQuiet @Beefeater on the kisslicer forum thread is characterizing the actual flow rates at constant extruder velocity as an exponential system with time constant tau. Looks like Beefeater has actually taken some relevant math courses (unlike me) as their terminology is matching the wikipedia page... Their tau is the same info as our K (tau = 1/K) and it looks like they have a wizard somewhere similar to our calibration generator to estimate the value. They are assuming the whole extruder system is rigid and calculating Tau from viscoelasticity of the filament only, which their wizard is nominally measuring. But I think in the end it comes to the same thing -- both our wizards are doing an experiment to measure total stretch in the system by comparing ooze/blob sizes at different extrusion rates. Lots of detailed analysis in that page which are relevant to us, some main bits which are relevant to Marlin:
|
By my calculation, time to ooze down from one real extrude rate to another with stopped extruder is: Using equation (5) we can track extrusion_rate as extra_steps (current linear advance) instead, which may fit better in the code. Using either one of these facts will break the invariant that we always extrude exactly the correct total stepcount of filament -- we can still count the change as extra_steps and track exactly how much filament left the nozzle, but it will be subject to floating point error now. All these log functions are very expensive, but we can cache or precompute them as we will be seeing the same extrusion rates over and over again in the gcode. |
OK so I would say Kisslicer is more or less guessing. While the math can be fine, the slicer just hasn't the needed informations. All we have in gcode is a maximum execution speed. No real achieved speed, no junction speeds, no information about planner buffer state. |
Agreed, firmware is better to put something so tied-in to the physics. Lots of complaints in the slicer thread that they never know just how the firmware does acceleration. I think we can benefit from Beefeater's analysis of the math though. Picking an acceleration profile to minimize error in K is good and not something I thought to try. |
@Sebastianv650 , any more on this? You have said already that you have a solution in mind for resolving jitter.
Is this a workable plan for the discontinuous width problem? |
I paused this due to research and work on the planner and stepper, as a perfectly working planner and a deep understanding of both planner and stepper is needed for a LIN_ADVANCE integration.
One positive thing about all my research is that I also recognised something basicaly obvious, that as long as the extruder acceleration is constant, we just need to overlay the extruder speed with a fixed speed offset for advance during acceleration and deceleration. That might be helpful for a faster implementation, but I'm not realy sure because for the stepper we need time intervalls, so finding an implementation that makes use of adding a speed offset is not available now. With this, it would be also easy to prevent the printer from loosing steps: All we have to make sure is that the speed offset is not bigger then extruder jerk speed.. So I think I have to adjust my goal "a bit":
|
Any thoughts on a way to filter LIN_ADVANCE response in the time domain? If there was a lightweight way to identify the duration of a new extruder speed, you could avoid unnecessary corrections. |
@CCS86 I don't know if it's even true that we can safely ignore short-duration changes in speed. I've been looking at the output of Slic3r (1.38.5 Prusa) on one model, and it's putting little squirts of fill in a variety of different tiny thicknesses to fill small holes in my thinnish-wall model. @Sebastianv650 the existing linear math works fine for constant extrusions, right? All the funny different width stuff seems to come in the fill, where it's much harder to do right with odd-size fill, but also we care less about small blobs. Can we make an M-code for the slicer to tell us when we're doing fill, and with help from slicers that uptake this idea alternate between LIN_ADVANCE for perimeters and extra retract for fill? |
I'm also thinking that's not a good way and it solves the problem only in a small area of all possible combinations. If the extruder is basicaly able to go from pressure release speed to pressure adding speed without skipping, it can do that also during short blocks. Might sound bad on geared extruders, but it will to it's job.
That's true. My hope is we don't need another M code by comparing to jerk speed. If we check that at the first step of a new block and it's OK, it's very likely OK for the complete block. So we can avoid rechecking again each loop. Time to get another branch and start once more. |
Does it make sense to look at #8348, which might provide a smoother acceleration transition? The code seems to be already there: https://github.com/MarlinFirmware/Marlin/blob/bugfix-1.1.x/Marlin/planner.cpp#L1212-L1259 though with my limited knowledge I could not get something useful from it. |
On the time filtering: Take Cura's normal method of infill, which functionally works quite well:
1: LIN_ADVANCE seems to see the flow rate as zero between these passes, but that does not accurately reflect reality. The overshoot move takes around 0.002 seconds to execute. I'm not sure how long the rapid move takes with acceleration, but it is also extremely short. I think it is counter productive to use advance here. I don't think it will provide a functional benefit to the print, but will beat up the filament at the drive gear (like excessive retracts can), add heat to the extruder motor, noise, etc. Long and narrow areas of this infill can contain a huge number of these successive reversals. If advance even used an oversimplified calculation to look ahead (even a few moves), see that the "zero" extrusion rate will be over in milliseconds, then back to higher flow rate, it could defer any correction. |
@Sineos it's not important how jerk is calculated for LIN_ADVANCE. Only thing that would be helpful is if we would know the max. and final speeds from a block. Junctions share the identical end/start speed and while the planner does this, the way how the stepper loop is calculating it's way along the trapezoid leads to never-reached final or max. speeds especialy at lower step rates. @CCS86 So your proposed solution would be to ignore the slowdown at the end of the infill line and keep the filament pressure, so we can also ignore the next acceleration part from next infill line. |
@Sebastianv650 Thanks for the explanations and insights. Appreciated. |
Sometimes the K needed for bowden systems is above the physical limit of the extruder assembly, and in this cases perhaps a more rudimentary form of pressure control could be used, which should be much more simple to program and while not giving the full advantages of a proper physically correct pressure control, could give quite decent results in systems where lin_advance can't be implemented. My idea is a form of adaptive "coast at end" (a feature that stops extruding some distance before a line ends to relieve the pressure in the extruder before starting the next move, for those who don't know), like the one in simplify 3d, but smarter. The difference would be that instead of having a fixed value for the coast, it could be adapted depending on the delta speed. For example, if you were printing an inner perimeter at 60 mm/s and then got to the outside perimeter at 30 mm/s, the delta speed would be 30 mm/s, which could mean (for example) a coast of 0.3 mm just before the speed change. If you were printing at 60 mm/s and then came to a stop (0 mm/s) the delta speed would be 60 mm/s, which could be a 0.6 mm coast. The coast amount would be controlled by a single constant (which would be 0.01 in this example). This approach I believe could give good results, because if I understood correctly from the discussion above, "The force needed to push the filament through the nozzle is linear proportional to the extrusion speed", which suits well the proportional coast to delta speed I described above. Hope the coding/printing gurus can get something useful from this idea. Cheers! |
@Itox001 this approach would not always work as expected. When I understand it correctly, "at end" means a move followed by a non-extrusion move (travel, z jump, etc). The problem is that in some situations Marlin will not see the end until it's too late:
With a hughe buffer, which is not possible on the ATMega, it should be possible to implement such a smart coast at end. But it wouldn't be a pressure advance feature anyway, as it's only bleeding pressure away, never building it up. |
Ah, I see. The difference with the simplify 3d implementation would be that the coast would not only be at the end of lines, but rather on every deceleration, so marlin wouldn't need to know if a line is ending, only that the print head is slowing down in order to start coasting. If I understand correctly, on the advanced configuration file on marlin there's a constant called MIN_STEPS_PER_SEGMENT which is 6 by default. This gives us a lower limit on how far ahead we can peek. With 1/16 microstepping and the most common pulley-motor config which results of 80 steps per mm, 14 6-step-blocks would be a length of 1.05 mm, which would effectively be the higher limit of how we can look ahead and how long we can coast. Reductions in the drivetrain or 400 steps per revolution motors would effectively cut this distance, but if I understand correctly, the coast that simplify 3d folks use is in the order of 0.2-0.3 mm and seems to give good results, so there would be a bit of play here. You're right that this isn't a proper pressure control, but it seems to give very good results in simplify 3d to make z scar less visible and other parts where pressure buildup results in undesired blobbing. It doesn't build up pressure (could a reverse mechanism be applied to help with that?), but compromises have to be made in order to get a decent result in otherwise not working configs. Perhaps this feature would be better implemented in the slicer side of things? Anyway I hope that if this isn't a viable idea, it can at least inspire someone to come up with something that can help us bowden folks with our extruder pressure problems. |
If someone wants to do some testing, there is a new version in development here: #9379 |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
This will be a quite long one but if you like to solve problems and you want to help me improving LIN_ADVANCE I would be very pleased if you continue reading and dive with me into the details of planner code, stepper code and nozzle pressure correction.
I will explain as much of my findings and knowledge I got since I started the LIN_ADVANCE implementation as possible so it should be a quite good start point for everyone who want's to touch LIN_ADVANCE related code or help improving it.
Why we need a LIN_ADVANCE "version 2"
While LIN_ADVANCE works great for me and most (I have no real numbers) others, issue reports here are showing it's not working for everyone. Especialy bowden printers struggle with high needed K values and it doesn't work at all for kinematic printers due to the way the extruder speed is calculated.
It's possible to track this down to two main problems:
The extruder step resolution, or the way how the planner treats the extruder
You might know how the trapezoids looks like which are calculated by the planner code. Here is an example I found, just ignore the numbers:
Here we see two joined motion segments. First we have a linear acceleration ramp followed by a cruising distance. Then, the planner decelerates for cornering or something similar to respect jerk limits. Next is accelerating to cruising speed again and decelerating to 0 as this is the last move.
Note that the planner ties final speed of segment 1 and the start speed of segment 2 together. In reality, there can be a small difference due to numerical rounding and the step resolution, but it's nearly perfect.
But the problem is, that's only valid for the 3-dimensional print head move (X, Y, Z). It's physicaly not possible to link the E axis in the same nice way without coming to a full stop, except we have only one extrusion width within the whole print. While this was maybe true during the beginning of 3D printing, nowadays every slicer can use different extrusion widths, for example thin lines for perimeters and thick solid ones for infill. Even variable gap fill, like when you want to fill the tip of a triangle, is done.
As a result, the extruder speed sometimes jumps between motion segments. Imagine the example of the triangle tip again. If we approach the tip from the triangle center, the print head moves along a straight line with a constant speed. But at points defined by the resolution of the slicer, the extrusion width gets reduced further and further. While we have a constant X, Y motion, the E axis reduces it's speed at the segment junction without deceleration.
As extrusion speeds are low during print moves, this speed changes are well below the extruder jerk limits in all cases I have seen so far, and they will never cause the printer to loose steps - well, as long as we don't use a nozzle pressure correction like LIN_ADVANCE..
With LIN_ADVANCE, needed advance extra steps are calculated with "extra_steps = extruder_velocity * some_factor", therefore if we have a sudden speed change like due to the example above, this will result in an amplified sudden extruder move as LIN_ADVANCE wants to adjust the preload step amount.
Up to now, it's my "dogma" that every printer who runs LIN_ADVANCE has to have the capability to do that.
And it becomes even more "funny" due to the resolution of the extruder stepper. The following example will clarify what I mean.
The right section of the sketch below shows the line path that gets printed in our example. It's a straight line, followed by a 90° arc and again a straight line. In the graph on the left, we are only watching the marked section of the line path, so we exclude the acceleration to cruising speed and the deceleration to full stop. The XY jerk setting is high enough, so the planner will not slow down between the arc segments:
When we have a look at the graph from left to right, we have a nice cruising (extruder) speed line first. As soon as the arc starts, we see some jitter: Some segments are printed at a slightly higher speed than the others. No one is an accelerated move. A stable extruder speed is not reached until the line starts again.
What's going on? Let's have a look into one of the arc gcode segments. While it has a length of 0.583mm, it only needs 0.00772mm of extrusion (0.2mm layer height, 0.48mm line width and 3mm filament). My printer uses 100.5steps/mm in X and Y and 801steps/mm for the extruder, so in step unit this means:
print move length = 58.592 steps
extruded length = 6.184 steps
As the printer can't do fractions of a step, the planner will cut the decimal places. But the fraction isn't lost. If the decimal places accumulates to a full step, it will be executed in one of the next segments. This "rounding" leads to the jitter around the nominal cruising speed. In real numbers, during this arc the extruder speed in terms of steps per second has a variation between the fastest speed and the lowest of impressive 20%!
While this is not even noticeable in normal printings, it jerks around the extruder with LIN_ADVANCE just as the triangle gap fill example above did.
Note that my demonstration arc with 0.583mm segment length is not even a very high resolution one. With increasing resolution, this problem gets worse as we might reach a point where some segments have no extruder moves at all and the extruder does one step in segment 1, no step in segment 2, one in segment 3 and so on.
The way how LIN_ADVANCE calculates the extruder speed as a work around
In fact LIN_ADVANCE as it's implemented today isn't using the real, physical extruder steps/s speed to calculate the needed advance steps because the speed jumps explained above would lead to an extruder jumping back and forth like crazy, maybe even losing steps due to LIN_ADVANCE wants to adopt the nozzle pressure in every single stepper ISR loop. Instead, it calculates the ratio between length of extruded filament and distance traveled based on the numbers given from the gcode (see planner.cpp, near the end of
Planner::_buffer_line
).Inside the step execution code, it then uses this ratio together with the ratio from nominal speed and nominal rate to recalculate the extruder speed from the current step rate (see stepper.cpp, inside the main stepper ISR). This way, LIN_ADVANCE has more something like the intended stepper speed in mind and not the jumping real extruder speed.
While this solves the jitter problem in arcs, it's not a solution for variable gap fill which will still lead to speed jumps!
Goals for a LIN_ADVANCE v2
My goals for a version two are as follows:
Current status of my v2 ideas and implementation
As @thinkyhead pointed out, the actual extrusion speed can always be calculated by
step_rate
*block->steps[E_AXIS]
/block->step_event_count
. Beside the before described fact that the calculated speed will be off in short print segments, this works fine and requires even much less cycle-consuming math operations.The second point, finding a smooth way from one extruder speed to the next, is the real challenge. Any help is welcome.
Up to now I have created a working draft version, but it's not handling all real world cases and I even met my good old friend again, called lack of calculation power on the ATMega. I will not write down every idea I had in the last days which wasn't working in the end, instead here are two possibly working ones for you to give a start point for thinking:
Smoothing the extruder speed, as implemented in my local branch
To avoid junction extruder speed jumps, only use the final extruder speed of the last segment as a reference. My first idea was to even say the extruder speed can only change if segment has an acceleration or deceleration part, therefore this statement changes to: Keep track of the last extruder speed that we had at the end of the last acceleration or deceleration. This way, we can avoid two problems:
To avoid writing acceleration or deceleration 100 times more, in the next part I will only use acceleration. Deceleration works in the same way:
For each acceleration ramp we can now calculate an extruder acceleration so we reach final extruder speed at the end of acceleration starting from extruder speed at end of last deceleration within the time we have for that acceleration section given by the planner. In a graph, this would mean we take the last extruder speed from segment before and draw a straight line to the extruder speed at the end of the acceleration part, ignoring a possible different extruder speed at the actual segment start.
Within the stepper ISR, we can now use that extruder acceleration to calculate the smoothened extruder speed for every loop we have and from that calculate the needed advance steps.
Easy at first glance, but problematic if you think about all the possible details:
As acceleration and deceleration are handled slightly different in the code for two reasons
this is something which has to be handled with care while coding.
To handle variable extrusion widths, it would be possible to roll back watching extrusion speeds at end of accelerations / decelerations only, resulting in watching extrusion speed at end of each segment again. This will lead to some unnecessary extruder moves during arcs, but they should be smooth enough (hopefuly).
Furthermore if there is no acceleration part at the beginning of a segment, we would have to adjust the advance step pretension during the cruising part. Should be possible, but something to keep in mind.
Another idea using variable
block->steps[E_AXIS]
As I'm already seeing some slow down under certain circumstances, I'm thinking about a way to get rid of all or most of the extra calculations due to LIN_ADVANCE. One might be to alter the executed stepper speed during acceleration and deceleration by overwriting block->steps[E_AXIS] value. But up to now, I'm not sure if this would result in the wanted effect, at least it will create a bunch of new challanges. Some of my points where this idea seems to stall:
If you got up to this point, thanks a lot for your patience! If you even understood everything that's amazing, if not and you are still intrested just ask questions.
Finaly, every proposal is welcome!
The text was updated successfully, but these errors were encountered: