moggieuk / Happy-Hare

MMU software driver for Klipper (ERCF, Tradrack, Box Turtle, Night Owl, Angry Beaver, 3MS, ...)
GNU General Public License v3.0
509 stars 129 forks source link

Extrude Length Preprocessing #491

Open k1-801 opened 1 month ago

k1-801 commented 1 month ago

WORK IN PROGRESS

Currently has syntax errors. Working on it.

This change aims to provide a basis for Endless Spool functionality improvement. It scans each block of GCode between toolchanges and records the total length of filament used within each block. This data is then attached to the MMU_CHANGE_TOOL macro (in the EXTRUDE_LENGTH=... parameter).

Additionally, this change removes buffering of GCode lines between the toolchange macro and the next G1 move. This potentially can reduce RAM consumption. This is achieved by recording the file position after the Tx macro and then rewinding the file stream to that point.

moggieuk commented 4 weeks ago

This is an interesting idea. What kind of overhead does it add to the parsing? I persuaded the moonraker crew to accept my PR for specifying the timeout of the pre-processing step so at least we can bump that up.

Can you give me the use case of how and when you would use this or is this a precursor to something else?

k1-801 commented 4 weeks ago

This is an interesting idea. What kind of overhead does it add to the parsing?

The parsing is currently pretty slow =\ But I'm working on it, I know what is taking the longest and I have a few ideas that could help avoid it.

Can you give me the use case of how and when you would use this or is this a precursor to something else?

This is indeed a precursor to the Endless Spool feature upgrade. The idea was described in my comment in https://github.com/moggieuk/Happy-Hare/issues/340#issuecomment-22876069507, but in short - the plan is to check whether it's reasonable to continue printing after a runout detection without unloading the remaining bit of plastic. If we continue printing, it will no longer be possible to extract the bit through the MMU, and, thus, it will have to be either fully used up in the print, or it will have to be purged through the nozzle. So we need to know, how much we need before the toolchange, and we compare it to how much we have left (bowden_length). The way I see it, this parsing change is the only way to know how much more plastic we need.

k1-801 commented 4 weeks ago

persuaded the moonraker crew to accept my PR for specifying the timeout of the pre-processing step so at least we can bump that up.

I don't think long preprocessing is a good idea in general. I'd look into optimizing it instead. For example, the placeholders for "MMU_START_SETUP" (!referenced_tools! etc.) - those don't have to be substituted in every line, so substituting them everywhere may be a bad idea. I'd say, a good marker that we no longer need to look for those placeholders is extruding moves, as we definitely don't expect a setup macro AFTER the printer starts printing. So, if at least one extruding move was found, I suggest we stop looking for those placeholders. Additionally, I think checking the first letter of the line to be T or G before running REGEXes may save us a LOT of time. Finally, I believe the parameters being passed to some functions waste a lot of time copying containers, so making a single class to hold some of the pre-processing-related stuff may save even more time. I can look into all these within this same PR.

k1-801 commented 4 weeks ago

Made the MMU-related parsing into it's own class. Hid some of the parameters into object attributes. This should reduce some overhead.

moggieuk commented 3 weeks ago

Any performance optimization of current parsing would definitely be appreciated but it is actually quite fast. Once a placeholder is found it won't look in subsequent lines, but the logic parses to the end of file to do the NEXT_POS insertions. I see you changing the approach slightly. It would be interesting to see the orig/new parsing performance numbers if you have any..

JFYI I'm not going to be able to spend time looking at this for some time (i know it is still in development). The reason is that I'm really busy getting type-B MMU support polished (in the v3alpha branch)

[if you do look at the v3alpha branch you will see a lot of code/class breakout - no changes on the moonraker side though]

moggieuk commented 3 weeks ago

@k1-801 I've been thinking about this and have an idea for you... The approach you are taking is certainly an option but what about thinking about it another way (this assumes a extruder entry sensor):

To things can happen: A) No toolchanges occur...

B) A toolchange occurs.

The manipulation of the tool change is not really any different to your approach but it saves having to pre-process the gcode ahead of time...

k1-801 commented 2 weeks ago

The approach you are taking is certainly an option but what about thinking about it another way (this assumes a extruder entry sensor):

In the absence of preprocessing, be it disabled or just had it failed, AND with the presence of an extruder entry sensor, this is certainly how this would work. However, there are plenty of machines that don't have an extruder entry sensor, so without preprocessing there isn't much we could do.

Furthermore, there are instances where it woud be wasteful to go on with the print after a runout trigger on MMU, as it would lead to a purge of a whole meter of filament - it would be much better to eject it (if possible), change the spool and maybe use the ejected bit the next time this tool is requested.

I think we are going to need a flowchart :)

moggieuk commented 2 weeks ago

Flowchart, ha ha. Yes it is a complex challenge. The statement above "it would be much better to eject it (if possible), change the spool and maybe use the ejected bit the next time this tool is requested." can't work though ... if you are past the point of no return you cannot eject (because the filament cannot be grabbed be the MMU gear stepper) thus you can either continue as far as possible and if the remaining filament is beyond a user defined threshold, say 300mm, then PAUSE and wait for user interaction. else do the very long purge. You can't eject a filament that is too short...

k1-801 commented 2 weeks ago

because the filament cannot be grabbed be the MMU gear stepper

But there is some more filament between the extruder gears and the nozzle, I always assumed that unloading from the extruder makes the filament reach the MMU gears again. This assumption, however, also heavily relies on the MMU sensor to gears distance being significantly shorter than extruder gears to nozzle distance...

UPD: as well as on the runout response time being short enough

If these conditions are not met, then a runout is indeed a point of no return, and our only options are to continue printing, purge, or request manual intervention.

k1-801 commented 2 weeks ago

if you are past the point of no return you cannot eject

This gave me another thought. What if we used the pre-gate sensor, when available? That would notify the system about a runout in advance, thus, allowing to run checks earlier

moggieuk commented 1 week ago

I always assumed that unloading from the extruder makes the filament reach the MMU gears again. This assumption, however, also heavily relies on the MMU sensor to gears distance being significantly shorter than extruder gears to nozzle distance... Correct, and this is the case today ... BEFORE passing the point of no return then filament fragment is unloaded and another (endless spool) is substituted.

My point is that often users will have over 1m of filament between that "point of no return" and the extruder. So, once past, you have no choice but a massive purge IF a toolchange occurs.

moggieuk commented 1 week ago

if you are past the point of no return you cannot eject

This gave me another thought. What if we used the pre-gate sensor, when available? That would notify the system about a runout in advance, thus, allowing to run checks earlier

Indeed the pre-gate sensor IS used today for runout unless the user explicitly turns it off. If can be turned off by disabling the mmu_pre_gate sensor in Mainsail OR by configuring a "waste gate". This functionality was added at the request of the community so the waste filament can be dumped out a single gate -- that obviously requires the filament to clear the selector before triggering runout.