Skip to content
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

[FR] Get Linear Advance + S_Curve completed and reliable #22547

Open
MarkusThur opened this issue Aug 10, 2021 · 79 comments
Open

[FR] Get Linear Advance + S_Curve completed and reliable #22547

MarkusThur opened this issue Aug 10, 2021 · 79 comments
Labels

Comments

@MarkusThur
Copy link
Contributor

MarkusThur commented Aug 10, 2021

Is your feature request related to a problem? Please describe.

This feature request, or better first Request for discussion, is related with the issue described in #14728 [BUG] Linear advance incompatible with S-Curve acceleration

If I see it right this issue is not solved, except by the sanity check that warns / throws a error if you enable LIN_ADVANCE and S_CURVE_ACCELERATION without marking you explicitly want it by activating EXPERIMENTAL_SCURVE at the same time. Where EXPERIMENTAL_SCURVE does not activate any special s-curve feature, just only marks that you definitely want it.

I use https://github.com/knutwurst/Marlin-2-0-x-Anycubic-i3-MEGA-S, which relies on Marlin 2.0.5.4 on a Anycubic Mega S.
There Linear_Advance and S_Curve are activated by default and work very well. The described problems are not seen.

Problem observed is (that obviously) the time prediction is a mess, as triangular movement is exspected and S-Curve Movements are obviously slower.

But Linear_advance with a K factor of 0.51 works well with printing speed of 50 to 70 mm/s, as well as printing acceleration of 3200 mm/s^2 is possible without interfering with print or causing strange "sound" of the extruder. Starting with a print acceleration of 3600 mm/s^2 the print gets a little "dirty" as the break is to hard and causes vibration / resonance, but does not cause issues on the extruder.

Travel acceleration even up to 4500 mm/s^2 is possible, but 4000 mm/s^2 travels more nicely and vibration / resonance on brake is absorbed without hampering a print at travel speed of 120 mm/s. Faster travels are possible, but may end in step losses of the bed and / or imprecise positioning at end-position.

Are you looking for hardware support?

NO
Nevertheless, related with statement above is following hardware:
Anycubic Mega S with:
Trigorilla 0.0.2 board, using a ATMEGA2560
TMC2208_standalone Steppers
So obviously S_Curve + Lin_Advance is possible on a AVR Controller, or was possible till 2.0.5.4

Describe the feature you want

What I want to do / the feature to be requested is as follows.

  1. Look into the issue, especially what may changed between there and now in S_CURVE and / or LINEAR_ADVANCE

  2. Discuss potential solutions (independent if it works together or not, there is a issue in time prediction of the S_CURVE and therewith the point where LIN_ADVANCE has to start doing it's work)

  3. Implement the solution

Additional context

From a first feeling, the main issue is the longer and "hard" to predict time an S_CURVE accelerated movement will need.

The S-curve accelerated movement takes a longer time, as the maximum acceleration of the S_CURVE is the same as the one of a "triangular" movement. In worst case, the S_Curve is not even able to reach max. speed and does not reach maximum acceleration, similar to the "normal" triangular movement, which at some point is not able to reach travel speed, before braking has to start. But this point is obvious earlier for S_Curved movements.

But for any S_Curve accelerated movement, there is a "corresponding" triangular movement, that has the "same" timing,
e.g. a triangular acceleration from 0 to 50 mm/s with a acceleration of 2500 ,mm/s^2 obviously needs 0.02s to reach the max speed and will travel 0.5mm during that time. (exact half of what it would have been at full speed, or an unaccelerated movement with 25mm/s). An S_Curve accelerated movement with a max_acceleration of 2500 mm/s^2 will need a little longer due to the lower accel at the beginning and ending of the acceleration phase,
For ease of explaination I use a Z_Curve with following parameter,

form 0 to 12.5 mm/s use 1250 mm/s^2 (accel/2)
from 12.5 to 37.5 mm/s use 2500mm/s^2 (accel)
from 37.5 to 50 mm/s use 1250 mm/s^2 (accel/2)

This way we will need 0.3s to reach travel speed. And the moving distance will be:

distance after each Phase of the Z:
s(0.01) = (0.5*1250*0.01*0.01+0+0)mm = 0,0625mm
s(0.02) = (0.5*2500*0.01*0.01 + 12.5*0.01 + 0.0625)mm = 0.3125mm
s(0.03) = (0.5*1250*0.01*0.01 + 37.5*0.01 + 0.3125)mm = 0,75mm

This exactly equals an unaccelerated movement with 25mm/s for 0.03 seconds. so this also shall equal a movement with a linear acceleration of:

(50mm/s)/0.03s = 1666.66mm/s²
s(0.03) = (0.5*1666.66*0.03*0.03)mm = 0.75mm

So the idea is, to either

  • calculate the equivalent acceleration of the S_Curve and use it in Linear_advance
    or
  • to calculate a S_Curve acceleration that is equivalent to the triangular acceleration imposed by the desired acceleration.

Advantage of solution one is, the set max_accel is not exceeded, disadvantage is, time prediction for the total print still stays a mess.
Advantage of solution two is time prediction of the print does not need to know if it is S_Curved or not, disadvantage is the max Accel is exceeded by the "form factor" of the S_Curve.
Solution two imposes, that the max_accel of printers, that already use S_Curve, would have to reduce their max_accel value, as it now would represents the "equivalent" acceleration instead of the real acceleration.

Both solutions could be implemented in a first approach, using the EXPERIMENTAL_SCURVE flag, which would give the flag a more "useful" meaning.

I am happy to hear your opinions on it.

@MarkusThur MarkusThur added the T: Feature Request Features requested by users. label Aug 10, 2021
@MarkusThur MarkusThur changed the title [FR] (feature summary) [FR] Linear Advance + S_Curve Warning, Discussion on potential solution Aug 10, 2021
@RipperDrone
Copy link

RipperDrone commented Aug 10, 2021

wow, wasn't aware that EXPERIMENTAL_S_CURVE was just a flag for the time being, never checked other occurrences of this flag in the code :-)

I'd go with option 2 - having a reasonably accurate print time prediction seems important to many users. On the other hand, redefining accel as effective accel seems a reasonable price to pay...

Curious to see what others are thinking...

PS: Yes, my Ender 3 V2 is acting up with weird sounds if I play around with K values in LIN_ADVANCE at high accelerations... (S_CURVE commented out)

@thinkyhead
Copy link
Member

The feature is still experimental in the sense that this post represents one of the few confirmations we have that it is behaving okay and not causing strange issues. Any improvements to this feature to make it more robust will be much appreciated. It would be especially useful to put a scope on a variety of 8- and 32-bit boards to observe how XYZ and E behave together and to see the effects of various adjustments. The time I personally have for testing is limited, due to general management of the project, so any help in the area of testing and refinement of these kinds of details is also much appreciated.

@thinkyhead thinkyhead changed the title [FR] Linear Advance + S_Curve Warning, Discussion on potential solution [FR] Get Linear Advance + S_Curve completed and reliable Aug 10, 2021
@MarkusThur
Copy link
Contributor Author

@thinkyhead
Thank you for the answer. As I am in the lucky position to have a 8bit Trigorilla and a 32bit SKR Pro aviable and was going to test the behaviour of both with the same mechanics anyways, I will go on and and look deeper into it.
@RipperDrone
Let me think about it, cause from what you say the issue of "wired" sounds is maybe not related with the combo of S_Curve and Lin_advance, but in LIN_ADVANCE itself or maybe in "unsuitable" settings for the mechanics at all.
Can u tell, where the strange noise comes from (Extruder-Stepper, X-Stepper, Y-Stepper, bearings, whatever)?

@RipperDrone
Copy link

@MarkusThur sure, sound is limited to extruder (Hemera direct drive). Comes from hard retraction moves. More pronounced at higher extruder accels or feed rates, looks like I have to stay below 25mm/s retract speed. NO noise at retraction = OFF. Therefore, I was assuming that IF accelerations in all axes are ramped over S-shaped curves, extruder / filament should 'see' lower effective accels / speeds and run more silently...

@MarkusThur
Copy link
Contributor Author

@RipperDrone thank you for your input, this fits to what I am asuming, and will look for in the code. 25mm/s shouldn't be too much, especially as you shoudn't need much retraction on a Herma anyways, and with Lin_Advance the needed retraction of a direct extruder should go to nearly 0. On my bowden the needed retraction reduced from 6.5 to 7.5mm to 1 to 1.5mm, as Lin_Advance already reduces the pressure in the nozzle and relaxes the material in the bowden. On a direct drive the effect should be much higher, bringing the needed retraction close to zero.

So I suspect there is something going on, that leeds to multiple direction changes while advancing Linear and then retract, which should not be.

I'd like to see your settings (and the one the slicer may do) for Ejerk, and Eacceleration and the K value for linear advance. to exclude that wired settings cause it.

Normaly a retract should even be "easier" as the material already got "riffled" by the forward movement and the grip is better than the on "round material" and the "counterforce" is close to zero, as it does not need to push the material through a tight nozzle.

If you can, maybe a screen or copy of the printers answer to M503 could help us both.
Does your printer retract smoothly for material changes?
And how about the K-Value is it sufficient?

@RipperDrone
Copy link

RipperDrone commented Aug 13, 2021

@MarkusThur Thank you. Pls find my 503 gcode response as follows:
M503.zip

It has to be noted that I tuned down accels and feedrates to suppress the annoying retract noises. Going back to higher values will trigger them again...

K=0.04 is very moderate, setting higher K values will ruin the K factor test print (no continuous line on accelerations and decelerations). xyz test cube still has overshoot corner edges, so seems printer needs higher K, however I cannot test since the retract issue spoils the prints when I try...

Printer loads and unloads filament smoothly, PTFE tube has no increased friction, gripping spring force set to "normal" in Hemera (flush to surface) but tried min to max as well.

Jerk is set to Marlin stds (8,8,.4,5). Tried higher and lower values as well...

@MarkusThur
Copy link
Contributor Author

@RipperDrone I looked into it, on first view nothing directly strange. On second view I have some questions to your settings:
The E feedrate is limited to 10mm/s, the Hemera should even run better than a Titan, so 45 - 50 should be doable.
Your X,Y speed is pretty high, a normal setting, bur i think only deltas do reach that high speed without issues.
Your Acceleration is aprox 1/10 of what I usually see, while your jerk is normal... This maybe part of causing noises, your extruder on a speedchange may just only jerk. (just a guess). And if you use cura, cura overwrites your settings for X and Y acceleration and that then may interfere with the max accel you did set for the extruder,
And in the last sector i found Stepper current... Not sure which steppers u use, but If I am not mistaken, M906 is for TMC steppers, so TMC2208 and better in UART mode.... You may should check your motors, usual Nema17 motors have a rated current between 1A and 2A (some smallers and some high power with 2.8A exist).
The original E3D hemera comes with a 1.33A rated Motor, so a setting up to that should be OK. Same counts for your other motors.
Especially, I can't believe that your high speed and low accel does fit with your extra low current limits.
And there I fear we come to the noise production on a retract.

@RipperDrone
Copy link

RipperDrone commented Aug 14, 2021

@MarkusThur Very interesting, you might be up something there... let me follow up:

  • E feedrate had been set to 50mm/s default, but the clicking sound caused me to reduce it step by step, hitting a more silent range at this low a setting. Hemera is capable of up to 45mm/s for feed/retract speeds, their manual says.

  • x, y speeds are as per Ender 3V2 defaults, however in Cura max speeds are reduced further:
    image
    Anyway what would be a reasonable recommended range - I can try setting it in the firmware as default and/or saving lower values to EEPROM

  • I am using SKR 2 E3 Mini with TMC2209 drivers in UART mode

  • stepper current is set as per Hemera manual: 1.33A max amps, reduced by a safety factor of 10% and RMS'ed to get effective current. Therefore, 940mA is the correct setting. Other stock Ender 3 V2 steppers have been set to 800mA initially (as per Crerality MArlin profile), when stepper motors got quite hot I followed some guides recommending values around 540-650mA

  • These are CURA printer tab settings, just for information:
    image

In a nutshell, what you'd recommend trying out is 45mm/s E max feedrate and reduced xyz speeds (down to to which values) to rule out that the screachy-eachy noise has to do with accel settings? :-)

@MarkusThur
Copy link
Contributor Author

MarkusThur commented Aug 16, 2021

@RipperDrone
Then let's try following;
Your calculation for the steppercurrent is right, if Irms is set in the register of the TMC 2209. Am not 100% sure, if it sets Irms or Imax in the internal registeres. But as I understood, this value is supposed to be the RMS value https://teemuatlut.github.io/TMCStepper/class_t_m_c_stepper.html

Concerning your other motors, if the original steppers were TMC2208 in UART mode, set to 800ms RMS by firmware 800ms should be fine also with the 2209.
If they were in step/dir mode with a value of 800mV, then your calc to around 560 to 570mA RMS is right.

https://reprapworld.com/customer/service/technical_information/adjusting_stepper_driver_current_on_the_ender3_v2/
They recommend a voltage setting of 1.22V for Step/Dir from the original board. Which means 860 to 870mA RMS. So 800mA rMS for those motors shall be fine. A Temperature of the Motor of up to 60°C is also fine. (a little hotter still is doable)
Simple rule for motors, if it's hot, but u can touch it, it's in the limits.

And now we come to difference between Cura setting and firmware:
setting your firmware Cura
M203 E10.0 E40.0
M201 E1000.0 E2000.0

So cura tries and maybe even uses 4x the max speed, you limit in Firmware and 2x the accel you did set the firmware limit to => It's unsure, what will be done.
I'd first of all recommend to have both same to make sure, it happens, what u think is happening.

I just came to another idea also, I will try to visualize it. In principle I have the feeling, with your settings, the printer never leaves the accel and decel phases.

As I am working on a way to easily visualize the movement in general in order to get a better idea on what happens.

@MarkusThur
Copy link
Contributor Author

MarkusThur commented Aug 16, 2021

Got a visualisation for trapezoid accelerated movement. (on S_curved movement, I'm still working).
https://www.desmos.com/calculator/isogmb9uzz?lang=de
I did preset values from your screens.

a9999 = max x/y acceleration 500 mm/s^2 
v9999 = max spped 500 mm/s
s3 = distance we wanna move
j = X/Y jerk 8 mm/s
v00 = start and endspeed

This may help to figure out, what may cause the noise / supresses the noise in your extruder. with your current settings, you need:
a 14mm movement to change from 50 to 100mm/s and back. Otherwise you do not leave accel / decel phase.
to come to your print speed of 50 / 100 mm/s from a standing and come back to stand you need movement length of
5 / 20 milimeters.
To reach your travelling speed, you need a 125mm move, so half your bed.
With S_curve_Movement this even seem to be a longer way, but this is where I am looking into atm.

Am pretty sure that there something wired is going on in combination with linear advance, as we definitely run into limits.

@RipperDrone
Copy link

@MarkusThur Thank you so much for your time you are putting into this - even not being 100% sure yet whether I am facing a general S_Curve accel issue or mismatching parameters. Let's see, here is my follow-up:

  • TMC RMS current setting: Pls refer this document, I think it's solid: https://e3d-online.zendesk.com/hc/en-us/articles/360016249057-Hemera-Current-Adjustment-PDF-
  • other axes: I had them set to 800 stock, no change. They were in step/dir mode. Now set to UART/STEALTHCHOP mode:
    image
  • difference CURA vs firmware: I was under the impression that EEPROM values overwrite firmware fallbacks, and CURA for each print job overrules EEPROM. MAybe this assumption is wrong. Anyway, responding to your hint directly: I tried to set both firmware and Cura to same values, extruder speed was down to 10mm/s, so was accel. Then increased in CURA only, and speed/accel was actually increasing, up to a point when the weirdo screetchy noise was back. Hypothesis seems proven, CURA overrides firmware.
  • hehe, keeping the printer busy accelerating and decelerating, never giving it a chance to settle on a constant speed - I like that image, maybe there's more to it :-)

@RipperDrone
Copy link

RipperDrone commented Aug 16, 2021

Thank you for the little trajectory/kinematics helper tool, gives valuable insights. Is this leading to an assumption that the printer NEEDS to move at constant speed over a certain distance to make screetching sounds disappear? If so - yes, S-curve should cure it as well since it chops off the abrupt change of sign in accel, doesn't it?

Or r u recommending I should try

  • some less aggressive settings for speed OR
  • more aggressive settings for accel in the first place?

Of course I'm after min printing time as an optimization goal like everybody else, and the current time/quality tradeoffs seems pretty much ok... would not want to see printing times skyrocket :-)
image

@MarkusThur
Copy link
Contributor Author

MarkusThur commented Aug 17, 2021

@RipperDrone
I tonight also had those wired sounds. And some more thoughts on it. And now I see you print, which is pretty nice.

What I had is, I generaly use arcWelder in order to reduce G-Code Size and find curves are a bit nicer with it, then if cura decides how to square a circle. But yesterday I printed something with a lot of different curves, leading to slow down due to calcs not fast enough and then I got first time strange noises from the extruder during those slowed down curves. Then I printed same thing without arcWelder post processing, Problem gone. Maybe you can do something similar to increase or decrease CPU load.

So whats suggestion:
-On a potential issue in code, am working on it, especially from creating visualisations of what happens, I found out that I not only sometimes had a "thinking" mistake.

  • CPU Overload obviously causes it. Reduced speed improves that, so you may want to deactivate Lin_Advance by K=0.00 and see where you end up with speed and acceleration (and if i makes a difference). @thinkyhead there will be a difference between 8-bit and 32-bit systems.
  • I (you may also) will check if Junction derivation instead of classic jerk does a difference. I asume JD needs more calc, so the extruder may get worse
  • And last thing (or better first) check the mechanics of the extruder, especially the bearings. You may have a look how they designed it, especially the way the use the IGUS bearing. If those are in good condition the hemera really should run well and much better and less noisy than the full metal Titan clone I use. If they have wear already and higher tolerance this also may cause noise and replacing them is "pretty" cheap. The most expensive on them is the handling and transportation to you :-)
  • somewhere (i think its in the code comments) I found a suggestion to reduce communication speed on the USB connection in order to get more CPU capacity for calculations.

@RipperDrone
Copy link

RipperDrone commented Aug 17, 2021

@MarkusThur Exciting - never used ArcWelder but found somewhere that it is not recommended to use it along with LIN_ADVANCE due to some alias / interference effects. CPU load is something to look into, however with my 32bit board and not overly complicated contours I'm not sure this is the direction to chase suspects - wierd noise even happens on a simple xyz cube! Which rather leads me into a direction of incorrect handling of accels / decels in conjunction with extruder feed + particularly extruder retracts. I tried to simplify the model in Windows 10 3D Builder (e.g. from 10k splines to 700 splines for model approximation), but the issue persisted.

  • deactivating LIN_ADVANCE by setting K factor to 0.00 is worth a try, I'll do
  • using junction deviation instead of classic jerk I tried once, didn't really help - priner was acting up quite similarly for both settings
  • I have taken the Hemera apart completely once the issue showed up first since I suspected a mechanical issue in the first place. Full metal dual gears and bearings were in pristine condition, couldn't see anything abnormal causing wiggle / noise
  • USB connection speed change is a completely new thought. I did play around with buffer sizes for UART communication, Marlin baudrate for SKR is at 115k default.

Will do some further tryouts at different settings and report back if any new findings materialize :-)

