eyal0 / OctoPrint-PrintTimeGenius

Use a gcode pre-analysis to provide better print time estimation
190 stars 32 forks source link

[Feature request] Compensate for tool changes #114

Open szafran81 opened 5 years ago

szafran81 commented 5 years ago

Before reporting, check if your problem is here: https://github.com/eyal0/OctoPrint-PrintTimeGenius/wiki/Common-problems

Please fill this out:

OctoPrint Version: 1.3.10

PrintTimeGenius Version (if you know): 1.3

In compsation values there are: Heating | Extruding | Cooling

I think it would great idea to add compensation for tool changes to better predict print times depending on the number of them in each print (and on prints that use only one tool on a multi tool machine).

eyal0 commented 5 years ago

What do you mean tool changes? Like switching filament?

szafran81 commented 5 years ago

Exactly. I have 5, but even when using only 2 filaments the differences are big. When using single filament the predictions are on the spot (+/- few minutes on 2 day prints is really awesome). But... I've just finished a print with soluble supports (just 2 filaments)... predicted time: 10:49:30... real print time: 11:44:13. On 5 color test print yesterday I've had a predicted time of a bit less than 4h a the print finished after over 6h (sorry don't remeber the exact times).

I think that tool change compensation would account for that.

Brandoskey commented 5 years ago

I second this.

This could be more difficult to compensate for times when you print a waste item or purge to infill

TobbeJ commented 4 years ago

This problem must be fixed. Because if you get a stuck tool change, for example during night when you sleep, then this random user delay is going to be included in the final estimate and this will badly screw up the print estimate to the point that this addon is not usable any more.

So a good start is to either completely ignore the tool change itself and live with the problem that the tool changes will not be estimated properly or try to detect when tool change is taking exceptionally long time during a print.

Perhaps split the tool changing estimate out in to its own category like what is there for heating vs extruding and cooling.

Trying to predict randomness, like the end user is never going to work out very well.

eyal0 commented 4 years ago

Tool changes are already skipped. The problem is that the clock is still running during this time so it gets added into the final result, which is why the compensation gets screwed up.

The solution is to have PTG notice when the tool change starts and start counting up the seconds until the tool change is done. And then PTG needs to subtract that from the total printing time in order to compute the proper printing them.

Is the uncompensated print time usually right, not counting the time to switch filaments?

TobbeJ commented 4 years ago

When i noticed this problem (had not paid attention to estimates before) i had a file sliced by prusaslicer and it reported the time to take 7 hours (pretty accurate) and estimate as displayed by octoprint was 10 hours.

Afterwards i went in and deleted some of the bad compensation values from the settings and next time i printed exactly the same thing estimates was much closer to reality.

eyal0 commented 4 years ago

Yeah, so it sounds like that is what is happening. The estimates assume that you change filament instantly so the estimates are good. But the compensation is based on reality and the reality includes the time to change filament.

The solution is for PTG to notice a filament change starting and stop the clock until it's done. How can PTG notice the filament change? What is the instruction that a printer has when filament change begins? What is the instruction that a printer has when filament change ends?

I could make it an option so that the default will be something reasonable, like M600 or whatever, but the use can pick a different one as needed.

TobbeJ commented 4 years ago

Tool change code is T followed by the number of the extruder to select or in the case of MMU2S the filament to select and load. You can look at: https://prusa3d.github.io/Prusa-Firmware-Doc/group__GCodes.html near the end you have "T Codes"

eyal0 commented 4 years ago

I don't have a printer with tool changes. In fact, I don't even have a printer! 😜

So I'm wondering how to test this. My thought is like this: you send me a file that uses multiple filaments. I'll look at it, make some code changes, and send you a version that maybe does the right thing. And then you give it a shot and let me know how it worked.

What do you think? If you send the gcode, I can get started.

TobbeJ commented 4 years ago

perhaps you can use the virtual printer and then test using that: https://docs.octoprint.org/en/master/development/virtual_printer.html there is also several sample files at: https://www.prusa3d.com/printable-3d-models/ the multi material ones link to prusaprinters and there most if not all of the linked objects got a presliced gcode file for download.

eyal0 commented 4 years ago

That won't suffice for testing because what I want to see is if it will correctly measure the delay when waiting for the material change. The virtual printer doesn't do delays.

I don't have a printer for testing so I'm not sure how to proceed.

TinkerTob commented 2 years ago

Hi,

sorry for necro'ing such an old issue, but I'm running into the same problem. In my case, the filament changes add several hours to the printing process which the plugin doesn't account for.

In my case, filament changes are handled automatically, so they should always take the same amount of time.

for example, consider the following G-Code generated by Cura:

T1
G92 E0
G1 F2100 E-3
M204 S3000
M205 X30 Y30
G0 F7200 X152.664 Y124 Z1.255
G0 X142.48 Y135.208
M204 S800
M205 X20 Y20
;TYPE:SUPPORT-INTERFACE
G1 F600 Z1.115
G1 F2100 E0
G1 F1311.6 X142.395 Y134.875 E0.01
[...]
G92 E0
T0
G92 E0
M204 S3000
M205 X30 Y30
G1 F600 Z1.43
G0 F7200 X94.62 Y134.797 Z1.43

T1 switches from Extruder 1 to Extruder 2. T0 switches back to Extruder 1. At each of these commands, the nozzle is moved to a parking position, the old filament is retracted, the new filament is pushed forward, the nozzle is purged by additional extrusion and the print gets resumed. All of this takes a fixed amount of time, maybe 1-2 minutes. You can imagine what this amounts to in prints with over 100 filament changes.

Sooo, in my case, the ideal solution would be a fixed delay to compensate for each ´Tx´ command. It would be pretty nice if the plugin could determine this automatically by measuring the time the command takes. If this is too complicated, a workaround would might be an option to determine manual delay times in the plugin settings, so I can time it with a stopwatch and enter the delay manually.

I would really appreciate it if you could look into this again. I would also be willing to run some test prints, if that would help.

Thank you for your great work!

eyal0 commented 2 years ago

I have considered something like this. I thought that PTG might maintain a list of commands that it knows to take some length of time and it would add it into the estimate. If we knew how long each command takes, adding it into the calculation is really easy. I would make is a parameter to marlin-calc (the marlin simulation that calculates the print time). You'd say, for example, if the print command matches T0 then add some number of seconds and if it's T1 then add some other number of seconds, etc. That part is pretty easy.

The hard part is knowing how many seconds to add. If you know the number yourself, I could put a place to type it in. However, if you don't, then you want for the printer to figure it out automatically. And here is where the trouble is:

Your printer is caching commands. That is, it's not like OctoPrint sends a command, then the printer does it, says okay, and then OctoPrint sends another. No, that would be inefficient. What's worse, if you're rounding a curve and have a ton of very small commands, the commands sent to the printer would not get there on time and the printer would experience an empty buffer of commands, sometimes called a buffer underrun.

So what actually happens is that OctoPrint sends commands even before the printer is ready for them. And the printer lets us regularly know when it has room for more, so that they printer doesn't experience underrun. You can see this in your prints if you look at the OctoPrint tab that shows what's being printed while it's printing. You'll see that OctoPrint is always a few steps ahead of reality. This is because OctoPrint already sent the command to the printer but the printer hasn't done it yet.

So if I want to time the T0, OctoPrint would need to know exactly when it starts and when it ends. But OctoPrint only knows when the T0 was sent to the printer, which might be well before it actually happens. So PTG cannot measure it. :-(

I have no idea how to fix this. If you have a good idea, I'm all ears.

I would also be willing to run some test prints

You'd have to because not only do I not have a printer with tool changes, I don't have a printer at all!

What if I made it so that you could type in the T0 and T1 times yourself. Would that be good enough a solution? Or not worthwhile?

szafran81 commented 2 years ago

As I'm watching the PTG options window... This comes to mind... Add another section in options like this one: image name it something like "Long running non-standard g-code commands" and let the user add a code on the left (eg. T0) and a corresponding time on the right (eg. 30s) and leave the abillity to add more of them, as with the analyzers section.

@Tr0llmops - I've printed things with up to 3000 filament changes - the time difference there was even over 10x

TinkerTob commented 2 years ago

What if I made it so that you could type in the T0 and T1 times yourself. Would that be good enough a solution? Or not worthwhile?

That would be a great workaround, and @szafran81's suggestion would be a perfect way to implement it.

The hard part is knowing how many seconds to add. If you know the number yourself, I could put a place to type it in. However, if you don't, then you want for the printer to figure it out automatically. And here is where the trouble is:

I believe that for Marlin, injecting M31 before and after the command in question could do the trick. However, I haven't yet worked with the printjob timer, so I have no idea wether it is widely supported and wether it's automatically started or if PTG would have to start it itself. See https://marlinfw.org/docs/gcode/M031.html It should be possible to simulate that using the virtual printer and G4 (Dwell pauses the command queue and waits for a period of time.) If you implement this, it would be great to give the user the choice: Set the value yourself, or let PTG measure it. This would ensure compatibility with firmwares or configurations which don't support M31, such as klipper.

(btw, as a sidenote: I previously stated that the time is the same for each Tx command. In my case, that's actually not quite true because the length of the travel moves (park & resume) depends on the X position of the nozzle when Tx is issued. But in comparison to the overall time differences we're talking about, that's negligible. Using an average value should be sufficient.)

I would also be willing to run some test prints, if that would help.

When I made this offer, I didn't consider that PTG primarily relies on Marlin and I'm currently running klipper. I could (and will, if necessary) temporarily switch back to Marlin for tests, but if there's anyone willing to test this who's routinely using Marlin, that would probably yield better results. (And yes, I'm used to PTG results being a little off due to me using Klipper... I personally only need a rough estimate, and in this regard, PTG is still a lot better than Cura or Octoprint itself.)

eyal0 commented 2 years ago

There's a bug open for klipper support: #105

I have even talked to the author but we've never gotten anywhere. Kipper already computes the total time to print, you would just need it to provide the line-by-line time to print. I wrote a patch for klipper that I thought might help but it was not accepted and it was probably not well done, either. ...ah, I just looked and it seems that you found it. Well, no progress there yet.

The M31 idea is pretty smart! It's possible for plugins to inject gcode into a print. So I could just put an M31 before and after each T command and then PTG could learn the time to do a filament change. That's not a bad idea.

the length of the travel moves (park & resume) depends on the X position of the nozzle when Tx is issued

Yes. Probably we'd ignore it. I think that it would be difficult to compensate for it. Does the tool change always start by moving the nozzle to a certain position anyway? For users that want extreme accuracy, just make sure that the nozzle is moved to a known position before doing a tool change. Like, insert some G0 X Y Z command before the tool change. The tool change will need to move the nozzle anyway!

Add another section in options like this one

Yes, that's how it would work, a table where you can add entries. It would be a list of entries where each one has a name, then a pattern, then a time. The name is just whatever you want to call it, like "tool change". The pattern would be the test to look for in the gcode line, like T0. And the time would be how many seconds.

The pattern would be a regex. If you don't know what regex is, search on the web to read about it. So the pattern could be T[0-9] to capture all tool changes 0 through 9. Regex is pretty flexible without being too complex.

I guess that I could implement this even before we have the M31 support and auto measuring of the tool change time because I would anyway need support for custom timing for commands like T0 ready to go before the measuring works. So I could start by doing that and then later on look at how to measure automatically.

TinkerTob commented 2 years ago

So I could start by doing that and then later on look at how to measure automatically.

Sounds perfect! Thank you so much. And I really like the idea of using regex.

Does the tool change always start by moving the nozzle to a certain position anyway?

Difficult question. I think there has to be a move, or the printed object would get damaged. However, in some setups, this could also be handled by the slicer instead of the firmware (so there's a normal G0/ G1 move before the Tx). The same applies to the purging: Most slicers support purge towers which are printed right after the toolchange, but some setups (including mine) use a purge bucket at the parking position (usually at one end of the x axis), so the purge time is included in the toolchange itself. All of this goes for single-nozzle multi-extrusion... I have no idea how it's handled in multi-nozzle systems. But my guess is that both the problem and proposed solution still apply.

szafran81 commented 2 years ago

I think that adding measuring (or custom g-code delays) should be enough. If a machine uses custom moves when doing Tx g-codes then the measured time will include those allready.

Also there can be different Tx change times that depend on which Tx is the starting one and which Tx is the ending one (eg. different change times from T1 to T4 then from T3 to T0). But in most multimaterial constructions those are so small that I think it can be left alone. I think that measuring changes between Tx should be enough (excluding initial load, and final unload, as those are partial operations).

alidaf commented 2 years ago

I change filament manually and the estimates are out by around 9 hours for a 2 hour job!