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

Experiment with s-curves #2030

Closed
wants to merge 17 commits into from
Closed

Experiment with s-curves #2030

wants to merge 17 commits into from

Conversation

KevinOConnor
Copy link
Collaborator

This branch contains the code to implement an experiment with s-curves to try and reduce "ringing" (aka "ghosting") on prints. This is just a test, and is likely only of interest to other developers.

The current Klipper code uses a standard "trapezoid" velocity motion planner. PR #1776 changes that planner to implement "s-curves" during acceleration:

trapezoid-bezier svg

This branch attempts a different approach:

trapezoid-antires svg

That is, instead of implementing the curves within the time allotted for normal acceleration, the code permits acceleration leading up to and after the nominal acceleration time. This does result in the steppers taking a "path" that deviates from the commanded path - but it is done with the high-level thinking that it actually results in the toolpath more closely following the commanded path.

For example, it is currently believed that "ringing" is the result of the toolhead not following the "stepper path":

ringing

And thus commanding the steppers to take a deviated path could result in an improved overall toolhead path:

ringing-avoid

This code is an experiment. It defines new spring_x, spring_x_smooth_time, spring_y, spring_y_smooth_time config settings that define the new s-curves. The duration of the s-curve is controlled by the smooth_time settings. The amount of deviation is determined by the spring parameters and the amount of estimated acceleration. (The code uses estimated acceleration instead of the nominal acceleration, and thus does not have the "double acceleration" type issues with the bezier s-curve implementation.) Different s-curves may be used for x and y axes.

There are several caveats with this code:

I was able to tune this on my Makergear M2 printer (a "bed slinger"). The results were a noticeable, but small improvement. I suspect an improved calibration routine may yield better results. The calibration method I used was: print a tuning tower and measure the resonance, set the smooth_time parameters based on 1/4th the resonance time, print a tuning tower with changing spring value for each level (eg, TUNING_TOWER COMMAND=SET_SPRING PARAMETER=SPRING_Y START=0 FACTOR=.000010, measure the point of least resonance, and finally test on typical xyz calibration cubes.

-Kevin

@KevinOConnor KevinOConnor mentioned this pull request Oct 1, 2019
@ezrec
Copy link
Contributor

ezrec commented Oct 1, 2019

Suggestion for an object that would more easily demonstrate ringing:

A 5mm by 40mm by 40mm calibration object, with a dashed series of 0.2mm high x 0.5mm x 0.5mm recessed pockets going up the middle of one face.

Then every other 0.2mm slice doesn't have the 'recessed pcoket, making every other 0.2mm line straight (and have little to no expected ringing).

With a script that generates a calibration modification as a function of every 0.4mm of Z, it should be relatively easy for a user to iterate through 4 or so objects, measuring the Z height of each in turn where the best results occurred, and inputting that result into the generation of the next object.

@BlackStump
Copy link
Contributor

BlackStump commented Oct 5, 2019

@KevinOConnor
I am trying to test this patch but not understanding if I have the parameters correct

The calibration method I used was: print a tuning tower and measure the resonance, set the >
smooth_time parameters based on 1/4th the resonance time

so if I have measured the ringing on Y to be 39Hz then spring_y_smooth_time: is
spring_y_smooth_time: 0000975
?

@KevinOConnor
Copy link
Collaborator Author

@BlackStump - FWIW, I still need to come up with a good tuning methodology.

To retest what I last did (which showed a small improvement) then a 39Hz (25.64ms resonance) would be a 6.41ms quarter wave time. So, spring_y_smooth_time: 0.006410. Then run a tuning tower test with: TUNING_TOWER COMMAND=SET_SPRING PARAMETER=SPRING_Y START=0 FACTOR=.000030 (which, at 1000 accel and 50mm tower, should vary the spring compensation distance between 0 and 1.5mm).

-Kevin

@KevinOConnor
Copy link
Collaborator Author

Actually, a FACTOR=.000030 might be too aggressive. When I last ran the test I used FACTOR=.000010.

-Kevin

@KevinOConnor
Copy link
Collaborator Author

KevinOConnor commented Oct 5, 2019

After further thought, I no longer think the motion planning on this branch makes sense. The code should be adding in the "belt spring offset" over the smooth_time period, but it does not smooth the acceleration over the smooth_time period. I don't think that will be productive.

I'll keep this open for a few days to see if I can improve the math. I don't think there's value in testing this branch currently.

-Kevin

@dmbutyugin
Copy link
Collaborator

dmbutyugin commented Oct 7, 2019

A few thoughts:

The problem arises from discontinuity of acceleration with AO=2. Then your code can be used as-is with 'normal' S-curves to compensate toolhead displacement during acceleration/deceleration.

You can try to get rid of discontinuity of acceleration, this requires computing X(t) as X_base(t) + (A_smth(t) - A_inst(t)) * t^2/2 + A_smth(t) * spring_coeff; the problem is the current code does not have access to instant acceleration A_inst(t) on the rail, it can probably be approximated in the same manner as A_smth(t) right now but with t_diff much smaller than cs->smooth_time; I'm not sure if this will lead to any precision issues around points where acceleration changes.

Strictly speaking, there is no need to smoothen the acceleration - it is only one of the options. The real issue with AO=2 is that the force kicks in during accel/decel and can cause the vibrations. If we command X(t) = X_base(t) + X_spr(t) just before acceleration, and that X_spr creates the necessary force to match the subsequent acceleration - it should be good enough. X_spr(t) = A_base(t) * spring_coeff can be computed using second order forward derivative of X_base before the acceleration, and second order backward derivative - after the acceleration. An interesting case is acceleration right after deceleration (or deceleration right after acceleration). I think (though I may have missed some corner cases) it can be handled in a generic manner as such: compute forward and backward derivatives, and if they are of the same sign - take the one with the max absolute value, otherwise take the sum as A_base(t). I did not think it through what should be the smoothing time however, though I suspect it should be the half of the ringing period rather than the quarter of it.

@KevinOConnor
Copy link
Collaborator Author

KevinOConnor commented Oct 7, 2019

You can try to get rid of discontinuity of acceleration, this requires computing X(t) as X_base(t) + (A_smth(t) - A_inst(t)) * t^2/2 + A_smth(t) * spring_coeff; the problem is the current code does not have access to instant acceleration A_inst(t) on the rail

I'm not sure I understand. The step generation code does have access to the instantaneous acceleration (as well as instantaneous velocity). Unfortunately, using those values leads to artefacts because both of those values are not continuous. That's the primary gain to using the calculated position - it's always going to be a continuous value.

Strictly speaking, there is no need to smoothen the acceleration - it is only one of the options. The real issue with AO=2 is that the force kicks in during accel/decel and can cause the vibrations.

Totally agree. Alas, the big issue with the bezier curve implementation (AO=4, AO=6) is that it does the wrong thing in many common situations - for example, it "double accelerates" on two back-to-back accel g-code segments, and it does a slow decel into an instantaneous velocity change on cornering.

FWIW, I've reworked the code on this branch and I am now seeing good results locally. However, I remain unsure if the math is sane - I fear my results may only be improving the test prints. More testing is needed - but I also think a new test model is needed - so it's slow going.

The key insight to the updated code is that it never makes sense to have a spring_advance_factor outside of .250 to .500 (and likely doesn't make sense to have anything other than .333 or .500). (The spring_advance_factor used to be calculated as spring_consant / (2 * smooth_time * smooth_time).) In essence, the code could be thought of as performing "velocity smoothing" during cornering.

With the above observation, tuning becomes much easier - on the new code one can run: TUNING_TOWER COMMAND=SET_SMOOTH_VELOCITY PARAMETER=SMOOTH_Y START=0 FACTOR=.001. Then print a tuning object and find the Z point with the least resonance (if unsure use the lowest Z point).

I also wrote some software to graph what the code does for the settings I found for my Makergear M2 printer's Y axis (SMOOTH_Y=.019):

resonance

The graphing script is in scripts/graph_motion.py on this test branch. One will notice that the resulting axis velocity is still linear and it still has some instantaneous velocity jumps. However, the overall velocity curve does somewhat resemble an s-curve and the positional offset being added does look smooth. There are still some quirks introduced during instantaneous velocity shifts during cornering (modelled in the deceleration part of the graph).

-Kevin

@dmbutyugin
Copy link
Collaborator

dmbutyugin commented Oct 8, 2019

I'm not sure I understand. The step generation code does have access to the instantaneous acceleration (as well as instantaneous velocity).

I meant, there is only move_get_coord, which gives the coordinate. Velocity and acceleration currently must be computed using finite differences.

Alas, the big issue with the bezier curve implementation (AO=4, AO=6) is that it does the wrong thing in many common situations - for example, it "double accelerates" on two back-to-back accel g-code segments,

Agree on this one, the current implementation has this issue.

and it does a slow decel into an instantaneous velocity change on cornering.

Do you mean here that it's sort of pointless to do a smooth deceleration when followed by the cornering with instant velocity change?

FWIW, I've reworked the code on this branch and I am now seeing good results locally. However, I remain unsure if the math is sane - I fear my results may only be improving the test prints. More testing is needed - but I also think a new test model is needed - so it's slow going.

TBH, I initially though of this code as being problematic:
+ return base_pos + (end_diff - start_diff) * cs->spring_factor;
because the acceleration jumps here a few times during acceleration (as your chart shows too) - which means that the applied force can change too. I personally thought of this extra part with spring_factor as 'pre-loading' factor - sort of preload the printer frame and belts with force so that when the 'real' acceleration is applied - there is no jump in the force. But it is very possible that your current implementation is doing the similar thing - simply with several discrete steps.

FWIW, I suppose the smooth and balance parameters should be chosen such that the toolhead offset (from the chart) is equal to max_accel / (2 pi F)^2 with F - ringing frequency on that axis.

@KevinOConnor
Copy link
Collaborator Author

I meant, there is only move_get_coord, which gives the coordinate. Velocity and acceleration currently must be computed using finite differences.

The code on this branch has the ability to walk the trapezoid motion queue (it's in trapq.c). So, it can look at all the moves, the move accelerations, velocities, etc.

Do you mean here that it's sort of pointless to do a smooth deceleration when followed by the cornering with instant velocity change?

Yes.

I personally thought of this extra part with spring_factor as 'pre-loading' factor - sort of preload the printer frame and belts with force so that when the 'real' acceleration is applied - there is no jump in the force.

Yes - that's what I initially was thinking as well. However, I came to the conclusion that it only makes sense to "pre-load the spring" over a time frame that directly correlates with the acceleration. For example, it wouldn't make sense for the pre-load acceleration rate to exceed the the move acceleration and it wouldn't make sense for the pre-load acceleration to be drastically less than the move acceleration - either of these would just cause more stress on the spring. That led me to instead think of it in terms of a "velocity smoother".

-Kevin

@KevinOConnor
Copy link
Collaborator Author

FWIW, it occurred to me that another way to approach this is to implement a "positional smoother". That is: position(t) = definitive_integral(nominal_position, from=t-smooth_time/2, to= t+smooth_time/2) / smooth_time

Or, at a high level rational: "The belts/frame can be thought as a stiff spring and it isn't possible to make drastic velocity changes of the toolhead over a small time frame. Attempting to do that results in exciting the spring which results in worse positional accuracy. So, at small time periods, we can instead average the position to reduce excitations."

Implementing a definitive integral would result in a graph that looks like:
resonance2
(Updated graphing code in scripts/graph_motion.py on this branch.)

It should do a much better job at handling instantaneous velocity changes. Calculating the definitive integral in the step generation code is annoying, but shouldn't be difficult.

-Kevin

@ezrec
Copy link
Contributor

ezrec commented Oct 8, 2019

Instead of printing test objects; have you considered using a physics simulation of the printer head to visualize the output?

Shouldn’t be more complex than a square mass in a frame held by two springs that have the elasticity of 100mm of GT belt.

@nophead
Copy link

nophead commented Oct 8, 2019

I think stepper motor springiness is more than a decent Kevlar or steel reinforced belt.

Also with a belt I think a lot of the "springiness" comes from it not being supported and sagging. On a Shapoko mill the belts are supported and I think it is much stiffer than 3D printer.

Also I would expect an unsupported belt mounted on its edge to be stiffer than one rotated 90 degrees from that.

@KevinOConnor
Copy link
Collaborator Author

FYI, this development branch is a follow up from the many discussions in #57 - a simulator was developed as well as a test procedure with a phone accelerometer.

-Kevin

@dmbutyugin
Copy link
Collaborator

Do you mean here that it's sort of pointless to do a smooth deceleration when followed by the cornering with instant velocity change?

Yes.

Good point. FWIW, I also consider experimenting with explicit cornering by approximating corners with arcs (for AO=2) and/or bezier curves (for AO=2,4,6) with fixed precision. As a positive, it should work well with constant acceleration mode too. High-level estimation even gives reasonable cornering velocities: e.g. for square corner a good v_c = max_accel / (2 pi F) * \sqrt(\sqrt(2)-1)) with an arc and v_c = max_accel / (2 pi F) with a bezier curve of second order. But it's not easy to predict how will, or rather how should the velocity, acceleration and etc. behave as the toolhead passes through a bezier curve.

FWIW, it occurred to me that another way to approach this is to implement a "positional smoother". That is: position(t) = definitive_integral(nominal_position, from=t-smooth_time/2, to= t+smooth_time/2) / smooth_time

A very interesting idea! Looking forward to it!

I also think it would be great to run these ideas through some simulation. Of course, a simulation can never replace a real-world testing, because we cannot simulate the whole complex dynamic of the printer with unknown frame rigidity, etc. But it can help discard or compare the ideas - if something does not work in simulation - that's a bad sign :) And we can test on wider range of parameters to see if good results are due to lucky combination of parameters, or if they are consistently reproducible with different parameters.

@KevinOConnor
Copy link
Collaborator Author

FWIW, I also consider experimenting with explicit cornering by approximating corners with arcs (for AO=2) and/or bezier curves (for AO=2,4,6) with fixed precision. As a positive, it should work well with constant acceleration mode too. High-level estimation even gives reasonable cornering velocities: e.g. for square corner a good v_c = max_accel / (2 pi F) * \sqrt(\sqrt(2)-1)) with an arc and v_c = max_accel / (2 pi F) with a bezier curve of second order. But it's not easy to predict how will, or rather how should the velocity, acceleration and etc. behave as the toolhead passes through a bezier curve.

Sounds intriguing. However, most of that "went over my head".

I also think it would be great to run these ideas through some simulation. Of course, a simulation can never replace a real-world testing, because we cannot simulate the whole complex dynamic of the printer with unknown frame rigidity, etc. But it can help discard or compare the ideas - if something does not work in simulation - that's a bad sign :) And we can test on wider range of parameters to see if good results are due to lucky combination of parameters, or if they are consistently reproducible with different parameters.

I agree. I looked briefly at @Islandman93's simulator, but wasn't sure how to go about enhancing it for other types of kinematics. Maybe there's some format that we could use as input/output to a simulator so that we could reuse the simulation and generation code.

-Kevin

@KevinOConnor
Copy link
Collaborator Author

KevinOConnor commented Oct 10, 2019

FYI, I've updated this branch to the "positional smoother" idea. I'm seeing noticeable, but modest improvements on benchmark prints with this code.

To test:

  • Update to the latest code on this branch.
  • Select a test print (eg, @BlackStump's, a regular "square tower", or docs/prints/square_notch_tower.stl on this branch).
  • Run TUNING_TOWER COMMAND=SET_AXIS_SMOOTH_TIME PARAMETER=SMOOTH_Y START=0 FACTOR=.002
  • Print the tuning object.
  • Measure the Z level that shows the best anti-resonance. If in doubt, prefer a lower z. Then configure y_smooth_time in the printer config section with that value (value = start + z * factor).
  • Repeat test with SMOOTH_X if desired.
  • Run tests on regular prints to observe the general performance.

-Kevin

@mattkenn4545
Copy link

I just printed a square_notch_tower using the recommended TUNING_TOWER COMMAND using 100mm/s speed and saw the smooth_y output showing that TUNING_TOWER COMMAND appeared to be working however I really can't see /any/ difference in the tower. Every layer looks the same. Is that an indication that my max_accel is too low (ie can really get resonances to show up)? Or does the MCU need to be rebuilt/flashed. The MCU is current with current master.

I'm using an Ender 3 with max_accel of 1500. I've tuned my PA with the other changes in this branch and corners look awesome and I've been able to enable many of the 'banned' slicer features without issue.

Awesome things happening in klipper-land!

@mattkenn4545
Copy link

I think I see now what I was missing. I thought I was looking for 'ringing' on the flat surface. It looks like its more the 'squareness' in the corner section 'notch' without any curves. Before realizing this I bumped max_accel to 4000 and that did change how the print turned out however with two towers to compare against and knowing better what I need to look for they both resulted in the same value for smooth_y which for me was ~0.0465. Unfortunately when I put that in the printer section the MCU immediately crashes with 'mcu' shutdown: No next step

@mattkenn4545
Copy link

I got it to print... I think there is a relationship between max_accel and smooth_time. If smooth_time is > 0.0400 the MCU crashes, less then that it works. If I drop accel down to 2000 it breaks at 0.0200.

Thanks again for this awesome project.... does mean I print more calibration cubes and benchy's then 'real' projects but I'm amazed and what this can do.

@BlackStump
Copy link
Contributor

BlackStump commented Oct 11, 2019

I tried to print with this patch and did not get good results,
I disabled PA for the test and set accel to 6000
I manually set the SET_AXIS_SMOOTH_TIME to change every 3mm, the first 3mm was with no smooth time

smooth_x:0.000000 smooth_y:0.010000 (2nd notch)
smooth_x:0.000000 smooth_y:0.020000
smooth_x:0.000000 smooth_y:0.030000
smooth_x:0.000000 smooth_y:0.040000
smooth_x:0.000000 smooth_y:0.050000
smooth_x:0.000000 smooth_y:0.060000
smooth_x:0.000000 smooth_y:0.070000
smooth_x:0.000000 smooth_y:0.080000
smooth_x:0.000000 smooth_y:0.090000

P91011-135641

It didnt seem to do much for the ringing but it did have a big effect on the notches
I did try another print but starting at 0.004 adding 0.004 every notch. was not as extreme as the first print but still the notches had the biggest impact. it was the notches straight after the corner that was impacted the most.

@mattkenn4545
Copy link

mattkenn4545 commented Oct 11, 2019

I've done some more tests on a basic calibration cube and getting nearly perfect results with almost 0 ringing and sharp corners. PA and both smooth values tuned. 100mm/s speed with 4000mm/s/s accel.

One thing that I noticed and maybe this is a coincidence but both of my smooth values are very close to 0.040 with accell at 4000.... I'm if I halve the smooth values to 0.0200 I get ringing and obove 0.0400 MCU crashes. I'm retesting now with accel of 2000 to see if ringing goes away.

Possible that whatever the smooth_times are effecting should scale with accel and the real value needs to be a factor of that value based on corning angle/speed. Is that what Junction Deviation does/is in marlin?

@mattkenn4545
Copy link

@BlackStump where can I get the model you're using to test?

@mattkenn4545
Copy link

My current settings. I'm getting 'perfect' benchys and calibration cubes. Seems like I can't go any higher the 0.0325 on y_smooth_time without mcu crashes. Thought I'd set that higher at one point but no go however I'm very impressed with my results.

[printer] y_smooth_time: 0.0325 x_smooth_time: 0.0400 kinematics: cartesian max_velocity: 250 max_accel: 4000 max_z_velocity: 25 max_z_accel: 100

@KevinOConnor
Copy link
Collaborator Author

@mattkenn4545 - Thanks. Can you attach the klipper log file from an attempt that causes an mcu failure? Could you post a "before and after" picture of a print - a print with smooth_x/y set next to the same print with smooth_x/y at zero (but code and configuration otherwise unchanged)?

@BlackStump - Thanks. My initial reaction is that pressure_advance should be tuned first and that 6K accel is too high to calibrate with. My suspicion is that this branch will do better at cancelling high/mid frequencies, but only indirectly reduce low frequencies. (That is, only reduce low frequencies by virtue of reducing some high frequencies that could otherwise excite a low frequency.) I need to see if I can come up with a tuning methodology that exploits that (and then verify it locally).

-Kevin

@BlackStump
Copy link
Contributor

@KevinOConnor thanks Kevin, I will retry after tuning PA and dropping accel.
@mattkenn4545 model can be found here
https://www.thingiverse.com/thing:3847206
I used the 3mmx10 model

@mattkenn4545
Copy link

x
y
z

Here are some text prints z, y and z faces of a calibration cube.

Speed is 100mm/s, 4000mm/s/s max_accel Ender 3

First is y_smooth_time: 0.0325 x_smooth_time: 0.0400 and PA of 0.440
Second is just PA
Third is no smooth_times or PA

The first does appear to need PA tunned down just a bit (corners are a bit round) but other then some elephant's foot due to the first layer being a bit too close to the bed I think it looks amazing and in person it's next to impossible to feel any ridges/imperfections. Not absolutely perfect but getting there. I was able to print the makers muse new v2 tolerance test with no raft at 100mm/s and free everything (down to 0.15mm).

The most interesting thing I thought was the z-face lines being 'squiggly' on the non-smooth_time'd cubes. This might be a less time/plastic consuming way to tune those settings. Ie a flat print with lots of accel and speed going at a 45' tool path. If there is a 'Junction Deviation` type missing variable maybe that variable could be tuned with different tool path angles?

@BlackStump
Copy link
Contributor

BlackStump commented Oct 11, 2019

@mattkenn4545
what slicer are you using if I may ask?

@KevinOConnor
Copy link
Collaborator Author

As a separate note, if I were to naively estimate these vibrations, they would be (7.5 / 100)^-1 ~= 13 Hz. This is really low, and I'd say it is impractical to try to fully suppress such vibrations with any technique (i.e. any shaper/smoother for ~0.0.75 seconds duration will be introducing too much smoothing in parts, so fine details will be lost). If that's frequency is real, perhaps it would make sense to invest into mechanics of the machine - maybe tension the belts or install some frame stiffening upgrades.

FYI, this m2 printer is old and has several deficiencies. I don't consider results on it to be a "good benchmark". I'm actually surprised it can produce anything at 7000 accel.

For those that are curious, the following are some of the deficiencies I've identified on this printer: the X rail may not be straight; the belt pulleys aren't geared and may be introducing wobble with each 2mm tooth; the hotend uses a peek insulator which has some flexibility when hot; the extruder motor itself is bound to the x rail only by friction; the control board has old a4984 steppers which only support 8 microsteps; the Y axis is very heavy and only constrained by two linear rails one on side of the printer - it is likely to have X, Y, Z and rotational wobble; the direct drive extruder pulls the filament all the way from the filament spool - any regular snags caused by the filament spool turning might show up as a pattern in the print.

-Kevin

@BlackStump
Copy link
Contributor

scurve-shaping

from back to front
zv x75 y63
mzv x79 y68
mzv x75 y63
ei x75 y63
ei x79 y68
ei x82 y73
mzv x82 y73
mzv x82 y73 scurve

Not sure what to think of the artifact apart from changing frequency makes a difference.

@dmbutyugin
Copy link
Collaborator

dmbutyugin commented Jun 15, 2020

@BlackStump Very interesting (and strange)! I have a few questions about your tests:

  • How did you print the tests? With TUNING_TOWER command suggested, changing acceleration? What speed did you print it at?
  • Which part of the prints is top and which one is bottom in your pictures?
  • Do you observe this defect only at one corner of the model, or is it present on some other corners?
  • Which pressure advance did you use for the prints? Did you disable it as suggested? Otherwise, which value was used?
  • How was the model sliced? In smooth vase mode, or 'non-smooth' with explicit layers? If it wasn't smooth, where was the seam located?
  • Did you have a specific reason to try different frequencies for the same shaper? Or just to try and see if something changes?
  • What about ringing itself? How was it in different prints?
  • Which commit was this printed from? You can use git show command and post the hash present in commit abc0134567... output.

@BlackStump
Copy link
Contributor

@dmbutyugin sorry it was late last night and I should have included all that info but I wanted to get the pictures on because of timezone, ie I am sleeping when most of you folks are awake.

The artifact is on front run of Y at the end before it does a short x then the return y run, and only on that one end corner (a backwards L on the bed)
Print speed = 140mm/s

No I did not use the tuning tower so it was fixed parameters for all prints only shaper parameters changed.

Pressure advanced was used it was initially 0.36 I dropped it a tad to 0.34 but I was resisting changing to many parameters. pa was enabled for all tests.

I will include the gcode - sliced s3d vase mode

I changed frequency on the whim of the accelerometer-acceleration test done prior ...the misguided idea was to see if changing would make a difference.

There was no ringing to speak of, I want to use the same parameters that I had been using with the scurve-smoothing branch

git show (caveat coming)
commit 55c67e4 (HEAD, origin/scs-ar)
Merge: 89c61e3 8a23525
I used my branch that has Arksine's web api merged with your's so I can use Mainsail.
That may be a problem all tho I have use this printing the exact gcode with the scurve-smoothing branch merged as above, with no artifact.
here

Accel_test_model_3mmx10_spans.zip

skrpro_input_shaper.txt

@dmbutyugin
Copy link
Collaborator

@BlackStump OK, thanks! And which side is up on the picture?

So, if I understood you correctly, the prints were printed as a whole with no parameters changing? (except this small decrease in PA?)

Also, maybe when you have time, you could re-print the test model with the config measured for your params with Pressure Advance disabled?

[input_shaper]
shaper_freq_x: 75
shaper_freq_y: 63
shaper_type: mzv

Generally, I suspect this could be some layer instability that can happen when printing a single wall sharp corner at high velocity and acceleration - i.e. the filament can be pulled by the nozzle around the corner, and because it is a single wall, it can move into a corner a bit.

@BlackStump
Copy link
Contributor

Y is up, correct printed as a whole no parameters changed during the print.
I will do a print with PA disabled and another with tuning tower accel changes

@BlackStump
Copy link
Contributor

BlackStump commented Jun 16, 2020

X ends
X-ends

Y ends
Y-ends

as requested PA disabled the better print is same PA disabled but with this tuning tower command

TUNING_TOWER COMMAND=SET_VELOCITY_LIMIT PARAMETER=ACCEL START=750 FACTOR=167 >BAND=3

I will reslice at a slower speed 140mm/s is pushing the envelope with a single perm wall

Generally, I suspect this could be some layer instability that can happen when printing a single wall >sharp corner at high velocity and acceleration - i.e. the filament can be pulled by the nozzle around >the corner, and because it is a single wall, it can move into a corner a bit.

@dmbutyugin
Copy link
Collaborator

I will reslice at a slower speed 140mm/s is pushing the envelope with a single perm wall

You don't even need to reslice - just run SET_VELOCITY_LIMIT VELOCITY=100 prior to printing the test. BTW, printing at 140 mm/sec with 0.46 mm line width and 0.2 layer height is ~ 12.9 mm^3/sec filament melting through hotend. Unless you're using Volcano or other high-performance hotend, this is really over the boundary of what e3d-like hotend can do - and I suspect this can have a negative effect. It is possible that because with different shapers the exact hotened timing near the corner is slightly different, this can create different defects. But I didn't see anything suspicious in GCode that s3d generated or in the shapers code that could provoke that.

@BlackStump
Copy link
Contributor

BlackStump commented Jun 19, 2020

@dmbutyugin
You will be pleased to know the print artifacts are all caused by a hotend thermistor reading high
The thermistor was reading 220 when actual was 190
190 is too cold for the filament and the print speed.
one thing I have noticed is a reduction in PA is required for scurve-shaping compared to scurve-smoothing.
Print quality is very comparable between scurve-shaping and scurve-smoothing tho now I have sorted the thermistor, I need to do some reprints
After reprinting scurve-smoothing, and now comparing the prints, I think scurve-shaping is slightly better.

@KevinOConnor
Copy link
Collaborator Author

@dmbutyugin - FYI, I connected two different adxl345 sensors to my makergear m2 printer.

IMG_20200619_014906

(The picture shows one sensor wired to the toolhead, and if you look in the rear right corner of the bed you can see the sensor attached to the bed (not currently wired).)

I ran two tests - one gathering the data from the sensor attached to a corner of the bed (vib-y.csv and vib-x.csv). I then moved the wires to a sensor attached to the toolhead (vib-th-x.csv and vib-th-y.csv). Due to the way the toolhead sensor was mounted, the reported x is actually z, the reported y is actually x, and the reported z is actually y.

vibtest-20200619.zip

If I'm reading this data correctly, the vibrations on this printer are a mess. It seems the main issue is not directly due to X vibrations nor Y vibrations. Instead, it would seem just about any vibration causes the cantilevered bed to vibrate up/down and side-to-side.

-Kevin

@BlackStump
Copy link
Contributor

@dmbutyugin
xaxis
X axis from left to right, advanced-smoothing, scurve-shaping, scurve-smoothing
Yaxis
Y axis from left to right, scurve-smoothing, scurve-shaping, advanced-smoothing

I have included in the zip the parameters I used
parameters.zip

printed at 120mm/s, I would be happy to use any of the three

@dmbutyugin
Copy link
Collaborator

@BlackStump Thanks! It is hard to tell from the pictures, but I guess the quality is pretty comparable between different versions. The only interesting this is that advance-smoothing branch does not have adaptive acceleration control from SCurves, so it was likely printed at higher effective accelerations - but the quality is still good.

one thing I have noticed is a reduction in PA is required for scurve-shaping compared to scurve-smoothing.

If you observed this with ei shaper, it could be attributed to higher smoothing that becomes visible earlier at lower accelerations than with mzv or zv shapers. If you observed this effect with mzv shaper - I do not know why that would be exactly. But I guess it is possible.

@dmbutyugin
Copy link
Collaborator

dmbutyugin commented Jun 22, 2020

@KevinOConnor

If I'm reading this data correctly, the vibrations on this printer are a mess. It seems the main issue is not directly due to X vibrations nor Y vibrations. Instead, it would seem just about any vibration causes the cantilevered bed to vibrate up/down and side-to-side.

It would appear so, yes. Still, normally the bed should have its own vibration frequencies, but it could have several vibration modes on each axis, and you may be observing increased response at different exciting frequencies.

It also appears that the frame may have its own resonances, or at least something that the bed can excite. The 2 data sets that are particularly interesting are vib-x.csv and vib-th-y.csv. If I understood your setup correctly, you should be reading only noise here, but there are clear resonances, which don't match the resonances from the other sensor (note that I corrected the axes for the toolhead measurements):

vib-x vib-y
vib-x vib-y
vib-th-x vib-th-y
vib-th-x vib-th-y

I suppose this indicates that both when the toolhead moves in X direction, it can excite resonances in bed, and conversely, when the bed moves in Y direction, it can shake the whole frame, including the toolhead.

Practically speaking, it appears that you'd need to compensate for resonances from at least 15 Hz to at least ~55 Hz, which is pretty wide range. I do not think there is an input shaper that covers such a wide range simultaneously. However, it might be possible to choose a sparse range for a shaper - e.g. it would seem that ~40 Hz there is no excitation, so maybe the shaper can be chosen such that it does not reduce vibrations around there.
Edit: Also, 3hump EI shaper tuned for 35 Hz (and damping ratio = 0.1) might be a reasonable choice:
3hump-ei-35hz

Separately, from the testing done by other users I don't we have a clear winner or a looser - both shapers and smoothers can be a reasonable choice. So, we will need to make a choice based on some considerations other than quality of prints (which can be decent in both cases).

@BlackStump
Copy link
Contributor

@dmbutyugin
I was wrong about needing a different PA, I have since done a bucket load of test prints using the same PA with all the different variants, also I can see no difference between the shapers as far as quality is concerned.
I even thought I better retest master to compare. There is definitely a difference there.
I am really bad at getting detailed pics with my phone.
P00622-150017
from left zvd, master, ei, visually I can not see any different with the other shapers zv, mzv

@dmbutyugin
Copy link
Collaborator

@BlackStump Thanks for all your testing! It would appear that in your case the resonance are very 'well-behaving' - that is, there is a single strong resonance per axis. So ZV and MZV shapers work as good as EI and ZVD. You can likely just use ZV shaper, or MZV which is more robust than ZV for resonance frequency changes/imprecise measurements (though this is less of concern for you, I suppose). EI and ZVD shapers are even more robust than MZV, but they have more smoothing than MZV and ZV shapers. And you can use shaper_freq == resonance freq for a given axis.

@BlackStump
Copy link
Contributor

BlackStump commented Jun 23, 2020

@dmbutyugin you are welcome print quality has certainly improved using your branches.
now after a pause I will attempt to do some test prints on the Ender3, I suspect that may be a different story to the corexy.
I will keep you posted.

By the way I did a test print using max accel =10000 and shaper_type ei
I did not see a difference in print quality compared to the other test prints using half that accel.

@Sineos
Copy link
Collaborator

Sineos commented Jun 23, 2020

Could the accelerometer also help in determining the best possible max_accel, max_accel_to_decel and max_jerk?

@dmbutyugin
Copy link
Collaborator

@Sineos No, unfortunately, I do not think so. However, I think we may be able to suggest max_accel parameter, as well as min_accel (which I think I will replace max_jerk with), from the normal test print. Basically, max_accel could be chosen such that the corners of the ringing test model are not 'smooth' yet, and min_accel can be chosen such that there is no ringing in the test print yet. I'll think more about it and will update the docs hopefully soon.

@KevinOConnor BTW, I also published a script graph_shaper, which plots a vibration response for the shapers supported, and also how the shaper 'shapes' a step function, for instance:
ei-50hz
I hope this may be used by experienced users to better select a shaper for the resonances they know about, and may also help develop some intuition as to how exactly the shapers 'look like' and work.

@dmbutyugin
Copy link
Collaborator

@BlackStump, @Sineos Since you've already had some success in using accelerometer, could you try one more test using a newly added test? On adxl345-spi branch, after running sudo pigpiod, position the toolhead in the middle of the bed (at some height over it, e.g. G1 X100 Y100 Z50) and run (one after another, letting the previous command finish)

TEST_RESONANCES AXIS=X RAW_OUTPUT=/tmp/res_data_x.csv
TEST_RESONANCES AXIS=Y RAW_OUTPUT=/tmp/res_data_y.csv

and attach the 2 generated files here in the archive? This won't do any good for you right now - just run the test generate those raw measurements. I am trying some experiments with FFT to detect resonances, but I feel that I need more data, preferably from other printers too.

@BlackStump
Copy link
Contributor

BlackStump commented Jun 26, 2020

@dmbutyugin
I had a chance to do both the Ender3 and the CoreXY
ender3
ender3_res_data_y.zip

corexy
corexy_res_data_x.zip

@Sineos
Copy link
Collaborator

Sineos commented Jun 26, 2020

After the initial vibration test, I tore down my entire printer and implemented following modifications:

  • Re-Assembled the entire frame, making best effort to get it as square as possible
  • Added 14 additional corner brackets all over the frame
  • Put the entire printer on 4 squash-balls as feet
  • Improved the belt tension and more importantly the belt alignment on y and x axes (IMO a very weak design on this printer)
  • Increased microsteps from 16 to 128, while turning off the TMC interpolation

The results are quite drastic:

Y Axis:
grafik

X Axis
I redid the X Axis twice because I was kind of surprised by the result: No clear resonance (except right at the beginning where the amplitude of the movement is quite high)

grafik
grafik

Please find all the raw data including the requested new measurement here: https://drive.google.com/file/d/1ipeWnuznC2aWX4qyfM0EnBjk5Mx00RGP/view?usp=sharing

@KevinOConnor
Copy link
Collaborator Author

KevinOConnor commented Jun 28, 2020

I'm closing this PR as I feel confident that there are superior alternatives to my code on this particular branch. I believe the input-shaping code by @dmbutyugin is superior (and his input-smoothing work as well). The discussion on this ticket has gotten a bit long, so I think it makes sense to move the discussion to the newer tickets focused on the new methodology (see #3025 and #3027).

Thanks everyone for their participation!
-Kevin

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

Successfully merging this pull request may close these issues.