@MarkusThur
Copy link
Contributor Author

MarkusThur commented Aug 18, 2021

@RipperDrone
Where we are at the beginning point. :-)Something strange / unexspected happens. But I think it's good to talk about it. And once I am prepared, with the thoughts on how it should be, I will look the code what it does.

So from my suggestions only one stays for you, a tryout with deactivated LIN_ADVANCE as the others you already did.
And for me, I have to get my SKR Pro running to compare the behaviour of the STM32 to the ATMega.

(hope we don't bore all that that are notified on this, but I have the very hope, this will create the right idea.)
As obviously, getting LIN_ADVANCE, S_CURVE_ACCEL and JUNCTION_DEVIATION to work at the same time is the right thing for optimum corners.

In order to have same understanding what those options do I summarize, what I understood, they should do:

LIN_ADVANCE:

Reduces / Increases the nozzlepressure on accelrations / decelerations, as this is not a simple linearity to the movement, because of compression / decompression of material. Therefor it predicts the needed additional movement of the Extruder by the K factor.

S_CURVE_ACCELERATION:

Does a S_Curved acceleration profile instead of the "simple" trapezoid. This gives a more smooth movement, but is more difficult to calculate and predict. It's "unknown" how exactly the S-Curve is formed, but this is readable from the code. S-curved acceleration is a typical technic to get better movement profiles for all kinds of electrical motors, as the "impossible" dirac impulse on the change of accel, is not only transformed by the characteristics of electronics and mechanics, but by reducing it. This shall and does reduce resonancy and swinging caused by it. There is no "user influencable" factor to influence how the curve is formed at the moment.

JUNCTION_DEVIATION:

Is a concept how to approach / calculate the cornering speed for different corner angles, especialy corners that are not nearly a straight or a nearly a return.
In short, it calculates a "ideal line through" the corner, where the derivation between real corner and the shortcut is the factor to be set.
It calculates the maximum doable speed on the curve, by assuming that max accel equals max lateral accel.
But then does not drive this line that derives from the "real" corner, just uses the speed calculated for the shortcut as the speed at the corner point.
This should lead to exactly classic jerk on 90° corners if settings for max accel and JD are choosen right.
larger JD leads to faster corners, smaller JD to slower corners.
larger accel leads to faster corners, lower accel to slower corners.

@RipperDrone
Copy link

RipperDrone commented Aug 18, 2021

@MarkusThur You seem to be as obsessed with optimizing things as I am :-)

