Add 4th order S_CURVE_ACCELERATION with configurable S_CURVE_FACTOR #27101
+65
−15
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Add configurable 4th order motion support within
S_CURVE_ACCELERATION
alongside the existing 6th order motion support.Background
4th? 6th? What? Short explanation: by default (trapezoidal motion), you set an acceleration limit (example 500mm/s^2), and then whenever the gcode/instructions involve a change in speed it is achieved by accelerating (or decelerating) at that set limit for the required amount of time to achieve the desired speed change. The acceleration goes from 0 (at previous speed) ~instantly to 1x of set limit then back to 0 (at newly desired speed). Force is mass times acceleration which means sudden changes in forces whenever changing speed.
Trapezoidal motion, showing only X-axis. Most speed changes are at 500mm/s^2 acceleration limit.
However, with
S_CURVE_ACCELERATION
the acceleration will smoothly ramp up from 0, go to roughly 2x of the limit then smoothly ramp down to 0 exactly right to achieve the desired speed change. 2x? Yes. We must temporarily go over 1x to complete the same speed change in the same amount of time but while ramping from 0 acceleration. Overall, the average acceleration remains at the set acceleration limit.S_CURVE_ACCELERATION
6th order, showing reaching roughly 2x of the acceleration limitIt's "6th order" because the motion model is position over time as a 6th order polynomial function.
However, the actual implementation works with velocity (derivative of speed) modeled as a 5th order polynomial.
Details
The problem, I might argue, is that it's "too smooth" for some applications, including 3d printers.
S_CURVE_ACCELERATION
6th order spends a lot of time around 0 slowly ramping up then it has to hit high acceleration levels. The solution would be a model with a lower order polynomial. So I did the math for a 4th order polynomial (3rd order in velocity) and this is the result:4th order, with
S_CURVE_FACTOR
of 0Note how it only reaches roughly 1.6x of the acceleration limit.
The 4th order motion allows some configuration: the acceleration will start at
S_CURVE_FACTOR
of the limit, ramp up to above 1x then smoothly back down toS_CURVE_FACTOR
of the limit exactly right to achieve the desired speed change.4th order, with
S_CURVE_FACTOR
of 0.25Note how it only reaches roughly 1.4x of the acceleration limit.
Benefits
Less smooth is more smooth™.
For 3d printing in particular, parts are printed line by line with direction changes/corners in between. Cornering is done with "jerk" or junction deviation, both of which involve basically instant speed changes. Basically instant speed change means high acceleration spikes. That doesn't pair that well with a very slowly smoothly ramping
S_CURVE_ACCELERATION
. It should pair better with a still smooth 4th order motion model that ramps up faster, like starting at a 0.25S_CURVE_FACTOR
. Lower peak acceleration should pair better with low-torque motors used in 3d printers.TL;DR
Enable
S_CURVE_ACCELERATION
, uncommentS_CURVE_FACTOR 0.25
and check whether you get less ringing and/or if the printer sounds better/quieter. Then check how much you can increase the acceleration limits before you get too much ringing.Acceleration only, this will have zero or minimal effect on ringing induced by jerk/junction deviation (but you don't know which type of ringing you have until you test). For the other kind of ringing I think you can try input shaping.
Configurations
This feature is not implemented for AVR. If interested I encourage you to have a go at implementing if you have a logic analyzer, an AVR board and are interested in assembly.
The graphs were obtained with a logic analyzer capturing 15M samples at 12Mhz, directly from the X-axis step/dir pins. (Just FYI my boards are LPC176x). Tiny note that captures were done with PRs #26881 and #27035 already applied. I did that to fix some issues that would pollute the captures a tiny bit.
Test gcode:
Related Issues