From e01b1406e31c87b580f0f9640d0cabe440473dc7 Mon Sep 17 00:00:00 2001 From: GregValiant <64202104+GregValiant@users.noreply.github.com> Date: Thu, 29 Jun 2023 17:08:41 -0400 Subject: [PATCH 1/3] Update LimitXYAccelJerk.py Added Gradual Accel Change. Update LimitXYAccelJerk.py Round the Accel numbers to nearest "50". Create LimitXYAccelJerk.py New post processor to limit the X and or Y accel and jerk for bed-slinger printers. Update LimitXYAccelJerk.py Removed debug code. Update LimitXYAccelJerk.py Remove debug code Update LimitXYAccelJerk.py Bug Fix --- .../scripts/LimitXYAccelJerk.py | 273 ++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 plugins/PostProcessingPlugin/scripts/LimitXYAccelJerk.py diff --git a/plugins/PostProcessingPlugin/scripts/LimitXYAccelJerk.py b/plugins/PostProcessingPlugin/scripts/LimitXYAccelJerk.py new file mode 100644 index 0000000000..8932d8e4ea --- /dev/null +++ b/plugins/PostProcessingPlugin/scripts/LimitXYAccelJerk.py @@ -0,0 +1,273 @@ +# Limit XY Accel: Authored by: Greg Foresi (GregValiant) +# July 2023 +# Sometimes bed-slinger printers need different Accel and Jerk values for the Y but Cura always makes them the same. +# This script changes the Accel and/or Jerk from the beginning of the 'Start Layer' to the end of the 'End Layer'. +# The existing M201 Max Accel will be changed to limit the Y (and/or X) accel at the printer. If you have Accel enabled in Cura and the XY Accel is set to 3000 then setting the Y limit to 1000 will result in the printer limiting the Y to 1000. This can keep tall skinny prints from breaking loose of the bed and failing. The script was not tested with Junction Deviation. +# If enabled - the Jerk setting is changed line-by-line within the gcode as there is no "limit" on Jerk. +# if 'Gradual ACCEL change' is enabled then the Accel is changed gradually from the Start to the End layer and that will be the final Accel setting in the file. If 'Gradual' is enabled then the Jerk settings will continue to be changed to the end of the file (rather than ending at the End layer). + +from ..Script import Script +from cura.CuraApplication import CuraApplication +import re + +class LimitXYAccelJerk(Script): + def __init__(self): + super().__init__() + + def initialize(self) -> None: + super().initialize() + # Get the Accel and Jerk and set the values in the setting boxes--------------------------------------------- + mycura = CuraApplication.getInstance().getGlobalContainerStack() + extruder = mycura.extruderList + accel_print = extruder[0].getProperty("acceleration_print", "value") + accel_travel = extruder[0].getProperty("acceleration_travel", "value") + jerk_print_old = extruder[0].getProperty("jerk_print", "value") + jerk_travel_old = extruder[0].getProperty("jerk_travel", "value") + self._instance.setProperty("X_accel_limit", "value", round(accel_print)) + self._instance.setProperty("Y_accel_limit", "value", round(accel_print)) + self._instance.setProperty("X_jerk", "value", jerk_print_old) + self._instance.setProperty("Y_jerk", "value", jerk_print_old) + + def getSettingDataString(self): + return """{ + "name": "Limit the X-Y Accel/Jerk", + "key": "LimitXYAccelJerk", + "metadata": {}, + "version": 2, + "settings": + { + "X_accel_limit": + { + "label": "X MAX Acceleration", + "description": "If this number is lower than the 'X Print Accel' in Cura then this will limit the Accel on the X axis. Enter the Maximum Acceleration value for the X axis. This will affect both Print and Travel Accel. If you enable an End Layer then at the end of that layer the Accel Limit will be reset (unless you choose 'Gradual' in which case the new limit goes to the top layer).", + "type": "int", + "enabled": true, + "minimum_value": 50, + "unit": "mm/sec² ", + "default_value": 500 + }, + "Y_accel_limit": + { + "label": "Y MAX Acceleration", + "description": "If this number is lower than the Y accel in Cura then this will limit the Accel on the Y axis. Enter the Maximum Acceleration value for the Y axis. This will affect both Print and Travel Accel. If you enable an End Layer then at the end of that layer the Accel Limit will be reset (unless you choose 'Gradual' in which case the new limit goes to the top layer).", + "type": "int", + "enabled": true, + "minimum_value": 50, + "unit": "mm/sec² ", + "default_value": 500 + }, + "jerk_enable": + { + "label": "Change the Jerk", + "description": "Whether to change the Jerk values.", + "type": "bool", + "enabled": true, + "default_value": false + }, + "X_jerk": + { + "label": " X jerk", + "description": "Enter the Jerk value for the X axis. Enter '0' to use the existing X Jerk. This setting will affect both the Print and Travel jerk.", + "type": "int", + "enabled": "jerk_enable", + "unit": "mm/sec ", + "default_value": 8 + }, + "Y_jerk": + { + "label": " Y jerk", + "description": "Enter the Jerk value for the Y axis. Enter '0' to use the existing Y Jerk. This setting will affect both the Print and Travel jerk.", + "type": "int", + "enabled": "jerk_enable", + "unit": "mm/sec ", + "default_value": 8 + }, + "start_layer": + { + "label": "From Start of Layer:", + "description": "Use the Cura Preview numbers. Enter the Layer to start the changes at. The minimum is Layer 1.", + "type": "int", + "default_value": 1, + "minimum_value": 1, + "unit": "Lay# ", + "enabled": "not gradient_change" + }, + "end_layer": + { + "label": "To End of Layer", + "description": "Use the Cura Preview numbers. Enter '-1' for the entire file or enter a layer number. The changes will end at your 'End Layer' and revert back to the original numbers.", + "type": "int", + "default_value": -1, + "minimum_value": -1, + "unit": "Lay# ", + "enabled": "not gradient_change" + }, + "gradient_change": + { + "label": "Gradual ACCEL Change", + "description": "Gradually change the Accel numbers 'From layer' - 'To Layer'. If Jerk is enabled the Jerk changes are not 'Gradual' because there is no Max Jerk setting. Unlike Constant change - using 'Gradual' the Accel and Jerk change continues from the End Layer to the end of the file.", + "type": "bool", + "default_value": false, + "enabled": true + }, + "gradient_start_layer": + { + "label": " Gradual From Layer:", + "description": "Use the Cura Preview numbers. Enter the Layer to start the changes at. The minimum is Layer 1.", + "type": "int", + "default_value": 1, + "minimum_value": 1, + "unit": "Lay# ", + "enabled": "gradient_change" + }, + "gradient_end_layer": + { + "label": " Gradual To Layer", + "description": "Use the Cura Preview numbers. Enter '-1' for the top layer or enter a layer number. The last 'Gradual' change will continue to the end of the file.", + "type": "int", + "default_value": -1, + "minimum_value": -1, + "unit": "Lay# ", + "enabled": "gradient_change" + } + } + }""" + + def execute(self, data): + mycura = CuraApplication.getInstance().getGlobalContainerStack() + extruder = mycura.extruderList + constant_change = not bool(self.getSettingValueByKey("gradient_change")) + accel_print_enabled = bool(extruder[0].getProperty("acceleration_enabled", "value")) + accel_travel_enabled = bool(extruder[0].getProperty("acceleration_travel_enabled", "value")) + accel_print = extruder[0].getProperty("acceleration_print", "value") + accel_travel = extruder[0].getProperty("acceleration_travel", "value") + jerk_print_enabled = str(extruder[0].getProperty("jerk_enabled", "value")) + jerk_travel_enabled = str(extruder[0].getProperty("jerk_travel_enabled", "value")) + jerk_print_old = extruder[0].getProperty("jerk_print", "value") + jerk_travel_old = extruder[0].getProperty("jerk_travel", "value") + if int(accel_print) >= int(accel_travel): + accel_old = accel_print + else: + accel_old = accel_travel + jerk_travel = str(extruder[0].getProperty("jerk_travel", "value")) + if int(jerk_print_old) >= int(jerk_travel_old): + jerk_old = jerk_print_old + else: + jerk_old = jerk_travel_old + + #Set the new Accel values--------------------------------------------------------------------------------- + x_accel = str(self.getSettingValueByKey("X_accel_limit")) + y_accel = str(self.getSettingValueByKey("Y_accel_limit")) + x_jerk = int(self.getSettingValueByKey("X_jerk")) + y_jerk = int(self.getSettingValueByKey("Y_jerk")) + # Put the strings together + M201_limit_new = "M201 X" + x_accel + " Y" + y_accel + M201_limit_old = "M201 X" + str(round(accel_old)) + " Y" + str(round(accel_old)) + if x_jerk == 0: + M205_jerk_pattern = "Y(\d*)" + M205_jerk_new = "Y" + str(y_jerk) + if y_jerk == 0: + M205_jerk_pattern = "X(\d*)" + M205_jerk_new = "X" + str(x_jerk) + if x_jerk != 0 and y_jerk != 0: + M205_jerk_pattern = "M205 X(\d*) Y(\d*)" + M205_jerk_new = "M205 X" + str(x_jerk) + " Y" + str(y_jerk) + M205_jerk_old = "M205 X" + str(jerk_old) + " Y" + str(jerk_old) + + #Get the indexes of the start and end layers---------------------------------------- + if constant_change: + start_layer = int(self.getSettingValueByKey("start_layer"))-1 + end_layer = int(self.getSettingValueByKey("end_layer")) + else: + start_layer = int(self.getSettingValueByKey("gradient_start_layer"))-1 + end_layer = int(self.getSettingValueByKey("gradient_end_layer")) + start_index = 2 + end_index = len(data)-2 + for num in range(2,len(data)-1): + if ";LAYER:" + str(start_layer) + "\n" in data[num]: + start_index = num + break + if int(end_layer) > 0: + for num in range(3,len(data)-1): + try: + if ";LAYER:" + str(end_layer) + "\n" in data[num]: + end_index = num + break + except: + end_index = len(data)-2 + + #Add Accel limit and new Jerk at start layer----------------------------------------------------- + if constant_change: + layer = data[start_index] + lines = layer.split("\n") + for index, line in enumerate(lines): + if lines[index].startswith(";LAYER:"): + lines.insert(index+1,M201_limit_new) + if self.getSettingValueByKey("jerk_enable"): + lines.insert(index+2,M205_jerk_new) + data[start_index] = "\n".join(lines) + break + + #Alter any existing jerk lines. Accel lines can be ignored----------------------------------- + for num in range(start_index,end_index,1): + layer = data[num] + lines = layer.split("\n") + for index, line in enumerate(lines): + if line.startswith("M205"): + lines[index] = re.sub(M205_jerk_pattern, M205_jerk_new, line) + data[num] = "\n".join(lines) + if end_layer != -1: + try: + layer = data[end_index-1] + lines = layer.split("\n") + lines.insert(len(lines)-2,M201_limit_old) + lines.insert(len(lines)-2,M205_jerk_old) + data[end_index-1] = "\n".join(lines) + except: + all + else: + data[len(data)-1] = M201_limit_old + "\n" + M205_jerk_old + "\n" + data[len(data)-1] + return data + + + elif not constant_change: + layer_spread = end_index - start_index + x_accel_hyst = round((accel_old - int(x_accel)) / layer_spread) + y_accel_hyst = round((accel_old - int(y_accel)) / layer_spread) + x_accel_start = round(round((accel_old - x_accel_hyst)/50)*50) + y_accel_start = round(round((accel_old - y_accel_hyst)/50)*50) + M201_limit_new = "M201 X" + str(x_accel_start) + " Y" + str(y_accel_start) + #Add Accel limit and new Jerk at start layer------------------------------------------------------------- + layer = data[start_index] + lines = layer.split("\n") + for index, line in enumerate(lines): + if lines[index].startswith(";LAYER:"): + lines.insert(index+1,M201_limit_new) + if self.getSettingValueByKey("jerk_enable"): + lines.insert(index+2,M205_jerk_new) + data[start_index] = "\n".join(lines) + break + for num in range(start_index + 1, end_index,1): + layer = data[num] + lines = layer.split("\n") + x_accel_start -= x_accel_hyst + if x_accel_start < int(x_accel): x_accel_start = int(x_accel) + y_accel_start -= y_accel_hyst + if y_accel_start < int(y_accel): y_accel_start = int(y_accel) + M201_limit_new = "M201 X" + str(round(round(x_accel_start/50)*50)) + " Y" + str(round(round(y_accel_start/50)*50)) + for index, line in enumerate(lines): + if line.startswith(";LAYER:"): + lines.insert(index+1, M201_limit_new) + continue + data[num] = "\n".join(lines) + #Alter any existing jerk lines. Accel lines can be ignored----------------------------------- + if self.getSettingValueByKey("jerk_enable"): + for num in range(start_index,len(data)-1,1): + layer = data[num] + lines = layer.split("\n") + for index, line in enumerate(lines): + if line.startswith("M205"): + lines[index] = re.sub(M205_jerk_pattern, M205_jerk_new, line) + data[num] = "\n".join(lines) + data[len(data)-1] = M201_limit_old + "\n" + M205_jerk_old + "\n" + data[len(data)-1] + return data \ No newline at end of file From ae33d03eb25faa3d7fc7ed5a4e83e60a021ffa2a Mon Sep 17 00:00:00 2001 From: GregValiant <64202104+GregValiant@users.noreply.github.com> Date: Sat, 19 Aug 2023 08:42:27 -0400 Subject: [PATCH 2/3] Update LimitXYAccelJerk.py Add Exit for Ultimaker printers. Add notice that Accel is not-extruder specific. Changed variable names to lower case. --- .../scripts/LimitXYAccelJerk.py | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/plugins/PostProcessingPlugin/scripts/LimitXYAccelJerk.py b/plugins/PostProcessingPlugin/scripts/LimitXYAccelJerk.py index 8932d8e4ea..d50726fc76 100644 --- a/plugins/PostProcessingPlugin/scripts/LimitXYAccelJerk.py +++ b/plugins/PostProcessingPlugin/scripts/LimitXYAccelJerk.py @@ -9,6 +9,10 @@ from ..Script import Script from cura.CuraApplication import CuraApplication import re +<<<<<<< Updated upstream +======= +from UM.Message import Message +>>>>>>> Stashed changes class LimitXYAccelJerk(Script): def __init__(self): @@ -16,13 +20,18 @@ class LimitXYAccelJerk(Script): def initialize(self) -> None: super().initialize() +<<<<<<< Updated upstream # Get the Accel and Jerk and set the values in the setting boxes--------------------------------------------- +======= + # Get the Accel and Jerk and set the values in the setting boxes-- +>>>>>>> Stashed changes mycura = CuraApplication.getInstance().getGlobalContainerStack() extruder = mycura.extruderList accel_print = extruder[0].getProperty("acceleration_print", "value") accel_travel = extruder[0].getProperty("acceleration_travel", "value") jerk_print_old = extruder[0].getProperty("jerk_print", "value") jerk_travel_old = extruder[0].getProperty("jerk_travel", "value") +<<<<<<< Updated upstream self._instance.setProperty("X_accel_limit", "value", round(accel_print)) self._instance.setProperty("Y_accel_limit", "value", round(accel_print)) self._instance.setProperty("X_jerk", "value", jerk_print_old) @@ -31,12 +40,36 @@ class LimitXYAccelJerk(Script): def getSettingDataString(self): return """{ "name": "Limit the X-Y Accel/Jerk", +======= + self._instance.setProperty("x_accel_limit", "value", round(accel_print)) + self._instance.setProperty("y_accel_limit", "value", round(accel_print)) + self._instance.setProperty("x_jerk", "value", jerk_print_old) + self._instance.setProperty("y_jerk", "value", jerk_print_old) + ext_count = int(mycura.getProperty("machine_extruder_count", "value")) + machine_name = str(mycura.getProperty("machine_name", "value")) + + # Warn the user if the printer is an Ultimaker------------------------- + if "Ultimaker" in machine_name: + Message(text = " [Limit the X-Y Accel/Jerk] WILL NOT RUN because Ultimaker printers have fixed beds (it is intended for 'bed slinger' printers only.").show() + + # Warn the user if the printer is multi-extruder------------------ + if ext_count > 1: + Message(text = " 'Limit the X-Y Accel/Jerk': The post processor treats all extruders the same. If you have multiple extruders they will all be subject to the same Accel and Jerk limits imposed. If you have different Travel and Print Accel they will be subject to the same limit. If that is not acceptable then you should not use this Post Processor.").show() + + def getSettingDataString(self): + return """{ + "name": "Limit the X-Y Accel/Jerk (all extruders equal)", +>>>>>>> Stashed changes "key": "LimitXYAccelJerk", "metadata": {}, "version": 2, "settings": { +<<<<<<< Updated upstream "X_accel_limit": +======= + "x_accel_limit": +>>>>>>> Stashed changes { "label": "X MAX Acceleration", "description": "If this number is lower than the 'X Print Accel' in Cura then this will limit the Accel on the X axis. Enter the Maximum Acceleration value for the X axis. This will affect both Print and Travel Accel. If you enable an End Layer then at the end of that layer the Accel Limit will be reset (unless you choose 'Gradual' in which case the new limit goes to the top layer).", @@ -46,7 +79,11 @@ class LimitXYAccelJerk(Script): "unit": "mm/sec² ", "default_value": 500 }, +<<<<<<< Updated upstream "Y_accel_limit": +======= + "y_accel_limit": +>>>>>>> Stashed changes { "label": "Y MAX Acceleration", "description": "If this number is lower than the Y accel in Cura then this will limit the Accel on the Y axis. Enter the Maximum Acceleration value for the Y axis. This will affect both Print and Travel Accel. If you enable an End Layer then at the end of that layer the Accel Limit will be reset (unless you choose 'Gradual' in which case the new limit goes to the top layer).", @@ -64,7 +101,11 @@ class LimitXYAccelJerk(Script): "enabled": true, "default_value": false }, +<<<<<<< Updated upstream "X_jerk": +======= + "x_jerk": +>>>>>>> Stashed changes { "label": " X jerk", "description": "Enter the Jerk value for the X axis. Enter '0' to use the existing X Jerk. This setting will affect both the Print and Travel jerk.", @@ -73,7 +114,11 @@ class LimitXYAccelJerk(Script): "unit": "mm/sec ", "default_value": 8 }, +<<<<<<< Updated upstream "Y_jerk": +======= + "y_jerk": +>>>>>>> Stashed changes { "label": " Y jerk", "description": "Enter the Jerk value for the Y axis. Enter '0' to use the existing Y Jerk. This setting will affect both the Print and Travel jerk.", @@ -136,6 +181,17 @@ class LimitXYAccelJerk(Script): def execute(self, data): mycura = CuraApplication.getInstance().getGlobalContainerStack() extruder = mycura.extruderList +<<<<<<< Updated upstream +======= + machine_name = str(mycura.getProperty("machine_name", "value")) + + # Exit if the printer is an Ultimaker------------------------- + if "Ultimaker" in machine_name: + Message(text = " [Limit the X-Y Accel/Jerk] DID NOT RUN. This post processor is not intended for fixed printers (for 'bed slinger' printers only.").show() + data[0] += "; [LimitXYAccelJerk] DID NOT RUN because the printer doesn't have a sliding bed.\n" + return data + +>>>>>>> Stashed changes constant_change = not bool(self.getSettingValueByKey("gradient_change")) accel_print_enabled = bool(extruder[0].getProperty("acceleration_enabled", "value")) accel_travel_enabled = bool(extruder[0].getProperty("acceleration_travel_enabled", "value")) @@ -145,6 +201,10 @@ class LimitXYAccelJerk(Script): jerk_travel_enabled = str(extruder[0].getProperty("jerk_travel_enabled", "value")) jerk_print_old = extruder[0].getProperty("jerk_print", "value") jerk_travel_old = extruder[0].getProperty("jerk_travel", "value") +<<<<<<< Updated upstream +======= + +>>>>>>> Stashed changes if int(accel_print) >= int(accel_travel): accel_old = accel_print else: @@ -156,10 +216,17 @@ class LimitXYAccelJerk(Script): jerk_old = jerk_travel_old #Set the new Accel values--------------------------------------------------------------------------------- +<<<<<<< Updated upstream x_accel = str(self.getSettingValueByKey("X_accel_limit")) y_accel = str(self.getSettingValueByKey("Y_accel_limit")) x_jerk = int(self.getSettingValueByKey("X_jerk")) y_jerk = int(self.getSettingValueByKey("Y_jerk")) +======= + x_accel = str(self.getSettingValueByKey("x_accel_limit")) + y_accel = str(self.getSettingValueByKey("y_accel_limit")) + x_jerk = int(self.getSettingValueByKey("x_jerk")) + y_jerk = int(self.getSettingValueByKey("y_jerk")) +>>>>>>> Stashed changes # Put the strings together M201_limit_new = "M201 X" + x_accel + " Y" + y_accel M201_limit_old = "M201 X" + str(round(accel_old)) + " Y" + str(round(accel_old)) @@ -227,6 +294,7 @@ class LimitXYAccelJerk(Script): all else: data[len(data)-1] = M201_limit_old + "\n" + M205_jerk_old + "\n" + data[len(data)-1] +<<<<<<< Updated upstream return data @@ -236,6 +304,29 @@ class LimitXYAccelJerk(Script): y_accel_hyst = round((accel_old - int(y_accel)) / layer_spread) x_accel_start = round(round((accel_old - x_accel_hyst)/50)*50) y_accel_start = round(round((accel_old - y_accel_hyst)/50)*50) +======= + return data + + elif not constant_change: + layer_spread = end_index - start_index + if accel_old >= int(x_accel): + x_accel_hyst = round((accel_old - int(x_accel)) / layer_spread) + else: + x_accel_hyst = round((int(x_accel) - accel_old) / layer_spread) + if accel_old >= int(y_accel): + y_accel_hyst = round((accel_old - int(y_accel)) / layer_spread) + else: + y_accel_hyst = round((int(y_accel) - accel_old) / layer_spread) + + if accel_old >= int(x_accel): + x_accel_start = round(round((accel_old - x_accel_hyst)/25)*25) + else: + x_accel_start = round(round((x_accel_hyst + accel_old)/25)*25) + if accel_old >= int(y_accel): + y_accel_start = round(round((accel_old - y_accel_hyst)/25)*25) + else: + y_accel_start = round(round((y_accel_hyst + accel_old)/25)*25) +>>>>>>> Stashed changes M201_limit_new = "M201 X" + str(x_accel_start) + " Y" + str(y_accel_start) #Add Accel limit and new Jerk at start layer------------------------------------------------------------- layer = data[start_index] @@ -250,11 +341,27 @@ class LimitXYAccelJerk(Script): for num in range(start_index + 1, end_index,1): layer = data[num] lines = layer.split("\n") +<<<<<<< Updated upstream x_accel_start -= x_accel_hyst if x_accel_start < int(x_accel): x_accel_start = int(x_accel) y_accel_start -= y_accel_hyst if y_accel_start < int(y_accel): y_accel_start = int(y_accel) M201_limit_new = "M201 X" + str(round(round(x_accel_start/50)*50)) + " Y" + str(round(round(y_accel_start/50)*50)) +======= + if accel_old >= int(x_accel): + x_accel_start -= x_accel_hyst + if x_accel_start < int(x_accel): x_accel_start = int(x_accel) + else: + x_accel_start += x_accel_hyst + if x_accel_start > int(x_accel): x_accel_start = int(x_accel) + if accel_old >= int(y_accel): + y_accel_start -= y_accel_hyst + if y_accel_start < int(y_accel): y_accel_start = int(y_accel) + else: + y_accel_start += y_accel_hyst + if y_accel_start > int(y_accel): y_accel_start = int(y_accel) + M201_limit_new = "M201 X" + str(round(round(x_accel_start/25)*25)) + " Y" + str(round(round(y_accel_start/25)*25)) +>>>>>>> Stashed changes for index, line in enumerate(lines): if line.startswith(";LAYER:"): lines.insert(index+1, M201_limit_new) From 8f0fb5ef12f72b63223b28cd8fc3f358f36a29bc Mon Sep 17 00:00:00 2001 From: GregValiant <64202104+GregValiant@users.noreply.github.com> Date: Tue, 29 Aug 2023 07:51:58 -0400 Subject: [PATCH 3/3] Update LimitXYAccelJerk.py Changes made per Rburema requests. --- .../scripts/LimitXYAccelJerk.py | 174 ++++++------------ 1 file changed, 60 insertions(+), 114 deletions(-) diff --git a/plugins/PostProcessingPlugin/scripts/LimitXYAccelJerk.py b/plugins/PostProcessingPlugin/scripts/LimitXYAccelJerk.py index d50726fc76..b47a5876d8 100644 --- a/plugins/PostProcessingPlugin/scripts/LimitXYAccelJerk.py +++ b/plugins/PostProcessingPlugin/scripts/LimitXYAccelJerk.py @@ -5,42 +5,26 @@ # The existing M201 Max Accel will be changed to limit the Y (and/or X) accel at the printer. If you have Accel enabled in Cura and the XY Accel is set to 3000 then setting the Y limit to 1000 will result in the printer limiting the Y to 1000. This can keep tall skinny prints from breaking loose of the bed and failing. The script was not tested with Junction Deviation. # If enabled - the Jerk setting is changed line-by-line within the gcode as there is no "limit" on Jerk. # if 'Gradual ACCEL change' is enabled then the Accel is changed gradually from the Start to the End layer and that will be the final Accel setting in the file. If 'Gradual' is enabled then the Jerk settings will continue to be changed to the end of the file (rather than ending at the End layer). +# This post is intended for printers with moving beds (bed slingers) so UltiMaker printers are excluded. +# When setting an accel limit on multi-extruder printers ALL extruders are effected. +# This post does not distinguish between Print Accel and Travel Accel. The limit is the limit for all regardless. Example: Skin Accel = 1000 and Outer Wall accel = 500. If the limit is set to 300 then both Skin and Outer Wall will be Accel = 300. from ..Script import Script from cura.CuraApplication import CuraApplication import re -<<<<<<< Updated upstream -======= from UM.Message import Message ->>>>>>> Stashed changes class LimitXYAccelJerk(Script): - def __init__(self): - super().__init__() def initialize(self) -> None: super().initialize() -<<<<<<< Updated upstream - # Get the Accel and Jerk and set the values in the setting boxes--------------------------------------------- -======= # Get the Accel and Jerk and set the values in the setting boxes-- ->>>>>>> Stashed changes mycura = CuraApplication.getInstance().getGlobalContainerStack() extruder = mycura.extruderList accel_print = extruder[0].getProperty("acceleration_print", "value") accel_travel = extruder[0].getProperty("acceleration_travel", "value") jerk_print_old = extruder[0].getProperty("jerk_print", "value") jerk_travel_old = extruder[0].getProperty("jerk_travel", "value") -<<<<<<< Updated upstream - self._instance.setProperty("X_accel_limit", "value", round(accel_print)) - self._instance.setProperty("Y_accel_limit", "value", round(accel_print)) - self._instance.setProperty("X_jerk", "value", jerk_print_old) - self._instance.setProperty("Y_jerk", "value", jerk_print_old) - - def getSettingDataString(self): - return """{ - "name": "Limit the X-Y Accel/Jerk", -======= self._instance.setProperty("x_accel_limit", "value", round(accel_print)) self._instance.setProperty("y_accel_limit", "value", round(accel_print)) self._instance.setProperty("x_jerk", "value", jerk_print_old) @@ -50,26 +34,31 @@ class LimitXYAccelJerk(Script): # Warn the user if the printer is an Ultimaker------------------------- if "Ultimaker" in machine_name: - Message(text = " [Limit the X-Y Accel/Jerk] WILL NOT RUN because Ultimaker printers have fixed beds (it is intended for 'bed slinger' printers only.").show() + Message(text = " [Limit the X-Y Accel/Jerk] DID NOT RUN because Ultimaker printers don't have sliding beds.").show() # Warn the user if the printer is multi-extruder------------------ if ext_count > 1: - Message(text = " 'Limit the X-Y Accel/Jerk': The post processor treats all extruders the same. If you have multiple extruders they will all be subject to the same Accel and Jerk limits imposed. If you have different Travel and Print Accel they will be subject to the same limit. If that is not acceptable then you should not use this Post Processor.").show() + Message(text = " 'Limit the X-Y Accel/Jerk': The post processor treats all extruders the same. If you have multiple extruders they will all be subject to the same Accel and Jerk limits imposed. If you have different Travel and Print Accel they will also be subject to the same limits. If that is not acceptable then you should not use this Post Processor.").show() def getSettingDataString(self): return """{ "name": "Limit the X-Y Accel/Jerk (all extruders equal)", ->>>>>>> Stashed changes "key": "LimitXYAccelJerk", "metadata": {}, "version": 2, "settings": { -<<<<<<< Updated upstream - "X_accel_limit": -======= + "type_of_change": + { + "label": "Immediate or Gradual change", + "description": "An 'Immediate' change will insert the new numbers immediately at the Start Layer. A 'Gradual' change will transition from the starting Accel to the new Accel limit across a range of layers.", + "type": "enum", + "options": { + "immediate_change": "Immediate", + "gradual_change": "Gradual"}, + "default_value": "immediate_change" + }, "x_accel_limit": ->>>>>>> Stashed changes { "label": "X MAX Acceleration", "description": "If this number is lower than the 'X Print Accel' in Cura then this will limit the Accel on the X axis. Enter the Maximum Acceleration value for the X axis. This will affect both Print and Travel Accel. If you enable an End Layer then at the end of that layer the Accel Limit will be reset (unless you choose 'Gradual' in which case the new limit goes to the top layer).", @@ -79,11 +68,7 @@ class LimitXYAccelJerk(Script): "unit": "mm/sec² ", "default_value": 500 }, -<<<<<<< Updated upstream - "Y_accel_limit": -======= "y_accel_limit": ->>>>>>> Stashed changes { "label": "Y MAX Acceleration", "description": "If this number is lower than the Y accel in Cura then this will limit the Accel on the Y axis. Enter the Maximum Acceleration value for the Y axis. This will affect both Print and Travel Accel. If you enable an End Layer then at the end of that layer the Accel Limit will be reset (unless you choose 'Gradual' in which case the new limit goes to the top layer).", @@ -101,11 +86,7 @@ class LimitXYAccelJerk(Script): "enabled": true, "default_value": false }, -<<<<<<< Updated upstream - "X_jerk": -======= "x_jerk": ->>>>>>> Stashed changes { "label": " X jerk", "description": "Enter the Jerk value for the X axis. Enter '0' to use the existing X Jerk. This setting will affect both the Print and Travel jerk.", @@ -114,11 +95,7 @@ class LimitXYAccelJerk(Script): "unit": "mm/sec ", "default_value": 8 }, -<<<<<<< Updated upstream - "Y_jerk": -======= "y_jerk": ->>>>>>> Stashed changes { "label": " Y jerk", "description": "Enter the Jerk value for the Y axis. Enter '0' to use the existing Y Jerk. This setting will affect both the Print and Travel jerk.", @@ -135,7 +112,7 @@ class LimitXYAccelJerk(Script): "default_value": 1, "minimum_value": 1, "unit": "Lay# ", - "enabled": "not gradient_change" + "enabled": "type_of_change == 'immediate_change'" }, "end_layer": { @@ -145,15 +122,7 @@ class LimitXYAccelJerk(Script): "default_value": -1, "minimum_value": -1, "unit": "Lay# ", - "enabled": "not gradient_change" - }, - "gradient_change": - { - "label": "Gradual ACCEL Change", - "description": "Gradually change the Accel numbers 'From layer' - 'To Layer'. If Jerk is enabled the Jerk changes are not 'Gradual' because there is no Max Jerk setting. Unlike Constant change - using 'Gradual' the Accel and Jerk change continues from the End Layer to the end of the file.", - "type": "bool", - "default_value": false, - "enabled": true + "enabled": "type_of_change == 'immediate_change'" }, "gradient_start_layer": { @@ -163,7 +132,7 @@ class LimitXYAccelJerk(Script): "default_value": 1, "minimum_value": 1, "unit": "Lay# ", - "enabled": "gradient_change" + "enabled": "type_of_change == 'gradual_change'" }, "gradient_end_layer": { @@ -173,7 +142,7 @@ class LimitXYAccelJerk(Script): "default_value": -1, "minimum_value": -1, "unit": "Lay# ", - "enabled": "gradient_change" + "enabled": "type_of_change == 'gradual_change'" } } }""" @@ -181,18 +150,22 @@ class LimitXYAccelJerk(Script): def execute(self, data): mycura = CuraApplication.getInstance().getGlobalContainerStack() extruder = mycura.extruderList -<<<<<<< Updated upstream -======= machine_name = str(mycura.getProperty("machine_name", "value")) + print_sequence = str(mycura.getProperty("print_sequence", "value")) + + # Exit if 'one_at_a_time' is enabled------------------------- + if print_sequence == "one_at_a_time": + Message(text = " [Limit the X-Y Accel/Jerk] DID NOT RUN. This post processor is not compatible with 'One-at-a-Time' mode.").show() + data[0] += "; [LimitXYAccelJerk] DID NOT RUN because Cura is set to 'One-at-a-Time' mode.\n" + return data # Exit if the printer is an Ultimaker------------------------- if "Ultimaker" in machine_name: - Message(text = " [Limit the X-Y Accel/Jerk] DID NOT RUN. This post processor is not intended for fixed printers (for 'bed slinger' printers only.").show() + Message(text = " [Limit the X-Y Accel/Jerk] DID NOT RUN. This post processor is for bed slinger printers only.").show() data[0] += "; [LimitXYAccelJerk] DID NOT RUN because the printer doesn't have a sliding bed.\n" return data ->>>>>>> Stashed changes - constant_change = not bool(self.getSettingValueByKey("gradient_change")) + type_of_change = str(self.getSettingValueByKey("type_of_change")) accel_print_enabled = bool(extruder[0].getProperty("acceleration_enabled", "value")) accel_travel_enabled = bool(extruder[0].getProperty("acceleration_travel_enabled", "value")) accel_print = extruder[0].getProperty("acceleration_print", "value") @@ -201,10 +174,7 @@ class LimitXYAccelJerk(Script): jerk_travel_enabled = str(extruder[0].getProperty("jerk_travel_enabled", "value")) jerk_print_old = extruder[0].getProperty("jerk_print", "value") jerk_travel_old = extruder[0].getProperty("jerk_travel", "value") -<<<<<<< Updated upstream -======= ->>>>>>> Stashed changes if int(accel_print) >= int(accel_travel): accel_old = accel_print else: @@ -215,34 +185,29 @@ class LimitXYAccelJerk(Script): else: jerk_old = jerk_travel_old - #Set the new Accel values--------------------------------------------------------------------------------- -<<<<<<< Updated upstream - x_accel = str(self.getSettingValueByKey("X_accel_limit")) - y_accel = str(self.getSettingValueByKey("Y_accel_limit")) - x_jerk = int(self.getSettingValueByKey("X_jerk")) - y_jerk = int(self.getSettingValueByKey("Y_jerk")) -======= + #Set the new Accel values---------------------------------------------------------- x_accel = str(self.getSettingValueByKey("x_accel_limit")) y_accel = str(self.getSettingValueByKey("y_accel_limit")) x_jerk = int(self.getSettingValueByKey("x_jerk")) y_jerk = int(self.getSettingValueByKey("y_jerk")) ->>>>>>> Stashed changes - # Put the strings together - M201_limit_new = "M201 X" + x_accel + " Y" + y_accel - M201_limit_old = "M201 X" + str(round(accel_old)) + " Y" + str(round(accel_old)) + + # Put the strings together------------------------------------------- + m201_limit_new = "M201 X" + x_accel + " Y" + y_accel + m201_limit_old = "M201 X" + str(round(accel_old)) + " Y" + str(round(accel_old)) if x_jerk == 0: - M205_jerk_pattern = "Y(\d*)" - M205_jerk_new = "Y" + str(y_jerk) + m205_jerk_pattern = "Y(\d*)" + m205_jerk_new = "Y" + str(y_jerk) if y_jerk == 0: - M205_jerk_pattern = "X(\d*)" - M205_jerk_new = "X" + str(x_jerk) + m205_jerk_pattern = "X(\d*)" + m205_jerk_new = "X" + str(x_jerk) if x_jerk != 0 and y_jerk != 0: - M205_jerk_pattern = "M205 X(\d*) Y(\d*)" - M205_jerk_new = "M205 X" + str(x_jerk) + " Y" + str(y_jerk) - M205_jerk_old = "M205 X" + str(jerk_old) + " Y" + str(jerk_old) - + m205_jerk_pattern = "M205 X(\d*) Y(\d*)" + m205_jerk_new = "M205 X" + str(x_jerk) + " Y" + str(y_jerk) + m205_jerk_old = "M205 X" + str(jerk_old) + " Y" + str(jerk_old) + type_of_change = self.getSettingValueByKey("type_of_change") + #Get the indexes of the start and end layers---------------------------------------- - if constant_change: + if type_of_change == 'immediate_change': start_layer = int(self.getSettingValueByKey("start_layer"))-1 end_layer = int(self.getSettingValueByKey("end_layer")) else: @@ -264,14 +229,14 @@ class LimitXYAccelJerk(Script): end_index = len(data)-2 #Add Accel limit and new Jerk at start layer----------------------------------------------------- - if constant_change: + if type_of_change == "immediate_change": layer = data[start_index] lines = layer.split("\n") for index, line in enumerate(lines): if lines[index].startswith(";LAYER:"): - lines.insert(index+1,M201_limit_new) + lines.insert(index+1,m201_limit_new) if self.getSettingValueByKey("jerk_enable"): - lines.insert(index+2,M205_jerk_new) + lines.insert(index+2,m205_jerk_new) data[start_index] = "\n".join(lines) break @@ -281,33 +246,22 @@ class LimitXYAccelJerk(Script): lines = layer.split("\n") for index, line in enumerate(lines): if line.startswith("M205"): - lines[index] = re.sub(M205_jerk_pattern, M205_jerk_new, line) + lines[index] = re.sub(m205_jerk_pattern, m205_jerk_new, line) data[num] = "\n".join(lines) if end_layer != -1: try: layer = data[end_index-1] lines = layer.split("\n") - lines.insert(len(lines)-2,M201_limit_old) - lines.insert(len(lines)-2,M205_jerk_old) + lines.insert(len(lines)-2,m201_limit_old) + lines.insert(len(lines)-2,m205_jerk_old) data[end_index-1] = "\n".join(lines) except: all else: - data[len(data)-1] = M201_limit_old + "\n" + M205_jerk_old + "\n" + data[len(data)-1] -<<<<<<< Updated upstream - return data - - - elif not constant_change: - layer_spread = end_index - start_index - x_accel_hyst = round((accel_old - int(x_accel)) / layer_spread) - y_accel_hyst = round((accel_old - int(y_accel)) / layer_spread) - x_accel_start = round(round((accel_old - x_accel_hyst)/50)*50) - y_accel_start = round(round((accel_old - y_accel_hyst)/50)*50) -======= + data[len(data)-1] = m201_limit_old + "\n" + m205_jerk_old + "\n" + data[len(data)-1] return data - elif not constant_change: + elif type_of_change == "gradual_change": layer_spread = end_index - start_index if accel_old >= int(x_accel): x_accel_hyst = round((accel_old - int(x_accel)) / layer_spread) @@ -326,28 +280,20 @@ class LimitXYAccelJerk(Script): y_accel_start = round(round((accel_old - y_accel_hyst)/25)*25) else: y_accel_start = round(round((y_accel_hyst + accel_old)/25)*25) ->>>>>>> Stashed changes - M201_limit_new = "M201 X" + str(x_accel_start) + " Y" + str(y_accel_start) + m201_limit_new = "M201 X" + str(x_accel_start) + " Y" + str(y_accel_start) #Add Accel limit and new Jerk at start layer------------------------------------------------------------- layer = data[start_index] lines = layer.split("\n") for index, line in enumerate(lines): if lines[index].startswith(";LAYER:"): - lines.insert(index+1,M201_limit_new) + lines.insert(index+1,m201_limit_new) if self.getSettingValueByKey("jerk_enable"): - lines.insert(index+2,M205_jerk_new) + lines.insert(index+2,m205_jerk_new) data[start_index] = "\n".join(lines) break for num in range(start_index + 1, end_index,1): layer = data[num] lines = layer.split("\n") -<<<<<<< Updated upstream - x_accel_start -= x_accel_hyst - if x_accel_start < int(x_accel): x_accel_start = int(x_accel) - y_accel_start -= y_accel_hyst - if y_accel_start < int(y_accel): y_accel_start = int(y_accel) - M201_limit_new = "M201 X" + str(round(round(x_accel_start/50)*50)) + " Y" + str(round(round(y_accel_start/50)*50)) -======= if accel_old >= int(x_accel): x_accel_start -= x_accel_hyst if x_accel_start < int(x_accel): x_accel_start = int(x_accel) @@ -360,21 +306,21 @@ class LimitXYAccelJerk(Script): else: y_accel_start += y_accel_hyst if y_accel_start > int(y_accel): y_accel_start = int(y_accel) - M201_limit_new = "M201 X" + str(round(round(x_accel_start/25)*25)) + " Y" + str(round(round(y_accel_start/25)*25)) ->>>>>>> Stashed changes + m201_limit_new = "M201 X" + str(round(round(x_accel_start/25)*25)) + " Y" + str(round(round(y_accel_start/25)*25)) for index, line in enumerate(lines): if line.startswith(";LAYER:"): - lines.insert(index+1, M201_limit_new) + lines.insert(index+1, m201_limit_new) continue data[num] = "\n".join(lines) - #Alter any existing jerk lines. Accel lines can be ignored----------------------------------- + + #Alter any existing jerk lines. Accel lines can be ignored--------------- if self.getSettingValueByKey("jerk_enable"): for num in range(start_index,len(data)-1,1): layer = data[num] lines = layer.split("\n") for index, line in enumerate(lines): if line.startswith("M205"): - lines[index] = re.sub(M205_jerk_pattern, M205_jerk_new, line) + lines[index] = re.sub(m205_jerk_pattern, m205_jerk_new, line) data[num] = "\n".join(lines) - data[len(data)-1] = M201_limit_old + "\n" + M205_jerk_old + "\n" + data[len(data)-1] + data[len(data)-1] = m201_limit_old + "\n" + m205_jerk_old + "\n" + data[len(data)-1] return data \ No newline at end of file