From cbb704d7b0d693f133cd2deb65d182ee7196d081 Mon Sep 17 00:00:00 2001 From: larsbrubaker Date: Sat, 28 Nov 2015 07:46:57 -0800 Subject: [PATCH] made a new gcode stream that only implements Line working to implement baby steps (and other line processing) --- MatterControl.csproj | 1 + PrinterCommunication/Io/BabbySteps.cs | 56 ++++++ PrinterCommunication/Io/GCodeFileProxy.cs | 6 +- .../PrinterConnectionAndCommunication.cs | 176 +++++++----------- PrinterControls/EditMacrosWindow.cs | 2 +- PrinterEmulator.py | 2 +- .../SlicerMapping/EngineMappingMatterSlice.cs | 5 +- Submodules/MatterSlice | 2 +- Submodules/agg-sharp | 2 +- 9 files changed, 132 insertions(+), 120 deletions(-) create mode 100644 PrinterCommunication/Io/BabbySteps.cs diff --git a/MatterControl.csproj b/MatterControl.csproj index 7217d8418..b98815713 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -198,6 +198,7 @@ + diff --git a/PrinterCommunication/Io/BabbySteps.cs b/PrinterCommunication/Io/BabbySteps.cs new file mode 100644 index 000000000..78cbf25bd --- /dev/null +++ b/PrinterCommunication/Io/BabbySteps.cs @@ -0,0 +1,56 @@ +/* +Copyright (c) 2014, Lars Brubaker +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System; +using MatterHackers.Agg; +using MatterHackers.GCodeVisualizer; +using MatterHackers.VectorMath; + +namespace MatterHackers.MatterControl.PrinterCommunication.Io +{ + public class BabbySteps : GCodeFileProxy + { + public BabbySteps(GCodeFile source) + : base(source) + { + } + + #region Abstract Functions + public override void Insert(int indexToStartInjection, PrinterMachineInstruction printerMachineInstruction) + { + throw new NotImplementedException(); + } + + public override PrinterMachineInstruction Instruction(int i) + { + throw new NotImplementedException(); + } + #endregion Abstract Functions + } +} \ No newline at end of file diff --git a/PrinterCommunication/Io/GCodeFileProxy.cs b/PrinterCommunication/Io/GCodeFileProxy.cs index fbdb29858..c119ff388 100644 --- a/PrinterCommunication/Io/GCodeFileProxy.cs +++ b/PrinterCommunication/Io/GCodeFileProxy.cs @@ -1,5 +1,5 @@ /* -Copyright (c) 2014, Lars Brubaker +Copyright (c) 2015, Lars Brubaker All rights reserved. Redistribution and use in source and binary forms, with or without @@ -36,7 +36,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io { public class GCodeFileProxy : GCodeFile { - private GCodeFile source; + private GCodeFile source; + + protected GCodeFile Source { get { return source; } } public GCodeFileProxy(GCodeFile source) { diff --git a/PrinterCommunication/PrinterConnectionAndCommunication.cs b/PrinterCommunication/PrinterConnectionAndCommunication.cs index 7f869652e..b1c14de1e 100644 --- a/PrinterCommunication/PrinterConnectionAndCommunication.cs +++ b/PrinterCommunication/PrinterConnectionAndCommunication.cs @@ -179,7 +179,11 @@ namespace MatterHackers.MatterControl.PrinterCommunication private List LinesToWriteQueue = new List(); - private GCodeFile loadedGCode = new GCodeFileLoaded(); + private GCodeFile loadedGCode = new GCodeFileLoaded(); + + private GCodeStream rootGCodeStream = null; + private QueuedCommands gcodeCommandQueue = null; + private LoadedGCodeStream loadedGCodeStream = null; private PrinterMachineInstruction.MovementTypes movementMode = PrinterMachineInstruction.MovementTypes.Absolute; @@ -187,8 +191,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication private double previousGcodeRequestedExtrusionPosition = 0; - private int printerCommandQueueLineIndex = -1; - private DetailedPrintingState printingStatePrivate; private string printJobDisplayName = null; @@ -515,8 +517,13 @@ namespace MatterHackers.MatterControl.PrinterCommunication { get { - int instructionIndex = printerCommandQueueLineIndex - backupAmount; - return loadedGCode.GetLayerIndex(instructionIndex); + if (loadedGCodeStream != null) + { + int instructionIndex = loadedGCodeStream.LineIndex - backupAmount; + return loadedGCode.GetLayerIndex(instructionIndex); + } + + return 0; } } @@ -613,7 +620,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication else if (NumberOfLinesInCurrentPrint > 0 && loadedGCode != null) { - return loadedGCode.PercentComplete(printerCommandQueueLineIndex); + return loadedGCode.PercentComplete(loadedGCodeStream.LineIndex); } else { @@ -820,7 +827,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication { get { - int instructionIndex = printerCommandQueueLineIndex - backupAmount; + int instructionIndex = loadedGCodeStream.LineIndex - backupAmount; return loadedGCode.Ratio0to1IntoContainedLayer(instructionIndex); } } @@ -838,29 +845,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication } } - public int SecondsRemaining - { - get - { - if (NumberOfLinesInCurrentPrint > 0) - { - if (printerCommandQueueLineIndex >= 0 - && printerCommandQueueLineIndex < loadedGCode.LineCount - && loadedGCode.Instruction(printerCommandQueueLineIndex).secondsToEndFromHere != 0) - { - if (FeedRateRatio != 0) - { - lastRemainingSecondsReported = (int)(loadedGCode.Instruction(printerCommandQueueLineIndex).secondsToEndFromHere / FeedRateRatio); - } - } - - return lastRemainingSecondsReported; - } - - return 0; - } - } - public double TargetBedTemperature { get @@ -1245,7 +1229,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication } if (temperatureRequestTimer.ElapsedMilliseconds > 2000) { - if (MonitorPrinterTemperature + if (!PrinterIsPrinting + && MonitorPrinterTemperature && (!timeWaitingForTemperature.IsRunning || timeWaitingForTemperature.Elapsed.TotalSeconds > 60)) { timeWaitingForTemperature.Restart(); @@ -1797,13 +1782,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication SendLineToPrinterNow("M84"); } - public void RequestPause(int injectionStartIndex = 0) + public void RequestPause() { - if (injectionStartIndex == 0) - { - injectionStartIndex = printerCommandQueueLineIndex; - } - if (PrinterIsPrinting) { if (CommunicationState == CommunicationStates.PrintingFromSd) @@ -1819,27 +1799,27 @@ namespace MatterHackers.MatterControl.PrinterCommunication { // inject the resume_gcode to execute when we resume printing string resumeGCode = ActiveSliceSettings.Instance.GetActiveValue("resume_gcode"); - int lastIndexAdded = InjectGCode(resumeGCode, injectionStartIndex); + InjectGCode(resumeGCode); // put in the code to return to our pre-pause postion - lastIndexAdded = InjectGCode("G0 X{0:0.000} Y{1:0.000} Z{2:0.000} F{3}".FormatWith(currentDestination.x, currentDestination.y, currentDestination.z, currentFeedRate), injectionStartIndex); + InjectGCode("G0 X{0:0.000} Y{1:0.000} Z{2:0.000} F{3}".FormatWith(currentDestination.x, currentDestination.y, currentDestination.z, currentFeedRate)); DoPause(); } else { using (TimedLock.Lock(this, "RequestPause")) { - int lastIndexAdded = InjectGCode(pauseGCode, injectionStartIndex); + InjectGCode(pauseGCode); // inject a marker to tell when we are done with the inserted pause code - lastIndexAdded = InjectGCode("MH_PAUSE", lastIndexAdded); + InjectGCode("MH_PAUSE"); // inject the resume_gcode to execute when we resume printing string resumeGCode = ActiveSliceSettings.Instance.GetActiveValue("resume_gcode"); - lastIndexAdded = InjectGCode(resumeGCode, lastIndexAdded); + InjectGCode(resumeGCode); // put in the code to return to return to our pre-pause postion - lastIndexAdded = InjectGCode("G0 X{0:0.000} Y{1:0.000} Z{2:0.000} F{3}".FormatWith(currentDestination.x, currentDestination.y, currentDestination.z, currentFeedRate), lastIndexAdded); + InjectGCode("G0 X{0:0.000} Y{1:0.000} Z{2:0.000} F{3}".FormatWith(currentDestination.x, currentDestination.y, currentDestination.z, currentFeedRate)); } } } @@ -1922,15 +1902,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication { if (PrinterIsPrinting && CommunicationState != CommunicationStates.PrintingFromSd) { - // insert the command into the printing queue at the head - if (printerCommandQueueLineIndex >= 0 - && printerCommandQueueLineIndex < loadedGCode.LineCount - 1) - { - if (!loadedGCode.Instruction(printerCommandQueueLineIndex + 1).Line.Contains(lineToWrite)) - { - loadedGCode.Insert(printerCommandQueueLineIndex + 1, new PrinterMachineInstruction(lineToWrite, loadedGCode.Instruction(printerCommandQueueLineIndex))); - } - } + // insert the command into the printing queue at the head + InjectGCode(lineToWrite); } else { @@ -2113,7 +2086,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication if (cancelGCode.Trim() != "") { // add any gcode we want to print while canceling - InjectGCode(cancelGCode, printerCommandQueueLineIndex); + InjectGCode(cancelGCode); } // let the process know we canceled not ended normaly. printWasCanceled = true; @@ -2257,7 +2230,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication private void ClearQueuedGCode() { loadedGCode.Clear(); - printerCommandQueueLineIndex = 0; lastRemainingSecondsReported = 0; allCheckSumLinesSent.Clear(); @@ -2419,14 +2391,13 @@ namespace MatterHackers.MatterControl.PrinterCommunication PrintingCanContinue(this, null); } - private int InjectGCode(string codeToInject, int lineIndexToStartInjection) + private void InjectGCode(string codeToInject) { codeToInject = GCodeProcessing.ReplaceMacroValues(codeToInject); codeToInject = codeToInject.Replace("\\n", "\n"); string[] lines = codeToInject.Split('\n'); - int linesAdded = 0; for (int i = lines.Length - 1; i >= 0; i--) { string[] splitOnSemicolon = lines[i].Split(';'); @@ -2435,19 +2406,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication { trimedLine = ReplacePrinterMacros(trimedLine); - if (loadedGCode.LineCount > lineIndexToStartInjection) - { - loadedGCode.Insert(lineIndexToStartInjection, new PrinterMachineInstruction(trimedLine, loadedGCode.Instruction(lineIndexToStartInjection))); - } - else - { - loadedGCode.Add(new PrinterMachineInstruction(trimedLine)); - } - linesAdded++; + gcodeCommandQueue.Add(trimedLine); } } - - return lineIndexToStartInjection + linesAdded; } private string KeepTrackOfPostionAndDestination(string lineBeingSent) @@ -2489,9 +2450,13 @@ namespace MatterHackers.MatterControl.PrinterCommunication { string gcodeFilename = e.Argument as string; loadedGCode = GCodeFile.Load(gcodeFilename); - } - private void loadGCodeWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + loadedGCodeStream = new LoadedGCodeStream(loadedGCode); + gcodeCommandQueue = new QueuedCommands(loadedGCodeStream); + rootGCodeStream = new RequestTemperatures(gcodeCommandQueue); + } + + private void loadGCodeWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { switch (communicationState) { @@ -2526,17 +2491,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication } } - private double MaxTimeToMoveForSentInstructions() - { - double maxTime = 0; - for (int i = Math.Max(0, printerCommandQueueLineIndex - backupAmount); i < printerCommandQueueLineIndex; i++) - { - maxTime = Math.Max(maxTime, loadedGCode.Instruction(i).secondsThisLine); - } - - return maxTime * 1.5; - } - private void MovementWasSetToAbsoluteMode(object sender, EventArgs e) { movementMode = PrinterMachineInstruction.MovementTypes.Absolute; @@ -2759,22 +2713,31 @@ namespace MatterHackers.MatterControl.PrinterCommunication } } - private void TryWriteNextLineFromGCodeFile() + private double MaxTimeToMoveForSentInstructions() + { + // TODO: do the math for the currently pending move + // expectedTime = 1 / movementspeed / (currentSentLine - previousSentLine).Length + + return 5; + } + + string currentSentLine; + string previousSentLine; + + private void TryWriteNextLineFromGCodeFile() { - bool forceContinueInCaseOfNoResponse = false; // wait until the printer responds from the last command with an ok OR we waited too long - if (timeHaveBeenWaitingForOK.IsRunning - && !forceContinueInCaseOfNoResponse) + if (timeHaveBeenWaitingForOK.IsRunning) { using (TimedLock.Lock(this, "WriteNextLineFromGCodeFile1")) { // we are still sending commands - if (printerCommandQueueLineIndex > 0 && printerCommandQueueLineIndex < loadedGCode.LineCount - 1) + if (currentSentLine != null) { // the last instruction was a move - PrinterMachineInstruction lastInstruction = loadedGCode.Instruction(printerCommandQueueLineIndex - 1); + string lastInstruction = previousSentLine; double epectedSecondsToWait = Math.Max(5, MaxTimeToMoveForSentInstructions()); - bool wasMoveAndNoOK = (lastInstruction.Line.Contains("G0 ") || lastInstruction.Line.Contains("G1 ")) + bool wasMoveAndNoOK = (lastInstruction.Contains("G0 ") || lastInstruction.Contains("G1 ")) && timeHaveBeenWaitingForOK.Elapsed.TotalSeconds > epectedSecondsToWait; { // This code is to try and make sure the printer does not stop on transmission errors. @@ -2788,7 +2751,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication // Basically we got some response but it did not contain an OK. // The theory is that we may have recieved a transmission error (like 'OP' rather than 'OK') // and in that event we don't want the print to just stop and wait forever. - forceContinueInCaseOfNoResponse = true; firstLineToResendIndex--; // we are going to resend the last command } } @@ -2805,7 +2767,10 @@ namespace MatterHackers.MatterControl.PrinterCommunication bool pauseRequested = false; using (TimedLock.Lock(this, "WriteNextLineFromGCodeFile2")) { - if (printerCommandQueueLineIndex < loadedGCode.LineCount) + previousSentLine = this.currentSentLine; + currentSentLine = rootGCodeStream.ReadLine(); + + if (currentSentLine != null) { if (firstLineToResendIndex < allCheckSumLinesSent.Count) { @@ -2820,33 +2785,31 @@ namespace MatterHackers.MatterControl.PrinterCommunication return; } - string lineToWrite = loadedGCode.Instruction(printerCommandQueueLineIndex).Line; - string[] splitOnSemicolon = lineToWrite.Split(';'); + string[] splitOnSemicolon = currentSentLine.Split(';'); string trimedLine = splitOnSemicolon[0].Trim().ToUpper(); - if (lineToWrite.Contains("M114")) + if (currentSentLine.Contains("M114")) { waitingForPosition.Restart(); } if (trimedLine.Length > 0) { - if (lineToWrite == "MH_PAUSE") + if (currentSentLine == "MH_PAUSE") { pauseRequested = true; } - else if (lineToWrite == "M226" || lineToWrite == "@pause") + else if (currentSentLine == "M226" || currentSentLine == "@pause") { - RequestPause(printerCommandQueueLineIndex + 1); + RequestPause(); } else { - WriteChecksumLineToPrinter(lineToWrite); + WriteChecksumLineToPrinter(currentSentLine); } firstLineToResendIndex++; } - printerCommandQueueLineIndex++; } } else if (printWasCanceled) @@ -2857,22 +2820,15 @@ namespace MatterHackers.MatterControl.PrinterCommunication TurnOffBedAndExtruders(); printWasCanceled = false; } - else + else // we finished printing normalyl { - if (printerCommandQueueLineIndex == loadedGCode.LineCount) - { - CommunicationState = CommunicationStates.FinishedPrint; + CommunicationState = CommunicationStates.FinishedPrint; - printJobDisplayName = null; + printJobDisplayName = null; - // never leave the extruder and the bed hot - ReleaseMotors(); - TurnOffBedAndExtruders(); - } - else if (!PrinterIsPaused) - { - CommunicationState = CommunicationStates.Connected; - } + // never leave the extruder and the bed hot + ReleaseMotors(); + TurnOffBedAndExtruders(); } } diff --git a/PrinterControls/EditMacrosWindow.cs b/PrinterControls/EditMacrosWindow.cs index 5453d34a5..0ecd530c8 100644 --- a/PrinterControls/EditMacrosWindow.cs +++ b/PrinterControls/EditMacrosWindow.cs @@ -326,7 +326,7 @@ namespace MatterHackers.MatterControl } Button addMacroButton = textImageButtonFactory.Generate(LocalizedString.Get("Add"), "icon_circle_plus.png"); - addMacroButton.ToolTipText = "Add an new Macro".Localize(); + addMacroButton.ToolTipText = "Add a new Macro".Localize(); addMacroButton.Click += new EventHandler(addMacro_Click); Button cancelPresetsButton = textImageButtonFactory.Generate(LocalizedString.Get("Close")); diff --git a/PrinterEmulator.py b/PrinterEmulator.py index d2f7ea6c5..f4740e505 100644 --- a/PrinterEmulator.py +++ b/PrinterEmulator.py @@ -77,7 +77,7 @@ def main(argv): if len(argv) > 0: ser = serial.Serial(argv[0], 250000, timeout=1) else: - ser = serial.Serial('COM14', 250000, timeout=1) + ser = serial.Serial('COM4', 250000, timeout=1) waitForKey = True print "Initializing emulator..." while True: diff --git a/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs b/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs index 7956d3f72..d9d638478 100644 --- a/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs +++ b/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs @@ -84,9 +84,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration //continuousSpiralOuterPerimeter=False # This will cause the z height to raise continuously while on the outer perimeter. new MapItemToBool("continuousSpiralOuterPerimeter", "spiral_vase"), - //doCoolHeadLift=False # Will cause the head to be raised in z until the min layer time is reached. - new MapItemToBool("doCoolHeadLift", "cool_extruder_lift"), - new VisibleButNotMappedToEngine("extruder_count"), new VisibleButNotMappedToEngine("extruders_share_temperature"), @@ -130,7 +127,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration //firstLayerToAllowFan=2 # The fan will be force to stay off below this layer. new MapItem("firstLayerToAllowFan", "disable_fan_first_layers"), - //outputType=REPRAP # Available Values: REPRAP, ULTIGCODE, MAKERBOT, BFB, MACH3 + //outputType=REPRAP # Available Values: REPRAP, ULTIGCODE, MAKERBOT, MACH3 new MapItem("outputType", "gcode_output_type"), //generateInternalSupport=True # If True, support will be generated within the part as well as from the bed. diff --git a/Submodules/MatterSlice b/Submodules/MatterSlice index 246646827..2620de812 160000 --- a/Submodules/MatterSlice +++ b/Submodules/MatterSlice @@ -1 +1 @@ -Subproject commit 2466468276345410ac41b362ead12b5dce693c21 +Subproject commit 2620de812e9b1441307dd899f1e2096353631ef4 diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index fb3ee47f7..685115254 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit fb3ee47f70c5a67d97da5f3a2b52b8e31014236e +Subproject commit 685115254a7d274734dd82291d1f8bca3a27e182