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] (Practical algorithm provided) Vibration compensation #16531

Closed
nalimcos opened this issue Jan 11, 2020 · 54 comments
Closed

[FR] (Practical algorithm provided) Vibration compensation #16531

nalimcos opened this issue Jan 11, 2020 · 54 comments
Labels

Comments

@nalimcos
Copy link

nalimcos commented Jan 11, 2020

Hello!

'Ringing' (wavy surface pattern) is a common problem when attempting higher printing speeds; vibration compensation has been brought up here before, but this approach seems new, and I believe it would require little enough processing power to comfortably run even on 8-bit controllers.

Quick description

  • No acceleration, high jerk - any speed change is 'instantaneous' here. We can tone that down later on.
  • Roughly sinusoidal pattern -> print head motion can be approximated as a simple sprung mass system.
  • Let's call T the vibration period of the system when disturbed. (/!\ T is something else in the article)

<some math here, check the article for details>

By cutting each corner with an additional segment, along which the speed vector is the average of the speed vector for the previous and next segments, and starting T/4 before reaching the initial corner, and ending T/4 after when it would have been reached (i.e. T/2 after the start of the corrective segment), we can replace the usual oscillation by two waves which cancel each other, resulting in strongly reduced artefacts.
output
This image was output by a simple simulator I wrote to test my idea.

  • Grey lines: uncompensated and compensated 'ideal' trajectories
  • Red line: actual print head motion, no compensation, slight damping.
  • Blue line: actual print head motion, compensation calculated without accounting for damping, slight damping applied anyway. i.e. non ideal conditions but a nice demonstration
    (No damping in the model leads to a slightly wilder red line and an even better fit of the blue line)

Full explanation with lots of math in attached PDF: vibcomp.pdf . Old work in progress so a bit messy though.

A simple acceleration-induced-vibration correction method as a by-product
While extending this approach to compensate for linear-acceleration-induced vibrations is not as easy, acceleration can be replaced by segments of movement at varying velocities, such that each segment has the duration of half a vibration period of the uncorrected system. Incidentally, this requires much less processing power than even true linear acceleration.

I will add more information and further ideas later on, time for bed here!

Milan

EDIT:

  • Requires one printer-specific correction factor per corrected axis (or one for all of them in case of a symmetrical design)
  • Factors easily measured on a test cube printed without compensation, at suitable settings
  • Article provides bits of formulas linking max acceleration, average acceleration, max uncompensated deviation, max compensated deviation...
  • Problem when working with files sliced into short segments: no solution for adjacent segments; solution: look for first further segment for which a suitable end point exists within its first half? needs more thought
@boelle boelle added the T: Feature Request Features requested by users. label Jan 11, 2020
@nalimcos
Copy link
Author

The simulation I wrote can be found at https://github.com/nalimcos/VibComp , along with a copy of the article and a (currently non-functional) gcode postprocessor.

I am starting work on a simple proof-of-concept gcode generator, which will print a simple geometric shape over a few layers and could also serve as a calibration tool later on (though of course an accelerometer attached to the print head for auto calibration would be less finicky...)

@italocjs
Copy link
Contributor

This seems really interesting and useful, i'll love to help developing/testing.

@nalimcos
Copy link
Author

nalimcos commented Jan 11, 2020

Yay!
Here is the test print generator I mentioned:
https://github.com/nalimcos/VibComp/tree/master/proof-of-concept
Probably a few errors in there, I haven't tested it yet. But it compiles on my computer, and outputs valid-looking gcode.
It automatically sets classic jerk to a high value; if you use junction deviation, it should be set to some high value manually, I can't say how high is enough without reading up on the subject though.
If everything goes according to plan, it should print a single-walled square with some corner correction.
You will probably need to modify start gcode, filament parameters and final retraction amount (in source or output), and of course correction amount (in source only).