Tried to set K factor to 0.0 (has been @0.04 only before), and printer got completely silent in retract moves, even at high extruder retract speeds of 40mm/s retract and 45mm/s re-feed. Print speed still @100mm/s x-y. Accels 500, 500, 100. Jerks 10, 10, 0.3, 5. Retract set to .4mm which was optimum acc retract tower test.

Results of xyz test cube quite good, need to reduce z offset a bit, first layer needs to be more dense. Main challenge is overshoot at cube edges at higher speeds, this is why I tried to get my head around LIN_ADVANCE. Didn't find an effective way of really un-bulging the edges. Maybe choosing super-low jerk values could be an option, but then printing times become very long.

Getting a good combined S-curve mode working along with LIN_ADVANCE would do the trick, I suppose. Any other thoughts?

image
image
image

@RipperDrone
Copy link

RipperDrone commented Aug 18, 2021

Tried another run with halved jerk values, looks exactly same. Taking edge un-bulging to next level will require LIN_ADVANCE (and S-Curve smoothing), I suppose...

@MarkusThur
Copy link
Contributor Author

@RipperDrone
I continued testing and calculations during the week.
Yes, Lin_advance shall and does remove the overshot on edges. if you want to reduce without linear advance, the trick is a "higher" Jerk. Using JD instead of Classic jerk also may help a bit, but Lin_advance is the trick inavoid the overextrusion in the corners.
Now what I found, I could also make my extruder doing "noise" by having fast "direction" changes short after each other. But it was not directly the extruder, it was the fillament that started to vibrate like a guitar string.
So I got a idea and did some calcs on what should happen, still without checking the code if this really does happen.
Before I explain it, the summary in order to not force everybody to read the details:

  1. Lin_Advance may lead to a retract.
  2. If you change directions fast, this has to lead to a vibration of the fillament and maybe even more parts.
  3. especially on direct extruders the movement of fillament imposed by the release and recompression acording to LIN_ADV settings maybe that short, that it is shorter than the Gearbacklash of geared extruders like the Titan or the hemera. Doing forward and backward movement shorter than the gear backlash, especially if done in short after each other must lead to "strange" noise.
  4. a way to reduce that is already implemented by setting the XY_FREQUENCY_LIMIT in configuration_adv.h https://hydraraptor.blogspot.com/2010/12/frequency-limit.html It is intended to adress something else, but as a side effect also limits the frequency of the extruder doing the decompression / recompression.

What you could check please is, if strange sounds also occur, if you use Linear_advance but do not use S_Curve_Acceleration.
From what I suspect the sound also should be there, but not that loud hearable.
This especially with short and fast infill moves.
Please there try also much higher acceleration values, maybe not the 3200 i use, but 1800 should be fine

