Jump to content

Possible to make dynamic gcode in cura?


bcsteeve

Recommended Posts

Posted · Possible to make dynamic gcode in cura?

Cura knows the size of the object being sliced (it says it down in the bottom).  Let's say I want to send a G29 command to the printer suffixed by the size of the print job.  For example, I'm printing a 50x50 object I see no reason to wait 5 minutes while it autolevels across a 300 x 300 bed.

 

I see other applications as well and I wondered if there was a way for me to instead of say "send G29 at print start", say "send G29 X{x of project] Y{y of project]"  or even better (if I want to get complex) something like this psuedo code:  "send G29 P{int(print size / 25)"  {the idea being to scan a smaller grid number for a smaller grid size).

 

I hope I'm making sense.


Basically:  can variables be used to dynamically generate gcode based on data generated by Cura (primarily object size)?

  • Link to post
    Share on other sites

    Posted (edited) · Possible to make dynamic gcode in cura?

    It's not currently possible, or at least not easily.

     

    We expose all settings through the bracket syntax in the start and end g-code, but nothing other than those settings except the current date and time. Those are the only thing you can use when typing start/end g-code in the interface with the Machine Settings menu. See here for the source code that handles the bracket syntax: https://github.com/Ultimaker/Cura/blob/6a053a9f46c56a94cfaf611cb55376b4d0ad09d1/plugins/CuraEngineBackend/StartSliceJob.py#L270-L285

     

    When you're writing a definition file (.def.json) a few more things will be possible if you specify the "value" property instead of "default_value". The "value" property can be any arbitrary Python expression, so you could make calculations like "G29 P" + str(int(machine_width / 25)) or something, and all the setting names have already been filled in as variables. There are other (hidden) functions available then as well, for instance extruderValues(setting_name) which gets a list of all values for a setting for each extruder. But there is nothing there either that can get the size of the print.

     

    Warning: I'm getting gradually more technical here...

     

    There is a vulnerability of sorts that allows you to devise a setting value that escapes the sandboxed environment in which the setting expressions are evaluated, and you can obtain data from the internals of Cura this way, including the dimensions and positions of the models. I won't disclose it here. But doing this will have problems with updating the setting value if the build volume changes, so it's not going to work reliably.

     

    Also for the purpose of bed levelling you'd probably want to know the size of the final print rather than the size of the input models. The actual print can be quite different due to brims, rafts and horizontal expansion (of model and/or support). Most of these can be predicted beforehand (you know the desired brim width and such). Some of them can't though, for instance if you have conical support enabled. In those cases it is really impossible to get the dimensions of the print before slicing has completed.

     

    I'll shoot in a feature request ticket to add the size of the input models as a key replacement for the bracket syntax. No promises, of course. Our backlog is long.

    https://github.com/Ultimaker/Cura/blob/6a053a9f46c56a94cfaf611cb55376b4d0ad09d1/plugins/CuraEngineBackend/StartSliceJob.py#L275
    Edited by ghostkeeper
    Saying that I'll make a feature request.
  • Link to post
    Share on other sites

    Posted · Possible to make dynamic gcode in cura?

    @ghostkeeper 
    I'm very much interested in this. 

    How would you use the 'value' property in place of the 'default_value' ?
    (in a printer definition file) 
     

    This does not work (cura crashes on startup)

    "machine_start_gcode": { "value": "G29 P" + str(int(machine_width/25)) },

    and this does not work either (not that surprisingly)

    "machine_start_gcode": { "default_value": "G29 P" + str(int(machine_width/25)) },

     

    The question is... what would work? 


    Thanks!

  • Link to post
    Share on other sites

    Posted · Possible to make dynamic gcode in cura?

    "default_value always" needs to be a literal (ie: a numeric value for a setting that expects a number, and a string ONLY when the setting expects a string vaue).

    "value" should always be a string that can be interpreted by python. The string can contain a number, or a calculation, or another string, and any pythonically valid combination thereof.

     

    By that logic, only "value" can hold any sort of manipulation and/or calculation.

     

    This should work:

    "machine_start_gcode": { "value": "'G29 P' + str(int(machine_width/25))" },

    'G29 P' is a string in the python expression. The whole expression is enclosed as a string.

    • Like 1
    • Thanks 1
    Link to post
    Share on other sites

    Posted · Possible to make dynamic gcode in cura?

    Awesome stuff @ahoeben. That works, and I understand. Python strings all the way!

    However, something still eludes me. The following examples do not work even though in a regular python shell I see no issues. 

     

    1. If statement

    "'cool' if material_bed_temperature > 0  else 'very cool'"

    - I actually use a similar construct in a cfg quality profile with no issues. I'm not sure why it would not work here. ¯\_(ツ)_/¯

    2. moar math

    "'M190 S' + str(floor(45*material_bed_temperature/material_bed_temperature))"

    - This should evaluate to 0 if the material_bed_temperature is 0 and to 45 if it is anything else. Yet, it's stuck at 45 no matter what. 

    Thanks for helping me dive into this. 

  • Link to post
    Share on other sites

    Posted · Possible to make dynamic gcode in cura?

    Check the logs. Do you get errors? What do the errors say?

  • Link to post
    Share on other sites

    Posted (edited) · Possible to make dynamic gcode in cura?
    1 hour ago, carvedblock said:

    1. If statement

    
    "'cool' if material_bed_temperature > 0  else 'very cool'"

    - I actually use a similar construct in a cfg quality profile with no issues. I'm not sure why it would not work here. ¯\_(ツ)_/¯

    Yeah, that looks like it should work, actually. I am confuzzled!

     

    1 hour ago, carvedblock said:

    2. moar math

    
    "'M190 S' + str(floor(45*material_bed_temperature/material_bed_temperature))"

    - This should evaluate to 0 if the material_bed_temperature is 0 and to 45 if it is anything else. Yet, it's stuck at 45 no matter what.

    I would expect a ZeroDivisonError here if the bed temperature is 0, because then you'll evaluate 45 * 0 / 0 = 0 / 0. I think the error is happening underwater and it is just displaying the old value then. Try this:

    "' M190 S' + ('45' if material_bed_temperature else '0')"

     

    Edited by ghostkeeper
    Simplified expression.
  • Link to post
    Share on other sites

    Posted · Possible to make dynamic gcode in cura?

    Puzzling times. 

    The dividing with a zero was a bit of a wishful hack, when I was not able to make the IF statement work... 


    Yet. No errors (with any of the mentioned constructs - including the dividing by zero) The only thing log tells me when I switch the temperature is

    2018-07-12 07:32:52,134 - DEBUG - [MainThread] cura.Machines.MachineErrorChecker._rescheduleCheck [129]: New error check scheduled.
    2018-07-12 07:32:52,584 - INFO - [MainThread] cura.Machines.MachineErrorChecker._setResult [181]: Error check finished, result = False, time = 0.5s

    ---

    After embarrassingly many tests, I found something! Many of the constructs (I did not test all) work if used with 

    material_bed_temperature_layer_0, but not when used with material_bed_temperature !

     

    You probably have an idea what's going on here? I don't see anything. 

     

    Maybe it has to do with some default calculations, but I tried various options and I see no interaction. Here's a limited case that does not work: I have a cfg quality file with these lines 

     

    this works fine
    ---------------
    material_bed_temperature = default_material_bed_temperature
    material_bed_temperature_layer_0 = =material_bed_temperature + material_bed_temperature / 13
    
    this alwas evaluates to +5, never to 0 (I tried many variations on this theme, this is just one of them)
    --------------------------------------
    material_bed_temperature = default_material_bed_temperature
    material_bed_temperature_layer_0 = =0 if material_bed_temperature = 0 else material_bed_temperature + 5

    It seems almost like Cura has issues with seeing material_bed_temperature as zero?
    (Because calculations with material_bed_temperature work fine, just the if evaluation seems to be failing with no error). 

    (Well, most. It seems that more complex calculations fail, but that could be an error of syntax.) 

     

    SO

    ?Both of the IF statements work (mine and ghostkeepers simplified one)

    ?Everything seems to work with that (other than the dividing with zero, which was another issue that made the testing pattern harder to see). 

    ?no clue why material_bed_temperature does not work all around

     

  • Link to post
    Share on other sites

    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now
    • Our picks

      • UltiMaker Cura 5.7 stable released
        Cura 5.7 is here and it brings a handy new workflow improvement when using Thingiverse and Cura together, as well as additional capabilities for Method series printers, and a powerful way of sharing print settings using new printer-agnostic project files! Read on to find out about all of these improvements and more. 
         
        • 18 replies
      • S-Line Firmware 8.3.0 was released Nov. 20th on the "Latest" firmware branch.
        (Sorry, was out of office when this released)

        This update is for...
        All UltiMaker S series  
        New features
         
        Temperature status. During print preparation, the temperatures of the print cores and build plate will be shown on the display. This gives a better indication of the progress and remaining wait time. Save log files in paused state. It is now possible to save the printer's log files to USB if the currently active print job is paused. Previously, the Dump logs to USB option was only enabled if the printer was in idle state. Confirm print removal via Digital Factory. If the printer is connected to the Digital Factory, it is now possible to confirm the removal of a previous print job via the Digital Factory interface. This is useful in situations where the build plate is clear, but the operator forgot to select Confirm removal on the printer’s display. Visit this page for more information about this feature.
        • 0 replies
    ×
    ×
    • Create New...