EDIT:
By reframing the problem, I may also have found a solution for true linear acceleration, which may allow up to sqrt(2) times higher average acceleration by spending more time at peak acceleration on long moves than the jerky version above. I'll have to write it down and do the math properly. The processing power advantage of the jerky version is lost though. I'll also check what happens when the segment frequency is a higher harmonic of the system's vibration frequency, and whether this can lead to a hybrid approach. (i.e. maybe better Aavg to Amax ratio and less noise, while still costing less in terms of processing power than linear acceleration)

@nalimcos
Copy link
Author

nalimcos commented Jan 13, 2020

First version of the test print generator had a lot of errors, I uploaded a new version a few minutes ago.

Here is a little demo, printed at 60mm.s-1, cornering at full speed (marlin 'jerk' set to 120mm.s-1), Tc = 0.007s (see code).
IMG_1783

/!\ I forgot to specify the correct feedrates for the corrective segments so my comments below must be taken with a grain of salt

  • Upper part with correction, bottom part without
  • Some improvement, but not as much as I had hoped; some oscillation remains, out of phase with the original oscillation. This is similar to the blue line in the simulation above, suggestion damping should be taken into account. I think simply biasing the speed difference repartition towards the first corner of the corrective segment may do the trick.
  • Corners get a bit rounded, as expected. Higher frame rigidity / lighter mechanism mass would result in shorter oscillations -> shorter Tc -> shorter corrective segment -> less rounding. Lower speeds would help too.
  • There is a bit less noise when using correction, but still, 60mm.s-1 speed changes are noisy.

EDIT:
Corrected feedrates for the corner segments (they were sqrt(2) times too high).
IMG_1791
Much better results:

  • Better oscillation cancellation
  • Less corner rounding, due to best correction now being attained with Tc = 0.005s
  • Noise: less of a loud thud at each corner

@italocjs
Copy link
Contributor

can you share your config.h? ? i'll try printing with the closest settings possible to yours to see if these artifacts on might be software or hardware related, i have some suspicious that jerk and scurve might interfere with it, i got one machine that is pretty solid and has no vibrations until ~130mms (which i never print to be honest), and the other start to appear around 70mms.

@nalimcos
Copy link
Author

nalimcos commented Jan 13, 2020

scurve and junction deviation are disabled; config.zip

Ringing is much less visible on a normal print, the idea here was to voluntarily push the machine to its limits (60mm.s-1 right angles without normal acceleration due to jerk being over 2*feedrate) and show that most of the vibrations could be eliminated.

Or did you mean you could print with 130mm.s-1 jerk?

@AnHardt
Copy link
Member

AnHardt commented Jan 14, 2020

1.2.2 Axis modelisation
Effective motion along each axis will be assumed to be analogous to that of a
load attached using a spring to a point following the ideal tool path.

Usually we have at least two different "spring systems". One is the elasticity of the belts. The other is the possible angle between the rotors static magnetic field and the rotating magnetic field of the coils under load. We also have two masses. That of the rotor and that from the 'sled'.
For me that's looking as if that could be a difficult to calculate system, like a 'Double pendulum'.
Only with some luck, one of the systems is contributing much more to the amplitude. Than the other can be ignored.

@AnHardt
Copy link
Member

AnHardt commented Jan 14, 2020

often called ”jerk”, but not related to the thirdorder derivative of position

For that i prefer the term "jerk-speed" when i talk about Marlins (grbl s) parameter. (Not because this is a exceptional good term, but to differentiate it from "physical jerk")

@AnHardt
Copy link
Member

AnHardt commented Jan 14, 2020

At t = 0, there is by definition no deviation from the path yet;

That's questionable. If the previous line segment ended with a deceleration phase we already have a displacement. (spring loaded)

@nalimcos
Copy link
Author

Usually we have at least two different "spring systems". One is the elasticity of the belts. The other is the possible angle between the rotors static magnetic field and the rotating magnetic field of the coils under load. We also have two masses. That of the rotor and that from the 'sled'.
For me that's looking as if that could be a difficult to calculate system, like a 'Double pendulum'.
Only with some luck, one of the systems is contributing much more to the amplitude. Than the other can be ignored.

Yes, I was afraid this would be a problem. However, the artefacts I've seen on actual prints show a more simple vibration pattern.

At t = 0, there is by definition no deviation from the path yet;

That's questionable. If the previous line segment ended with a deceleration phase we already have a displacement. (spring loaded)

Fair enough. I'm assuming no acceleration (instantaneous target speed changes only) or corrected acceleration (more on that later; but basically, if my more recent calculations are correct, acceleration changes can be treated in pretty much the same way as velocity changes: start at half acceleration during one half of the system's vibration period, then switch to full acceleration.)


I wonder whether correction factors would need to change with speed? Not if structure rigidity (a big issue on dirt-cheap Prusa i3 derivatives) or belt elasticity (but I doubt this is often an issue with steel core belts?) is the main issue, but if it's motor torque, then speed will have to be taken into account.

@karabas2011
Copy link

Usually we have at least two different "spring systems". One is the elasticity of the belts.

I use cartesian printers without belts. Only leadscrews. 12mm/turn or 20mm/turn.
I see no difference compare to belts.

@nalimcos
Copy link
Author

nalimcos commented Jan 27, 2020

Hello! A simple gcode postprocessor is in the works as I'm not quite up to the task of rewriting parts of the planner yet. Slightly held up by a mathematical error somewhere in my code but I'll figure it out :p

@karabas2011
Copy link

Is it possible to use it as a postprocessing plugin for Cura?

@nalimcos
Copy link
Author

I'll have to figure out how that works, I normally use PrusaSlicer.
A word of warning though, if I am happy with the postprocessor's functionality, I'll publish it as commercial software (with a demo only correcting up to, say, Z=12mm), while leaving all my notes freely available to anyone interested in implementing the algorithm into firmware.

@italocjs
Copy link
Contributor

italocjs commented Jan 28, 2020 via email

@nalimcos
Copy link
Author

nalimcos commented Jan 29, 2020

I make saxophone mouthpieces on several different 3d printers: e3d bigbox (converted to top-mounted bowden setup), heavily modified anet e10, anycubic delta with linear rails (with flying extruder)...

While they all print very well for most purposes, the tiny bit of ringing I can see even at 20mm.s-1 speed / 5mm.s-1 jerk-speed / 800mm.s-2 acceleration when using a 0.15 or 0.2mm nozzle is more than I like.

All in all I have to make this for my own use anyway :)

I've fixed the error which was giving me problems BTW, time to handle segments too short for direct correction and I'll be able to start testing!

EDIT: simple 'drop segment' solution ready for testing :D
EDIT2: aaaand more errors to fix, very silly behaviour around retractions.

@karabas2011
Copy link

I printed tenor mouthpieces too. But it seems you need refacing in any cases. I hoped I can print exact replicas but failed. Rails are not perfect even at 0.05 layer. Nevetheless I played on one chemically refaced.

@ProfessorChi
Copy link

ProfessorChi commented Feb 25, 2020

Congrats and nice work. The method you are working on is not new though. The idea has been around since the 1950s in the form of Posicast Control. There is a much more elegant and simpler way of doing the same thing. In the firmware, just set the acceleration A [mm/s^2] = F/T, where F is the feedrate in mm and T is the period of vibration in seconds. You can try it on your square part - you'll probably notice some reduction in ringing if you do everything right.

However, your approach and that described above have a lot of issues that limit their practicality (some of which you've already noted). 1) The system has to be severely under-damped; (2) They are not robust to slight modeling errors; (3) They address only one vibration frequency; (4) They typically force the motion to slow down (or take longer time) to achieve vibration cancellation; and (5) Your particular approach leads to corner rounding and is unlikely to work on short line segments.

Input Shaping is another approach that was specifically designed to mitigate some of the issues discussed above. However, it often leads to corner rounding and severe shape distortions.

You can visit www.ulendo.io to try a method we've developed to cancel vibration. Using it, we are able to print at high speeds (e.g., 100 mm/s) and accelerations (e.g., 10,000 mm/s^2) without ringing.

Again, nice work and great out-of-the-box thinking!

@thinkyhead
Copy link
Member

An important point to note is that the X axis is often entirely stationary in the Y and Z direction and so it will only generate ringing in the X direction according to its own independent changes in momentum. And the moving bed will only generate ringing in the Y direction according to its specific momentum. The amount of expected ringing in each dimension will differ according to its mass.

If the model is based on an inertial mass supported on an XY gantry with no movement in the bed, the prediction will not match what you get on a system where the X and Y inertial masses are de-coupled, though you can get close by asserting that the two masses are equal.

While a certain amount of rigidity in belts and couplings can do a lot to mitigate ringing, the best trick we have in the firmware is the S-Curve Acceleration feature. It doesn't in any way adapt dynamically to the kind of situations I mentioned above, but it can be tuned to a certain point where it covers enough of the gamut.

@thinkyhead
Copy link
Member

thinkyhead commented Feb 25, 2020

The 20x faster acceleration (10m/s/s versus 0.5m/s/s) on Ulendo is pretty impressive, though of course the Benchy Groot does display ghost ringing artifacts at that speed. This is understandable given that the Lulzbot TAZ has a pretty massive print head.

Now that we've got 32-bit boards that can handle it I do wonder if we could ramp up the acceleration to these kinds of rates with S-Curve Acceleration, and what sort of results we would get. It would be good to explore these limits.

@ProfessorChi
Copy link

ProfessorChi commented Feb 25, 2020

@thinkyhead Thanks for the feedback. Because no compensation is perfect, you are right that there is still a little bit of ringing at 10,000 mm/s^2 but it is less than what we see at 500 mm/s^2. In our whitepaper you can see what happens when we run at 10,000 mm/s^2 without compensation. The ringing is off the charts!

I'm glad to see that Marlin has S-curve profiling now. However, while S-curve profiling reduces ringing a bit it does this at the expense of longer printing time. You probably know this already. We have S-curve profiling in Ulendo and it helps a tiny bit but the real benefit in reducing ringing without lengthening printing time comes from vibration compensation.

In any case, I'm glad to see concerted effort in tackling the problem of vibration and ringing. It is one of those problems that people can easily avoid by slowing down but they never realize how much they are losing in productivity in the process. This is why I believe that the best solutions to this problem should aim at reducing ringing without sacrificing speed (if possible). That's what we are gunning for.

@AnHardt
Copy link
Member

AnHardt commented Feb 25, 2020

Indeed we discussed this approach (or an earlier iteration) already in #8071.

My conclusion was:
Nice to have.
But measuring the printer for determining the parameters for the algorithm is/was to complicated/expensiv for a single hobby machine - maybe interesting for a some 100/1000 machine series.

Some more details at https://umich.app.box.com/s/n9cvs27ckehdr64gzv5igtmboykymgk6

@ProfessorChi
Copy link

You have a very good point. Actually, even high end machines (that cost half a million dollars) that I worked with in industry did not have this type of capability, even though they had severe vibration problems. Our goal with Ulendo is to make it easy for hobbyist machines and industrial machines alike to have easy access to high end algorithms like ours that make a huge difference in performance. In other words, "high end algorithms for all." It's not an easy task but we'll try. We are thinking of creative ways to make the system ID easy and it is looking very promising. Stay tuned.

@nalimcos
Copy link
Author

nalimcos commented Feb 26, 2020

I printed tenor mouthpieces too. But it seems you need refacing in any cases. I hoped I can print exact replicas but failed. Rails are not perfect even at 0.05 layer. Nevetheless I played on one chemically refaced.

In my experience, it can work quite well, but requires a lot of dedication. I use a 0.2mm (or sometimes 0.15mm) nozzle sanded to make the tip as thin as possible, 15-20mm/s speed, a silicone cover for the heatblock; and of course very carefully tuned temperature and fan settings: use the lowest temperature you can get away with, and only then add fan for the tip of the mouthpiece.

====

ProfessorChi , thanks for all the insight! I'll keep an eye on your solution, too.

There is a much more elegant and simpler way of doing the same thing. In the firmware, just set the acceleration A [mm/s^2] = F/T

Now this is a veeeery interesting result :D
I haven't looked at this properly yet; I guess this makes the vibrations induced by the start and end of the acceleration phase cancel each other out, without correcting for instantaneous target speed changes, which should therefore be kept reasonably low?

  1. The system has to be severely under-damped

This can probably be overcome by applying a greater portion of the required velocity change at the first output velocity change?

(4) They typically force the motion to slow down (or take longer time) to achieve vibration cancellation

In this case, the output moves take exactly as much time as the input moves. This made it easier to synchronize separate per-axis corrections.

Your particular approach leads to corner rounding and is unlikely to work on short line segments.

Yes, this is where it gets complicated. I did manage to make a working gcode postprocessor with separate corrections for each axis, but it only works on simple large-scale features, and makes a mess of my mouthpieces. I've been trying to figure out either how to pre-process the moves before feeding them to the algorithm...
There is the obvious option of slowing down so segments are long enough for correction, but... indeed, that would defeat the point.

====

An important point to note is that the X axis is often entirely stationary in the Y and Z direction and so it will only generate ringing in the X direction according to its own independent changes in momentum. And the moving bed will only generate ringing in the Y direction according to its specific momentum. The amount of expected ringing in each dimension will differ according to its mass.

I now do have separate correction factors working, but still have more residual ringing than expected after separate tuning of X and Y correction periods, so I wonder...

  • Significant vibrations transmitted from one axis to the other?
  • Too much damping for the model to work properly? (the printer has softish wheels on aluminium extrusion for X axis)
  • Complex vibration pattern rather than one dominating frequency like I had on the BigBox?

the best trick we have in the firmware is the S-Curve Acceleration feature

I haven't used it yet, I think it was incompatible with something else? I should look into it a bit more.

@thinkyhead
Copy link
Member

I think it was incompatible with something else?

Depends on the time of day and position of Mars.

@LSchwerdt
Copy link

LSchwerdt commented Mar 8, 2020

I think this is a great idea, and a relatively easy to implement step on the path to smoother high speed printing.

One advantage of this approach is that it never worsens vibrations when choosing bad parameters. In the worst case the vibrations are as bad as before. So the easiest thing would be to chamfer all corners between G1 moves by the same amount. Here is a Matlab script that does this for verbose G-code exported from PrusaSlicer. Sadly I have no printer to test this myself yet. (Waiting for Prusa Mini atm.)

To explore the dynamics of different speed/acceleration profiles I created a Jupyter notebook, which you can find here. To simplify the problem I used the following assumptions:

  • Only one axis is modelled.
  • The goal is do decelerate from a starting velocity to a full stop. This is needed for a 90 degree corner aligned with the axes.
  • Speed, acceleration and Marlin-jerk are taken form the Prusa MK3S presets in PrusaSlicer (100 mm/s, 1000 mm/s², 8 mm/s), where the speed is a compromise between speeds for different print moves.
  • The dynamics are modeled as a single degree of freedom harmonic oscillator with base excitation. The model is an approximate fit to the measured x axis dynamics from this paper.
PLOT: X axis model sdofFitX

No deceleration phase
Starting from a constant speed, splitting the Marlin-jerk (jump in velocity) into two jumps perfectly eliminates the resulting vibration. The results are impressive even with damping present. Pictured is the target position u and velocity u', the actual position x, and the position error x - u over time.

PLOTS: No deceleration phase (without damping) 01 02
PLOTS: No deceleration phase (with damping) 01 02

No Marlin-jerk
In reality not only the Marlin-jerk is a problem, but the deceleration itself. As noted by ProfessorChi, the resulting vibration amplitude is dependent on the duration of the deceleration phase. When the duration is an integer multiple of the period of the oscillator, the effects of starting and stopping the acceleration cancel out. With damping some vibrations remain:

PLOT: No Marlin-jerk, best case (without damping) 07
PLOT: No Marlin-jerk, best case (with damping) 07

The worst case is when the deceleration time is (n + 0.5) times the period:

PLOT: No Marlin-jerk, worst case (without damping) 06
PLOT: No Marlin-jerk, worst case (with damping) 06

Deceleration phase and Marlin-jerk
Combining a deceleration phase and Marlin-jerk, the gain from splitting the Marlin-jerk into two jumps is reduced, because the vibrations caused by the start and end of the deceleration phase still exist:

PLOTS: Deceleration phase and Marlin-jerk (without damping) 11 10
PLOTS: Deceleration phase and Marlin-jerk (with damping) 11 10
In reality this problem might not be as bad as demonstrated here, because the acceleration should be reduced and the Marlin-jerk should be increased when using this method for vibration reduction. Using s-curve acceleration would lead to futher improvement.

Deceleration without velocity jumps and optimized physical jerk
As a longer term effort, I hope we can implement a motion profile with no velocity jumps and limited physical jerk. When using a jerk thas is exactly acceleration times the natural frequency, no vibrations are induced when starting and stopping acceleration phases. Compared to the case with constant acceleration, damping worsens the results much less:

PLOT: Optimized jerk-limited motion (without damping) 13
PLOT: Optimized jerk-limited motion (with damping) 13

Sadly this does not work perfectly when the maximum acceleration is not reached. The vibration amplitude depends on the starting velocity. It is quite low, so the extra effort to implement a more complicated solution might be wasted, especially considering the limited accuracy of the dynamic model. I have not calculated the worst case, so it is not exact.

PLOT: Short optimized jerk-limited motion, best case (without damping) 14_a
PLOT: Short optimized jerk-limited motion, ~worst case (without damping) 14_b
PLOT: Short optimized jerk-limited motion, best case (with damping) 14_a
PLOT: Short optimized jerk-limited motion, ~worst case (with damping) 14_b

Since this concept is much more complicated, starting with theoriginal proposed algorithm seems to be a sensible choice, especially considering the work nalimcos has already put in. I will start a seperate issue for my proposal, when it is ready. But the motion planning with multiple axes and sensible cornering is not trivial, so that may take a bit. My plan is to use my InvenSense MPU-9250 to measure my printer, when I get the printer in june. A breakout board is just a couple of bucks on aliexpress, so hopefully someday most printers will have accelerometers to calibrate the settings, just like bed leveling sensors today. Determinig the first eigenfrequencies for each axis should be doable. (Compared to measuring complete frequency responses as required for #8071.)

@ProfessorChi
Copy link

@ LSchwerdt, nice work! Your split jerk solution looks like the effect of using the ZV input shaper. Is that what you used? Input shaping is very elegant and easy to implement. It is also very robust. The main problem is that it can lead to severe corner rounding and shape distortions.

With regard to measuring complete FRFs, it's not as challenging as you seem to suggest. Having the complete FRF allows one to compensate all servo errors and avoid corner rounding. I really need to get my act together and provide the community with a tutorial on software vibration compensation techniques - together with training on how to easily measure FRFs. I've been thinking of doing this for a while but life just gets in the way. Maybe this summer.

@LSchwerdt
Copy link

Your split jerk solution looks like the effect of using the ZV input shaper. Is that what you used?

Splitting the velocity jump this way is just a special case of the corner cutting method proposed by nalimcos. But the paper you linked looks great on first glance. Thanks :)

With regard to measuring complete FRFs, it's not as challenging as you seem to suggest.

Measuring FRFs with professional gear is easy. But I expect some challenges when using sensors with milliseconds of delay on a microcontroller with very limited memory. Although I have not really looked into that.

Having the complete FRF allows one to compensate all servo errors and avoid corner rounding.

That is definitely the superior solution. But #8071 seems to suggest that simpler methods are preferred for now. Hopefully this changes when/if ulendo can demonstrate good results and gains popularity. And having a good basic motion algorithm is desirable as well, even if it is only for low end printers.

@ProfessorChi
Copy link

Our paper used high end hardware for measuring FRFs. However, as part of Ulendo, we currently use Raspberry Pi combined with Arduino and two low-cost (ADXL345) accelerometers to measure 3D printer FRFs.

I completely agree that simple is better. We tried to implement simple vibration compensation algorithms in Marlin but the fundamental challenge is that Marlin uses displacement-based interpolation instead of time-based interpolation used in higher end controllers. Therefore, we could not implement simple solutions like notch filtering or input shaping. For Ulendo, we completely re-wrote the interpolation to be time-based so we can use notch filtering, input shaping or our FBS algorithm.

The corner cutting method is interesting and can work with Marlin, since it is implemented via Gcode, but I see a lot of limitations of trying to implement vibration compensation by corner cutting. However, I'll be the first to cheer anyone that can accomplish it because it would be a simple solution that is compatible with existing firmware.

@haarp
Copy link

haarp commented Dec 26, 2020

Klipper does now support something similar to cancel out vibrations: https://www.klipper3d.org/Resonance_Compensation.html

@SFRSKZ
Copy link

SFRSKZ commented Mar 21, 2021

when will we see this feature in marlin?

@thinkyhead
Copy link
Member

when will we see this feature in marlin?

Your guess is as good as mine. It's a lot of work and will require a serious effort by a skilled coder. We are open to volunteers, and whoever accomplishes it will be rewarded.

@nalimcos
Copy link
Author

A little update as I log into my github account for the first time in a while... can't really say when, but as I'm now studying computer science and starting work as a software developer, skill won't be the limiting factor anymore. I'll 'just' need the time :)

@ahmetcemturan
Copy link

ahmetcemturan commented Mar 11, 2022

Hi Everyone,
I was intriqued by this and had a try at @ProfessorChi's " A [mm/s^2] = F/T ".
It works but my problem is obviously that the printer does not have a constant feedrate for most scenarios. Even if I set every speed setting in the slicer to the same still speed varies when cooling is enabled etc.
So I tried to Play around with Marlin to make the acceleration rate dependent on the feedrate.
There is this part in planner.cpp that I thought could be modified:

// Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
void Planner::reset_acceleration_rates() {
  uint32_t highest_rate = 1;
  LOOP_DISTINCT_AXES(i) {
    //max_acceleration_steps_per_s2[i] = settings.max_acceleration_mm_per_s2[i] * settings.axis_steps_per_mm[i];//ACT FEEDRATE
    max_acceleration_steps_per_s2[i] = (feedrate_mm_s/(3.3/feedrate_mm_s))[i] * settings.axis_steps_per_mm[i];//ACT FEEDRATE
    if (TERN1(DISTINCT_E_FACTORS, i < E_AXIS || i == E_AXIS_N(active_extruder)))
      NOLESS(highest_rate, max_acceleration_steps_per_s2[i]);
  }
  acceleration_long_cutoff = 4294967295UL / highest_rate; // 0xFFFFFFFFUL
  TERN_(HAS_LINEAR_E_JERK, recalculate_max_e_jerk());
}

3.3 is obviously my OScillation rate.

Unfortunatly I get:

Marlin\src\module\planner.cpp:3163:81: error: invalid types 'feedRate_t {aka float}[uint8_t {aka unsigned char}]' for array subscript

Does my approach seem logical?
Is there a quick way to fix this?

Thanks in advance,
Ahmet (Action68)

@doxxx
Copy link

doxxx commented Mar 11, 2022

(feedrate_mm_s/(3.3/feedrate_mm_s))[i]

The array subscript at the end [i] should not be there.

@ahmetcemturan
Copy link

(feedrate_mm_s/(3.3/feedrate_mm_s))[i]

The array subscript at the end [i] should not be there.

Thank You so much. It compiled and works. Now I need to test whether it will have an effect on quality

@ahmetcemturan
Copy link

It works great.
Now I need to figure out how to
1-create accelerations for the different axis. (My first test was on a CoreXY but need it also on my clone Prusas.)
2-Make the same automation for the junction deviation distance
3-Create a gcode that makes it possible to enter the distance and/or frequency of the marks.

I have attached a photo of before and after. Both used the same gcode..
Acceleration was set to 1352 in accordance with 1.38mm and 43.2mm/sec (2594mm/min) feedrate on the first one.

Any help is appreciated. I am no programmer and can use any help..