Now the calculations to that:
Asuming linear_advance, 1.75mm fillament, 0.4mm nozzle and 0.2mm layer high, 0.4mm line width, trapezoid acceleration and a printing speed of 50mm/s.
and we do it for a K-factor of 0.04 like you have on a direct drive and 0.51 like i have on a bowden. and we will do it for 3200mm/s^2 and 500mm/s^2.
For ease of calc, we will asume XY jerk infinite close to 0 and Extruder allowed to jerk as it needs. :-). We will use 400 steps/mm for our extruders instead of the 384 it really needs, also for ease of calc.
fillament_feedrate(printing_feedrate) = (p_FR*0.4*0.2)/((d/2)^2)*Pi) = 1.667 mm/s = 665.2 steps/s
the time to decellerate to 0 is:

t=v/a
t=50/500=0.1s
t=50/3200=0.0156s

the distance during the decelleration is:

s=50/2*t
s=2.5mm
s=0.391mm

therewith the volumina to be printed is:

V=s*0.2*0.4
V=2.5*0.2*0,4=0.2mm^3
V=0.391*0.2*0.4=0.03128mm^2

this needs a fillament feed of

feed=V/((1,75/2)^2*pi)
feed=0.2/2.405=0.0831503376154mm=33.26Steps
feed=0.03128/2.405=0.013004712803mm=5.20 Steps

for the decompression the k value says, you have to substract following from the needed steps:

deduction=k(v1-v0)*steps/mm
deduction=0.04*(50)*400=2*400=800steps
deduction=0.51*(50)=25.5*400=10200steps

both values are bigger than the needed extrusion, so it has to come to a "retract" during the break. and a additional feed during the following acceleration e.g. on a 90° corner or a return move like during infill.

5 - 10200 steps are quite many, and much more than the gearbacklash of the extruder, the stepper (with 1/16 microstepping) 3200 steps are a full turn, so it will do aprox 3 full turns backwards, this is a lot of movement.
800 - 33.2 767 steps to turn backwards, what is obviously only aprox 1/4 turn backwards only. A quarter turn back and fort in 0.2 secs should not make strange noise... as you say.
But with accel 3200 the extruder needs to do a quarter turn back and forth in 0.03seconds. there we most probably will and do hear the backlash of the gearing.
And now we do this fast on a short infill reverse moves. It has to vibrate.
So it also should happen on linear advance without S_Curve....

And so I am more close to what exactly I should look at. Most probably, the "retraction" will not be done, where the decel starts and then the needed value will be feeded nor it will retract and coast to the end i asume.
The idea, I would have is to linear share the retract over the distance. So retract the 10215 steps over the 0.015s, repectively the 767 steps over the 0.1s.
And most probably it uses the actual moving speed to determine the extruder speed. and there we come where this can or should crash with S_Curve... while with triangular movement it will reverse at a constant speed.7670 steps / second. having to yerks during it.
with S_Curved accel the speed should change during it. Doing a high retract, while deceleration is low and nearly no retract while decelleration is high. This depends, how the linear advance exactly is calculated.
Both are able to make the "sound" louder.

Thanks a lot, as I now get a idea where to search.

@MarkusThur
Copy link
Contributor Author

MarkusThur commented Aug 20, 2021

@RipperDrone
admentment from observing my printer, now knowing, what I wanna look for:
Higher Jerk leads to less / no retract from Linear advance. Slower speed leads to less /no retract needed. obtuse angles, need less retract, acute angels need more retract.
I can even see this if I observe the movement of the fillament, as I with k0.51 can see the 25,5mm of fillament moving. your 2mm are maybe not even seeable

@MarkusThur
Copy link
Contributor Author

@RipperDrone
@thinkyhead
After I changed my bearings on the Extruder today as I wanted to test something, I was "able" to produce "strange" noises with it on retracts.
Or more exactly on direction changes of the fillament, independent if they are from Lin_Advance, a planned retract or a fillament loading / unloading. But the retracts from Lin_Advance happen "most often" so it's free first point to recognize them.
So what happened:
I tried and was successful in making my idler arm more powerful and more precise in reducing its clearance at the joint. At same time I changed the bearings of the drive shaft as they already showed wear.
This together now leads to some kind of a "spring load and sudden release" effect, especially if I grab the fillament more tense for more grip, making exactly that noise, which is in principle exspectable on sudden direction changes.
So from what I have now, there is no issue between Lin_Advance and S_curve, but a issue Extruders may have with "retract" in general. This issue should be there always when there is a retract...
What I will look for now is, why it is more obvious and from my feeling louder on a retract caused by the combo of Lin_Advance and S_curve, than on Lin_Advance only. And what exactly of my changes in the mechanics of the Extruder made my Extruder start making the noise. But I think I already know what it is, I reduced the clearance of the idler wheel to much, so it comes to a slip-stick effect loading the spring of the idler. And then when moving finally releasing it. Causing the sound.
Alternatively I didn't align the wheels of the gear (titan and hemera are geared) properly / changed the alignment a bit and the teeth jump over. (also would produce that sound).
I will report on that.
But in general, from what I found till now, I don't see a issue in the combo of Lin_Advance and S_curve_acceleration... (except that "improper" mounted or designed Extruders don't like retracts). But that's not a issue from that combo of options, only that combo may make the weakness more visible / hearable.
From printing results point of view, Lin_Advance + S_Curve_Accel definitely give the best and fastest corners I ever had and those even should get better with Junction_Derivation if used right.

@MarkusThur
Copy link
Contributor Author

MarkusThur commented Aug 21, 2021

@RipperDrone
UPDATE: Got rid of the noise again. The reason was definitely that the drive shaft (in your case you have drive shafts on both sides) was not able to perfectly follow the retract moves. As I reduced its clearance by the new bearings and closing the case too tight.
So for your issue you should make sure that you mount in a way that your drive shafts can move freely.

@RipperDrone
Copy link

RipperDrone commented Aug 22, 2021

