Proportional acceleration control

This is a set modifications to the kinematics parameters that I developed on my printer. The end goal is to allow the printing time to be dynamically changed while preserving the distances over which the toolhead accelerates, cruises, and decelerates.

I make this topic for judging interest and to discuss the naming, compatibility and user experience issues.

max_accel

It is a bit of a misnomer with the current Klipper implementation. max_accel is not a upper bound on acceleration but the acceleration of every accelerating segments. Only cruising segments have lower acceleration, equal to 0.

Another surprising fact to newcomers is that the value set with [printer] max_accel: in the config, the value set by SET_VELOCITY_LIMIT ACCEL=, and the value set by the slicer through M204 are all assigned to the same internal parameter.

The issue is that, when using dynamic acceleration settings in the slicer, it’s is not possible to adjust the acceleration during the print on the fly from the front-end. It would be useful to have an acceleration override factor similar to the Speed factor override M220 S<percent>. [1]

max_accel_to_decel

Again, the max_ prefix is a bit superfluous. But more importantly, this feature is often misunderstood, as evidenced by the fact that the mainsail front-end labeled it “Deceleration” for a long time.

It has nothing to do with a counterpart of the acceleration for the deceleration of the tool head. Instead, the smoothed look-ahead feature of the motion planer uses this parameter to lower the maximum velocity reachable by a set of moves accelerating together. When max_accel_to_decel < max_accel, it enforces that a portion of the distance is traveled at cruising velocity before deceleration. For example, if max_accel_to_decel = (3 / 4) * max_accel, it ensures that at least 1/4 of the distance covered by a trapeze is traveled at cruising speed.

Viewed this way, It is clear that the effect of max_accel_to_decel is relative to the value of max_accel. Most users of dynamic slicer acceleration use an overloaded M204 macro that sets both max_accel and max_accel_to_decel, keeping the proportion. While this works, the ratio can’t be changed on the fly. I’d rather have something like:
image
This tells explicitly that 25% of the distance of a group of moves accelerating together is cruised. max_accel_to_decel is set to 75% of the acceleration, regardless of its value.
0% is an obvious value to disables this feature.

square_corner_velocity

This sets the toolhead velocity when cornering at a 90° angle.

The default value of 5 mm/s is recommended for entry level level printers. On the worst printers, exceeding this value would skip steps on the steppers if Input Shaping is not enabled. When IS is setup, this would result in smoothing, unacceptable for extrusion moves.

However, with IS, the cornering velocity of travels can be set much higher (I use 20-25 mm/s on my ender 3). Smoothing is not an issue with a reasonable “travel avoid distance” set in the slicer. The suggestion here is to scale the square corner velocity proportionally to √accel. With dynamic acceleration set in the slicer this would allow the travels to corner much faster, while preserving the extrusion move from smoothing, with special care for the outer walls.

This is in fact what old versions of Klipper were doing. The junction velocities were set by a junction_distance parameter and a max centripetal acceleration equal to max_accel. It was proved difficult for the users to relate this to actual cornering velocity. square_corner_velocity was added and KLipper solves for the junction_distance that would result in a 90° cornering velocity at the current acceleration setting.
A side effect of this is that acceleration changes from the slicer now affect the junction distance. I’d argue that the junction distance is the real machine dependent parameter here, and that it should be derived from the maximum acceleration set in the config instead of the dynamic one. This is equivalent to scaling square_corner_velocity proportionally to the square root of dynamic acceleration, as suggested above.

Global “speed” control

Given a factor k, if you scale:

  • The gcode velocities by k (like M220 does),
  • The max_accel and max_accel_to_decel by a factor k²,
  • square_corner_velocity by a factor k,

Then you’re scaling the print time by k while preserving the distances over which the toolhead accelerates, cruises, and decelerates.

Users often find surprising that cranking up the “speed override factor” (M220) doesn’t increase the print speed. This is because the acceleration is too low for reaching the increased requested velocity. If the accelerations are set by the slicer, there is currently no way to increase them on the fly.

Discussion

Well, first I want to thank you if you’ve made it this far :sweat_smile:

I have all the behaviors suggested in this post implemented and working reasonably well on my printer.
Now, it is unclear to me how to implement the user facing aspects of this proposal:

  • Should M220 be replaced with the “global speed control” or should a separate control be introduced?
  • How to manage the derived kinematics parameters without introducing “hidden behaviors” that would be confusing for newcomers?
  • Many problems that I did not foresee.

  1. I’m already using something similar where the actual acceleration is equal to <slicer accel> * <SET_VELOCITY_LIMIT's accel> / <config's max_accel>, with two separate variables, one set by the the slicer with M204 and one set by the front-end with SET_VELOCITY_LIMIT. Thus, in the front-end the “Acceleration” value is unaffected by the slicer dynamic acceleration and modifying it scales the acceleration accordingly. ↩︎

4 Likes

As far as I know @koconnor, he will be very leery intruducing such a change.

Before spending too much time on it, it might make sense to post a develoment branch with some instructions so that willing users can test and provide feedback.

I moved the post into the developers sections

I know, and this is what I answered to people asking me to move this forward. This is my last attempt, and if nothing comes out of it, I’ll shut up forever on these issues.

This isn’t about a specific change in the implementation, but rather to highlight a set of problems, and discussing solutions.

While they work for me, the user facing parts are far from polished. I’ll consider it, but extracting the patch set from my fork and documenting it for tester is already a lot of work that I’d rather not commit to until some sort of interest is shown.

I know @dmbutyugin has been working in code area a lot recently, at least I think so. Maybe he could bring in some thoughts.

Whatever might bring the project forward and offer a better printing experience is worthwhile to pursue. All I can offer is to test, if there is something to test.

@Piezo, first, thanks for your feedback. Let me share my thoughts on the matter.

First, I understand that you want to have some relative control of different acceleration and cornering parameters, right? If that is the case, I think you can achieve the desired effect perfectly with macros and macro variables, something along the lines of

[gcode_macro M204]
variable_accel_factor: 1.0
variable_accel_to_decel_factor: 0.5
gcode:
    {% set vars = printer["gcode_macro M204"] %}
    {% if params.S is defined %}
    {% set S = params.S|float %}
    {% set accel = S * vars.accel_factor %}
    {% set accel_to_decel = S * vars.accel_to_decel_factor %}
    {% set scv = accel * printer.toolhead.square_corner_velocity / printer.toolhead.max_accel %}
    SET_VELOCITY_LIMIT ACCEL={accel} ACCEL_TO_DECEL={accel_to_decel} SQUARE_CORNER_VELOCITY={scv}
    {% endif %}

[gcode_macro M222]  # set acceleration factor
gcode:
    {% if params.S is defined %}
    {% set S = params.S|float %}
    {% set accel_factor = S * 0.01 %}
    SET_GCODE_VARIABLE MACRO=M204 VARIABLE=accel_factor VALUE={accel_factor}
    {% endif %}

# And similarly for the accel_to_decel_factor

[menu __main __tune __accel]
type: input
name: Acceleration: {'%3d' % (menu.input*100)}%
input: {printer["gcode_macro M204"].accel_factor}
input_min: 0.01
input_max: 5
input_step: 0.01
realtime: True
gcode:
    M222 S{'%d' % (menu.input*100)}

I haven’t tested this myself, so I may have gotten some details wrong, but you get an idea, and that should work in general.

Now, to some of your points about the parameters.

max_accel

TBH, I do not understand this point. It does limit the acceleration, does it not? I’m not sure where the expectation to have different accelerations would come from.

I agree that there is a valid usecase to tune the acceleration even if you are using the acceleration control in slicer, but I do believe that no Klipper code changes are necessary to achieve that.

max_accel_to_decel

This is a feature that is fairly undocumented. There is some explanation about it in the smoothed lookahead description, but there isn’t much info provided on how it should be set. In general, this appears to be an advanced feature that the users are usually not expected to change and if they do, they should understand what they are doing. At the same time, this is a parameter that doesn’t have ‘the right value’, in my opinion. Initially, this was a de-resonance feature. Now with the input shaping available, its usefulness decreased in that regard, I think. So, a user could set accel_to_decel to anything from 0 to max_accel. Specific choices of 0.5 * max_accel, 0.75 * max_accel, 2/3 * max_accel, max_accel are just that - I do not think there is a way to argue about which value is good or ‘right’. The default value is 0.5 * max_accel, but even max_accel would likely be fine. I had a proposal to suggest to the users to up it by default to around 2/3 or 3/4 of max_value if they enable input_shaping, but I didn’t make any progress to demonstrate how much it would save on print times. I personally 2/3 * max_accel.

FWIW, in practice this wouldn’t work that way because of the upper limits on the move velocity. Depending on the geometry and the type of feature that’s being printed, the actual cruise fraction of the move(s) may very well be different even if accel_to_decel is set to a specific fraction of max_accel. In general, I do agree that it should be a fraction of max_accel, but as I mentioned above, that effect could be achieved with a custom GCode macro. And right now Klipper simply provides ‘raw access’ tools to set the parameter to whatever value you want.

square_corner_velocity

This might be the parameter that’s most frequently misunderstood by the users. FWIW, I also had misunderstanding of the purpose of this parameter, so it might be something that could be improved in the documentation. What Kevin explained to me at some point (I think it was in some thread on GitHub), is that the actual intention behind this parameter is to improve the extrusion performance rather than kinematics performance.

In short, any non-zero square_corner_velocity means non-physical cornering. That is, it is impossible for the toolhead to turn 90 degrees at non-zero velocity. Turning 90 degrees at 1 mm/sec, 5 mm/sec, 20 mm/sec or whatever will definitely result in a deviation of the toolhead from the desired square corner trajectory, and the higher the velocity, the larger the deviation will be. However, decelerating to 0 velocity at corners is also bad because, even if PA is enabled, it is a simple model that does not work very well at very small velocities. It is likely that there are other factors at play that become significant at slow velocities that are not accounted for in a PA model, such as thermal expansion of the plastic, gravity, backlash in extruder, etc. As a result, the corners would be bulging even at high PA values. So, non-zero square corner velocity is used to prevent or reduce that effect and make sure that there is at least some filament flow even at corners. So, a choice of scv should depend primarily on the extruder rather than the printer kinematic system (though one must account for the latter too). And indeed it might be a good idea to set higher scv values for bowden extruders that aren’t preforming that great with the Pressure Advance in order to reduce PA jumps. The value scv=5 mm/sec is a good all-round default value that works well for most printers. And that is why it is not advisable to increase the scv just to get higher print speeds: it is better to keep scv the same and bump the acceleration instead. That is, if the printer can sustain scv = 20 and max_accel = 3000, it is better to have, say, scv = 5 and max_accel = 5000 instead. Also, my experiments with smoothing calculation for input shaping indicated that the smoothing grows very rapidly with scv, so it is undesirable to increase scv from that POV too.

FWIW, I know that the same square corner velocity (junction deviation) model can be used on the CNC machines as well. However, I’d say from kinematics perspective 3D printers and CNC machines are very different, so considerations to chose that model are also different. For 3D printers its just nice that the junction deviation model produces reasonable cornering speeds for all angles from 0 to 180, but virtual accelerations produced by the model have nothing to do with the actual accelerations experienced by the toolhead.

Global “speed” control

FWIW, I think it would be a misnomer:

it wouldn’t work that way because in practice there are other factors involved, such as retractions, heating times, etc. So one wouldn’t get the desired reduction of the print time. That’s why, in my opinion, it wouldn’t be great to offer and/or advertise this feature to the general audience. Besides, it would mix too many limits together: velocity limits, maximum acceleration, maximum extrusion rate, etc. It is dangerous to bump them up all simultaneously, because they will have different practical limits and default maximum values in the configuration may be configured differently vs their practical limits on a given printer. Instead, it might be more practical for super-fast printing to manually tune them up to their respective limits. Also, my experience is that by cranking up the speed and accelerations one can quickly get into diminishing returns territory: the quality of the prints starts to drop very substantially for tiny gains in print times.

FWIW, it might be not a bad thing. If a user bumps the velocity by, say, 50%, and then the accelerations would be bumped by 125%, there is no guarantee that the printer will not just start skipping steps.

But in any case, that speed factor can be created using macros today (similarly to my example above). I just think that this feature may be not very well suited for the general audience (but that’s just my opinion). It still might be worthwhile to add it to some macros repo (being it on Klipper Discord or somewhere else). Is there a well-established repo for Klipper macros, BTW?

Then, Kevin some time ago had a branch with a proposal for advanced tuning for speed prints:

I think that guide never got much of discussions, but it might be worthwhile to revive it and/or put together a guide for tuning a printer for high-speed printing (e.g. faster-high-quality printing and faster-at-all-cost).

Thank you for the answer :slightly_smiling_face:

I do agree that a macro would be great for experimenting with this workflow. This is one of the reason I’ve been reticent to encourage experimentation with my modified klipper version which include other changes and an opinionated interface to these features. On the other hand I’m not arguing about weather this possible to achieve in klipper, but on the high level presentation of the settings.

I will edit the OP with a macro for testing, once I have it tested and running on unmodified klipper.

There is a few issues with your macro: SCV should scale with the square root of the acceleration. The macro is not idempotent because it queries printer.toolhead.max_accel which was set by the previous M204 invocation, it should use config.toolhead.max_accel instead.

Side note: I’ve seen a user report that a M204 macro overload for setting max_accel_to_decel caused some cpu overloads on his setup. While I find it doubtful, it might be something to worry about.

max_accel

No, it doesn’t limit the acceleration, but sets it. The acceleration is always equal to either 0 or max_accel. For contrast, on your S-curve branch, max_accel is indeed a proper acceleration limit.

For it’s current name, The expectation would be that max_accel enforces a limit on the accelerations set by slicer and the fronted.

If there is no code change in klipper, frontends won’t provide the user interface to easily change the gcode variable. They don’t want to become dependent on user macros.

How many users are there using such a macro?

max_accel_to_decel

In my opinion the documentation is not doing badly given the poor naming and parameterization of the feature. This leads to misunderstandings (lumping it to some notion of “deceleration”, like mainsail did) and cargo culting (set it to 50% accel, or > accel, but don’t ask why). My point is that, if it were instead advertised as enforcing cruising for a fraction of distances, it would be much simpler to explain it.

I’m not advocating for a ‘right’ value. I regularly use values ranging from 10% to 100% of max_accel. My main use of low values for this settings is for overloading the gcode velocities with velocities that better match the feature length relative to acceleration. This limits jumps in extrusion rate by enforcing a fraction of cruising in each trapeze.
This works great for me as I combine it with a feature that convert trapezes into linear velocity ramps if the relative print time cost is low enough (but this is getting off topic).

The ratio of cruised distance over total distance of a trapeze will always be greater than “min cruise ratio”, independently of the entry and exit velocity. The only way it can differ is when the gcode or toolhead velocity limit is reached. In this case, the cruising will be longer, hence the name “minimum cruise ratio”. This relation is quite easy to derive[1] and I’ve run analyses on simulated prints showing that the overall ratio of cruised distance matches when the gcode and toolhead speed are never reached.

Maybe we are disagreeing on the notion of move vs. trapeze (which I called “set of moves accelerating together” for simplicity)

square_corner_velocity

I agree with this, but I think it still does involve the kinematics performance: it is a balancing act of cornering fast enough to mitigate the dips in flow rate, against what the axis are capable of before skipping steps or producing too much smoothing. The upper limit for scv still is the kinematic system.

And when we do this, the junction_distance is decreased, which is nonsensical in my opinion. For extrusion moves, increasing the acceleration and decreasing junction_distance (to keep scv constant) generates trapezes with larger delta_v² which cause more deterioration of the flow rate quality than just increasing the acceleration alone.

FWIW, I think that the point of scaling SCV with √accel stands stronger with the extruder performance argument: it keeps the time spent cornering proportional to the time spent accelerating. I’m not sure how to explain this, it would be easier with data.

Also, if Klipper’s philosophy were to present raw parameter values that don’t affect each other, then junction_distance wouldn’t scale with run-time acceleration.

I grant you that it’s a stretch, but on a cross gantry or a CoreXY printer, the centripetal forces applied to the toolhead when it follows a smoothed junction (smoothed by IS and the damping of the system) are vaguely proportional to the acceleration limit, thank to the SCV limiting. Vaguely proportional rather than equal because the junction distance is indeed purely virtual.

Global “speed” control

I agree that the naming is bad, hence the double quote. But I think that you missed the point, by reaching for heating time and retraction (whose speed does scale with M220, sadly…).
The goal is not to provide an accurate scaling of the print time, but to scale the result of the motion planer in the time axis while keeping the shape of motion profile identical.

When changing the gcode velocity, acceleration or scv parameters one at a time, the motion planer output will change unpredictably in a discontinuous fashion: some move will be limited differently, other will only accelerate instead of cruising, etc. This is bad for reproducibility when experimenting with print settings.

In short, my print tuning workflow has two main parts: the ratio of v²/a relative to mean feature length, and the acceleration which controls the allowed deviation (or “sloppiness”) of the kinematic system. I want to control them independently. FWIW, I think that it’s easier for users to use this knob rather than needing to understand how all the limits interact with each other.

If the print time doesn’t decrease, it means that the print is fully acceleration bounded. The toolhead is constantly accelerating and decelerating which is bad for extrusion quality. On some printers, bumping the speed alone could deteriorate the print quality faster than if acceleration were scaled with it.
The issue of quadratic increase in acceleration could be mitigated with a proper machine_max_accel envelope and warnings that the print is going to be acceleration bounded.

I’m currently working on an implementation of this inside klipper_estimator along with an analysis pipeline for integrating the toolhead deviations under acceleration and measuring how constant the flow rate is. This should provide a test bed for different scaling methodologies of print parameters.

edits: rambling on syntax, sorry for my english :slightly_frowning_face:


  1. Without a CAS, a geometrical proof would be simpler and maybe more intuitive. ↩︎

Some random high-level comments:

Technically, max_accel is an upper bound. Although most moves will use max_accel as the acceleration, the kinematics and extruder can (and do) limit the acceleration of some moves.

If this setting is causing confusion to users, then I’d recommend trying to resolve with documentation updates. (Actually renaming the option would break many working setups.)

max_accel_to_decel is a “goofy” system. I’d happily replace it with an improved system. In the meantime, it provides useful functionality (in particular, some slicers emit zig-zag “gap fill” which causes resonances that max_accel_to_decel nicely squashes) and in my experience it has little impact on overall printing time.

I think of max_accel_to_decel as a limit on “change of acceleration”. Without this system, it is possible for the toolhead to go directly from acceleration to deceleration, which would effectively be a change in acceleration of twice max_accel. With the system, over sufficiently large time periods, the max change in acceleration while the toolhead is moving is twice max_accel_to_decel. (Though, there is still a change in acceleration of twice max_accel during deceleration to acceleration.)

It’s not clear to me that max_accel_to_decel should scale with max_accel. It was intended to prevent resonances - for example, if set to an appropriate value, I don’t see why it should further decrease when decreasing max_accel.

That said, if max_accel_to_decel can be better understood with different units or different config values, then I’m open to that. I’ve never considered it based on cruising distance ratios. (It is certainly intended to introduce some amount of cruising distance.)

As Dmitry indicated above, I view this as an extruder quality setting and not as a “kinematic setting”.

I think converting from “junction_deviation” to “square_corner_velocity” was a big user improvement. The junction_deviation parameter is difficult to conceptualize - it’s not a distance, it is a limiter on instantaneous velocity changes. Previously, I saw users doubling junction_deviation and not realize that increased instantaneous velocity by a factor of 4. I saw users try to calibrate acceleration and not realize that increasing max_accel also increased corner velocities - thus invalidating their calibration test (changing corning speed also alters extruder quality and resonance - so the test wasn’t limited to the effects of acceleration).

I think cornering velocities should be configured in a parameter specified in mm/s.

In my opinion, this would only add another knob. In my opinion, one of the most important thing 3d printing needs right now is less knobs.

Cheers,
-Kevin

I haven’t mentioned specific changes like renaming max_accel for this very reason. I do agree that backward compatibility is important.

I’m (lightly) suggesting that max_accel could be kept as an immutable parameter acting as a hard limit on a new parameter/state accel. It would initially be set from a default_accel (or whatever) in the config, and then, altered by M204 during the print.[1]

If I were traveling at 20k mm/s² and extruding at 2k mm/s², I’d have to chose a max_accel_to_decel value that would either not affect extrusion moves at all (ie. 15k), or a value (ie. 1.5k) that would needlessly enforce that 92.5% of the traveled distances are cruised. I don’t see a way around this without scaling max_accel_to_decel with M204.

In my opinion this use case against resonances is mostly deprecated when using input shaping.
As a limit on “change of acceleration", it remains useful for saving a print that would otherwise be severely acceleration bounded, by enforcing a smoother motion profile on the extruder. Not only that, but it is sensitive to local feature lengths in the print and can act as a safeguard on details even on print with well tuned v²/a. For this usage, it is more intuitively defined as enforcing a faction of cruised distance, which implies that max_accel_to_decel = (1 - min_cruise_ratio) * max_accel.

However, it’s not perfect for that use case either, because it introduces short bursts of acceleration / deceleration between cruised sections[2]. I mitigates this by converting some trapezes into linear velocity ramps if the relative time cost for the change is low enough. This further smooths the toolhead velocity in curves bounded by SCV.
This two heuristics work well together and it may be possible to derive an unified approach from them, since you’re looking for an improved system.

Indeed it was a big improvement. And, to be clear, I’m not advocating for a comeback of junction_deviation.

What I’m trying to say is that it would be better if it were computed from the config’s max_accel instead of the acceleration set at runtime. A constant junction deviation is equivalent to setting scv = sqrt( max_accel / config.max_accel) * config.scv.

I need to gather more data to weight this, but I’m mostly convinced that this is needed to keep the same motion profiles when changing the acceleration. (along with scaling the gcode velocities by √accel)

That would be an issue, yes. I’d argue that an informed user would understand that acceleration is a proxy for the forces applied to the tool-head, thus affecting cornering velocity under the centripetal model (but that might be asking too much). Also that the test itself might not be ideal if it requires out of the ordinary kinematics parameters. (Assuming that we are speaking of the PA tower test here, I think that @dmbutyugin is onto something with his new PA tuning method)

I can’t agree more.
Now, to change the acceleration of a print while keeping overall shape of the motion profile, I need to do some calculations and turn at least three knobs.

Ok, maybe I’m the weird one needing this and frantically making v²/a and v0*√(a1/a0) calculations while tuning a print. :crazy_face:

I’ve opened this topic to challenge these ideas and to see what workflow improvements could come from them. Nothing more.


  1. Actually, I have refactored the accel state out of toolhead.py into the gcode.py, if that’s of interest for discussion. ↩︎

  2. I think this was discussed in this issue: Junction velocity limits: sharp corners and smooth traversal of circles are mutually exclusive #4228 ↩︎

FWIW, I fear this would be “adding a knob” - “config accel knob” vs “runtime accel knob”.

Thanks - I think it is good to discuss these topics.

I also like your idea of changing max_accel_to_decel to something like minimum_cruise_ratio.

Cheers,
-Kevin

@Piezo, I tried to reply to most points below, but I may have missed something.

Oh well, historically, it was actually a hard limit in the config that a user could not exceed with SET_VELOCITY_LIMIT, so it was a limit in that regard. That was relaxed eventually, but the config option name stayed there. Renaming things in the config is another challenge and is annoying to the users who have to redo the config, and I heard numerous complaints in that regard, so perhaps renaming it wasn’t worth the trouble.

Yeah, as I said, it could have some bugs.

FWIW, it was intentional in case a user changed the relation between max_accel and square_corner_velocity at run-time. But the macro should be preserving the desired relation when the acceleration rate is changed.

If the acceleration is changed on every move, then maybe. But that would be bad by itself (so enabling X/Y limits may be a wrong call, but enabling different accelerations for extrude vs travel moves - quite possibly a reasonable thing).

FWIW, I do not see why it would have to be that way. Klipper itself provides rich mechanisms to customize the menus, for example. It would be a great feature if the Klipper frontends offered customizable controls too. As it is, the variables of the macros are exported in the same manner as the toolhead velocity overrides to the Moonraker, so there’s no special handling needed. Also, as far as I recall, the frontends actually require the users to define some common macros.

I do not know, but if not many, then probably this feature is not in a very high demand? But maybe users do not realize that they could easily achieve that desired effect with macros. Or maybe it actually is popular?

In the end, my conclusion is that acceleration rate adjustment may be a useful feature, but for now it may suffice to have it handled via macros. If there is a lot of demand, then its integration as Python code could be discussed. Also, it is a lot easier to iterate over the feature functionality design while it is implemented as a macro. FWIW, the similar feature for velocity rate cannot be [easily] implemented in a macro, so there’s a big difference in that regard. Flow rate, on the other hand, could be (and I did that for a mixing extruder).

As for max_accel_to_decel, I do not have a very strong opinion. As Kevin indicated, there could be arguments in favor of keeping it a separate constant and for scaling it with max_accel. Again, for now it might be worthwhile to implement it as a macro, publish it and get the feedback from the users.

I don’t think it is even vaguely proportional. Basically, with scv = 1, 5, 10, 20, 50 mm/sec (with all other parameters being equal) the toolhead will experience very different accelerations regardless of what max_accel value is. And junction_distance is just that - a virtual parameter computed from scv and max_accel and used later in the formulae, but it has no relation to the actual printer kinematics (because it does not come from the measurements). So, I find it difficult to discuss if it is sensible or not that it changes with a change of scv or max_accel - it is merely a math trick. Also, FWIW, if a move uses max_accel acceleration too, then max_accel is simply eliminated from the subsequent calculations of the maximum cornering velocity at other angles (so it is basically a function of scv and an angle, and it is linearly proportional to the scv). Only if a move uses smaller acceleration than max_accel, then the cornering velocity is proportionally reduced (may happen if a move is limited by z acceleration, or on delta printers far away from the center of the print bed).

Um, what? No, as I indicated above, if max_accel is changed, junction_deviation is updated accordingly, so then the cornering speeds for the moves (assuming they also use updated max_accel) stay the same. So, delta_v^2 is also the same. Granted, it happens over a shorter period of time, which puts more pressure on the extruder, but it’s just that.

From the ideal kinematics point of view, there is no ‘time spent cornering’, it is just 0. There is pressure_advance_smooth_time for extruder, but it is a separate parameter. It might be that the actual time the toolhead spends on the transient cornering processes increases with scv (though I do not know in which proprotion), but that time wouldn’t affect the commanded extruder trajectory - because extruder does not know that time and does not account for it. However, when you account for pressure_advance_smooth_time, then increasing scv may have more significant effect on the PA than just via delta_v - because the toolhead velocity ‘perceived’ by extruder will change due to smoothing of toolhead speed.

So, in general, you could bump scv to help extruder keep up with the PA. However, you will still have extrusion start and finish (e.g. after and before a retract), or sharp angles, where the speed anyways gets to 0 (or close to 0), so it doesn’t help there. So, raising scv only reduces problems in some places but keeps them in other places. If the extruder cannot keep up with the PA, the right solution is to either decrease the acceleration, or disable the PA and set scv high and feed rate low (as a last resort). FWIW, I never had issues with PA on direct drive extruders, so the issue might be more relevant for bowden and remote direct drive extruders (where PA may not work that well anyways).

There is indeed a kinematic limit, but arguably, it may not be a great idea to get close to that limit. At the end of the day, the stepper motor can deviate by up to 1 full step before losing a step, and that would be a whole 0.2mm (half a nozzle width) on popular configurations.

Now to Global “speed” control

My biggest concern is not that ‘it’s just another knob’, but that it’s a knob that’s unsafe to turn. * Snark * I also wish to have a knob I could turn and just get a print 50% faster. Alas, it does not work that way in practice. I suspect that if such a knob was provided and a user tried to do that, all they’d get out if it is a blob of molten plastic. So, on a printer with a reasonably tuned configuration it might be safe to bump the speed by 10-20% max. I’m not sure this feature would be broadly useful at that rate.

BTW, don’t take my words as a discouragement. In fact, on some points we do agree, like acceleration rate and accel_to_decel. And when we do disagree, my goal is just to bring different perspectives, as you anyways wanted to discuss this topic. I understand that you may have some unique needs and some things may work particularly well for your setup. I also think there are others in the same boat as you, so they may very well benefit from your work and your proposals.

You lost me in this regard. I’m not sure what second heuristic you are talking about. Is it something separate that you are working on? FWIW, I still stand by my opinion there that the circle tower being printed is too low polygonal in that case, and Klipper is trying its best to print it as a polygonal object (and it does achieve that, considering the end result). However, further velocity planning optimizations may be useful, if they are robust enough.

Sorry, I meant delta_v^2/a here.
And by ‘time spent cornering’ I really meant ‘distances traveled while decelerating to cornering velocity and accelerating from cornering velocity’. This is all about preserving these distances under acceleration changes.

I won’t delve further into this until I have actual velocity graphs to show.

So let’s forget about it. I mentioned it only to bring the relation between the four parameters and print time, which is probably a mistake on my part.
I haven’t actually implemented it. In my klipper version, the gcode speeds (M220) are left alone and M204 is the actual input that modifies the acceleration while keeping junction_deviation and min_cruise_ratio constant. That’s all there is to it. (And no, I don’t have a junction_deviation setting anywhere in my config, instead scv is specified at config.max_accel)

On that ‘second heuristic’ (slightly off topic):

Yes, that is what I meant by replacing some trapezes with a simple velocity ramp.

The problem is that there is often little benefit to accelerating above the junction speed between closely spaced vertices when SCV is the limiting factor.

When the entry and exit velocities of short segments on a curve are limited by the junction algorithm, the motion planer generates short burst of accesl/decels. The smoothed look-ahead alleviate this by reintroducing some cruising. However this yields even shorter bursts of accelerations.

After the smoothed look-ahead, the move duration is only a tiny bit shorter than if it were simply accelerating from entry velocity to exit velocity. The suggested heuristic detects this condition and replace the trapeze with a velocity ramp of low acceleration (which could be = 0 mm/s² on constant curvature paths).

Can you share your macro for M220 that acts like a global speed control. The Macro later in this topic was not yet tested.
An idea might me to limit the acceleratie/SQV to hard machine limits.

FYI, as suggested in this thread, I am proposing to replace max_accel_to_decel with minimum_cruise_ratio in PR #6418 - Replace max_accel_to_decel with minimum_cruise_ratio by KevinOConnor ¡ Pull Request #6418 ¡ Klipper3d/klipper ¡ GitHub

-Kevin

2 Likes