bkubicek/Marlin

extruder retract breaks motion planer

dirk-makerhafen opened this issue · 4 comments

If extruder retract to prevent oozing is enabled, the motion planer does not decelerate at the end of a move when the next move is an extruder only move.

G1 X-10 Y-10 Z0.45 F6000.0
G1 F60000.0
G1 E10.00 ( retract )
G1 F6600.0
G1 X5 Y5 F1000

leads to a non decelerated stop after the first gcode command.
I think this happens because the Motion Planer ignores that the next move has a speed that isnt related to the axis of the current motion. On small, or standart makerbot/ultimaker Hardware this may be ignored, but our machines have an axis weight of 65kg, so any sudden stop is quite noticeable, especially at high speed at 60-120mm/s

I couldn fix it, but i think its in "void planner_reverse_pass_kernel(....}{....} "
exit_speed = next->entry_speed;

From a quick look, this seems to also happen in GRBL, and Erik Zalm's marlin version, although the code looks slightly different.

Greeting
Dirk

Attraktor Makerspace Hamburg

Ps: Hi Bernhard:)

me and Erik joined forces and merged our code. Due to my lack of git-wizardry at that time, the history was lost. The most current Marlin is to be found here: https://github.com/ErikZalm/Marlin
We are somewhere between the first public beta and the release candidate.
Erik did an upgrade of the grbl version there. Is this an issue with this version, or did you try an old one from my fork?
Please double check also the branch, as the marin_v1 branch which is what you want, became default only very very recently.
Very nice greetings,
Bernhard

PS: Thanks for the nice tour back then at the Attraktor. I have bought some green lamination foil, but have not had time to use it yet, and also upgraded our cnc mill with a "Gravouranschlag" approx. 1 week after my return. Also, I dumped the photos I did on my soup: http://bernhardkubicek.soup.io/post/159840064/At-the-attraktor-hackerspace-in-Hamburg-Dirk

Also, please be aware that emc2 in motion tracking an acceleration planning is much much superior. It is able to have a G63 (IIRC) that allows it to deviate from the original path by a setable value. This rounds corners, and makes the movement much more smooth. Even a value of 0.1mm helps dramatically. However, this is not doable on the microcontroller. What currently happens in grbl: it looks for the length of the velocity-change vector at corners, and tries to accelerate/decelerate so that this change is limitited to the xy-jerk-velocity. So there is a "Ruck" at corners.

I think one of the best setups would be: the average pc, either parallel port of a better EMC supported IO card (aka "Mesa"), and a microcontroller. The microcontroller is controlled by v-serial from special M codes in emc that call shell scripts, and it only controls the heating related things.
The downside would be that you can only use a max-stepping frequency of 100kHz, as the parallel port is limiting. But with not-so high microstepping that should still work very nice. (Alternative: The leadshine digital stepper drivers, that can upscale steppigs)
Also, print quality is very much about acceleration, and that you will have with your machine. On an Ultimaker, maximum velocity is around 480mm/sec and acceleration around 3000. If you can reach a acc of 8000, you have a nice machine.

Ah ok, nice, you updated eriks repository just yesterday. I did try your version from https://github.com/bkubicek/Marlin/tree/master/Marlin .
I will be back on my machine after Christmas and test the new Version in eriks repository. But from what i see in the code, in planner.cpp planner_recalculate_trapezoids() { ... still calls " calculate_trapezoid_for_block(current, current->entry_speed/current->nominal_speed,next->entry_speed/current->nominal_speed);"
The last value is the exit factor, "next->entry_speed/current->nominal_speed" , where next->entry_speed will still be the entry speed of an axis (E) that has nothing to do with the speeds to the current block (xyz).
So I think this bug is still present.

Ps: yes, emc2, some gui customizations and an attached microcontroller for temperatur reading would be nice, but there are 2 things. First you have to run a full computer to run you machine, whereas an arduino with lcd is much more power usage friendly. Second.. there are like 3 people in the world who have that setup running, so User and Support base is quite small :) So i think i will go with Marlin.

Greetings

Dirk

Ok, i did some testing.

This bug actually is a serious logical flaw inside the motion planer.
Though it is not present in GRBL, it was introduces when someone added the e axis support into grbl to create marlin.
I had no luck testing the new firmware that is in erics repository since Christmas, because i could not get replicatorg or pronterface to connect and i did not want to spend too much time on this, but since the motion planer is the same, i looked at the code and the same problem exists there.

Here is the fix:

void planner_reverse_pass_kernel(block_t *previous, block_t *current, block_t *next) {
(..)
if (next) {
exit_speed = next->entry_speed;
}
else {
exit_speed = safe_speed(current);
}
if(next->steps_x == 0 && next->steps_y == 0 && next->steps_z == 0 ){exit_speed=1; }
if (previous) {
(...)
}

and in "planner_forward_pass_kernel(..)"
if(previous) {
if(previous->entry_speed < current->entry_speed && (current->steps_x != 0 || current->steps_y != 0 || current->steps_z != 0 ) ) {
if(previous->entry_speed < current->entry_speed) {
float max_entry_speed = max_allowable_speed(-previous->acceleration, previous->entry_speed, previous->millimeters);
if (max_entry_speed < current->entry_speed) {
current->entry_speed = max_entry_speed ;
}}}}
should do the trick.
Also, dropsegments should not be used, it breaks the fix again.

Test Code:
G1 X0 Y0 Z1 F6000
G1 X20 Y20 Z1 F6000.0 ( non decelerated stop after this, because nextBlock->entryspeed is 60000 )
G1 F60000.0
G1 E10.00 ( retract )
G1 F6600.0
G1 X5 Y5 F1000

G1 X0 Y0 Z1 F6000
G1 X20 Y20 Z1 F6000.0
G1 X20.01 Y20 Z1 F6000.0 (drop segments test)
G1 F60000.0
G1 E10.00 ( retract )
G1 F6600.0
G1 X5 Y5 F1000

Ps: In "plan_buffer_line(..) i found this:
block->millimeters = sqrt(square(delta_x_mm) + square(delta_y_mm) + square(delta_z_mm) + square(delta_e_mm));
This adds up totally unrelated axis and later uses that value to calculate xyz accelerations and timings. This is most likely wrong,
but i had no time to investigate it any further, i will do this in the next days.

Greetings and Happy New Year from Hamburg

Dirk