@MarkusThur That's a lot of new findings, my sincere admiration for your endurance to chase this noise :-) Seems you are homing in on mechanical gear / gap tolerance settings. I can only state that my Hemera was brand new when the noise started (from Day 1 already), and when I took it apart, I checked that the gears could move freely but were sitting snug without any wiggle. It could actually be some close combing of drive shafts (and filament), and I agree it is stronger when combined with LIN_ADVANCE, but also happens on retract only IF retracts are too big in distance and/or too fast for the given retract distance. I'm still not 100% sure we are talking the exact same noise on our printers... to me the Hemera retract sounds like it is jerking in the retract moves, maybe it's even in the re-feed part of the move where filament can not be molten/softened enough at high feed speeds, so it chokes from trying to push solid material through the nozzle. I tried raising temps by 20K, didn't help, though...

@RipperDrone
Copy link

RipperDrone commented Aug 22, 2021

@MarkusThur found this video - noise is not recorded well and not exactly with the screetchy undertone, but this is exactly what I observe as well. Just a little more screetchy the faster I go :-) Is this exactly what you can reproduce as well?
https://www.youtube.com/watch?v=8YDNU6U_mHg&ab_channel=RonnyVed%C3%A5

Whereas this is NOT the noise we are focusing on:
https://www.youtube.com/watch?v=1ki-FwlVs7k&ab_channel=RichardGoiser

@MarkusThur
Copy link
Contributor Author

MarkusThur commented Aug 22, 2021

Yes and no... We are definitely not locking for that noise from the second video. That one obviously is jumping gear wheels and a issue of wear or bad assembly of the Extruder.

The noise I could produce was a little more obvious and a little more "spring like" but yes exactly that.
The noise in the first video is maybe even inside or short outside the limits for a fast retract and unretract move like Lin_advance imposes in every corner that is faster than XY jerk.
And it will sound even more wired if this let's call it "clong" occurs two times fast after each other while approaching and leaving the corner.
And it is definitely a issue of the clearance of bearing and drive shaft.
Look at the video, you hear it two times before and after each travel move. And with Lin Advance you will hear it on every corner that is approached faster than jerk. This is the idea of Lin_Advance.
You may even hold the fillament with your fingers a bit, in order to feel it..
The sound in the video may even be not produced by the Extruder, but by the fillament spool as mine e.g. With that nearly 20mm coming back reverses also a bit and then unreverses

Screenshot_20210823-003330

This shot is from the hemera video of E3d. You see the two shafts, the Igus bearing and the normal bearing on the other shaft.
What I did when I got that nose on my titan clone, I replaced the normal bearings by igus ones and then locked the face plate too tight. (in case of the hemera the cooling plate). This disturbed the clearance and alignment of the shafts and wheels.
They have to have a little but not too much clearance..
Also wear on ball bearings or even the igus one may produce the sound..
So what I would try in your place now, as you say, your bearings look OK, is closing the cooling plate tight, but not too tight. That at least helped me to get rid of the issue again

From my view, the hemera must be even more sensible to that issue, as it has two pairs of wheels and two drive shafts that have to align properly and work together while having the chance of being canted or locked.

@MarkusThur
Copy link
Contributor Author

MarkusThur commented Aug 23, 2021

@RipperDrone
What exactly i did, was loosening and retigthening the screws while I was printing something with lots of retract, but that will not work for you on a moving head :-).
So you should try if you can produce the sound with a custom GCode file, doing retracts and unretracts and then loosening and retighten the screws of the cooler plate.

@RipperDrone
Copy link

@MarkusThur Hemera has a no-wiggle transition fit roller bearing for the shafts, therefore tolerances should be quite precise. Anyway it makes sense that I might be able to slightly adjust the gear meshing tolerance (center distance) by losening and retightening screws under some gear load. Not sure I'm up for this after having disassembled it and put everything back together only 2 weeks ago... for now I found an acceptable balance of low k factor (0.02) and some higher retract speeds / accels so the noise is at least softened somewhat. Print results are good enough, overshoot still occurring, I'l trim jerk (if classic_jerk) or junction deviation (otherwise) a little more and will then try to make my peace with the remaining noise. At least until some new feature involving an S-curved acceleration comes up - sacrificing a little printing time for smoother moves and longer lasting gearing. :-)

@tombrazier
Copy link
Contributor

Hold on @thisiskeithb, it's not quite resolved yet. But #24533 brings it a lot closer. It's easy now - by which I mean it is easy to see what needs to be done. But there is some tightly optimised assembler to modify. Will need another PR.

@thisiskeithb thisiskeithb reopened this Jul 21, 2022
@ejtagle
Copy link
Contributor

ejtagle commented Oct 3, 2022

@tombrazier : I was the one who wrote the Bézier curve code in assembly. I have read that Linear Advance could work with it, if the _eval_bezier_curve() function could also calculate acceleration.
I see at least 2 ways to accomplish it: Direct evaluation of the formulas;

V_f(t) = A*t^5 + B*t^4 + C*t^3 + F => This is the Bézier curve that is evaluated. It returns speed (in steps/second)

If we need to get acceleration, we should differenciate that formula respect from time:

A_f(t) = t^2*(t*(5*A*t+4*B)+3*C)

That is the expression to compute, assuming we want to get acceleration in steps/second^2

5*A , 4*B, 3*C all are constants, so can be computed just once:
A_f(t) = t*t*(t*(5A*t+4B)+3C)

This eventually requires 4 extra multiplications, and 2 additions.
The original code to compute speed required 8 multiplications, and 3 additions. Computing acceleration would add 4 extra multiplications, and 2 extra additions, slowing down the computations 50%. For 32bit boards, this is absolutely an non issue, but for AVR, i am not sure if it is important or not: The code would take approximately 150*1.5 = 225 cycles to execute.

The other question is the exact acceleration units needed for linear advance computations...

@tombrazier
Copy link
Contributor

@ejtagle Your name is familiar to me from exploring your code, which is excellent.

I was planning to differentiate the polynomial as you suggest. I am running on an AVR and it has a fair bit of processor capacity still available after some optimisations so I am somewhat hopeful. Anyway, the main thing was that it was hand coded in assembler and I just needed the time to modify that. With one thing and another I haven't got round to it yet.

LA needs the same units as the rest of the stepper code, steps and seconds. In this code and the similar deceleration code, the variable current_block->la_advance_rate needs to be replaced with acceleration (in steps/s^2) * K factor (which the planner could populate into current_block.

#if ENABLED(S_CURVE_ACCELERATION)
// Get the next speed to use (Jerk limited!)
uint32_t acc_step_rate = acceleration_time < current_block->acceleration_time
? _eval_bezier_curve(acceleration_time)
: current_block->cruise_rate;
#else
acc_step_rate = STEP_MULTIPLY(acceleration_time, current_block->acceleration_rate) + current_block->initial_rate;
NOMORE(acc_step_rate, current_block->nominal_rate);
#endif
// acc_step_rate is in steps/second
// step_rate to timer interval and steps per stepper isr
interval = calc_timer_interval(acc_step_rate << oversampling_factor, steps_per_isr);
acceleration_time += interval;
#if ENABLED(LIN_ADVANCE)
if (current_block->la_advance_rate) {
const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
la_interval = calc_timer_interval(acc_step_rate + la_step_rate) << current_block->la_scaling;
}
#endif

@tombrazier
Copy link
Contributor

Do you fancy doing the assembler code work?

@ejtagle
Copy link
Contributor

ejtagle commented Oct 14, 2022

Do you fancy doing the assembler code work?

I could do it. The main issue here is getting sensible units, because the ASM is using fixed point to compute things.
There is an alternate way to do it, just computing acceleration from speed differences, but that requires a division... So not sure if it will be a win to do it that way...

@tombrazier
Copy link
Contributor

tombrazier commented Oct 14, 2022

I didn't like the cost of the division either which is why I have not explored that option.

However it has suddenly just struck me that there doesn't need to be a division. The time interval between calls to Stepper::_eval_bezier_curve() is the inverse of speed! So acceleration = (speed2 - speed1) * speed1. This is slightly complicated by ADAPTIVE_STEP_SMOOTHING and multi-stepping but the same thing holds: the division can be replaced by a multiplication.

@thinkyhead
Copy link
Member

ADAPTIVE_STEP_SMOOTHING

Fortunately, this just doubles (and doubles), so somewhere in there a shift operation using oversampling should be able to compensate.

@tombrazier
Copy link
Contributor

Indeed. It's in Stepper::calc_timer_interval().

I'll finish my work on IS first and then hit this. Hopefully will be quick.

@ejtagle
Copy link
Contributor

ejtagle commented Oct 18, 2022

I didn't like the cost of the division either which is why I have not explored that option.

However it has suddenly just struck me that there doesn't need to be a division. The time interval between calls to Stepper::_eval_bezier_curve() is the inverse of speed! So acceleration = (speed2 - speed1) * speed1. This is slightly complicated by ADAPTIVE_STEP_SMOOTHING and multi-stepping but the same thing holds: the division can be replaced by a multiplication.

You are right. There is already a division done in code... Do you want to smile a bit ? ... ;) ... I also was the one that implemented the function get_period_inverse() that calculates 1/d using a fast newton-rapson iteration xD ... I just forgot about that ... If needed, that routine could also be reused, but you are right. Time is the inverse of speed, and also, as @thinkyhead said, ADAPTIVE_STEP_SMOOTHING uses integer factors (yes, I was also the one that did it, the bresenham.txt file explaining the ADAPTIVE_STEP_SMOOTHING is mine) so, the division can be replaced by a way faster multiplication 👍

@Sophist-UK
Copy link
Contributor

Sophist-UK commented Mar 17, 2024

There have been several people on Discord asking whether this work was ever finished and whether...

  • S-Curve;
  • Linear Advance;
  • Input Shaping;
  • XY Frequency Limit; and
  • Adaptive Step Smoothing

are now compatible with one another.

Is anyone who was involved in this FR able to comment on this please?

(As an aside, in the LCD menus and Gcode, you can turn Linear Advance can be adjusted to/from zero and Input Shaping can be turned on and off in each dimension, but AFAIK there is no UI or Gcode to turn on/off or adjust S-Curve, XY Frequency Limit or Adaptive Step Smoothing. Are these things that really should have Advanced Configuration menu entries and Gcodes?)

@tombrazier
Copy link
Contributor

For LA & S_CURVE, I never did implement the solution I mentioned in #22547 (comment). The main reason was that with input shaping, S_CURVE is now far less relevant. Also LA & S_CURVE can coexist and it is still better to have LA than not have it when using S_CURVE even though it is less than theoretically perfect. Other considerations were that I have also added a lot of optimisations to the stepper code which needed to settle and that I just haven't had the time. But mainly, lacking the motivation because of the existence of IS, I don't think I will ever get round to it.

IS will work with any of the other items on the list (that is the ZV one I implemented - I don't really know about the FT_MOTION implementation).

ASS is also compatible with everything, I think. As far as I can remember it always has been but I might have forgotten something.

I don't know XY frequency limit well but I think it just adjusts print speed, so should be independent of everything else and work with everything else.

i.e. I think the only limitation is LA & S_CURVE but am open to correction. And rather than use S_CURVE, I'd just recommend IS now. (Which is sad because S_CURVE is really lovely code.)

@Sophist-UK
Copy link
Contributor

Sophist-UK commented Mar 17, 2024

@tombrazier Thanks for such a prompt response. If I may, can I just check that I have understood this ok. Your recommendations are:

  1. If you are going to use only one of LA or S_CURVE, then you should use LA by itself, but if you are going to use S_CURVE then with LA is better than S_CURVE by itself?

  2. IS/XY/ASS are all OK to use in conjunction with whatever you decide in point 1.?

@tombrazier
Copy link
Contributor

  1. If it is a choice between LA and S_CURVE, then I would say forget S_CURVE and use IS instead. But, yes, if using S_CURVE then with LA should be better than without LA.
  2. Yes, I think so.

Note also, the combination of IS with S_CURVE will work but is probably unnecessary. Maybe, just maybe, there's an edge case where there are multiple resonant frequencies and S_CURVE performs better than ZV input shaping. But even in such a case the key limitation of S_CURVE is that it does not affect cornering discontinuities which is where ringing and layer shifting primarily originate. S_CURVE is only applied to the acceleration segments of the trapezoidal speed profiles. IS is applied to both.

@Sophist-UK
Copy link
Contributor

@tombrazier Sorry - still confused by your most recent point 1.

Is the use of "IS" intentional or a typo i.e. did you mean "forget S_CURVE and use LA instead"?

Ultimately I (and probably most everyone else) just want a version of firmware that gives the best results.

@tombrazier
Copy link
Contributor

IS is input shaping.

@InsanityAutomation
Copy link
Contributor

I still see solid value in S-Curve, even with IS. When IS compiled in, I can enable / disable as needed depending on project accuracy requirements. When I have it off, I want S-Curve active. On a home users machine, just relying on IS is acceptable but its not a viable solution from an professional / engineering standpoint.

Adaptive Step Smoothing if my memory is correct drastically increases the stepper ISR rate, so it is called even more frequently than steps could possibly be sent there, in order to ensure planned moves are started ASAP. As far as I know there has never been an incompatibility issue with it. It just complicates the math slightly for some of the execution count code discussed above because it means the rate isnt fixed and needs a calc.

@Sophist-UK
Copy link
Contributor

@InsanityAutomation So I should just enable everything?

Is there a menu or Gcode switch to turn on/off S-Curve?

(I have posted a PR for Marlin to allow you to compile firmware with Input Shaping included but turned off (by specifying frequencies of zero.)

@thisiskeithb
Copy link
Member

thisiskeithb commented Mar 18, 2024

(I have posted a PR for Marlin to allow you to compile firmware with Input Shaping included but turned off (by specifying frequencies of zero.)

You can already compile IS in by default by enabling & setting SHAPING_MIN_FREQ to a value like 10/below any frequency that would affect a print. This allows you set INPUT_SHAPING_X/INPUT_SHAPING_Y to 0.

@Sophist-UK
Copy link
Contributor

Sophist-UK commented Mar 18, 2024

I am compiling Marlin for several hundred combinations of variants of a particular model.

For the model I have (and those with the same physical shape and extruder (there are size variants and extruder variants) I can calibrate IS frequencies and Zetas, but for other variants where I cannot calibrate because I don't have a physical machine I want to enable IS but turn it off - and I don't want to include a SHAPING MIN FREQ if I have no idea what that should be.

@thisiskeithb
Copy link
Member

and I don't want to include a SHAPING MIN FREQ if I have no idea what that should be.

You'd set it to a value like 10 so it's below any frequency that would affect a print.

@Sophist-UK
Copy link
Contributor

I was under the impression that the lower the min. freq. the greater the RAM usage.

@thisiskeithb
Copy link
Member

I was under the impression that the lower the min. freq. the greater the RAM usage.

Yes, that's how it works. Marlin needs to know how much ram to allocate to IS buffers at compile time and that is done through SHAPING_MIN_FREQ when you want to compile IS in, but leave it disabled.

@Sophist-UK
Copy link
Contributor

Hmmm. I think you are right - in the absence of any actual frequencies, you need to guess a frequency.

Since this is for an AVR board, there is a minimum frequency supported by the board anyway, so I need to work out what that is and use it.

@oliof
Copy link

oliof commented Mar 19, 2024

since the usual frequency for IS is between 40 and 50Hz and the algorithm centers on a set frequency, a minimum frequency of 30Hz is very likely to be more than sufficient.

@Sophist-UK
Copy link
Contributor

Sophist-UK commented Mar 19, 2024

I am having trouble determining the Y frequency on my bed-flinger. Obviously the bed has significant mass, so I would imagine that the resonant frequency would be quite low, however determining what this is using either the MarlinFW.org tests or the th3dstudio.com tests is proving difficult. The IS values as best as I can determine from both these sets of tests are:

#define SHAPING_FREQ_X  37.42f
#define SHAPING_ZETA_X   0.10f
#define SHAPING_FREQ_Y  18.48f
#define SHAPING_ZETA_Y   0.50f 

Also, the results on a calibration cube are showing almost exactly the same ringing in both directions with and without IS on (but I really need to print a few more experiments on this to check it).

@tombrazier
Copy link
Contributor

Hmmm. I think you are right - in the absence of any actual frequencies, you need to guess a frequency.

Since this is for an AVR board, there is a minimum frequency supported by the board anyway, so I need to work out what that is and use it.

If the actual frequency at runtime ends up lower than SHAPING_MIN_FREQ then the effect is just that input shaping becomes less effective at higher speeds. But since input shaping is needed most on corners where the speed is lower, this is not as bad a limitation as it sounds.

I also have an AVR bedslinger and shaping works really well. When RAM is a limitation, I think the best way to pick SHAPING_MIN_FREQ is to pick a value that results in enough spare RAM for the stack. You need about 1k of RAM for this. So on an ATmega2560, you need a maximum of about 7k of RAM used as reported by the compiler.

@tombrazier
Copy link
Contributor

I am having trouble determining the Y frequency on my bed-flinger. Obviously the bed has significant mass, so I would imagine that the resonant frequency would be quite low, however determining what this is using either the MarlinFW.org tests or the th3dstudio.com tests is proving difficult. The IS values as best as I can determine from both these sets of tests are:

#define SHAPING_FREQ_X  37.42f
#define SHAPING_ZETA_X   0.10f
#define SHAPING_FREQ_Y  18.48f
#define SHAPING_ZETA_Y   0.50f 

Also, the results on a calibration cube are showing almost exactly the same ringing in both directions with and without IS on (but I really need to print a few more experiments on this to check it).

These frequencies look reasonable for a bedslinger. Zeta of 0.5 for Y looks looks a bit high.

The best way to measure the frequencies in Marlin is with the single layer pattern at https://marlinfw.org/tools/input_shaping/freq-calibr.html. I suggest you do this, take a photo of it and ask for help interpreting it in #support-chat on the Marlin Discord server.

@Sophist-UK
Copy link
Contributor

I don't think that my problem is interpreting them. The explanation on the MarlinFW page is clear, and the prints come out looking similar in general terms. The problem is that the Y line doesn't actually show much vibration (because of the mass of the bed I think) - I tried editing the gcode, reversing the zig-zags to keep the zig length the same but half the width and so keep the frequencies the same but more exaggerated movement, but this didn't help. And most of the Y zeta pattern except for the 0.5 line was so broken up it was difficult to determine anything.

As soon as I get time I will redo these tests and ask on Discord as you suggest.

The th3dstudio ringing tower printed well, and so I took the frequencies (as best I could) off that. I will share that on Discord too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests