From 385cf2288b030d23b9ddda1ca3dd68a2a53ad4ca Mon Sep 17 00:00:00 2001 From: Lars Brubaker Date: Tue, 9 Oct 2018 14:29:51 -0700 Subject: [PATCH] ability to turn of line splitting for test --- .../PrinterCommunication/Io/GCodeSwitcher.cs | 58 +++--- .../Io/MaxLengthStream.cs | 172 +++++++++--------- .../PrinterCommunication/PrinterConnection.cs | 4 +- .../Settings/SettingsHelpers.cs | 1 + .../SlicerMapping/EngineMappingMatterSlice.cs | 1 + StaticData/SliceSettings/Properties.json | 9 + .../ReSliceTests.cs | 21 ++- 7 files changed, 147 insertions(+), 119 deletions(-) diff --git a/MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs b/MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs index 2938db837..0ca92be88 100644 --- a/MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs +++ b/MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs @@ -65,48 +65,46 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io if (LineIndex < GCodeFile.LineCount) { if (LineIndex > 1 - && GCodeFile is GCodeMemoryFile currentMemoryFile) + && GCodeFile is GCodeMemoryFile currentMemoryFile + && switchToGCode != null) { - if (switchToGCode != null) + var prevlayerIndex = currentMemoryFile.GetLayerIndex(LineIndex - 1); + var layerIndex = currentMemoryFile.GetLayerIndex(LineIndex); + // we only try to switch as we are changing layers + if (prevlayerIndex < layerIndex) { - var prevlayerIndex = currentMemoryFile.GetLayerIndex(LineIndex - 1); - var layerIndex = currentMemoryFile.GetLayerIndex(LineIndex); - // we only try to switch as we are changing layers - if (prevlayerIndex < layerIndex) + var currentBottom = currentMemoryFile.GetLayerBottom(layerIndex); + // see if there is a layer height that is compatible in the new gcode + for (int i = 0; i < switchToGCode.LayerCount; i++) { - var currentBottom = currentMemoryFile.GetLayerBottom(layerIndex); - // see if there is a layer height that is compatible in the new gcode - for (int i = 0; i < switchToGCode.LayerCount; i++) + // find the first layer in the new code that is greater than or eaqual to our current height + var switchBottom = switchToGCode.GetLayerBottom(i); + if (switchBottom >= currentBottom) { - // find the first layer in the new code that is greater than or eaqual to our current height - var switchBottom = switchToGCode.GetLayerBottom(i); - if (switchBottom >= currentBottom) + // is the current gcode the same or bigger than the new gcode + if (currentBottom >= switchBottom) { - // is the current gcode the same or bigger than the new gcode - if (currentBottom >= switchBottom) + // switch the first time we can + GCodeFile = switchToGCode; + LineIndex = switchToGCode.GetFirstLayerInstruction(i); + var line = $"G92 E{switchToGCode.Instruction(LineIndex).EPosition:0.###}"; + switchToGCode = null; + return line; + } + else // only switch if we are within one layer height of the new gcode + { + if (currentBottom - switchBottom < switchToGCode.GetLayerHeight(layerIndex)) { - // switch the first time we can GCodeFile = switchToGCode; LineIndex = switchToGCode.GetFirstLayerInstruction(i); - var line = $"G92 E{switchToGCode.Instruction(LineIndex).EPosition}"; + switchToGCode = null; + var line = $"G92 E{switchToGCode.Instruction(LineIndex).EPosition:0.###}"; switchToGCode = null; return line; } - else // only switch if we are within one layer height of the new gcode - { - if(currentBottom - switchBottom < switchToGCode.GetLayerHeight(layerIndex)) - { - GCodeFile = switchToGCode; - LineIndex = switchToGCode.GetFirstLayerInstruction(i); - switchToGCode = null; - var line = $"G92 E{switchToGCode.Instruction(LineIndex).EPosition}"; - switchToGCode = null; - return line; - } - } - // we are done evaluating after the first found layer - break; } + // we are done evaluating after the first found layer + break; } } } diff --git a/MatterControlLib/PrinterCommunication/Io/MaxLengthStream.cs b/MatterControlLib/PrinterCommunication/Io/MaxLengthStream.cs index c1cb00b83..32775784f 100644 --- a/MatterControlLib/PrinterCommunication/Io/MaxLengthStream.cs +++ b/MatterControlLib/PrinterCommunication/Io/MaxLengthStream.cs @@ -27,97 +27,26 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ -using MatterHackers.VectorMath; using System; using System.Collections.Generic; namespace MatterHackers.MatterControl.PrinterCommunication.Io { - public class MaxLengthStream : GCodeStreamProxy - { - protected PrinterMove lastDestination = new PrinterMove(); - private List movesToSend = new List(); - private double maxSecondsPerSegment = 1.0/20.0; // 20 instruction per second + public class MaxLengthStream : GCodeStreamProxy + { + protected PrinterMove lastDestination = new PrinterMove(); + // 20 instruction per second + private double maxSecondsPerSegment = 1.0 / 20.0; + private List movesToSend = new List(); - public MaxLengthStream(GCodeStream internalStream, double maxSegmentLength) - : base(internalStream) - { - this.MaxSegmentLength = maxSegmentLength; - } + public MaxLengthStream(GCodeStream internalStream, double maxSegmentLength) + : base(internalStream) + { + this.MaxSegmentLength = maxSegmentLength; + } - public PrinterMove LastDestination { get { return lastDestination; } } - public double MaxSegmentLength { get; set; } - - public override string ReadLine() - { - if (movesToSend.Count == 0) - { - string lineFromChild = base.ReadLine(); - - if (lineFromChild != null - && LineIsMovement(lineFromChild)) - { - PrinterMove currentDestination = GetPosition(lineFromChild, lastDestination); - PrinterMove deltaToDestination = currentDestination - lastDestination; - deltaToDestination.feedRate = 0; // remove the changing of the federate (we'll set it initially) - double lengthSquared = Math.Max(deltaToDestination.LengthSquared, deltaToDestination.extrusion * deltaToDestination.extrusion); - if (lengthSquared > MaxSegmentLength * MaxSegmentLength) - { - // create the line segments to send - double length = Math.Sqrt(lengthSquared); - int numSegmentsToCutInto = (int)Math.Ceiling(length / MaxSegmentLength); - - // segments = (((mm/min) / (60s/min))mm/s / s/segment)segments*mm / mm - double maxSegmentsCanTransmit = 1 / (((currentDestination.feedRate / 60) * maxSecondsPerSegment) / length); - - int numSegmentsToSend = Math.Max(1, Math.Min(numSegmentsToCutInto, (int)maxSegmentsCanTransmit)); - - if (numSegmentsToSend > 1) - { - PrinterMove deltaForSegment = deltaToDestination / numSegmentsToSend; - PrinterMove nextPoint = lastDestination + deltaForSegment; - nextPoint.feedRate = currentDestination.feedRate; - for (int i = 0; i < numSegmentsToSend; i++) - { - lock (movesToSend) - { - movesToSend.Add(nextPoint); - } - nextPoint += deltaForSegment; - } - - // send the first one - PrinterMove positionToSend = movesToSend[0]; - lock (movesToSend) - { - movesToSend.RemoveAt(0); - } - - string altredLineToSend = CreateMovementLine(positionToSend, lastDestination); - lastDestination = positionToSend; - return altredLineToSend; - } - } - - lastDestination = currentDestination; - } - return lineFromChild; - } - else - { - PrinterMove positionToSend = movesToSend[0]; - lock (movesToSend) - { - movesToSend.RemoveAt(0); - } - - string lineToSend = CreateMovementLine(positionToSend, lastDestination); - - lastDestination = positionToSend; - - return lineToSend; - } - } + public PrinterMove LastDestination { get { return lastDestination; } } + public double MaxSegmentLength { get; set; } public void Cancel() { @@ -127,8 +56,79 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io } } - public override void SetPrinterPosition(PrinterMove position) - { + public override string ReadLine() + { + if (movesToSend.Count == 0) + { + string lineFromChild = base.ReadLine(); + + if (lineFromChild != null + && LineIsMovement(lineFromChild)) + { + PrinterMove currentDestination = GetPosition(lineFromChild, lastDestination); + PrinterMove deltaToDestination = currentDestination - lastDestination; + deltaToDestination.feedRate = 0; // remove the changing of the federate (we'll set it initially) + double lengthSquared = Math.Max(deltaToDestination.LengthSquared, deltaToDestination.extrusion * deltaToDestination.extrusion); + if (lengthSquared > MaxSegmentLength * MaxSegmentLength) + { + // create the line segments to send + double length = Math.Sqrt(lengthSquared); + int numSegmentsToCutInto = (int)Math.Ceiling(length / MaxSegmentLength); + + // segments = (((mm/min) / (60s/min))mm/s / s/segment)segments*mm / mm + double maxSegmentsCanTransmit = 1 / (((currentDestination.feedRate / 60) * maxSecondsPerSegment) / length); + + int numSegmentsToSend = Math.Max(1, Math.Min(numSegmentsToCutInto, (int)maxSegmentsCanTransmit)); + + if (numSegmentsToSend > 1) + { + PrinterMove deltaForSegment = deltaToDestination / numSegmentsToSend; + PrinterMove nextPoint = lastDestination + deltaForSegment; + nextPoint.feedRate = currentDestination.feedRate; + for (int i = 0; i < numSegmentsToSend; i++) + { + lock (movesToSend) + { + movesToSend.Add(nextPoint); + } + nextPoint += deltaForSegment; + } + + // send the first one + PrinterMove positionToSend = movesToSend[0]; + lock (movesToSend) + { + movesToSend.RemoveAt(0); + } + + string altredLineToSend = CreateMovementLine(positionToSend, lastDestination); + lastDestination = positionToSend; + return altredLineToSend; + } + } + + lastDestination = currentDestination; + } + return lineFromChild; + } + else + { + PrinterMove positionToSend = movesToSend[0]; + lock (movesToSend) + { + movesToSend.RemoveAt(0); + } + + string lineToSend = CreateMovementLine(positionToSend, lastDestination); + + lastDestination = positionToSend; + + return lineToSend; + } + } + + public override void SetPrinterPosition(PrinterMove position) + { lastDestination = position; internalStream.SetPrinterPosition(lastDestination); } diff --git a/MatterControlLib/PrinterCommunication/PrinterConnection.cs b/MatterControlLib/PrinterCommunication/PrinterConnection.cs index 63555a820..324f67c00 100644 --- a/MatterControlLib/PrinterCommunication/PrinterConnection.cs +++ b/MatterControlLib/PrinterCommunication/PrinterConnection.cs @@ -42,6 +42,7 @@ using MatterHackers.Agg; using MatterHackers.Agg.UI; using MatterHackers.MatterControl.DataStorage; using MatterHackers.MatterControl.PrinterCommunication.Io; +using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.SerialPortCommunication; using MatterHackers.SerialPortCommunication.FrostedSerial; using MatterHackers.VectorMath; @@ -2128,7 +2129,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication queuedCommandStream3 = new QueuedCommandsStream(firstStreamToRead); macroProcessingStream4 = new MacroProcessingStream(queuedCommandStream3, printer); relativeToAbsoluteStream5 = new RelativeToAbsoluteStream(macroProcessingStream4); - babyStepsStream6 = new BabyStepsStream(printer.Settings, relativeToAbsoluteStream5, gcodeFilename == null ? 2000 : 1); + bool enableLineSpliting = gcodeFilename != null && printer.Settings.GetValue(SettingsKey.enable_line_spliting); + babyStepsStream6 = new BabyStepsStream(printer.Settings, relativeToAbsoluteStream5, enableLineSpliting ? 1 : 2000); if (activePrintTask != null) { // make sure we are in the position we were when we stopped printing diff --git a/MatterControlLib/SlicerConfiguration/Settings/SettingsHelpers.cs b/MatterControlLib/SlicerConfiguration/Settings/SettingsHelpers.cs index 2106452f1..e9894f366 100644 --- a/MatterControlLib/SlicerConfiguration/Settings/SettingsHelpers.cs +++ b/MatterControlLib/SlicerConfiguration/Settings/SettingsHelpers.cs @@ -64,6 +64,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public const string default_material_presets = nameof(default_material_presets); public const string device_token = nameof(device_token); public const string device_type = nameof(device_type); + public const string enable_line_spliting = nameof(enable_line_spliting); public const string enable_network_printing = nameof(enable_network_printing); public const string enable_retractions = nameof(enable_retractions); public const string enable_sailfish_communication = nameof(enable_sailfish_communication); diff --git a/MatterControlLib/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs b/MatterControlLib/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs index 9e165523a..b4b317ed6 100644 --- a/MatterControlLib/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs +++ b/MatterControlLib/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs @@ -107,6 +107,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration SettingsKey.make, SettingsKey.model, SettingsKey.enable_network_printing, + SettingsKey.enable_line_spliting, SettingsKey.enable_sailfish_communication, SettingsKey.print_time_estimate_multiplier, SettingsKey.ip_address, diff --git a/StaticData/SliceSettings/Properties.json b/StaticData/SliceSettings/Properties.json index 651dc0693..c3a7fed2c 100644 --- a/StaticData/SliceSettings/Properties.json +++ b/StaticData/SliceSettings/Properties.json @@ -1853,6 +1853,15 @@ "RebuildGCodeOnChange": false, "ReloadUiWhenChanged": true }, + { + "SlicerConfigName": "enable_line_spliting", + "PresentationName": "Enable Line Spliting", + "HelpText": "Allow MatterControl to split long lines to improve levesing and print canceling. Critical for printers that are significantly out of level.", + "ShowIfSet": "!sla_printer", + "DataEditType": "CHECK_BOX", + "DefaultValue": "1", + "RebuildGCodeOnChange": false + }, { "SlicerConfigName": "enable_sailfish_communication", "PresentationName": "Sailfish Communication", diff --git a/Tests/MatterControl.AutomationTests/ReSliceTests.cs b/Tests/MatterControl.AutomationTests/ReSliceTests.cs index 7175e0824..cc9b39d2a 100644 --- a/Tests/MatterControl.AutomationTests/ReSliceTests.cs +++ b/Tests/MatterControl.AutomationTests/ReSliceTests.cs @@ -35,6 +35,7 @@ using System.Threading.Tasks; using MatterHackers.Agg.UI; using MatterHackers.GuiAutomation; using MatterHackers.MatterControl.PartPreviewWindow; +using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.MatterControl.VersionManagement; using NUnit.Framework; @@ -43,15 +44,20 @@ namespace MatterHackers.MatterControl.Tests.Automation [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] public class ReSliceTests { - [Test, Category("Emulator")] + [Test, Category("Emulator"), Ignore("WIP")] + //[Test, Category("Emulator")] public async Task ReSliceHasCorrectEPositions() { await MatterControlUtilities.RunTest((testRunner) => { + AutomationRunner.TimeToMoveMouse = .1; //testRunner.ClickByName("Connection Wizard Skip Sign In Button"); using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator()) { + var printer = ApplicationController.Instance.ActivePrinter; + printer.Settings.SetValue(SettingsKey.enable_line_spliting, "0"); + var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget; var scene = view3D.InteractionLayer.Scene; @@ -65,9 +71,15 @@ namespace MatterHackers.MatterControl.Tests.Automation // distance greater than the largest distance minus the max retraction // amount and less than some amount that is reasonable double lastAbsoluteEPostion = 0; + double largestRetraction = 0; emulator.EPositionChanged += (e, s) => { - Assert.GreaterOrEqual(emulator.CurrentExtruder.AbsoluteEPosition, lastAbsoluteEPostion - 1, "We should never move back more than 1 mm"); + var delta = emulator.CurrentExtruder.AbsoluteEPosition - lastAbsoluteEPostion; + if(delta < largestRetraction) + { + largestRetraction = delta; + } + Assert.GreaterOrEqual(-7, delta, "We should never move back more than 1 mm"); Assert.LessOrEqual(emulator.CurrentExtruder.AbsoluteEPosition, lastAbsoluteEPostion + 10, "We should never move up more than 10 mm"); lastAbsoluteEPostion = emulator.CurrentExtruder.AbsoluteEPosition; }; @@ -77,6 +89,8 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.ClickByName("Row Item cube_20x20x20"); testRunner.ClickByName("Print Library Overflow Menu"); testRunner.ClickByName("Add to Plate Menu Item"); + testRunner.ClickByName("Print Library Overflow Menu"); + testRunner.ClickByName("Add to Plate Menu Item"); // start the print testRunner.StartPrint(); @@ -134,6 +148,9 @@ namespace MatterHackers.MatterControl.Tests.Automation // Wait for done testRunner.WaitForPrintFinished(); + + // this will make sure we turned off line spliting and had good data about the extruder position + Assert.AreEqual(-7, largestRetraction, "Airwolf HD has a retraction of 7mm, make sure we had one"); } return Task.CompletedTask;