Marlin
Marlin copied to clipboard
[FR] Improve LA with short segments
Description
I'm opening this ticket to address an undesired behaviour with Linear Advance. I believe it's technically not a bug, but it can be improved.
Curved lines are approximated by many short straight segments and at certain speeds, when LA is enabled, it causes the stepper motor to change direction every few steps. This makes a rather loud noise and doesn't produce any useful effect, because the motor is essentially just moving very slowly.
Here's a capture from my logical state analyzer, as you can see it's literally changing direction every 1 or 2 steps:
![LA_printing_noise](https://user-images.githubusercontent.com/1024000/86516214-011a8400-be1f-11ea-9eef-39e9c37dfa56.png)
Possible solutions
My current workaround is to not use LA for very short segments. I've achieved this by changing
block->use_advance_lead = esteps
&& extruder_advance_K[active_extruder]
&& de > 0;
to
block->use_advance_lead = esteps
&& extruder_advance_K[active_extruder]
&& de > 100; //100 forward steps = about 0.25mm for my extruder
This is a rough workaround. It could be improved to be independent from steps/mm.
I believe Klipper uses a different approach and "smooths" the Linear Advance between blocks. But that would be a non negligible amount of extra calculations, while the patch above has virtually none (I believe it would take only 1 or 2 extra instructions on AVR to load a constant into a register instead of just clearing it).
I agree that the LA behaviour isn't nice in this case. Maybe it should be improved. Your solution will break LA in some situations, though. At least as far as I know and understand the code:
If you are printing and approach a couple of short blocks which will be mostly decelerating and those happen to be flagged with block->use_advance_lead = 0
according to your check, LA can't reduce the advance steps and thereby can't reduce nozzle pressure. It will also not be able to "catch up" later on, because a reduction of advance steps is only carried out during deceleration phases and it is timed to fit into those phases pretty tightly. In the end, your line width will be incorrect until the pressure has normalized again by itself over a couple of centimeters.
Same holds true for the reverse case, where you might flag short blocks with block->use_advance_lead = 0
during an acceleration phase. But in this case, LA should be able to catch up on advance steps during cruising phases. It will still mess with the line width, though.
It's very possible there will be corner cases (ha!) where this rough workaround doesn't work as intended, as you say.
To be honest, I don't really understand the code. Hopefully you or other devs can find a better way to address this issue. I'm willing to help testing, but on the development side I feel like it would take me quite a bit of time to get my head in the planner/stepper code and also learn about the special conditions it's supposed to handle. It's kind of heart surgery.
This is probably a bug and not a feature request. My understanding of Linear Advance is that is should not have to advance and retract for every segment. At the end of each segment it should only retract as much as needed to reduce pressure if the next segment extrudes slower. In a smooth curve this should not be the case.
There are a lot of open issues regarding linear advance. Most likely this fits into one of them.
My first guess would be, that those small segments in curves induce very small changes in speed at each junction, causing LA to increase and decrease advance steps over and over during the resulting, very very short acceleration and deceleration phases. Hard to tell without the GCode and STL, though.
@marcoburato Please be so kind to upload your configs and the part in question (GCode and STL). Do you see this using Classic Jerk or Junction Deviation?
I've prepared a minimal test case. Here's the STL, Gcode and my Marlin configuration. LA_noise_test.zip
I'm using Junction Deviation.
Thanks. If you have the time and motivation, please check if you see the same repeated reversing when running Classic Jerk.
Just tried Classic Jerk, it's different and less pronounced, but it's happening too. Probably not affecting the first layer though.
I've taken a quick look at the provided GCode and it's in the best possible way close to the most boring scenario you could test.
Overview
Y-axis zoomed in
Histograms
If everything was working correctly, this should not provoke any such quirks when using LA. Yet, it does.
My guess would still be that the main problem are the junctions and that there's a small speed change at each one. Those would then provoke LA to reduce/increase LA steps in the single digits. This is in line with the observation that JD makes this worse. JD tends to induce steeper drops and a higher variation in junction speeds than CJ due to the way it is computed.
I would also guess that you can reduce the "overly active" LA stepping by switching to 32 microsteps for X and Y. If you are interested, give this a try and test it.
@XDA-Bam
Haha, if JD introduce "small speed change", would it be possible to introduce both JD AND jerk (lets call it mini_jerk) by deciding that the next segment speed is the same as the current if
(next speed - mini_jerk) < current speed < (next speed + mini_jerk)
???
I am not sure of the cost in terms of instructions code... Nor could I produce such a code...
I've taken a quick look at the provided GCode and it's in the best possible way close to the most boring scenario you could test.
As a non-native English speaker, I'm not sure how to interpret that... I've tried to make the test as simple and short as possible. I hope it's okay.
I would also guess that you can reduce the "overly active" LA stepping by switching to 32 microsteps for X and Y. If you are interested, give this a try and test it.
My main board is an OEM Trigorilla, which AFAIU is a RAMPS clone with hardwired pins for microstepping and no UART for drivers, so I can't change the microstepping.
Also, I just now realise that I didn't point out I'm using TMC2008 drivers (can be seen in Marlin config though). Not sure if that causes any difference in the signals timing. I'm pretty sure that, even if it did, it would only cause this problem to happen at different speeds and segments length.
As a non-native English speaker, I'm not sure how to interpret that... I've tried to make the test as simple and short as possible. I hope it's okay.
Yes, exactly. It does test no more and no less than required. It is a good test 😃
My best suggestion is to port the latest Linear Advance improvements from Prusa Firmware into Marlin. They spent a lot of time diving into the meticulous details with an oscilloscope and they claim to have solved many issues.
Any updates on this?
any news?
any news?
The Pull Request queue is open, so we welcome your contributions!
I wish I had knew coding. :) @thisiskeithb , but unfortunately I don't, but as an enthusiast user follow the updates and upcoming news very closely. That's all I can do at least.
There have been some major improvements to how LA steps are generated in #24533. That PR could also improve the issue reported here. It would be good if those affected could test the latest bugfix-2.1.x and report back.
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.