Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CURA-12093 Add ability to write condition Start/End gcode parts #19619

Merged
merged 10 commits into from
Sep 16, 2024

Conversation

wawanbreton
Copy link
Contributor

@wawanbreton wawanbreton commented Sep 5, 2024

Add a new syntax to the machine/extruder start/end custom g-code, to enable or disable large parts of code.

Please also review the associated documentation:
https://github.com/Ultimaker/Cura/wiki/Start-End-G%E2%80%90Code

Also feel free to add unit test cases. The more the better 😃

CURA-12093

@wawanbreton wawanbreton marked this pull request as ready for review September 6, 2024 10:24
@GregValiant
Copy link
Collaborator

GregValiant commented Sep 7, 2024

Currently I have these lines in my StartUp:
{'M92 E119' if 'TPU' in material_type else 'M92 E97'} ; Steps/mm for {material_type}
{'M206 X-116 Y-121 Z0' if machine_center_is_zero else 'M206 X-1 Y-6 Z0'} ; Home offsets {'(Origin at Center)' if machine_center_is_zero else '(Origin LF Corner)'}

It took a lot of trial and error (mostly errors) to get that right. It's difficult to do when everything must be on a single line.

Under this PR those two lines would appear to translate to:
{if 'TPU' in material_type}
M92 E119 ; Steps/mm for {material_type}
{else}
M92 E97 ; Steps/mm for {material_type}
{endif}
{if machine_center_is_zero}
M206 X-116 Y-121 Z0 ; Home offsets (Origin at Center)
{else}
M206 X-1 Y-6 Z0 ; Home offsets (Origin LF Corner)
{endif}

which is certainly both easier to read, and to edit in the text box.

A problem I have noticed has to do with multiple extruder printers and setting the temperature of the "Initial Extruder".
It seemed to be a problem because "nested" variables didn't work.
This looks like it would work:
{if initial_extruder_nr == 0}
M104 S{material_print_temperature_layer_0, 0} T0
M104 S175 T1
{elif initial_extruder_nr == 1}
M104 S{material_print_temperature_layer_0, 1} T1
M104 S175 T0
{endif}
That would work unless "T0" was disabled. This question has come up previously..."Will there be a method to check if an extruder is actually 'enabled'"?

Will nested "if" statements be allowed?
IF
....IF
....ENDIF
ELSE
ENDIF
I usually advise to simply allow Cura to handle the temperatures but some folks are philosophically opposed to letting the software do its job.

@wawanbreton
Copy link
Contributor Author

Hi @GregValiant, thank you for this very valuable feedback 😃

Under this PR those two lines would appear to translate to:
...
which is certainly both easier to read, and to edit in the text box.

You are completely correct, and this is indeed a case where this improvement would perform. It has really been designed for this.

This looks like it would work:
{if initial_extruder_nr == 0}
...

The second example would also work. However, now you can also set formulas in the extruder number, so you can actually do the following, assuming your printer has 2 extruders:

M104 S{material_print_temperature_layer_0, initial_extruder_nr} T{initial_extruder_nr}
M104 S175 T{(initial_extruder_nr + 1) % 2}

Will there be a method to check if an extruder is actually 'enabled'

This would be very handy indeed. I actually think that with the conditional G-Code parts, a few more variables/functions will be necessary to make it really useful. If you have others in mind, feel free to post an exhaustive list.

Will nested "if" statements be allowed?

This first implementation doesn't, I didn't feel a great need for it, as the conditional parts is already a nice improvement. I think we can start with this, and if you feel that it would be really helpful, please tell us.

I usually advise to simply allow Cura to handle the temperatures but some folks are philosophically opposed to letting the software do its job.

Good that you do so 😄 but I can also understand that some people want to control exactly what happens at start.

@GregValiant
Copy link
Collaborator

The world of multi-extruders is complicated once you get into mixing hot ends and 3 or 4 extruders. I have been playing with IDEX definitions and post-processing plugins to allow Cura to better support IDEX machines (in particular the SOVOL SV06 and the Raise3D IDEX because both use M605 to set the mode. That conveniently dumps all the axis conversion on the printer/processor making Cura a suitable slicer for them.

It is a niche situation but I thought I'd bring this up since you are looking at the StartUp. This problem might also extends to conventional dual extruder machines when "prime tower" is enabled.

  1. A print starts with T0 and T1 is not used in the print, or T1 is disabled.
    T1 needs to be ignored so it doesn't heat up.
  2. A print starts with T1 and T0 is not used in the print, or T0 is disabled.
    T0 needs to be ignored so it doesn't heat up.

What I had wished for was "T0_is_enabled" and "T0_is_used" which could be called in the StartUp. In post process I can pull "is_enabled" from the extruder stack. To get "is_used" for an enabled extruder I have to go through the entire gcode to see if it is being called at some point. If it is never called then it doesn't need to be heated up. That obviously is beyond can be can be done in the StartUp, but I thought I'd mention it.

There may be some use for these so I'll throw them at you.
"T0_is_used" and "T1_is_used"
"T0_is_enabled" and "T1_is_enabled"
"second_extruder_nr" which would always be the opposite of "initial_extruder_nr". This would not seem to be necessary with your new system since something like "if not T0 then T1" could be used.

PS: I'm glad I don't have to write the "how to" instructions for this.

@wawanbreton
Copy link
Contributor Author

What I had wished for was "T0_is_enabled" and "T0_is_used" which could be called in the StartUp

That does make very much sense indeed. It also depends on the printer's startup sequence though. For example, on UM printers, when the build plate Z-calibration sequence is being processed, it does both T0 and T1, and I am not sure we can actually disable the calibration for one of them, even if not used. Which means we have to heat it up anyway. But I agree that it is quite annoying, and those variables can probably help with other printers.

"second_extruder_nr" which would always be the opposite of "initial_extruder_nr". This would not seem to be necessary with your new system since something like "if not T0 then T1" could be used.

What about printers with more than 2 extruders ? Would you require the exact ordering of all the extruders ?

For now, the post-processing script is a good option indeed. One issue we currently have, is that we resolve the start/end G-Code before actually sending the data to the engine. So in some edge cases the engine may take different decisions than the front-end, resulting e.g. in the initial_extruder_nr to be incorrect. If we want to add an is_used variable, that really can be done only after the G-Code has been generated, which is quite a big change. So I'll add this as a new feature request, and hopefully we can implement it someday.

@GregValiant
Copy link
Collaborator

The "Initial Extruder Number is wrong" bug was a big problem. Resolving that fixed a lot of issues in the StartUp of dual extruder machines.
I'm fairly new at this but all the machines I've seen that have 3 or 4 extruders have been equipped with "mixing hot ends" that Share Heaters and Nozzles. They can be ignored because the printer might have E0, E1, E2 but will only have T0 and it's going to be hot regardless of which extruder is called. There isn't a chance that the "off nozzle" will be dragged around drooling. It's just the "multiple hot end" machines that can have a problem with the plastic cooking in an unused extruder.

I understand not wanting to make a huge change over this but I thought it was worth mentioning. A post-processor or plugin is a good option for a mass produced printer but not so much for a custom one-off or a machine that has been altered (butchered) by the owner. There is a commonality in those situations as most of the time each extruder would feed it's own hot end and the hot ends would be mounted on a common print carriage. When that is the case the "off nozzle" should not be brought to print temperature. Insuring that happens is where I've gotten stuck.

Copy link
Member

@rburema rburema left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small comments, but LGTM! I'll take a look at the component-test later.

plugins/CuraEngineBackend/StartSliceJob.py Outdated Show resolved Hide resolved
plugins/CuraEngineBackend/StartSliceJob.py Show resolved Hide resolved
plugins/CuraEngineBackend/StartSliceJob.py Outdated Show resolved Hide resolved
tests/Machines/TestStartEndGCode.py Show resolved Hide resolved
@GregValiant
Copy link
Collaborator

I'm playing with the StartUp and Endings in 5.9alpha. So far it looks good. I like it. Much greater flexibility when changing materials.

@HellAholic HellAholic merged commit f736ead into main Sep 16, 2024
3 checks passed
@HellAholic HellAholic deleted the CURA-12093_conditional-start-end-gcode branch September 16, 2024 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants