This is a follow-up to a topic which already was here a long time ago, but I can't find it anymore. If someone remebers it and can find the issue, you might link it here.
During the research for strange jerk behaviour today I stumbled around the suboptimal handling of junction speeds again. In one sentence: Marlins way of handling jerk and junction speeds leads to exceeded jerk in some daily situations.
The attached test gcode and the results in the table should clarify things a bit. The gcode does the following things:
I printed the following values over serial:
I did two runs, first with X and Y jerk set to 5 and E jerk set to 1mm/s, and a second one switching the values. As you can see, as soon as we are switching between extruder only moves and XY moves things start to get wired. Same should be true for Z only moves and XY moves.
The problem is that Marlin connects each segment by one single junction speed, which is not always what is needed. A simple example like the one from H13 in the table, lets assume a X Jerk of 1, an E jerk of 5. Let's do a print move along X followed by a prime move. What we want ist:
The two axis X and E are not linked, also their junction speeds shouldn't be linked. What Marlin does is in this case is:
It becomes crucial when we replace the first print move by a Z move. Z axis often have 0.x jerk values, but the final speed would be also 5mm/s due to the following retract move.
Conclusion:
Files:
Marlin Junction speeds.zip
GRBL will not help
Ah, well so much for my first suggestion…
Well, at some point we should try implementing a proper "junction deviation" and see whether it helps … and whether it's expensive to compute. We may be able to get away with using a table or some other cleverness to avoid having to do trigonometry.
But before we get into that, we should definitely figure out how to de-couple the E axis from the linear axes. And, it seems XY also needs to be less bothered by Z direction changes. Maybe for Z direction changes we can relax the Z jerk limit a bit. The thing is that Z seldom has anything like the same inertia as the XY axes. You'd think Z would be more amenable to direction changes, especially when going from raising to lowering.
I think the way we calculating jerk at the moment is already quite good. Check for all axis jerk limitation, reduce entry / exit speed if one axis is exceeding the limit. But as we have to check entry and exit speed for jerk, we need to know about the previous and (that would be new) the next segment. At the moment, the planner assumes exit speed = next entry speed is always OK. So it needs to go into the forward or reverse planner. And it has to make a decision if the junction speed has to be linked or not. Some draft ideas:
Clearly we need to do test prints to simulate some of the effects before start coding. I think I could have some fun doing that, but it's something for the middle future - we don't want to release such a big planner change without intensive tests..
I want to put some questions here to think about them. Maybe there are some intresting answers comming?
I'm looking forward to read your opinions!
Why do we link the junctions speeds at all?
This seems to be a legacy of the XY gantry design of the Ultimaker that probably should not apply to Mendel X carriage / Y bed setups. And neither of those should be linked to Z. Before bed leveling came along, in 3D printing Z moves were almost always isolated Z or Z/E moves.
The theory of XY gantries seems sound — you do want to limit the inertial load of the carriage block, even though XY each have their own separate inertial loads too. I think you're onto something in pointing out that separated axes should only apply load limits on a per-axis basis and not in terms of the combined motion in the XY plane.
Better not to think too hard about deltas.
Hi,
I apologize for barging in on the conversation, but I think I have some relevant information. In my opinion deltas are an important group of machines and Marlin has treated them as "second class citizens" long enough.
I have been trying Marlin 1.1.8 (https://github.com/ruevs/Marlin_Anycubic_Kossel) and Repetier 0.92.9 (https://github.com/ruevs/repetier_anycubic_kossel) on the same delta printer. The configurations are as close as possible to each other. Max speeds and accelerations are the same. The jerk is 10 in Marlin and 20 in Repetier. As I understand that after this https://github.com/MarlinFirmware/Marlin/pull/8888 those values should lead to similar results.
And now the interesting part. I tested the printer with this G-Code SpeedTest.zip with both firmwares.
And here is the result:
https://youtu.be/JCflNCotl70?t=1758
Repetier drives the steppers "smoother" (the sound is softer and less "scratchy"), finishes the test a bit faster and with less vibration/jerk.
In my opinion something in the way Marlin drives the steppers in deltas is... different and not optimal.
@ruevs please try the current bugfix-1.1.x
. We patched a basic fault in the delta planner code which resulted in real speeds (and all derived values) way off the defined value and I'm quite sure this PR was done quite some time after 1.8 was released.
In my opinion deltas are an important group of machines and Marlin has treated them as "second class citizens" long enough.
We continue to incrementally improve Marlin's delta support, and have done loads of optimization in recent releases and in the upcoming release. If someone brings us a comprehensive overhaul that addresses delta concerns in the form of a nice PR we would be _more than thrilled_.
In my opinion deltas are an important group of machines and Marlin has treated them as "second class citizens" long enough.
Perhaps nobody decided to treat Deltas as "Second Class Citizens". Maybe there is another explanation.
Deltas have only a small percentage of the users that Cartesian machines have. So this means first of all, it is much harder to get code developed and tested on Deltas. But it also means there are less people even interested in writing code for them. With that said, we do try hard to make the code work well on all machine types.
Please do not take my comment the wrong way. I realize that Marlin has improved a lot in 1.1.x in terms of delta support. I only said it in response to thinkyhead's comment:
Better not to think too hard about deltas.
As for a pull request - if I ever have enough time to understand the code deep enough to actually improve or revamp the planner and stepper motor control logic for deltas I would certainly do so. Unfortunately this is unlikely.
Better not to think too hard about deltas.
That is to say, for any indirect kinematic system Jerk and Acceleration apply to the movement of the steppers, and not to the linear movement of the tool. Thinking about this too hard may lead to headaches.
@thinkyhead Just retested the initial test pattern of this issue with the new junction code (#10650, JUNCTION_DEVIATION_INCLUDE_E is disabled) , this is the result:
I see some intresting results compared to the initial results:
Enabling JUNCTION_DEVIATION_INCLUDE_E increases the jerk speed for print moves and e-only moves slightly.
Thanks for bringing this back on topic. I definitely want to make the junction behavior more sensible, whether using the old jerk method or junction deviation. What we really need is to decide what the ideal behavior should be first, and then make needed adjustments to get it to produce those results as closely as possible. Your earlier points can act as a starting guide.
Just a short addition to my last post:
Not only e-only moves suffer due to the new jerk code, also z moves (layer shifts) are affected. As z-axis often uses very low jerk limitations (0.x), this can definitly result in missed z steps. Maybe even worse, on a system which uses 2 z steppers, only one might miss a step resulting in a skewed axis.
The code change was a good first step, but some more work is necessary to make it secure and fully usable.
Not only e-only moves suffer due to the new jerk code,
@Sebastianv650 — Which "new jerk code" are you referring to in your comment? We have the sort-of-new jerk code related to the planner refactor (though it should be essentially the same limit-per-axis method) and then we have the new (but optional) JUNCTION_DEVIATION
jerk code. The Bézier S-Curve acceleration is also new, but it follows after the main jerk calculations.
I'm refering to JUNCTION_DEVIATION
.
Should Z be excepted from the Junction Deviation technique? It's certainly not like the XY axes. Likewise, with any move not involving X and/or Y…
Should Z be excepted from the Junction Deviation technique
Only if you want to disregard 3D CNC Routing, my Z axis is the same as XY (velocity and acceleration wise) and in finishing passes on organic geometry can be moving pretty fast.
I think we probably want to disregard any axes that have low top speeds. That would filter Z and E on typical 3D printers, while allowing you to use CNC and arcs in vertical workspace planes.
Maybe we need a two-step approach. For example on acceleration we already use a print acceleration and a max. acceleration per axis. If one axis max. acceleration is violated by the print acceleration, it will get lowered.
Same procedure can be applied on junction jerk. If the speed change on an axis from current to previous is bigger than axis max. jerk, limit the junction speed.
If the user sets all max. jerk per axis values to a high number (as we already have it for max. acceleration on many printers), this limit will never engage. So no problem for 3D CNC for example.
This might also solve the problem with wrong junction speeds which I pointed out at the start of this issue?
What is Grbl doing to mitigate the issue? Have we failed to fully duplicate their approach?
I asked myself the same question, how GRBL sets limits for each axis, when I did my small Excel sheet for junction speed calculation. After reading their docs and code, I came to the conclusion that there is actualy no way to do this in GRBL since they use this jerk method.
OK I have to correct what I just wrote. It's not very obvious, but I guess @thinkyhead we are realy missing an important piece of GRBL for JUNCTION_DEVIATION
.
See https://github.com/gnea/grbl/blob/master/grbl/planner.c#L446, the key is junction_acceleration
which is an acceleration value based on used acceleration (we would call it travel or print acceleration) and the junction_unit_vec
. What they do is to calculate an acceleration which will not violate the acceleration limit per axis. For Z, which has the low jerk problem, we also use low accelerations. I checked that on my machines and the example configs inside Marlin. So, a low max jerk means also a low max acceleration on an axis.
Given that, a lower junction_acceleration
and therefore block->max_junction_speed_sqr
is the result.
In the Marlin implementation, we use a fixed JUNCTION_ACCELERATION
. This completely ignores the axis acceleration limits!
Should be easy to fix, lets see if I can patch it..
@sebastianv650 there is a hint in the comments in the main fork of the grbl that it should take the minimum acceleration of the two blocks, I think you might need this to cover off both sides of this problem.
I am completely on board with @Sebastianv650's suggestion of using the actual junction acceleration (I never really understood why we moved to a fixed value). In normal movement this means that junction deviation will factor a heavy slow moving accelerating axis (y) in the calculations. This would mean that the nonagon example (https://github.com/MarlinFirmware/Marlin/issues/10341#issuecomment-391051458) might not always produce the same junction speed - a move with more acceleration on a slower accelerating axis (i.e. mostly y) should slow down more.
However, I'm not completely convinced that it will solve this problem completely. Could it be as simple as hard setting the junction speed to 0 for E or Z only moves (with an option to not do this on Z for our CNC friends)? This method could also be applied to both Jerk and Junction Deviation solving the problem in both scenarios.
Edit: If done, how would setting a 0 junction speed work (or not work) for the z-hop in fwretract?
@Squid116
there is a hint in the comments in the main fork of the grbl that it should take the minimum acceleration of the two blocks.
I read that, but this note is no longer present in the recent 1.1 GRBL code with the use of junction_acceleration
. But I have that in mind to try it out. Basicaly it should make
Could it be as simple as hard setting the junction speed to 0 for E or Z only moves
not necessary.
I got the junction_acceleration
to work yesterday and I will create a PR for testing purposes in the next minutes or hours depending on my test results satisfaction.
But I have that in mind to try it out.
I think it would really be needed in order to get this working in all cases. Take the heavy Y bed as an example, if you go from a move along Y to a 90deg corner travelling along X, then this is only going to consider the acceleration on X for this junction, not the lower deceleration needed for stopping Y. The result will be a faster junction speed than Y can sensibly handle.
That's the best-looking junction ("jerk") speed result I have ever seen from Marlin! Now we head into the right direction 👍
So what do we see here:
It's my small junction speed test code using my patched JUNCTION_DEVIATION
code. On the left side, you can see the gcode lines colored into three sections.
This gcode can also be used for Z-axis test if you replace the limit values of the E axis in Marlin by values for Z.
On the right two collumns you see the initial and final speed of each move. The acceleration limits for each axis are 3000mm/s² for X and Y, 200mm/s² for E.
The print and travel acceleration is set to 1000mm/s² and JUNCTION_DEVIATION_MM
is set to 0.02mm.
Things that can be checked due to this result:
junction_unit_vec
. I have not yet dived into this so I can't tell exactly how, but it works.@Squid116
Take the heavy Y bed as an example, if you go from a move along Y to a 90deg corner travelling along X, then this is only going to consider the acceleration on X for this junction, not the lower deceleration needed for stopping Y. The result will be a faster junction speed than Y can sensibly handle.
Not any longer with the new jerk code. I will create a quick and dirty test-PR next so we can test it.
Awesome work - I look forward to testing it out this evening. :)
Not any longer with the new jerk code.
Looking at the PR, you are 100% correct - the junction_unit_vec
factors in the previous block so all should be 👍 .
Just thinking, now that junction acceleration is set proportional to the junction vector, do we still need the special case for blocks < 1mm? It cant hurt the output as it always takes the minimum, but is it necessary to add these extra calculations on small moves?
I wasn't looking at the <1mm code section. What was the intention for that special handling?
The code change I did in the PR shoudln't alter the handling of short moves, as all vectors are always unit vectors, therefore their length is always 1.
The special case was for a 90 degree corner that was broken up by the slicer into several smaller turns, with a fixed junction_acceleration (i.e. not proportional to the vector) it was basically slamming into a 90 degree corner at full speed.
Here is where the 'special' case was devised: https://github.com/MarlinFirmware/Marlin/issues/10341#issuecomment-387922944
If we have a very small fillet so that a 90° corner is split into some small segments as you described it, this behaviour will not be change by my PR.
On the other hand, this cornering at full speed is quite fine according to the theory and also handled like this by the original Marlin jerk code. Many small segments result in tiny angular deviations from segment to segment, therefore no need to slow down. Even if this segments form a radius of 0.001mm in reality.
So maybe if we slow that down in JUNCTION_DEVIATION
code, the same has to be applied to original jerk code. Or we handle it not at all, as we did all the years in the past. The centrifugal force should be limited by the acceleration setting even without that <1mm thing..?
Or in other words, I'm asking myself if that's only a problem due to an improper jerk setting.
If we have enough look-ahead we should be able to discern that an acute angle is formed by two or more very short moves. But also, Marlin will skip moves that are so small as to be pointless. With Junction Deviation enabled, perhaps it makes sense to simply skip any moves under —let's say— 0.125mm, and just let these tiny moves get merged into one less-tiny move.
It would be good if @hoffbaked couldn't this new change both with and without his special case for short segments - he implemented this due to problems he encountered in this scenario with a fixed acceleration.
I should have some time to get a closer look tonight, and run a few tests, but I never had the problem hoffbaked saw, mind you I only tested a) using block->acceleration and b) JUNCTION_ACCELERATION with the special case handling.
I’ll take a closer look in a few hours, but the issue I was running into was a rounded corner with sides about 1/10th of a mm and an angle approaching 180 at the junction. It added up to a 90 degree turn over the course of less than a mm, but the normal junction code perceived it as a nearly straight junction and didn’t slow down at all.
Okay, so that looks like a good way to go, but it seems like there's a problem, if I'm reading this right. They're subtracting the two vectors and then calculating the acceleration based on those proportions. Wouldn't it make a lot more sense to use:
float junction_acceleration = MIN(
limit_value_by_axis_maximum(settings.acceleration, unit_vec),
limit_value_by_axis_maximum(settings.acceleration, pl.previous_unit_vec)
);
I'm assuming limit_value_by_axis_maximum
uses the movement proportions and the axis max acceleration.
With subtracting the two vectors, it seems like a long move and then a z hop wouldn't correctly limit to the z acceleration value since it's a way shorter move. If I'm thinking about this right, it seems like you'd need to consider the two moves independently.
And we would definitely still need to check for rounded corners. The grbl code handled it by just slowing down as the line segments got shorter in a completely different section of code.
I'm not sure whether it's better or not. Something Grbl missed?
And, this might be quicker than calling limit_value_by_axis_maximum
twice…
float junction_acceleration = limit_value_by_axis_maximum(
settings.acceleration,
MIN(unit_vec, previous_unit_vec)
);
The grbl code handled it by just slowing down as the line segments got shorter
Interesting approach. Since we have a lot of short segments, due to kinematics and leveling, this might cause some weird side-effects.
I'm assuming that the function finds the proportionate maximum for the vector, such that a primarily Z move will return primarily the Z limit? Even if the Z hop is half a mm, it still should be setting the speed limit for that particular junction, I would think.
@hoffbaked can you link to the GRBL which causes short segments to slow down?
It seems like a long move and then a z hop wouldn't use the z acceleration value since it's way shorter of a move.
As we are talking about unit vectors, I don't think so. If we have a 100mm move along X, followed by a 0.5mm Z hop, the vectors are [1,0,0] and [0,0,1]. The length isn't important at all, only the direction of the move.
I would be very careful now making changes compared to the GRBL code. We now have a working junction speed code the first time since I started to use Marlin, we shouldn't screw this up again.
So, every change should be proved by numbers, not something like "it seems to move right".
@hoffbaked the junction_unit_vec accounts for the previous block - so you don't need to do the minimum of the two blocks.
I thought the vectors were of the deltas? Even so, their code looks weird. If you have a 10mm Z move, followed by another 10mm Z move with 1mm X, the Z moves get subtracted out, but it seems like X would win.
@hoffbaked yes X "wins" here, and that's perfectly fine as we only have a change along X in your example.
Let's go through it:
The unit vector of the first move is [0, 0, 1]. The second move is [0.1, 0, 0.995].
The junction vector is the delta between the two:
0.1 - 0 = 0.1
0 - 0 = 0
0.995 - 1 = -0.005
and then normalized, so the vectors lenth is 1: [0.995, 0, -0.05]. This is now used to check against axis acceleration limits. It's basicaly the same thing Marlin already does inside the planner when it checks if a move has to be executed with travel or print acceleration, where it checks each axis after that to see if the acceleration has to be lowered due to some slow axis.
Just done by vectors instead.
Okay, the above scenario is fine, but it still seems like the junction speed on the long movement, Z hop scenario is not going to take the Z max acceleration into account, and the junction speed will be higher than intended. It'll be treated as a 90 degree corner using the maximum acceleration value of the long move.
The vectors are in millimeters, and are not normalized. You can see they're used above to calculate the block->millimeters.
@hoffbaked they are calculated and normalized in this step:
https://github.com/MarlinFirmware/Marlin/blob/bugfix-1.1.x/Marlin/planner.cpp#L2123
Oh, jeez. Thanks!! I missed that. I guess it at least would end up the average of the two maxes on a Z hop, which is still not ideal, but it would at least make a dent.
I've been basing all my observations off the grbl code. If they're normalizing the values, I don't see it. Strange.
I've been basing all my observations off the grbl code. If they're normalizing the values, I don't see it. Strange.
At this point, they are setting up the non-normalized vector even if it's already named unit_vec
: https://github.com/gnea/grbl/blob/master/grbl/planner.c#L374
A few lines later, they normalize the vector and get the length of the move "at the same time": https://github.com/gnea/grbl/blob/master/grbl/planner.c#L387
This vector is baseline for all futher calculations like the junction speed.
@hoffbaked with this sorted out, what do you think about your check for small movements now? Is it still a valid change?
I had no time to check the result of this modification up to now, but with some luck I can do it this afternoon.
Ah, tricky. : ) Yes, it definitely will plow through tiny rounded corners at impressive speeds without it.
Incidentally, on the acos approximation, subtracting the .18 maximum error was probably a bit too conservative. I've been testing it on my machine with .05 with a bit less slowdown. As the angle approaches 180, the errors get magnified and it slows down more than it needs to in some cases. I've been meaning to try and find a little more accurate solution, but life has been pretty hectic.
I plotted a graph to get a feeling for this limited szenario, using segment lengths from 0.2 to 0.95mm and junction agles from 140 to 170°:
The steep curve is the original junction speed value, the more flat one is the limited one.
It definitly works as intended, thats nice to see. Nevertheless I still have that questionmark in mind if we realy need it. Sure, it will pass a high-resolution arc at whatever speed was set with G1 F command. But that's how it should be as we are saying the centrifugal force is the acceleration we are allowing based on axis limits and print / travel acceleration. The more segments, the closer we are on a perfect arc. A perfect arc can be driven at high speed, as no jerk occures at all. Slowdown should be only necessary if we have real corners, therefore we are not close to an arc.
I guess I have to do some test prints with and without that limiter active and see what I get.
OK, I can see the need in test prints (40mm cubes with 1mm radius on the edges). While the jerk seems not to be "hard" to the machine, it still results in quite an amount of ringing.
So we can see the basic junction_deviation code as a speed limiter for corners of any kind (as the name suggests), und this add-on as a speed limiter for close to real world arcs.
Great investigations @sebastianv650 picture paints a thousand words!
I have just been trying to dial things in with the new code, would it be worth adding JUNCTION_DEVIATION_MM to M205? After a machine is initially set up it is unlikely to change, but it would make the process of getting all set up easier.
In MK4duo we now have M205 J to set JUNCTION_DEVIATION_MM
At the moment the JUNCTION_DEVIATION has a very basic implementation. Yes, definitly we need an M code to change the value and we should also have an LCD menu entry for it.
On the other hand, X Y and Z jerk values should be removed from the LCD when the new version is used. E jerk is a special case, as linear advance needs it. So this one must be available in the menu if LA is enabled. Else, it should be also removed.
I think it's just a question of time until I or someone finds a free slot.
M205 J
sounds like a good plan. I'll add that soon.
I see that the max_jerk
array is completely unused when JUNCTION_DEVIATION
is enabled, with one exception. The max_jerk[E_AXIS]
is still used if LIN_ADVANCE
is enabled. Is that value important to retain while JUNCTION_DEVIATION
is in use, or could it be substituted? Asking because if max_jerk
can be dropped when JUNCTION_DEVIATION
is active, then it saves some SRAM and EEPROM space.
I'm just working on M205 J
and the LCD edit option… What's a good range of values for the planner.junction_deviation_mm
setting?
@thinkyhead 0.01 to 0.3 is the range I have tested with. The lower end being more realistic. 0.3 is getting very sloppy on the corners.
I'm using the default 0.02. As we are already at 0.0x level, maybe we need even 3 digits some day to get even lower?
@thinkyhead in theory it should be possible to replace max_jerk[E_AXIS]
for LA with the equivalent term from junction_deviation. This would be:
max_ejerk [mm/s] = SQRT(SQRT(0.5) * max_acceleration_mm_per_s2[E_AXIS] * junction_deviation_mm) / (1 - SQRT(0.5))
In reality, max_acceleration_mm_per_s2[E_AXIS]
is often not set properly (10000 for example) so it will result in some issue threads I think. But in the end that's "just" a problem with a bad configuration.
@Sebastianv650 — Based on your comment I've added a new planner variable that gets recalculated whenever junction_deviation_mm
is updated.
Given that a lot of configurations have an E acceleration of 10000, what would be a sensible starting setting for typical extruders? So for instance I have an e3d Titan Aero, but have no idea what acceleration figure to set or how to go about tuning it? I'm happy to run some tests if anyone has a recommended process? @Sebastianv650 @thinkyhead ?
@thinkyhead oh no I just realized I made a mistake with the brackets in the equation above while I calculated the acceleration for @gloomyandy using it!
Instead of
max_ejerk [mm/s] = SQRT(SQRT(0.5) * max_acceleration_mm_per_s2[E_AXIS] * junction_deviation_mm) / (1 - SQRT(0.5))
it should be
max_ejerk [mm/s] = SQRT((SQRT(0.5) * max_acceleration_mm_per_s2[E_AXIS] * junction_deviation_mm) / (1 - SQRT(0.5)))
It's the same equation used by the junction deviation code, but with a fixed sin_theta
value of 0.707 (=SQRT(0.5)) and a SQRT
in front of all as we don't need the squared speed for this example.
@gloomyandy I would start by searching for an acceleration which results in realistic speeds for "ejerk" with your used JUNCTION_DEVIATION_MM
value. Given the formula from above and a junction deviation value of 0.02mm, this would result in an max. e acceleration of 2100mm/s² for what would have been an ejerk before of 10mm/s.
Hi,
thanks for the update I will give 2100 a go and work from there. A quick question about the brackets error. Will this be likely to have impacted the tests I've been running using the linear advance test program to determine the best K to use(I was using a very recent bugfix-2.0.x with junction deviation enabled), should I run those tests again once the above change has been made?
Also on a related topic. When using a combination of junction deviation and linear advance, what is likely to be the best setting for JUNCTION_DEVIATION_INCLUDE_E, does it make sense to enable it or not?
@Sebastianv650 — Thanks for the correction! I've applied the patch to both bugfix branches.
Hi,
great work with the junction deviation! I just go through the math behind the junction deviation and linear advance. Since the max. velocity calculations for linear advance are not squared (like for the junction deviation), the calculations for the MAX_E_JERK is:
SQRT(SQRT(SIN(Theta/2)) * max_acceleration_mm_per_s2[_EINDEX] * junction_deviation_mm) / (1 - SIN(Theta/2))
You spitted this calc using max_e_jerk_factor:
max_e_jerk_factor SQRT(SQRT(0.5) * junction_deviation_mm * RECIPROCAL(1.0 - SQRT(0.5)))
and
MAX_E_JERK (max_e_jerk_factor * max_acceleration_mm_per_s2[_EINDEX])
But shouldn't it be like this? of did I get something wring?
MAX_E_JERK (max_e_jerk_factor * SQRT(max_acceleration_mm_per_s2[_EINDEX]))
Another Question: Did you you use a 90 degree angle (theta) for the extruder, because this represent a "stop"?
@JackDaFlow you have the same bracket error in your first equation I did initialy. Everything has to be SQRT(), not only the upper part of the fraction.
MAX_E_JERK (max_e_jerk_factor * SQRT(max_acceleration_mm_per_s2[_EINDEX]))
That's true. I have not looked into the code this moment, but this version results in the wanted value.
Another Question: Did you you use a 90 degree angle (theta) for the extruder, because this represent a "stop"?
Yes.
So to clarify the current code looks like..
#if ENABLED(JUNCTION_DEVIATION)
#define MAX_E_JERK (max_e_jerk_factor * max_acceleration_mm_per_s2[_EINDEX])
#else
#define MAX_E_JERK max_jerk[E_AXIS]
#endif
does it need to be changed to:
#if ENABLED(JUNCTION_DEVIATION)
#define MAX_E_JERK (max_e_jerk_factor *SQRT( max_acceleration_mm_per_s2[_EINDEX]))
#else
#define MAX_E_JERK max_jerk[E_AXIS]
#endif
It looks like it should be possible to avoid the repeated calls to SQRT if so...
At this point I think we've got it sorted in both branches! Anything more to discuss or should we close this thread?
I think there are still some documentation issues around. Like for instance when should you enable JUNCTION_DEVIATION_INCLUDE_E? Does this interact with linear advance? Does it make sense to enable both?
Sounds like we will need to gain more experience to be able to answer those questions.
@Sebastianv650 mentioned removing the JUNCTION_DEVIATION_INCLUDE_E here: https://github.com/MarlinFirmware/Marlin/pull/10906
I tend to agree, I think it should always be enabled and the option removed.
@Sebastianv650
I am somewhat puzzled… I used to have in my working configuration the following acceleration setting…
#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 } //tuning lrp 3000, 3000, 100, 10000 } Tested ok except E axis
/**
* Default Acceleration (change/s) change = mm/s
* Override with M204
*
* M204 P Acceleration
* M204 R Retract Acceleration
* M204 T Travel Acceleration
*/
#define DEFAULT_ACCELERATION 1500 // X, Y, Z and E acceleration for printing moves
#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts
#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves
/**
* Default Jerk (mm/s)
* Override with M205 X Y Z E
*
* "Jerk" specifies the minimum speed change that requires acceleration.
* When changing speed and direction, if the difference is less than the
* value set here, it may happen instantaneously.
*/
#define DEFAULT_XJERK 10.0
#define DEFAULT_YJERK 10.0
#define DEFAULT_ZJERK 0.3
#define DEFAULT_EJERK 5.0
I put your formula in excel
max_ejerk [mm/s] = SQRT((SQRT(0.5) * max_acceleration_mm_per_s2[E_AXIS] * junction_deviation_mm) / (1 - SQRT(0.5)))
For a junction deviation = 0.02, this formula gives me
either
a max acceleration of 517,9 for an ejerk of ~5,0
or
an ejerk of ~12,0 for a max acceleration of 3000
Obviously, one or several of my values were out of tune… Max acceleration was too high, the sloop of speed change was ok for the retract… should I conclude that my ejerk was too small??? I am driving a 3mm abs filament thru a greg wade extruder with a couple of gears with a ratio of 37-13...
I feel uneasy, did I miss something??? is that "calculated ejerk" value anything but limit or is that value actively used?? Of course I will conduct some testing and learn from my mistakes, but if you could help me make some educated guess, I would be quite thankful.
@Sebastianv650
Typing my question above led me to think from another perspective… Could it be that a 2mm retract is not enough of a move to go past the physical acceleration induced by the ejerk value???
If so, should I limit the max acceleration to 1500 leading to an Ejerk of 8,5???? I will be using S-curve-acceleration so this should allow my printer to allow higher number for moves (not higher overall speed I now predict)
@lrpirlet I'm not sure if I understand you problem. Is it because your initial max acceleration values don't result in the ejerk values you had before junction_deviation using the equation? That's fine, as they were not linked in any means by the "legacy" jerk / acceleration code.
You can think of the junction deviation = 0.02 being the new jerk value. Given an acceleration, it results in junction jerk speeds. So you can still tune jerk and acceleration separate from each other, but linked by this value.
For linear advance, this ejerk speed value is used as the upper speed limit at which pressure corrections can occur.
Could it be that a 2mm retract is not enough of a move to go past the physical acceleration induced by the ejerk value???
The length of a move and the acceleration are not linked. If you mean top speed: With 3000mm/s² you can reach about 110mm/s even when starting from 0mm/s speed after 2mm.
If so, should I limit the max acceleration to 1500 leading to an Ejerk of 8,5?
A typical retract speed of 40mm/s is reached after 0.25mm @ 3000mm/s² even without any jerk. So if you want to reach an ejerk of 8.5mm, even an max. e acceleration of 1500mm/s² will not limit your printing speed noticeable.
@Sebastianv650
Thanks, what makes me wonder, is that we use to be able to set INDEPENDENTLY max speed and jerk… When coming from a well tuned version 1.? to the bugfix_2.0.x version I did try to match my old parameters to the new… And here is a hardcoded relation...
Using the new features, I feel like facing a completely new firmware with nearly no relation with the old one… Trying to understand the interaction between the new features is quite a challenge… I do not want to keep hanging on the "good old way of doing things" when what I see could really solve some of the problems I am facing today…
Question was and is really: what is a good approach when the examples do NOT use the new features, I did try to understand from a theorycal side… I better have to jump in practical side and make mistakes, I guess…
Anyway, I do appreciate your help… thanks again.
I presume we'll have to document the updated (i.e., corrected) meaning of the jerk parameters for 1.1.9 and give recommendations for the appropriate values to use. And we should also update the configurations with reasonable values. @lrpirlet — What values are working well for you now, and what values were you using before?
@thinkyhead
Sorry, I have no experience yet… My heated bed shorted, the FET melted shorted, the RAMPS printed board heavily smoked, the fuse did not (completely) fuse… I am waiting a new bed, a new RAMPS... Not sure to get it before the holliday so not before 3 weeks or so...
I can still move the axis of the printer, I think I could extrude, but with ABS, there is no chances to get anything but a big mess…
To answer your question, the max acceleration for X, Y Z seems to be compatible (I did run a dryrun print). At completion, I was able to move the hot end back to the exact same place marked before execution. So no steps lost…
For E, I will limit the DEFAULT_MAX_ACCELERATION to 1500 giving an equivalent ejerk of about 8,5... I hope the extruder will bear with it… I may have to drop down to 500 if I really need an équivalent ejerk of 5... For what concerns retraction, that used to need 40*60 (2400), I was thinking to use LA and completely forget retraction…
AGAIN, NO EXPERIENCE YET... but I feel uneasy with E axis
I was starting to use junction deviation, currently set my initial parameters according to the equation:
max_ejerk [mm/s] = SQRT((SQRT(0.5) * max_acceleration_mm_per_s2[E_AXIS] * junction_deviation_mm) / (1 - SQRT(0.5)))
Using my old jerk values and the default junction deviation value of 0.02 I derived my accelerations, this seemed to work fine for x, y and e, it resulted in sensible values and printer seems to be pretty happy with it. But what hapens with the Z axis? Using my old jerk of 0.4, the formula results in an acceleration of 3.3 mm/s^2. This doesn´t seem right. Is this calculated differently?
The older acceleration I used in Z, 1500 mm/s^2, leads to a jerk of 8.5. I see on a post above that it was said that this values are fine if they are different becuase they are not linked to previous value. But then, what should it be set to?
@Itox001 your z axis will most likely be just happy with the values. Prior to all this changes even if you had set the z jerk to 0.4 the real jerk in about 50% of the situations was the XY jerk value. That's because this jerk was only applied to the entry speed, but the end of the move should have ended at z jerk speed also.
@Sebastianv650 @Roxy-3D
has the new JD calc's not made this one "surplus" or is it still relavant?
this one has gone stale and discussion could continue on discord
Marlin Discord server. Join link: https://discord.gg/n5NJ59y
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.
Most helpful comment
I plotted a graph to get a feeling for this limited szenario, using segment lengths from 0.2 to 0.95mm and junction agles from 140 to 170°:
The steep curve is the original junction speed value, the more flat one is the limited one.
It definitly works as intended, thats nice to see. Nevertheless I still have that questionmark in mind if we realy need it. Sure, it will pass a high-resolution arc at whatever speed was set with G1 F command. But that's how it should be as we are saying the centrifugal force is the acceleration we are allowing based on axis limits and print / travel acceleration. The more segments, the closer we are on a perfect arc. A perfect arc can be driven at high speed, as no jerk occures at all. Slowdown should be only necessary if we have real corners, therefore we are not close to an arc.
I guess I have to do some test prints with and without that limiter active and see what I get.