WhatsApp Image 2022-03-11 at 10 52 14 PM
zaqPart1__PLA@215oC_0.2x0.5@0.4mm_52m.zip

@ahmetcemturan
Copy link

Well,
celebrated too early. While the above formula as it is works for the specific measured speed we actually need distance converted to Hz and put that into the formula. Otherwise we get insane acceleration rates.
So now I will be trying it with : max_acceleration_steps_per_s2[i] = (feedrate_mm_s/(1/46)) * settings.axis_steps_per_mm[i];
(That was not the only problem btw. Movement at the beginning was very slow etc. need to see what happens with this version...

@ahmetcemturan
Copy link

ahmetcemturan commented Mar 12, 2022

max_acceleration_steps_per_s2 is an integer and my calculation is not.
This is getting more complicated ... I pass.
Btw. it seems You can measure the resonance frequency with a microphone and a spectrum analyzer with peak hold for the playstore. Just in case anyone else wants to play around.

Oddly enough it is 46Hz on two very different machines. (I think this 46Hz has some other source but need to find out yet)

@ahmetcemturan
Copy link

I was able to get around the divison by zero problem by putting in 0.021... instead of 1/46.
But it seems to sometimes work and sometimes not.
I will post here if I pursue this..

@AapoTahkola
Copy link

The way I would go about this would first get some accelerometer module working with Marlin in real time then use that data to get a sense of the problem and how to solve it. Another feature that comes to mind is that one could use accelerometer data to detect run out filament and other clear cases of failed prints. My guess is that there would enough of a change in the vibrations to detect when you are printing on something vs printing on air. Anyway accelerometers are a bit hard to work with because they can generate a lot of data.

@InsanityAutomation
Copy link
Contributor

@ProfessorChi I understand Ulendo is going to be present at Rapid TCT next month and id love to get a chance to chat! Are you going to be attending?

@ProfessorChi
Copy link

ProfessorChi commented Apr 21, 2022 via email

@InsanityAutomation
Copy link
Contributor

And im just noticing you are based all of 30 minutes from me! It would definitely make sense to meet up some time, even outside of rapid!

@jrabkid
Copy link

jrabkid commented May 24, 2022

I would love for this to come to Marlin, Its the only reason I left marlin was for klipper to get Input Shaper. Unfortunately I am not a programmer but there has to be someone who is a smart cookie that can figure this out. Its like a feature that I would say most would pay a few dollars for. Thanks so far to OP and others who have got it this far. Lets hope you or others can take it over the finish line. :)

@InsanityAutomation
Copy link
Contributor

To follow up for those tracking this, we did meet up at Rapid tct and had some good discussion. We do plan to work together and get the time based planner implemented, which is the backbone any vibration compensation relies on. Don't expect their FBS algorithm to be merged in natively, as that is their product being sold and I wouldn't even ask that.

@ProfessorChi
Copy link

@InsanityAutomation It was great to talk to you at RAPID + TCT. We look forward to working with you to bring in a time-based planner and FBS capabilities into Marlin. I'll be in touch!

@jrabkid
Copy link

jrabkid commented Sep 18, 2022

Hey folks, I don't suppose there has been any update on this project by any chance? Seems this one is the only project that seems to be focusing on this topic.

@AapoTahkola
Copy link

232a104 fixed lin advance + s curve combo :)
@tombrazier I salute you!

@thisiskeithb
Copy link
Member

See #24797

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Nov 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests