Example #1
0
        public void Report(ProgressStatus progressStatus)
        {
            double currentValue = 0;
            double destValue    = 10;

            string statusText = progressStatus.Status = progressStatus.Status.Trim().TrimEnd('.');

            if (GCodeFile.GetFirstNumberAfter("", statusText, ref currentValue) &&
                GCodeFile.GetFirstNumberAfter("/", statusText, ref destValue))
            {
                if (destValue == 0)
                {
                    destValue = 1;
                }

                progressStatus.Progress0To1 = currentValue / destValue;
                progressStatus.Target       = null;
            }
            else
            {
                progressStatus.Status = statusText;
                progressStatus.Target = "terminal";
            }

            reporter.Report(progressStatus);
        }
        private string KeepTrackOfPostionAndDestination(string lineBeingSent)
        {
            if (lineBeingSent.StartsWith("G0 ") || lineBeingSent.StartsWith("G1 "))
            {
                Vector3 newDestination = currentDestination;
                if (PrinterConnectionAndCommunication.Instance.MovementMode == PrinterMachineInstruction.MovementTypes.Relative)
                {
                    newDestination = Vector3.Zero;
                }

                GCodeFile.GetFirstNumberAfter("X", lineBeingSent, out newDestination.x);
                GCodeFile.GetFirstNumberAfter("Y", lineBeingSent, out newDestination.y);
                GCodeFile.GetFirstNumberAfter("Z", lineBeingSent, out newDestination.z);

                GCodeFile.GetFirstNumberAfter("E", lineBeingSent, out currentExtruderDestination);
                GCodeFile.GetFirstNumberAfter("F", lineBeingSent, out currentFeedRate);

                if (PrinterConnectionAndCommunication.Instance.MovementMode == PrinterMachineInstruction.MovementTypes.Relative)
                {
                    newDestination += currentDestination;
                }

                if (currentDestination != newDestination)
                {
                    currentDestination = newDestination;
                    DestinationChanged.CallEvents(this, null);
                }
            }

            return(lineBeingSent);
        }
Example #3
0
        public string ApplyLeveling(Vector3 currentDestination, string lineBeingSent)
        {
            if ((lineBeingSent.StartsWith("G0") || lineBeingSent.StartsWith("G1")) &&
                lineBeingSent.Length > 2 &&
                lineBeingSent[2] == ' ')
            {
                double extruderDelta = 0;
                GCodeFile.GetFirstNumberAfter("E", lineBeingSent, ref extruderDelta);
                double feedRate = 0;
                GCodeFile.GetFirstNumberAfter("F", lineBeingSent, ref feedRate);

                string newLine = "G1 ";

                if (lineBeingSent.Contains("X") || lineBeingSent.Contains("Y") || lineBeingSent.Contains("Z"))
                {
                    Vector3 outPosition = PrintLevelingPlane.Instance.ApplyLeveling(currentDestination);

                    newLine = newLine + String.Format("X{0:0.##} Y{1:0.##} Z{2:0.###}", outPosition.X, outPosition.Y, outPosition.Z);
                }

                if (extruderDelta != 0)
                {
                    newLine = newLine + String.Format(" E{0:0.###}", extruderDelta);
                }
                if (feedRate != 0)
                {
                    newLine = newLine + String.Format(" F{0:0.##}", feedRate);
                }

                lineBeingSent = newLine;
            }

            return(lineBeingSent);
        }
        private string ApplyExtrusionMultiplier(string lineBeingSent)
        {
            if (lineBeingSent != null)
            {
                if (LineIsMovement(lineBeingSent))
                {
                    double gcodeRequestedExtrusionPosition = 0;
                    if (GCodeFile.GetFirstNumberAfter("E", lineBeingSent, ref gcodeRequestedExtrusionPosition))
                    {
                        double delta = gcodeRequestedExtrusionPosition - previousGcodeRequestedExtrusionPosition;
                        double newActualExtruderPosition = currentActualExtrusionPosition + delta * ExtrusionRatio;
                        lineBeingSent = GCodeFile.ReplaceNumberAfter('E', lineBeingSent, newActualExtruderPosition);
                        previousGcodeRequestedExtrusionPosition = gcodeRequestedExtrusionPosition;
                        currentActualExtrusionPosition          = newActualExtruderPosition;
                    }
                }
                else if (lineBeingSent.StartsWith("G92"))
                {
                    double gcodeRequestedExtrusionPosition = 0;
                    if (GCodeFile.GetFirstNumberAfter("E", lineBeingSent, ref gcodeRequestedExtrusionPosition))
                    {
                        previousGcodeRequestedExtrusionPosition = gcodeRequestedExtrusionPosition;
                        currentActualExtrusionPosition          = gcodeRequestedExtrusionPosition;
                    }
                }
            }

            return(lineBeingSent);
        }
Example #5
0
        public static PrinterMove GetPosition(string lineBeingSent, PrinterMove startPositionPosition)
        {
            PrinterMove currentDestination = startPositionPosition;

            GCodeFile.GetFirstNumberAfter("X", lineBeingSent, ref currentDestination.position.x);
            GCodeFile.GetFirstNumberAfter("Y", lineBeingSent, ref currentDestination.position.y);
            GCodeFile.GetFirstNumberAfter("Z", lineBeingSent, ref currentDestination.position.z);
            GCodeFile.GetFirstNumberAfter("E", lineBeingSent, ref currentDestination.extrusion);
            GCodeFile.GetFirstNumberAfter("F", lineBeingSent, ref currentDestination.feedRate);
            return(currentDestination);
        }
Example #6
0
        public string ApplyLeveling(Vector3 currentDestination, PrinterMachineInstruction.MovementTypes movementMode, string lineBeingSent, bool addLFCR, bool includeSpaces)
        {
            if ((lineBeingSent.StartsWith("G0") || lineBeingSent.StartsWith("G1")) &&
                lineBeingSent.Length > 2 &&
                lineBeingSent[2] == ' ')
            {
                double extruderDelta = 0;
                GCodeFile.GetFirstNumberAfter("E", lineBeingSent, ref extruderDelta);
                double feedRate = 0;
                GCodeFile.GetFirstNumberAfter("F", lineBeingSent, ref feedRate);

                string newLine = "G1 ";

                if (lineBeingSent.Contains('X') || lineBeingSent.Contains('Y') || lineBeingSent.Contains('Z'))
                {
                    Vector3 outPosition = PrintLeveling.Instance.ApplyLeveling(currentDestination);
                    if (movementMode == PrinterMachineInstruction.MovementTypes.Relative)
                    {
                        Vector3 relativeMove = Vector3.Zero;
                        GCodeFile.GetFirstNumberAfter("X", lineBeingSent, ref relativeMove.x);
                        GCodeFile.GetFirstNumberAfter("Y", lineBeingSent, ref relativeMove.y);
                        GCodeFile.GetFirstNumberAfter("Z", lineBeingSent, ref relativeMove.z);
                        outPosition = PrintLeveling.Instance.ApplyLevelingRotation(relativeMove);
                    }

                    if (includeSpaces)
                    {
                        newLine = newLine + String.Format("X{0:0.##} Y{1:0.##} Z{2:0.##}", outPosition.x, outPosition.y, outPosition.z);
                    }
                    else
                    {
                        newLine = newLine + String.Format("X{0:0.##}Y{1:0.##}Z{2:0.##}", outPosition.x, outPosition.y, outPosition.z);
                    }
                }

                if (extruderDelta != 0)
                {
                    newLine = newLine + String.Format(" E{0:0.###}", extruderDelta);
                }
                if (feedRate != 0)
                {
                    newLine = newLine + String.Format(" F{0:0.##}", feedRate);
                }

                lineBeingSent = newLine;

                if (addLFCR)
                {
                    lineBeingSent += "\r\n";
                }
            }

            return(lineBeingSent);
        }
        private void GetZProbeHeight(object sender, string line)
        {
            if (line != null)
            {
                double sampleRead = double.MinValue;
                if (line.StartsWith("Bed"))                 // marlin G30 return code (looks like: 'Bed Position X:20 Y:32 Z:.01')
                {
                    sampledPosition.X = positionToSample.X;
                    sampledPosition.Y = positionToSample.Y;
                    GCodeFile.GetFirstNumberAfter("Z:", line, ref sampleRead);
                }
                else if (line.StartsWith("Z:"))                 // smoothie G30 return code (looks like: 'Z:10.01')
                {
                    sampledPosition.X = positionToSample.X;
                    sampledPosition.Y = positionToSample.Y;
                    // smoothie returns the position relative to the start position
                    double reportedProbeZ = 0;

                    GCodeFile.GetFirstNumberAfter("Z:", line, ref reportedProbeZ);
                    sampleRead = positionToSample.Z - reportedProbeZ;
                }

                if (sampleRead != double.MinValue)
                {
                    samplesForSinglePosition.Add(sampleRead);

                    int numberOfSamples = printer.Settings.GetValue <int>(SettingsKey.z_probe_samples);
                    if (samplesForSinglePosition.Count >= numberOfSamples)
                    {
                        samplesForSinglePosition.Sort();
                        if (samplesForSinglePosition.Count > 3)
                        {
                            // drop the high and low values
                            samplesForSinglePosition.RemoveAt(0);
                            samplesForSinglePosition.RemoveAt(samplesForSinglePosition.Count - 1);
                        }

                        sampledPosition.Z = Math.Round(samplesForSinglePosition.Average(), 2);

                        // When probe data has been collected, resume our thread to continue collecting
                        waitingToCompleteNextSample = false;
                    }
                    else
                    {
                        // add the next request for probe
                        printer.Connection.QueueLine("G30");
                        // raise the probe after each sample
                        var feedRates = printer.Settings.Helpers.ManualMovementSpeeds();
                        printer.Connection.QueueLine($"G1 X{positionToSampleWithProbeOffset.X:0.###}Y{positionToSampleWithProbeOffset.Y:0.###}Z{positionToSampleWithProbeOffset.Z:0.###} F{feedRates.X}");
                    }
                }
            }
        }
Example #8
0
        private void GetZProbeHeight(object sender, string line)
        {
            if (line != null)
            {
                double sampleRead = double.MinValue;
                if (line.StartsWith("Bed"))                 // marlin G30 return code (looks like: 'Bed Position X:20 Y:32 Z:.01')
                {
                    probePositions[probePositionsBeingEditedIndex].Position.X = probeStartPosition.X;
                    probePositions[probePositionsBeingEditedIndex].Position.Y = probeStartPosition.Y;
                    GCodeFile.GetFirstNumberAfter("Z:", line, ref sampleRead);
                }
                else if (line.StartsWith("Z:"))                 // smoothie G30 return code (looks like: 'Z:10.01')
                {
                    probePositions[probePositionsBeingEditedIndex].Position.X = probeStartPosition.X;
                    probePositions[probePositionsBeingEditedIndex].Position.Y = probeStartPosition.Y;
                    // smoothie returns the position relative to the start position
                    double reportedProbeZ = 0;

                    GCodeFile.GetFirstNumberAfter("Z:", line, ref reportedProbeZ);
                    sampleRead = probeStartPosition.Z - reportedProbeZ;
                }

                if (sampleRead != double.MinValue)
                {
                    samples.Add(sampleRead);

                    int numberOfSamples = printer.Settings.GetValue <int>(SettingsKey.z_probe_samples);
                    if (samples.Count >= numberOfSamples)
                    {
                        samples.Sort();
                        if (samples.Count > 3)
                        {
                            // drop the high and low values
                            samples.RemoveAt(0);
                            samples.RemoveAt(samples.Count - 1);
                        }

                        probePositions[probePositionsBeingEditedIndex].Position.Z = Math.Round(samples.Average(), 2);

                        // When probe data has been collected, resume our thread to continue collecting
                        autoResetEvent.Set();
                    }
                    else if (!this.HasBeenClosed)
                    {
                        // add the next request for probe
                        printer.Connection.QueueLine("G30");
                        // raise the probe after each sample
                        printer.Connection.MoveAbsolute(adjustedProbePosition, feedRates.X);
                    }
                }
            }
        }
        public override string ReadLine()
        {
            string lineToSend = base.ReadLine();

            if (lineToSend != null &&
                lineToSend.EndsWith("; NO_PROCESSING"))
            {
                return(lineToSend);
            }

            if (lineToSend != null &&
                lineToSend.StartsWith("T"))
            {
                int extruder = 0;
                if (GCodeFile.GetFirstNumberAfter("T", lineToSend, ref extruder))
                {
                    extruderIndex = extruder;
                }
            }

            if (lineToSend != null &&
                LineIsMovement(lineToSend))
            {
                inputNoBabyStepping = GetPosition(lineToSend, inputNoBabyStepping);

                // it is a struct so this is making a new copy we con modify
                PrinterMove moveToSend = inputNoBabyStepping;
                printer.Settings.ForTools <double>(SettingsKey.baby_step_z_offset, (key, value, i) =>
                {
                    if (extruderIndex == i)
                    {
                        moveToSend.position = new Vector3(moveToSend.position.X,
                                                          moveToSend.position.Y,
                                                          moveToSend.position.Z + GetBabbyStepOffset(i));
                    }
                });

                moveToSend.position -= extruderOffsets[Math.Min(extruderIndex, 4)];

                if (moveToSend.HaveAnyPosition)
                {
                    lineToSend = CreateMovementLine(moveToSend, outputWithBabyStepping);
                }

                outputWithBabyStepping = moveToSend;

                return(lineToSend);
            }

            return(lineToSend);
        }
        public override string ReadLine()
        {
            var baseLine = base.ReadLine();

            if (baseLine == null)
            {
                return(null);
            }

            if (baseLine.EndsWith("; NO_PROCESSING"))
            {
                return(baseLine);
            }

            // if the line has no content don't process it
            if (baseLine.Length == 0 ||
                baseLine.Trim().Length == 0)
            {
                return(baseLine);
            }

            var lines = ProcessWriteRegEx(baseLine, printer);

            for (int i = lines.Count - 1; i >= 1; i--)
            {
                queueStream.Add(lines[i], true);
            }

            var lineToSend = lines[0];

            if (lineToSend != null &&
                LineIsMovement(lineToSend))
            {
                currentMove = GetPosition(lineToSend, currentMove);
            }

            // is it a position set?
            if (lineToSend.StartsWith("G92"))
            {
                GCodeFile.GetFirstNumberAfter("X", lineToSend, ref this.currentMove.position.X);
                GCodeFile.GetFirstNumberAfter("Y", lineToSend, ref this.currentMove.position.Y);
                GCodeFile.GetFirstNumberAfter("Z", lineToSend, ref this.currentMove.position.Z);
                GCodeFile.GetFirstNumberAfter("E", lineToSend, ref this.currentMove.extrusion);

                // tell the stream pipeline what the actual printer position is
                this.SetPrinterPosition(this.currentMove);
            }

            return(lineToSend);
        }
        private void GetZProbeHeight(object sender, EventArgs e)
        {
            StringEventArgs currentEvent = e as StringEventArgs;

            if (currentEvent != null)
            {
                double sampleRead = double.MinValue;
                if (currentEvent.Data.StartsWith("Bed"))                 // marlin G30 return code (looks like: 'Bed Position X:20 Y:32 Z:.01')
                {
                    probePositions[probePositionsBeingEditedIndex].position.X = probeStartPosition.X;
                    probePositions[probePositionsBeingEditedIndex].position.Y = probeStartPosition.Y;
                    GCodeFile.GetFirstNumberAfter("Z:", currentEvent.Data, ref sampleRead);
                }
                else if (currentEvent.Data.StartsWith("Z:"))                 // smoothie G30 return code (looks like: 'Z:10.01')
                {
                    probePositions[probePositionsBeingEditedIndex].position.X = probeStartPosition.X;
                    probePositions[probePositionsBeingEditedIndex].position.Y = probeStartPosition.Y;
                    // smoothie returns the position relative to the start position
                    double reportedProbeZ = 0;
                    GCodeFile.GetFirstNumberAfter("Z:", currentEvent.Data, ref reportedProbeZ);
                    sampleRead = probeStartPosition.Z - reportedProbeZ;
                }

                if (sampleRead != double.MinValue)
                {
                    samples.Add(sampleRead);

                    int numberOfSamples = printer.Settings.GetValue <int>(SettingsKey.z_probe_samples);
                    if (samples.Count == numberOfSamples)
                    {
                        samples.Sort();
                        if (samples.Count > 3)
                        {
                            // drop the high and low values
                            samples.RemoveAt(0);
                            samples.RemoveAt(samples.Count - 1);
                        }

                        probePositions[probePositionsBeingEditedIndex].position.Z = Math.Round(samples.Average(), 2);

                        UiThread.RunOnIdle(() => nextButton.InvokeClick());
                    }
                }
            }
        }
Example #12
0
        private string ApplyFeedRateMultiplier(string lineBeingSent)
        {
            if (lineBeingSent != null
                && FeedRateRatio != 1)
            {
                lineBeingSent = lineBeingSent.ToUpper().Trim();
                if (lineBeingSent.StartsWith("G0") || lineBeingSent.StartsWith("G1"))
                {
                    double feedRate = 0;
                    if (GCodeFile.GetFirstNumberAfter("F", lineBeingSent, ref feedRate))
                    {
                        lineBeingSent = GCodeFile.ReplaceNumberAfter('F', lineBeingSent, feedRate * FeedRateRatio);
                    }
                }
            }

            return lineBeingSent;
        }
        private void TrackExtruderState(string line)
        {
            if (line == null)
            {
                return;
            }

            if (line.StartsWith("G28)"))
            {
                activeExtruderIndex = 0;
                requestedExtruder   = 0;
            }

            if (line.StartsWith("T"))
            {
                GCodeFile.GetFirstNumberAfter("T", line, ref requestedExtruder);
            }
        }
Example #14
0
        public string DoApplyLeveling(string lineBeingSent, Vector3 currentDestination,
                                      PrinterMachineInstruction.MovementTypes movementMode)
        {
            double extruderDelta = 0;

            GCodeFile.GetFirstNumberAfter("E", lineBeingSent, ref extruderDelta);
            double feedRate = 0;

            GCodeFile.GetFirstNumberAfter("F", lineBeingSent, ref feedRate);

            StringBuilder newLine = new StringBuilder("G1 ");

            if (lineBeingSent.Contains("X") || lineBeingSent.Contains("Y") || lineBeingSent.Contains("Z"))
            {
                Vector3 outPosition = GetPositionWithZOffset(currentDestination);

                if (movementMode == PrinterMachineInstruction.MovementTypes.Relative)
                {
                    Vector3 delta = outPosition - lastDestinationWithLevelingApplied;
                    lastDestinationWithLevelingApplied = outPosition;
                    outPosition = delta;
                }
                else
                {
                    lastDestinationWithLevelingApplied = outPosition;
                }

                newLine = newLine.Append(String.Format("X{0:0.##} Y{1:0.##} Z{2:0.###}", outPosition.x, outPosition.y, outPosition.z));
            }

            if (extruderDelta != 0)
            {
                newLine = newLine.Append(String.Format(" E{0:0.###}", extruderDelta));
            }

            if (feedRate != 0)
            {
                newLine = newLine.Append(String.Format(" F{0:0.##}", feedRate));
            }

            lineBeingSent = newLine.ToString();

            return(lineBeingSent);
        }
        public override string ReadLine()
        {
            string lineToSend = base.ReadLine();

            if (lineToSend != null &&
                lineToSend.EndsWith("; NO_PROCESSING"))
            {
                return(lineToSend);
            }

            if (lineToSend != null &&
                lineToSend.StartsWith("T"))
            {
                int extruder = 0;
                if (GCodeFile.GetFirstNumberAfter("T", lineToSend, ref extruder))
                {
                    extruderIndex = extruder;
                }
            }

            if (lineToSend != null &&
                LineIsMovement(lineToSend))
            {
                PrinterMove currentMove = GetPosition(lineToSend, lastDestination);

                PrinterMove moveToSend = currentMove;
                if (extruderIndex < 4)
                {
                    moveToSend.position += BabbyStepOffset;
                    moveToSend.position -= extruderOffsets[extruderIndex];
                }

                if (moveToSend.HaveAnyPosition)
                {
                    lineToSend = CreateMovementLine(moveToSend, lastDestination);
                }
                lastDestination = currentMove;

                return(lineToSend);
            }

            return(lineToSend);
        }
Example #16
0
        public static PrinterMove GetPosition(string lineBeingSent, PrinterMove startPositionPosition)
        {
            if (lineBeingSent.StartsWith("G28") ||
                lineBeingSent.StartsWith("G29") ||
                lineBeingSent.StartsWith("G30"))
            {
                return(PrinterMove.Unknown);
            }

            PrinterMove currentDestination = startPositionPosition;

            GCodeFile.GetFirstNumberAfter("X", lineBeingSent, ref currentDestination.position.X);
            GCodeFile.GetFirstNumberAfter("Y", lineBeingSent, ref currentDestination.position.Y);
            GCodeFile.GetFirstNumberAfter("Z", lineBeingSent, ref currentDestination.position.Z);
            GCodeFile.GetFirstNumberAfter("E", lineBeingSent, ref currentDestination.extrusion);
            GCodeFile.GetFirstNumberAfter("F", lineBeingSent, ref currentDestination.feedRate);

            return(currentDestination);
        }
Example #17
0
        public void Leveling7PointsNeverGetsTooHigh()
        {
            StaticData.Instance = new MatterHackers.Agg.FileSystemStaticData(Path.Combine("..", "..", "..", "..", "StaticData"));

            MatterControlUtilities.OverrideAppDataLocation();

            var levelingData = new PrintLevelingData(ActiveSliceSettings.Instance);

            double radius = 100;

            levelingData.SampledPositions = new List <Vector3>();
            levelingData.SampledPositions.Add(new Vector3(130.00, 0.00, 0));
            levelingData.SampledPositions.Add(new Vector3(65.00, 112.58, 10));
            levelingData.SampledPositions.Add(new Vector3(-65.00, 112.58, 0));
            levelingData.SampledPositions.Add(new Vector3(-130.00, 0.00, 10));
            levelingData.SampledPositions.Add(new Vector3(-65.00, -112.58, 0));
            levelingData.SampledPositions.Add(new Vector3(65.00, -112.58, 10));

            levelingData.SampledPositions.Add(new Vector3(0, 0, 0));

            levelingData.SampledPositions.Add(new Vector3(0, 0, 6));

            Vector2 bedCenter = Vector2.Zero;

            RadialLevlingFunctions levelingFunctions7Point = new RadialLevlingFunctions(6, levelingData, bedCenter);
            int totalPoints = 2000;

            for (int curPoint = 0; curPoint < totalPoints; curPoint++)
            {
                Vector2 currentTestPoint = new Vector2(radius, 0);
                currentTestPoint.Rotate(MathHelper.Tau / totalPoints * curPoint);
                Vector3 destPosition = new Vector3(currentTestPoint, 0);

                Vector3 outPosition = levelingFunctions7Point.GetPositionWithZOffset(destPosition);
                Assert.IsTrue(outPosition.z <= 10);

                string outPositionString = levelingFunctions7Point.DoApplyLeveling(GetGCodeString(destPosition), destPosition, PrinterMachineInstruction.MovementTypes.Absolute);
                double outZ = 0;
                Assert.IsTrue(GCodeFile.GetFirstNumberAfter("Z", outPositionString, ref outZ));
                Assert.IsTrue(outZ <= 10);
            }
        }
        public override string ReadLine()
        {
            string lineToSend = base.ReadLine();

            if (lineToSend != null &&
                lineToSend.EndsWith("; NO_PROCESSING"))
            {
                return(lineToSend);
            }

            if (lineToSend != null &&
                lineToSend.StartsWith("T"))
            {
                int extruder = 0;
                if (GCodeFile.GetFirstNumberAfter("T", lineToSend, ref extruder))
                {
                    extruderIndex = extruder;
                }
            }

            if (lineToSend != null &&
                LineIsMovement(lineToSend))
            {
                inputNoBabyStepping = GetPosition(lineToSend, inputNoBabyStepping);

                // it is a struct so this is making a new copy we con modify
                PrinterMove moveToSend = inputNoBabyStepping;
                moveToSend.position += BabbyStepOffset;
                moveToSend.position -= extruderOffsets[Math.Min(extruderIndex, 4)];

                if (moveToSend.HaveAnyPosition)
                {
                    lineToSend = CreateMovementLine(moveToSend, outputWithBabyStepping);
                }

                outputWithBabyStepping = moveToSend;

                return(lineToSend);
            }

            return(lineToSend);
        }
Example #19
0
        public static string GetLayerFanSpeeds(this GCodeFile loadedGCode, int activeLayerIndex)
        {
            if (loadedGCode == null || loadedGCode.LayerCount == 0)
            {
                return("---");
            }

            int startInstruction = loadedGCode.GetFirstLayerInstruction(activeLayerIndex);

            if (activeLayerIndex == 0)
            {
                startInstruction = 0;
            }

            int endInstruction = loadedGCode.GetFirstLayerInstruction(activeLayerIndex + 1);

            string separator = "";
            string fanSpeeds = "";

            for (int i = startInstruction; i < endInstruction; i++)
            {
                var line = loadedGCode.Instruction(i).Line;
                if (line.StartsWith("M107"))                 // fan off
                {
                    fanSpeeds += separator + "Off";
                    separator  = ", ";
                }
                else if (line.StartsWith("M106"))                 // fan on
                {
                    double speed = 0;
                    if (GCodeFile.GetFirstNumberAfter("M106", line, ref speed, 0, ""))
                    {
                        fanSpeeds += separator + $"{speed / 255 * 100:0}%";
                        separator  = ", ";
                    }
                }
            }

            return(fanSpeeds);
        }
Example #20
0
        public void Leveling7PointsNeverGetsTooHeigh()
        {
            PrintLevelingData levelingData = new PrintLevelingData();

            double radius = 100;

            levelingData.SampledPositions = new List <Vector3>();
            levelingData.SampledPositions.Add(new Vector3(130.00, 0.00, 0));
            levelingData.SampledPositions.Add(new Vector3(65.00, 112.58, 10));
            levelingData.SampledPositions.Add(new Vector3(-65.00, 112.58, 0));
            levelingData.SampledPositions.Add(new Vector3(-130.00, 0.00, 10));
            levelingData.SampledPositions.Add(new Vector3(-65.00, -112.58, 0));
            levelingData.SampledPositions.Add(new Vector3(65.00, -112.58, 10));

            levelingData.SampledPositions.Add(new Vector3(0, 0, 0));

            levelingData.SampledPositions.Add(new Vector3(0, 0, 6));

            Vector2 bedCenter = Vector2.Zero;

            RadialLevlingFunctions levelingFunctions7Point = new RadialLevlingFunctions(6, levelingData, bedCenter);
            int totalPoints = 2000;

            for (int curPoint = 0; curPoint < totalPoints; curPoint++)
            {
                Vector2 currentTestPoint = new Vector2(radius, 0);
                currentTestPoint.Rotate(MathHelper.Tau / totalPoints * curPoint);
                Vector3 destPosition = new Vector3(currentTestPoint, 0);

                Vector3 outPosition = levelingFunctions7Point.GetPositionWithZOffset(destPosition);
                Assert.IsTrue(outPosition.z <= 10);

                string outPositionString = levelingFunctions7Point.DoApplyLeveling(GetGCodeString(destPosition), destPosition, PrinterMachineInstruction.MovementTypes.Absolute);
                double outZ = 0;
                Assert.IsTrue(GCodeFile.GetFirstNumberAfter("Z", outPositionString, ref outZ));
                Assert.IsTrue(outZ <= 10);
            }
        }
        public void Report(ProgressStatus progressStatus)
        {
            double currentValue = 0;
            double destValue    = 10;

            string statusText = progressStatus.Status = progressStatus.Status.Trim().TrimEnd('.');

            if (GCodeFile.GetFirstNumberAfter("", statusText, ref currentValue) &&
                GCodeFile.GetFirstNumberAfter("/", statusText, ref destValue))
            {
                if (destValue == 0)
                {
                    destValue = 1;
                }

                progressStatus.Progress0To1 = currentValue / destValue;
            }
            else
            {
                printer.Connection.TerminalLog.WriteLine(statusText);
            }

            reporter.Report(progressStatus);
        }
        private void GetZProbeHeight(object sender, string line)
        {
            if (line != null)
            {
                double sampleRead = double.MinValue;
                if (line.StartsWith("Bed"))                 // marlin G30 return code (looks like: 'Bed Position X:20 Y:32 Z:.01')
                {
                    sampledPositions[activeProbeIndex].Position.X = positionToSample.X;
                    sampledPositions[activeProbeIndex].Position.Y = positionToSample.Y;
                    GCodeFile.GetFirstNumberAfter("Z:", line, ref sampleRead);
                }
                else if (line.StartsWith("Z:"))                 // smoothie G30 return code (looks like: 'Z:10.01')
                {
                    sampledPositions[activeProbeIndex].Position.X = positionToSample.X;
                    sampledPositions[activeProbeIndex].Position.Y = positionToSample.Y;
                    // smoothie returns the position relative to the start position
                    double reportedProbeZ = 0;

                    GCodeFile.GetFirstNumberAfter("Z:", line, ref reportedProbeZ);
                    sampleRead = positionToSample.Z - reportedProbeZ;
                }

                if (sampleRead != double.MinValue)
                {
                    samplesForSinglePosition.Add(sampleRead);

                    int numberOfSamples = printer.Settings.GetValue <int>(SettingsKey.z_probe_samples);
                    if (samplesForSinglePosition.Count >= numberOfSamples)
                    {
                        samplesForSinglePosition.Sort();
                        if (samplesForSinglePosition.Count > 3)
                        {
                            // drop the high and low values
                            samplesForSinglePosition.RemoveAt(0);
                            samplesForSinglePosition.RemoveAt(samplesForSinglePosition.Count - 1);
                        }

                        sampledPositions[activeProbeIndex].Position.Z = Math.Round(samplesForSinglePosition.Average(), 2);

                        // If we are sampling the first point, check if it is unchanged from the last time we ran leveling
                        if (activeProbeIndex == 0)
                        {
                            var levelingData = printer.Settings.Helpers.PrintLevelingData;

                            var currentSample = sampledPositions[activeProbeIndex].Position.Z;
                            var oldSample     = levelingData.SampledPositions.Count > 0 ? levelingData.SampledPositions[activeProbeIndex].Z : 0;
                            var delta         = currentSample - oldSample;

                            printer.Connection.TerminalLog.WriteLine($"Validation Sample: Old {oldSample}, New {currentSample}, Delta {delta}");

                            if (levelingData.SampledPositions.Count == sampledPositions.Count &&
                                Math.Abs(delta) < printer.Settings.GetValue <double>(SettingsKey.validation_threshold))
                            {
                                // the last leveling is still good abort this new calibration and start printing
                                CancelValidation();
                                waitingToCompleteNextSample = false;
                                validationRunning           = false;
                                validationHasBeenRun        = true;
                            }
                        }

                        // When probe data has been collected, resume our thread to continue collecting
                        waitingToCompleteNextSample = false;
                        // and go on to the next point
                        activeProbeIndex++;
                    }
                    else
                    {
                        // add the next request for probe
                        queuedCommands.Enqueue("G30");
                        // raise the probe after each sample
                        var feedRates = printer.Settings.Helpers.ManualMovementSpeeds();
                        queuedCommands.Enqueue($"G1 X{positionToSampleWithProbeOffset.X:0.###}Y{positionToSampleWithProbeOffset.Y:0.###}Z{positionToSampleWithProbeOffset.Z:0.###} F{feedRates.X}");
                    }
                }
            }
        }
        public override string ReadLine()
        {
            if (queuedCommands.Count > 0)
            {
                return(queuedCommands.Dequeue());
            }

            string lineToSend = base.ReadLine();

            if (lineToSend == null)
            {
                return(null);
            }

            if (lineToSend.EndsWith("; NO_PROCESSING"))
            {
                return(lineToSend);
            }

            GCodeFile.GetFirstNumberAfter("F", lineToSend, ref lastSeenFeedRate);

            var requestedToolForTempChange = -1;

            // if we see a temp command remember what heat we are setting
            if (lineToSend.StartsWith("M109") || lineToSend.StartsWith("M104"))
            {
                int toolTemp = 0;
                // get the temp we are setting
                GCodeFile.GetFirstNumberAfter("S", lineToSend, ref toolTemp);
                // set it to the tool we will be changing to
                requestedToolForTempChange = RequestedTool;
                // check if this command contains a tool specification
                GCodeFile.GetFirstNumberAfter("T", lineToSend, ref requestedToolForTempChange);

                if (!lineToSend.Contains("; INACTIVE_COOL_DOWN"))
                {
                    if (targetTemps[requestedToolForTempChange] != toolTemp)
                    {
                        targetTemps[requestedToolForTempChange] = toolTemp;
                    }
                }
            }

            // check if any of the heaters we will be switching to need to start heating
            ManageReHeating(lineToSend);

            if (lineToSend == completedBeforeGCodeString &&
                sendState != SendStates.Normal)
            {
                activeTool = RequestedTool;
                sendState  = SendStates.Normal;
                QueueAfterGCode();
            }

            var lineNoComment = lineToSend.Split(';')[0];

            if (lineNoComment == "G28" ||
                lineNoComment == "G28 Z0")
            {
                sendState     = SendStates.Normal;
                RequestedTool = activeTool = 0;
            }

            // if this command is a temperature change request
            if (requestedToolForTempChange != -1)
            {
                if (requestedToolForTempChange != activeTool)
                {
                    if (DoSmoothieCorrections)
                    {
                        // For smoothie, switch back to the extrude we were using before the temp change (smoothie switches to the specified extruder, marlin repetier do not)
                        queuedCommands.Enqueue($"T{activeTool}");
                    }

                    var temp = GetNextToolTemp(requestedToolForTempChange);
                    if (temp > 0)
                    {
                        return($"{lineToSend.Substring(0, 4)} T{requestedToolForTempChange} S{temp}");
                    }
                    else                     // send the temp as requested
                    {
                        return(lineToSend);
                    }
                }

                // if we are waiting to switch to the next tool
                else if (activeTool != RequestedTool)
                {
                    // if this command does not include the extruder to switch to, than we need to switch before sending it
                    if (!lineNoComment.Contains("T"))
                    {
                        queuedCommands.Enqueue($"T{RequestedTool}");
                    }

                    if (DoSmoothieCorrections)
                    {
                        // For smoothie, switch back to the extrude we were using before the temp change (smoothie switches to the specified extruder, marlin repetier do not)
                        queuedCommands.Enqueue($"T{activeTool}");
                    }

                    // then send the heat command
                    return(lineToSend);
                }
            }

            // if this is a tool change request
            else if (lineToSend.StartsWith("T"))
            {
                int changeCommandTool = -1;
                if (GCodeFile.GetFirstNumberAfter("T", lineToSend, ref changeCommandTool))
                {
                    if (changeCommandTool == activeTool)
                    {
                        if (sendState == SendStates.WaitingForMove)
                        {
                            // we have to switch back to our starting tool without a move
                            // change back to normal processing and don't change tools
                            sendState = SendStates.Normal;
                            var lastRequestedTool = RequestedTool;
                            // set the requested tool
                            RequestedTool = changeCommandTool;
                            // don't send the change we are on the right tool now
                            return($"; switch back without move from T{lastRequestedTool} to T{activeTool}");
                        }
                    }
                    else                     // we are switching tools
                    {
                        if (sendState == SendStates.Normal)
                        {
                            sendState = SendStates.WaitingForMove;
                            // set the requested tool
                            RequestedTool = changeCommandTool;
                            // don't queue the tool change until after the before gcode has been sent
                            return($"; waiting for move on T{RequestedTool}");
                        }
                    }
                }
            }

            // if it is only an extrusion move
            if (sendState == SendStates.WaitingForMove &&
                activeTool != RequestedTool &&                 // is different than the last extruder set
                (lineNoComment.StartsWith("G0 ") || lineNoComment.StartsWith("G1 ")) &&                 // is a G1 or G0
                lineNoComment.Contains("E")                    // it is an extrusion move
                // and have no other position information
                && !lineNoComment.Contains("X") &&
                !lineNoComment.Contains("Y") &&
                !lineNoComment.Contains("Z"))
            {
                double ePosition = 0;

                if (GCodeFile.GetFirstNumberAfter("E", lineNoComment, ref ePosition))
                {
                    // switch extruders
                    queuedCommands.Enqueue($"T{RequestedTool}");

                    if (DoSmoothieCorrections)
                    {
                        // if we know the current E position before the switch
                        // set the E value to the previous E value.
                        if (lastDestination.extrusion != double.PositiveInfinity)
                        {
                            // On Marlin E position is shared between extruders and this code has no utility
                            // On Smoothie E is stored per extruder and this makes it behave the same as Marlin
                            queuedCommands.Enqueue($"G92 E{lastDestination.extrusion}");
                        }
                    }

                    // send the extrusion
                    queuedCommands.Enqueue(lineNoComment + " ; NO_PROCESSING");

                    lastDestination.extrusion = ePosition;

                    if (DoSmoothieCorrections)
                    {
                        // switch back
                        queuedCommands.Enqueue($"T{activeTool}");
                        queuedCommands.Enqueue($"G92 E{lastDestination.extrusion}");
                    }

                    return("");
                }
            }

            if (QueueBeforeIfNeedToSwitchExtruders(lineToSend, lineNoComment))
            {
                return("");
            }

            if (LineIsMovement(lineToSend))
            {
                lastDestination = GetPosition(lineToSend, lastDestination);
            }

            return(lineToSend);
        }
Example #24
0
        public override string ReadLine()
        {
            switch (state)
            {
            case State.passthrough:
            {
                string lineToSend = base.ReadLine();

                if (lineToSend != null &&
                    lineToSend.StartsWith("M"))
                {
                    // initial test is just to see if it is an M109
                    if (lineToSend.StartsWith("M109"))                                     // extruder set and wait temp
                    {
                        if (lineToSend.Contains("F") ||                                      // If it has a control character F (auto temp)
                            !lineToSend.Contains("S"))                                                // if it is a reset (has no S temperature)
                        {
                            // don't replace it
                            return(lineToSend);
                        }

                        // send an M104 instead
                        waitWhenCooling = false;
                        lineToSend      = "M104" + lineToSend.Substring(4);
                        GCodeFile.GetFirstNumberAfter("S", lineToSend, ref targetTemp);
                        extruderIndex = 0;
                        GCodeFile.GetFirstNumberAfter("T", lineToSend, ref extruderIndex);
                        if (targetTemp > ignoreRequestIfBelowTemp)
                        {
                            state = State.waitingForExtruderTemp;
                            timeHaveBeenAtTemp.Reset();
                        }
                        else
                        {
                            Thread.Sleep(100);                                     // sleep .1 second while waiting for temp
                            return("");                                            // return nothing until we reach temp
                        }
                    }
                    else if (lineToSend.StartsWith("M190"))                                     // bed set and wait temp
                    {
                        // send an M140 instead
                        bool gotR = GCodeFile.GetFirstNumberAfter("R", lineToSend, ref targetTemp);
                        bool gotS = GCodeFile.GetFirstNumberAfter("S", lineToSend, ref targetTemp);
                        if (gotR || gotS)
                        {
                            if (targetTemp > ignoreRequestIfBelowTemp)
                            {
                                waitWhenCooling = gotR;
                                lineToSend      = "M140 S" + targetTemp.ToString();
                                state           = State.waitingForBedTemp;
                                timeHaveBeenAtTemp.Reset();
                            }
                            else
                            {
                                Thread.Sleep(100);                                         // sleep .1 second while waiting for temp
                                return("");                                                // return nothing until we reach temp
                            }
                        }
                        else
                        {
                            Thread.Sleep(100);                                     // sleep .1 second while waiting for temp
                            return("");                                            // return nothing until we reach temp
                        }
                    }
                }

                return(lineToSend);
            }

            case State.waitingForExtruderTemp:
            {
                double extruderTemp    = PrinterConnectionAndCommunication.Instance.GetActualExtruderTemperature((int)extruderIndex);
                bool   tempWithinRange = extruderTemp >= targetTemp - sameTempRange && extruderTemp <= targetTemp + sameTempRange;
                if (tempWithinRange && !timeHaveBeenAtTemp.IsRunning)
                {
                    timeHaveBeenAtTemp.Start();
                }

                if (timeHaveBeenAtTemp.Elapsed.TotalSeconds > waitAfterReachTempTime ||
                    PrinterConnectionAndCommunication.Instance.PrintWasCanceled)
                {
                    // switch to pass through and continue
                    state = State.passthrough;
                    return("");
                }
                else
                {
                    // send a wait command
                    Thread.Sleep(100);                             // sleep .1 second while waiting for temp
                    return("");                                    // return nothing until we reach temp
                }
            }

            case State.waitingForBedTemp:
            {
                double bedTemp = PrinterConnectionAndCommunication.Instance.ActualBedTemperature;
                bool   tempWithinRange;
                if (waitWhenCooling)
                {
                    tempWithinRange = bedTemp >= targetTemp - sameTempRange && bedTemp <= targetTemp + sameTempRange;
                }
                else
                {
                    tempWithinRange = bedTemp >= targetTemp - sameTempRange;
                }

                // Added R code for M190
                if (tempWithinRange && !timeHaveBeenAtTemp.IsRunning)
                {
                    timeHaveBeenAtTemp.Start();
                }

                if (timeHaveBeenAtTemp.Elapsed.TotalSeconds > waitAfterReachTempTime ||
                    PrinterConnectionAndCommunication.Instance.PrintWasCanceled)
                {
                    // switch to pass through and continue
                    state = State.passthrough;
                    return("");
                }
                else
                {
                    // send a wait command
                    Thread.Sleep(100);                             // sleep .1 second while waiting for temp
                    return("");                                    // return nothing until we reach temp
                }
            }
            }

            return(null);
        }
        private void LineReceived(object sender, string line)
        {
            if (line != null)
            {
                if (line.Contains("ros_"))
                {
                    if (line.Contains("TRIGGERED"))
                    {
                        readOutOfFilament = true;
                    }
                }

                if (line.Contains("pos_"))
                {
                    double sensorDistance  = 0;
                    double stepperDistance = 0;
                    if (GCodeFile.GetFirstNumberAfter("SENSOR:", line, ref sensorDistance))
                    {
                        var checkDistance = printer.Settings.GetValue <double>(SettingsKey.runout_sensor_check_distance);

                        if (sensorDistance < -checkDistance || sensorDistance > checkDistance)
                        {
                            printer.Connection.FilamentPositionSensorDetected = true;
                        }

                        if (printer.Connection.FilamentPositionSensorDetected)
                        {
                            GCodeFile.GetFirstNumberAfter("STEPPER:", line, ref stepperDistance);

                            var stepperDelta = Math.Abs(stepperDistance - positionSensorData.LastStepperDistance);

                            // if we think we should have moved the filament by more than 1mm
                            if (stepperDelta > checkDistance)
                            {
                                var sensorDelta = Math.Abs(sensorDistance - positionSensorData.LastSensorDistance);
                                var deltaRatio  = sensorDelta / stepperDelta;

                                if (printer.Settings.GetValue <bool>(SettingsKey.report_runout_sensor_data))
                                {
                                    // report the position for debugging
                                    printer.Connection.TerminalLog.WriteLine($"RUNOUT ({positionSensorData.ExtrusionDiscrepency}): Sensor ({sensorDelta:0.##}) / Stepper ({stepperDelta:0.##}) = {deltaRatio:0.##}");
                                }

                                var ratio          = Math.Max(.1, Math.Min(20, printer.Settings.GetValue <double>(SettingsKey.runout_sensor_trigger_ratio)));
                                var sensorMaxRatio = Math.Max(ratio, 1 / ratio);
                                var sensorMinRatio = Math.Min(ratio, 1 / ratio);

                                // check if the sensor data is within a tolerance of the stepper data
                                if (deltaRatio < sensorMinRatio || deltaRatio > sensorMaxRatio)
                                {
                                    // we have a discrepancy set a runout state
                                    positionSensorData.ExtrusionDiscrepency++;
                                    if (positionSensorData.ExtrusionDiscrepency > 2)
                                    {
                                        readOutOfFilament = true;
                                        positionSensorData.ExtrusionDiscrepency = 0;
                                    }
                                }
                                else
                                {
                                    positionSensorData.ExtrusionDiscrepency = 0;
                                }

                                // and record this position
                                positionSensorData.LastSensorDistance  = sensorDistance;
                                positionSensorData.LastStepperDistance = stepperDistance;
                            }
                        }
                    }
                }
            }
        }
Example #26
0
        public static void Main(string[] args)
        {
#if false // this is for some early testing of SLA output
            var test = new PhotonFile();
            void Progress(string message)
            {
                Debug.WriteLine(message);
            }

            var sourceFile = @"C:\Users\LarsBrubaker\Downloads\10mm-benchy.photon";
            if (File.Exists(sourceFile))
            {
                test.ReadFile(sourceFile, Progress);
                test.SaveFile(@"C:\Users\LarsBrubaker\Downloads\10mm-bench2.photon");
            }
            else
            {
                sourceFile = @"C:\Users\larsb\Downloads\_rocktopus.ctb";
                test.ReadFile(sourceFile, Progress);
                test.SaveFile(@"C:\Users\larsb\Downloads\_rocktopus.photon");
            }
#endif

#if false // this is for processing print log exports
            var filename    = "C:\\Users\\LarsBrubaker\\Downloads\\210309 B2 print_log.txt";
            var lines       = File.ReadAllLines(filename);
            var newPosition = default(Vector3);
            var ePosition   = 0.0;
            var instruction = 0;
            var layer       = 0;
            using (var writetext = new StreamWriter("C:\\Temp\\printlog.gcode"))
            {
                foreach (var line in lines)
                {
                    if (line.Contains(" G1 "))
                    {
                        GCodeFile.GetFirstNumberAfter("X", line, ref newPosition.X);
                        GCodeFile.GetFirstNumberAfter("Y", line, ref newPosition.Y);
                        GCodeFile.GetFirstNumberAfter("Z", line, ref newPosition.Z);
                        GCodeFile.GetFirstNumberAfter("E", line, ref ePosition);

                        writetext.WriteLine($"G1 X{newPosition.X} Y{newPosition.Y} Z{newPosition.Z} E{ePosition}");
                        instruction++;

                        if (instruction % 500 == 0)
                        {
                            writetext.WriteLine($"; LAYER:{layer++}");
                        }
                    }
                }
            }
#endif

            // Set the global culture for the app, current thread and all new threads
            CultureInfo.DefaultThreadCurrentCulture   = CultureInfo.InvariantCulture;
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;
            Thread.CurrentThread.CurrentCulture       = CultureInfo.InvariantCulture;
            Thread.CurrentThread.CurrentUICulture     = CultureInfo.InvariantCulture;

            // make sure we can build a system relevant serial port
            FrostedSerialPortFactory.GetPlatformSerialPort = (serialPortName) =>
            {
                return(new CSharpSerialPortWrapper(serialPortName));
            };

            // Set default Agg providers
            AggContext.Config.ProviderTypes.SystemWindowProvider = "MatterHackers.GlfwProvider.GlfwWindowProvider, MatterHackers.GlfwProvider";
            // for now we will ship release with the old renderer
#if !DEBUG
            AggContext.Config.ProviderTypes.SystemWindowProvider = "MatterHackers.MatterControl.WinformsSingleWindowProvider, MatterControl.Winforms";
#endif

            string userProfilePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);

            _raygunClient = new RaygunClient("hQIlyUUZRGPyXVXbI6l1dA==")             // this is the PC key
            {
                ApplicationVersion = VersionInfo.Instance.ReleaseVersion
            };

#if !DEBUG
            if (AggContext.OperatingSystem == OSType.Windows)
            {
                waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset, "MatterControl#Startup", out bool created);

                if (!created)
                {
                    // If an instance is already running, create a service proxy and execute ShellOpenFile
                    var proxy = new ServiceProxy();

                    // and at least one argument is an acceptable shell file extension
                    var itemsToAdd = args.Where(f => File.Exists(f) && shellFileExtensions.Contains(Path.GetExtension(f).ToLower()));
                    if (itemsToAdd.Any())
                    {
                        // notify the running instance of the event
                        proxy.ShellOpenFile(itemsToAdd.ToArray());
                    }

                    System.Threading.Thread.Sleep(1000);

                    // Finally, close the process spawned by Explorer.exe
                    return;
                }

                var serviceHost = new ServiceHost(typeof(LocalService), new[] { new Uri(ServiceBaseUri) });
                serviceHost.AddServiceEndpoint(typeof(IMainService), new NetNamedPipeBinding(), mainServiceName);
                serviceHost.Open();

                Console.Write(
                    "Service started: {0};",
                    string.Join(", ", serviceHost.Description.Endpoints.Select(s => s.ListenUri.AbsoluteUri).ToArray()));
            }
#endif

            // If MatterControl isn't running and valid files were shelled, schedule a StartupAction to open the files after load
            var shellFiles = args.Where(f => File.Exists(f) && shellFileExtensions.Contains(Path.GetExtension(f).ToLower()));
            if (shellFiles.Any())
            {
                ApplicationController.StartupActions.Add(new ApplicationController.StartupAction()
                {
                    Title    = "Shell Files",
                    Priority = 0,
                    Action   = () =>
                    {
                        // Open each shelled file
                        foreach (string file in shellFiles)
                        {
                            ApplicationController.Instance.ShellOpenFile(file);
                        }
                    }
                });
            }

            // Load optional user configuration
            IConfiguration config = new ConfigurationBuilder()
                                    .AddJsonFile("appsettings.json", optional: true)
                                    .AddJsonFile(Path.Combine(userProfilePath, "MatterControl.json"), optional: true)
                                    .Build();

            // Override defaults via configuration
            config.Bind("Agg:ProviderTypes", AggContext.Config.ProviderTypes);
            config.Bind("Agg:GraphicsMode", AggContext.Config.GraphicsMode);

            Slicer.RunInProcess               = config.GetValue <bool>("MatterControl:Slicer:Debug");
            Application.EnableF5Collect       = config.GetValue <bool>("MatterControl:Application:EnableF5Collect");
            Application.EnableNetworkTraffic  = config.GetValue <bool>("MatterControl:Application:EnableNetworkTraffic", true);
            Application.MiniTouchScreen.Make  = config.GetValue <string>("MatterControl:MiniTouchScreen:Make", "");
            Application.MiniTouchScreen.Model = config.GetValue <string>("MatterControl:MiniTouchScreen:Model", "");

            // Make sure we have the right working directory as we assume everything relative to the executable.
            Directory.SetCurrentDirectory(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location));

            Datastore.Instance.Initialize(DesktopSqlite.CreateInstance());

            if (UserSettings.Instance.get(UserSettingsKey.ApplicationUseHeigResDisplays) == "true")
            {
                SetProcessDpiAwareness((int)DpiAwareness.PerMonitorAware);
            }

            var isExperimental = OemSettings.Instance.WindowTitleExtra == "Experimental";
#if !DEBUG
            // Conditionally spin up error reporting if not on the Stable channel
            string channel = UserSettings.Instance.get(UserSettingsKey.UpdateFeedType);
            if (string.IsNullOrEmpty(channel) ||
                channel != "release" ||
                isExperimental)
#endif
            {
                System.Windows.Forms.Application.ThreadException += (s, e) =>
                {
                    if (raygunNotificationCount++ < RaygunMaxNotifications)
                    {
                        _raygunClient.Send(e.Exception);
                    }

                    if (System.Windows.Forms.Application.OpenForms.Count > 0 &&
                        !System.Windows.Forms.Application.OpenForms[0].InvokeRequired)
                    {
                        System.Windows.Forms.Application.Exit();
                    }
                };

                AppDomain.CurrentDomain.UnhandledException += (s, e) =>
                {
                    if (raygunNotificationCount++ < RaygunMaxNotifications)
                    {
                        _raygunClient.Send(e.ExceptionObject as Exception);
                    }

                    System.Windows.Forms.Application.Exit();
                };
            }

            // Init platformFeaturesProvider before ShowAsSystemWindow
            string platformFeaturesProvider = "MatterHackers.MatterControl.WindowsPlatformsFeatures, MatterControl.Winforms";

            string textSizeMode = UserSettings.Instance.get(UserSettingsKey.ApplicationTextSize);
            if (!string.IsNullOrEmpty(textSizeMode))
            {
                if (double.TryParse(textSizeMode, out double textSize))
                {
                    GuiWidget.DeviceScale = textSize;
                }
            }

            AppContext.Platform = AggContext.CreateInstanceFrom <INativePlatformFeatures>(platformFeaturesProvider);
            AppContext.Platform.InitPluginFinder();
            AppContext.Platform.ProcessCommandline();

            config.Bind("MatterControl", MatterHackers.MatterControl.AppContext.Options);

            // Get startup bounds from MatterControl and construct system window
            // var systemWindow = new DesktopMainWindow(400, 200)
            var(width, height) = RootSystemWindow.GetStartupBounds();

            var systemWindow = Application.LoadRootWindow(width, height);

            var theme = ApplicationController.Instance.Theme;
            SingleWindowProvider.SetWindowTheme(theme.TextColor,
                                                theme.DefaultFontSize - 1,
                                                theme.InvertIcons,
                                                () => theme.CreateSmallResetButton(),
                                                theme.ToolbarPadding,
                                                theme.TabBarBackground,
                                                new Color(theme.PrimaryAccentColor, 175));

            ApplicationController.Instance.KeepAwake = KeepAwake;

            systemWindow.ShowAsSystemWindow();
        }
Example #27
0
        public override string ReadLine()
        {
            switch (state)
            {
            case State.passthrough:
            {
                string lineToSend = base.ReadLine();

                if (lineToSend != null &&
                    lineToSend.StartsWith("M"))
                {
                    if (lineToSend.StartsWith("M109"))                                     // extruder set and wait temp
                    {
                        // send an M104 instead
                        waitWhenCooling = false;
                        lineToSend      = "M104" + lineToSend.Substring(4);
                        GCodeFile.GetFirstNumberAfter("S", lineToSend, ref targetTemp);
                        extruderIndex = 0;
                        GCodeFile.GetFirstNumberAfter("T", lineToSend, ref extruderIndex);
                        if (targetTemp > ignoreRequestIfBelowTemp)
                        {
                            state = State.waitingForExtruderTemp;
                            timeHaveBeenAtTemp.Reset();
                        }
                        else
                        {
                            return("G4 P1000");                                            // 1 second
                        }
                    }
                    else if (lineToSend.StartsWith("M190"))                                     // bed set and wait temp
                    {
                        // send an M140 instead
                        bool gotR = GCodeFile.GetFirstNumberAfter("R", lineToSend, ref targetTemp);
                        bool gotS = GCodeFile.GetFirstNumberAfter("S", lineToSend, ref targetTemp);
                        if (gotR || gotS)
                        {
                            if (targetTemp > ignoreRequestIfBelowTemp)
                            {
                                waitWhenCooling = gotR;
                                lineToSend      = "M140 S" + targetTemp.ToString();
                                state           = State.waitingForBedTemp;
                                timeHaveBeenAtTemp.Reset();
                            }
                            else
                            {
                                return("G4 P1000");                                                // 1 second
                            }
                        }
                        else
                        {
                            return("G4 P1000");
                        }
                    }
                }

                return(lineToSend);
            }

            case State.waitingForExtruderTemp:
            {
                double extruderTemp    = PrinterConnectionAndCommunication.Instance.GetActualExtruderTemperature((int)extruderIndex);
                bool   tempWithinRange = extruderTemp >= targetTemp - sameTempRange && extruderTemp <= targetTemp + sameTempRange;
                if (tempWithinRange && !timeHaveBeenAtTemp.IsRunning)
                {
                    timeHaveBeenAtTemp.Start();
                }

                if (timeHaveBeenAtTemp.Elapsed.TotalSeconds > waitAfterReachTempTime ||
                    PrinterConnectionAndCommunication.Instance.PrintWasCanceled)
                {
                    // switch to pass through and continue
                    state = State.passthrough;
                    return(base.ReadLine());
                }
                else
                {
                    // send a wait command
                    return("G4 P1000");                                    // 1 second
                }
            }

            case State.waitingForBedTemp:
            {
                double bedTemp = PrinterConnectionAndCommunication.Instance.ActualBedTemperature;
                bool   tempWithinRange;
                if (waitWhenCooling)
                {
                    tempWithinRange = bedTemp >= targetTemp - sameTempRange && bedTemp <= targetTemp + sameTempRange;
                }
                else
                {
                    tempWithinRange = bedTemp >= targetTemp - sameTempRange;
                }

                // Added R code for M190
                if (tempWithinRange && !timeHaveBeenAtTemp.IsRunning)
                {
                    timeHaveBeenAtTemp.Start();
                }

                if (timeHaveBeenAtTemp.Elapsed.TotalSeconds > waitAfterReachTempTime ||
                    PrinterConnectionAndCommunication.Instance.PrintWasCanceled)
                {
                    // switch to pass through and continue
                    state = State.passthrough;
                    return(base.ReadLine());
                }
                else
                {
                    // send a wait command
                    return("G4 P1000");                                    // 1 second
                }
            }
            }

            return(null);
        }
        public void PauseHandlingStreamTests()
        {
            int readX = 50;

            // Validate that the number parsing code is working as expected, specifically ignoring data that appears in comments
            // This is a regression that we saw in the Lulzbot Mini profile after adding macro processing.
            GCodeFile.GetFirstNumberAfter("X", "G1 Z10 E - 10 F12000 ; suck up XXmm of filament", ref readX);
            // did not change
            Assert.AreEqual(50, readX, "Don't change the x if it is after a comment");

            // a comments that looks more like a valid line
            GCodeFile.GetFirstNumberAfter("X", "G1 Z10 E - 10 F12000 ; X33", ref readX);
            // did not change
            Assert.AreEqual(50, readX, "Don't change the x if it is after a comment");
            // a line that should parse
            GCodeFile.GetFirstNumberAfter("X", "G1 Z10 E - 10 F12000 X33", ref readX);
            // did change
            Assert.AreEqual(33, readX, "not in a comment, do a change");

            string[] inputLines = new string[]
            {
                "; the printer is moving normally",
                "G1 X10 Y10 Z10 E0",
                "G1 X10 Y10 Z10 E10",
                "G1 X10 Y10 Z10 E30",

                "; the printer pauses",
                "G91",
                "G1 Z10 E - 10 F12000 ; suck up XXmm of filament",
                "G90",

                "; the user moves the printer",

                "; the printer un-pauses",
                "G91",
                "G1 Z-10 E10.8 F12000",
                "G90",
                null,
            };

            // We should go back to the above code when possible. It requires making pause part and move while paused part of the stream.
            // All communication should go through stream to minimize the difference between printing and controlling while not printing (all printing in essence).
            string[] expected = new string[]
            {
                "; the printer is moving normally",
                "G1 X10 Y10 Z10 E0",
                "G1 E10",
                "G1 E30",

                "; the printer pauses",
                "",                  // G91 is removed
                "G1 Z20 E20 F12000", // altered to be absolute
                "G90",

                "; the user moves the printer",

                "; the printer un-pauses",
                "",                 // G91 is removed
                "G1 Z10 E30.8",
                "G90",
                null,
            };

            AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"));
            MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));

            var         printer             = new PrinterConfig(new PrinterSettings());
            GCodeStream pauseHandlingStream = CreateTestGCodeStream(printer, inputLines, out List <GCodeStream> streamList);

            ValidateStreamResponse(expected, pauseHandlingStream);
        }
Example #29
0
        private void AddContentItem(FeedSectionData content)
        {
            switch (content.content_type)
            {
            case "headline":
            {
                break;

                // use the Golden Ratio to calculate an attractive size relative to the banner
                var image       = new ImageBuffer(1520, (int)(170 / 1.618));
                var imageWidget = new ResponsiveImageWidget(image)
                {
                    Margin = new BorderDouble(5),
                    Cursor = Cursors.Hand
                };

                var graphics2D = image.NewGraphics2D();
                image.SetRecieveBlender(new BlenderPreMultBGRA());
                graphics2D.Clear(theme.AccentMimimalOverlay);

                // use the Golden Ratio to calculate an attractive size for the text relative to the text banner
                var pixelsPerPoint = 96.0 / 72.0;
                var goalPointSize  = image.Height / pixelsPerPoint / 1.618;

                var printer = new TypeFacePrinter(content.text, goalPointSize);

                graphics2D.DrawString(content.text, image.Width / 2, image.Height / 2 + printer.TypeFaceStyle.EmSizeInPixels / 2, goalPointSize,
                                      Justification.Center, Baseline.BoundsTop,
                                      theme.TextColor);

                if (content.link != null)
                {
                    imageWidget.Cursor = Cursors.Hand;
                    imageWidget.Click += (s, e) =>
                    {
                        if (e.Button == MouseButtons.Left)
                        {
                            ApplicationController.Instance.LaunchBrowser(content.link);
                        }
                    };
                }

                this.AddChild(imageWidget);
            }
            break;

            case "banner_rotate":
                // TODO: make this make a carousel rather than add the first item and rotate between all the items
                var rand = new Random();
                AddContentItem(content.banner_list[rand.Next(content.banner_list.Count)]);
                break;

            case "banner_image":
            {
                // Our banners seem to end with something like "=w1520-h170"
                // if present use that to get the right width and height
                int expectedWidth = 1520;
                GCodeFile.GetFirstNumberAfter("=w", content.image_url, ref expectedWidth);
                int expectedHeight = 170;
                GCodeFile.GetFirstNumberAfter("-h", content.image_url, ref expectedHeight);
                if ((content.theme_filter == "dark" && theme.IsDarkTheme) ||
                    (content.theme_filter == "light" && !theme.IsDarkTheme) ||
                    (content.theme_filter == "all"))
                {
                    var image       = new ImageBuffer(expectedWidth, expectedHeight);
                    var imageWidget = new ResponsiveImageWidget(image)
                    {
                        Margin = new BorderDouble(5),
                        Cursor = Cursors.Hand
                    };

                    if (content.link != null)
                    {
                        imageWidget.Cursor = Cursors.Hand;
                        imageWidget.Click += (s, e) =>
                        {
                            if (e.Button == MouseButtons.Left)
                            {
                                ApplicationController.Instance.LaunchBrowser(content.link);
                            }
                        };
                    }

                    imageWidget.Load += (s, e) => WebCache.RetrieveImageAsync(image, content.image_url, false, new BlenderPreMultBGRA());
                    this.AddChild(imageWidget);
                }
            }
            break;

            case "article_group":
            case "product_group":
                if (currentContentContainer == null)
                {
                    currentContentContainer = new FlowLeftRightWithWrapping();
                    this.AddChild(currentContentContainer);
                }
                currentContentContainer.AddChild(new ExploreSection(content, theme));
                break;
            }
        }
        public PauseHandlingStream(PrintHostConfig printer, GCodeStream internalStream)
            : base(printer, internalStream)
        {
            // if we have a runout sensor, register to listen for lines to check it
            if (printer.Settings.GetValue <bool>(SettingsKey.filament_runout_sensor))
            {
                printer.Connection.LineReceived += (s, line) =>
                {
                    if (line != null)
                    {
                        if (line.Contains("ros_"))
                        {
                            if (line.Contains("TRIGGERED"))
                            {
                                readOutOfFilament = true;
                            }
                        }

                        if (line.Contains("pos_"))
                        {
                            double sensorDistance  = 0;
                            double stepperDistance = 0;
                            if (GCodeFile.GetFirstNumberAfter("SENSOR:", line, ref sensorDistance))
                            {
                                if (sensorDistance < -1 || sensorDistance > 1)
                                {
                                    printer.Connection.FilamentPositionSensorDetected = true;
                                }

                                if (printer.Connection.FilamentPositionSensorDetected)
                                {
                                    GCodeFile.GetFirstNumberAfter("STEPPER:", line, ref stepperDistance);

                                    var stepperDelta = Math.Abs(stepperDistance - positionSensorData.LastStepperDistance);

                                    // if we think we should have move the filament by more than 1mm
                                    if (stepperDelta > 1)
                                    {
                                        var sensorDelta = Math.Abs(sensorDistance - positionSensorData.LastSensorDistance);
                                        // check if the sensor data is within a tolerance of the stepper data

                                        var deltaRatio = sensorDelta / stepperDelta;
                                        if (deltaRatio < .5 || deltaRatio > 2)
                                        {
                                            // we have a reportable discrepancy set a runout state
                                            positionSensorData.ExtrusionDiscrepency++;
                                            if (positionSensorData.ExtrusionDiscrepency > 2)
                                            {
                                                readOutOfFilament = true;
                                                positionSensorData.ExtrusionDiscrepency = 0;
                                            }
                                        }
                                        else
                                        {
                                            positionSensorData.ExtrusionDiscrepency = 0;
                                        }

                                        // and record this position
                                        positionSensorData.LastSensorDistance  = sensorDistance;
                                        positionSensorData.LastStepperDistance = stepperDistance;
                                    }
                                }
                            }
                        }
                    }
                };
            }
        }