diff --git a/MatterControl.Printing/GCode/GCodeMemoryFile.cs b/MatterControl.Printing/GCode/GCodeMemoryFile.cs index def53fbcd..4275f4573 100644 --- a/MatterControl.Printing/GCode/GCodeMemoryFile.cs +++ b/MatterControl.Printing/GCode/GCodeMemoryFile.cs @@ -379,14 +379,15 @@ namespace MatterControl.Printing return false; } - public (int toolIndex, double time) NextToolChange(int instructionIndex, int currentToolIndex = -1) + public (int toolIndex, double time) NextToolChange(int instructionIndex, int currentToolIndex = -1, int toolToLookFor = -1) { int nextToolChange = -1; // find the first tool change that we are less than for (int i = 0; i < toolChanges.Count; i++) { if (instructionIndex < toolChanges[i] - && GCodeCommandQueue[toolChanges[i]].ToolIndex != currentToolIndex) + && GCodeCommandQueue[toolChanges[i]].ToolIndex != currentToolIndex + && (toolToLookFor == -1 || GCodeCommandQueue[toolChanges[i]].ToolIndex == toolToLookFor)) { nextToolChange = i; break; diff --git a/MatterControl.Printing/Settings/SettingsKey.cs b/MatterControl.Printing/Settings/SettingsKey.cs index 181dd0060..94fcc3da2 100644 --- a/MatterControl.Printing/Settings/SettingsKey.cs +++ b/MatterControl.Printing/Settings/SettingsKey.cs @@ -88,6 +88,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public const string has_z_probe = nameof(has_z_probe); public const string has_z_servo = nameof(has_z_servo); public const string heat_extruder_before_homing = nameof(heat_extruder_before_homing); + public const string inactive_cool_down = nameof(inactive_cool_down); public const string include_firmware_updater = nameof(include_firmware_updater); public const string infill_overlap_perimeter = nameof(infill_overlap_perimeter); public const string infill_type = nameof(infill_type); @@ -137,6 +138,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public const string resume_gcode = nameof(resume_gcode); public const string running_clean_markdown2 = nameof(running_clean_markdown2); public const string running_clean_1_markdown = nameof(running_clean_1_markdown); + public const string seconds_to_reheat = nameof(seconds_to_reheat); public const string selector_ip_address = nameof(selector_ip_address); public const string send_with_checksum = nameof(send_with_checksum); public const string filament_has_been_loaded = nameof(filament_has_been_loaded); diff --git a/MatterControl.Printing/Settings/SliceSettingsFields.cs b/MatterControl.Printing/Settings/SliceSettingsFields.cs index 19e87afac..4ede6456c 100644 --- a/MatterControl.Printing/Settings/SliceSettingsFields.cs +++ b/MatterControl.Printing/Settings/SliceSettingsFields.cs @@ -103,6 +103,26 @@ namespace MatterHackers.MatterControl.SlicerConfiguration DefaultValue = "70" }, new SliceSettingData() + { + SlicerConfigName = SettingsKey.inactive_cool_down, + PresentationName = "Inactive Cool Down".Localize(), + HelpText = "The amount to lower the temperature when the hotend is inactive.".Localize(), + DataEditType = DataEditTypes.POSITIVE_DOUBLE, + Units = "°C", + ShowIfSet = "!sla_printer&extruder_count>1", + DefaultValue = "30" + }, + new SliceSettingData() + { + SlicerConfigName = SettingsKey.seconds_to_reheat, + PresentationName = "Warm up Time".Localize(), + HelpText = "The time it takes to heat back up from a cool down.".Localize(), + DataEditType = DataEditTypes.POSITIVE_DOUBLE, + Units = "s", + ShowIfSet = "!sla_printer&extruder_count>1", + DefaultValue = "20" + }, + new SliceSettingData() { SlicerConfigName = SettingsKey.load_filament_length, PresentationName = "Load Filament Length".Localize(), diff --git a/MatterControlLib/Library/Export/GCodeExport.cs b/MatterControlLib/Library/Export/GCodeExport.cs index 0e3500bce..5cf021a29 100644 --- a/MatterControlLib/Library/Export/GCodeExport.cs +++ b/MatterControlLib/Library/Export/GCodeExport.cs @@ -352,16 +352,22 @@ namespace MatterHackers.MatterControl.Library.Export { try { + var settings = this.printer.Settings; + var maxAcceleration = settings.GetValue(SettingsKey.max_acceleration); + var maxVelocity = settings.GetValue(SettingsKey.max_velocity); + var jerkVelocity = settings.GetValue(SettingsKey.jerk_velocity); + var multiplier = settings.GetValue(SettingsKey.print_time_estimate_multiplier) / 100.0; + this.ApplyStreamPipelineAndExport( new GCodeFileStream( GCodeFile.Load( gcodeFilename, - new Vector4(), - new Vector4(), - new Vector4(), - Vector4.One, - CancellationToken.None) - , printer), + new Vector4(maxAcceleration, maxAcceleration, maxAcceleration, maxAcceleration), + new Vector4(maxVelocity, maxVelocity, maxVelocity, maxVelocity), + new Vector4(jerkVelocity, jerkVelocity, jerkVelocity, jerkVelocity), + new Vector4(multiplier, multiplier, multiplier, multiplier), + CancellationToken.None), + printer), outputPath); } catch (Exception e) diff --git a/MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs b/MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs index e4fd9f7ee..07a44fb64 100644 --- a/MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs +++ b/MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MatterControl.Printing; +using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.PrinterCommunication.Io @@ -46,12 +47,18 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io public GCodeSwitcher(string gcodeFilename, PrinterConfig printer, int startLine = 0) : base(printer) { + var settings = this.printer.Settings; + var maxAcceleration = settings.GetValue(SettingsKey.max_acceleration); + var maxVelocity = settings.GetValue(SettingsKey.max_velocity); + var jerkVelocity = settings.GetValue(SettingsKey.jerk_velocity); + var multiplier = settings.GetValue(SettingsKey.print_time_estimate_multiplier) / 100.0; + var fileStreaming = GCodeFile.Load(gcodeFilename, - new Vector4(), - new Vector4(), - new Vector4(), - Vector4.One, - CancellationToken.None); + new Vector4(maxAcceleration, maxAcceleration, maxAcceleration, maxAcceleration), + new Vector4(maxVelocity, maxVelocity, maxVelocity, maxVelocity), + new Vector4(jerkVelocity, jerkVelocity, jerkVelocity, jerkVelocity), + new Vector4(multiplier, multiplier, multiplier, multiplier), + CancellationToken.None); this.GCodeFile = fileStreaming; LineIndex = startLine; @@ -151,11 +158,17 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io { Task.Run(() => { + var settings = this.printer.Settings; + var maxAcceleration = settings.GetValue(SettingsKey.max_acceleration); + var maxVelocity = settings.GetValue(SettingsKey.max_velocity); + var jerkVelocity = settings.GetValue(SettingsKey.jerk_velocity); + var multiplier = settings.GetValue(SettingsKey.print_time_estimate_multiplier) / 100.0; + var switchToGCode = GCodeFile.Load(gcodeFilename, - new Vector4(), - new Vector4(), - new Vector4(), - Vector4.One, + new Vector4(maxAcceleration, maxAcceleration, maxAcceleration, maxAcceleration), + new Vector4(maxVelocity, maxVelocity, maxVelocity, maxVelocity), + new Vector4(jerkVelocity, jerkVelocity, jerkVelocity, jerkVelocity), + new Vector4(multiplier, multiplier, multiplier, multiplier), CancellationToken.None); if (switchToGCode is GCodeMemoryFile memoryFile) diff --git a/MatterControlLib/PrinterCommunication/Io/HotendTemperatureStream.cs b/MatterControlLib/PrinterCommunication/Io/HotendTemperatureStream.cs index 11d834750..f73cff682 100644 --- a/MatterControlLib/PrinterCommunication/Io/HotendTemperatureStream.cs +++ b/MatterControlLib/PrinterCommunication/Io/HotendTemperatureStream.cs @@ -27,6 +27,7 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +using System; using MatterControl.Printing; using MatterHackers.MatterControl.SlicerConfiguration; @@ -34,17 +35,16 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io { public class HotendTemperatureStream : GCodeStreamProxy { - private bool haveSeenMultipleExtruders; - private int extruderIndex; + private int currentToolIndex; private QueuedCommandsStream queuedCommandsStream; - int extruderCount = 0; + int toolCount = 0; public HotendTemperatureStream(PrinterConfig printer, GCodeStream internalStream, QueuedCommandsStream queuedCommandsStream) : base(printer, internalStream) { this.queuedCommandsStream = queuedCommandsStream; - extruderCount = printer.Settings.GetValue(SettingsKey.extruder_count); - extruderIndex = printer.Connection.ActiveExtruderIndex; + toolCount = printer.Settings.GetValue(SettingsKey.extruder_count); + currentToolIndex = printer.Connection.ActiveExtruderIndex; } public override string DebugInfo @@ -65,55 +65,79 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io return lineToSend; } - TrackExtruderState(lineToSend); - - // when we are actively printing manage the extruder temperature - if (haveSeenMultipleExtruders - && printer.Connection.Printing) - { - // get the time to the next extruder switch - var toolChange = printer.Connection.NextToolChange(); - - // if we do not switch again - if (toolChange.time == double.PositiveInfinity) - { - // we do not switch extruders again, turn off any that are not currently printing - for (int i = 0; i < extruderCount; i++) - { - if(i != extruderIndex) - { - printer.Connection.SetTargetHotendTemperature(i, 0, true); - } - } - } - - // don't keep checking if need to turn off extruders - haveSeenMultipleExtruders = false; - } + TrackToolState(lineToSend); return lineToSend; } - private void TrackExtruderState(string line) + private void TrackToolState(string line) { if (line == null) { return; } - if (line.StartsWith("G28)")) + var timeToReheat = printer.Settings.GetValue(SettingsKey.seconds_to_reheat); + + // check if we need to turn on extruders while printing + if (printer.Connection.Printing) { - extruderIndex = 0; + // check if any extruders need to start heating back up + for (int i = 0; i < toolCount; i++) + { + var timeUntilUsed = printer.Connection.NextToolChange(i).time; + var targetTemp = printer.Settings.Helpers.ExtruderTargetTemperature(i); + if (timeUntilUsed < timeToReheat + && printer.Connection.GetTargetHotendTemperature(i) != targetTemp) + { + printer.Connection.SetTargetHotendTemperature(i, targetTemp); + } + } } if (line.StartsWith("T")) { - var newExtruder = extruderIndex; - GCodeFile.GetFirstNumberAfter("T", line, ref newExtruder); - if(newExtruder != extruderIndex) + var nextToolIndex = currentToolIndex; + GCodeFile.GetFirstNumberAfter("T", line, ref nextToolIndex); + if(printer.Connection.Printing + && nextToolIndex != currentToolIndex) { - haveSeenMultipleExtruders = true; - extruderIndex = newExtruder; + // get the time to the next tool switch + var timeToNextToolChange = printer.Connection.NextToolChange().time; + + // if we do not switch again + if (timeToNextToolChange == double.PositiveInfinity) + { + // we do not switch tools again, turn off any that are not currently printing + for (int i = 0; i < toolCount; i++) + { + if (i != nextToolIndex) + { + printer.Connection.SetTargetHotendTemperature(i, 0, true); + } + } + } + else // there are more tool changes in the future + { + // get the next time we will use the current tool + var nextTimeThisTool = printer.Connection.NextToolChange(currentToolIndex).time; + + // if we do not use this tool again + if (nextTimeThisTool == double.PositiveInfinity) + { + // turn off its heat + printer.Connection.SetTargetHotendTemperature(currentToolIndex, 0, true); + } + // If there is enough time before we will use this tool again, lower the temp by the inactive_cool_down + else if (nextTimeThisTool > timeToReheat) + { + var targetTemp = printer.Settings.Helpers.ExtruderTargetTemperature(currentToolIndex); + targetTemp = Math.Max(0, targetTemp - printer.Settings.GetValue(SettingsKey.inactive_cool_down)); + printer.Connection.SetTargetHotendTemperature(currentToolIndex, targetTemp); + } + } + + currentToolIndex = nextToolIndex; } } } diff --git a/MatterControlLib/PrinterCommunication/Io/ToolChangeStream.cs b/MatterControlLib/PrinterCommunication/Io/ToolChangeStream.cs index bb43c5e76..711344ec7 100644 --- a/MatterControlLib/PrinterCommunication/Io/ToolChangeStream.cs +++ b/MatterControlLib/PrinterCommunication/Io/ToolChangeStream.cs @@ -273,12 +273,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io return; } - if (line.StartsWith("G28)")) - { - extruderIndex = 0; - requestedExtruder = 0; - } - if (line.StartsWith("T")) { GCodeFile.GetFirstNumberAfter("T", line, ref requestedExtruder); diff --git a/MatterControlLib/PrinterCommunication/PrinterConnection.cs b/MatterControlLib/PrinterCommunication/PrinterConnection.cs index 624962e8f..256d1faea 100644 --- a/MatterControlLib/PrinterCommunication/PrinterConnection.cs +++ b/MatterControlLib/PrinterCommunication/PrinterConnection.cs @@ -326,14 +326,15 @@ namespace MatterHackers.MatterControl.PrinterCommunication /// seconds until the next tool change while printing /// /// - public (int toolIndex, double time) NextToolChange() + public (int toolIndex, double time) NextToolChange(int toolToLookFor = -1) { - if (gCodeFileSwitcher.GCodeFile is GCodeMemoryFile gCodeMemoryFile) + if (gCodeFileSwitcher != null + && gCodeFileSwitcher.GCodeFile is GCodeMemoryFile gCodeMemoryFile) { - return gCodeMemoryFile.NextToolChange(gCodeFileSwitcher.LineIndex); + return gCodeMemoryFile.NextToolChange(gCodeFileSwitcher.LineIndex, -1, toolToLookFor); } - return (0, 0); + return (-1, 0); } private void ExtruderIndexSet(string line) diff --git a/MatterControlLib/SlicerConfiguration/EngineMappingMatterSlice.cs b/MatterControlLib/SlicerConfiguration/EngineMappingMatterSlice.cs index 99a7639e6..9ffce38cf 100644 --- a/MatterControlLib/SlicerConfiguration/EngineMappingMatterSlice.cs +++ b/MatterControlLib/SlicerConfiguration/EngineMappingMatterSlice.cs @@ -90,6 +90,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration SettingsKey.has_z_probe, SettingsKey.has_z_servo, SettingsKey.heat_extruder_before_homing, + SettingsKey.inactive_cool_down, SettingsKey.include_firmware_updater, SettingsKey.insert_filament_markdown2, SettingsKey.insert_filament_1_markdown, @@ -121,6 +122,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration SettingsKey.resume_gcode, SettingsKey.running_clean_markdown2, SettingsKey.running_clean_1_markdown, + SettingsKey.seconds_to_reheat, SettingsKey.send_with_checksum, SettingsKey.show_reset_connection, SettingsKey.sla_printer, diff --git a/StaticData/SliceSettings/Layouts.txt b/StaticData/SliceSettings/Layouts.txt index 96dad1bfe..3057cb594 100644 --- a/StaticData/SliceSettings/Layouts.txt +++ b/StaticData/SliceSettings/Layouts.txt @@ -100,6 +100,8 @@ Advanced temperature2 temperature3 bed_temperature + inactive_cool_down + seconds_to_reheat Advanced Material Temperatures