コード例 #1
0
        public override PrinterMachineInstruction Instruction(int index)
        {
            lock (locker)
            {
                if (index < readLineCount - MaxLinesToBuffer)
                {
                    throw new Exception("You are asking for a line we no longer have buffered");
                }

                while (index >= readLineCount)
                {
                    string line = openGcodeStream.ReadLine();
                    if (line == null)
                    {
                        readLastLineOfFile = true;
                        line = "";
                    }

                    int ringBufferIndex = readLineCount % MaxLinesToBuffer;
                    readLinesRingBuffer[ringBufferIndex] = new PrinterMachineInstruction(line);

                    string lineToParse = line.ToUpper().Trim();
                    if (lineToParse.StartsWith("G0") || lineToParse.StartsWith("G1"))
                    {
                        double newFeedRateMmPerMin = 0;
                        if (GetFirstNumberAfter("F", lineToParse, ref newFeedRateMmPerMin))
                        {
                            feedRateMmPerMin = newFeedRateMmPerMin;
                        }

                        Vector3 attemptedDestination = lastPrinterPosition;
                        GetFirstNumberAfter("X", lineToParse, ref attemptedDestination.X);
                        GetFirstNumberAfter("Y", lineToParse, ref attemptedDestination.Y);
                        GetFirstNumberAfter("Z", lineToParse, ref attemptedDestination.Z);

                        double ePosition = lastEPosition;
                        GetFirstNumberAfter("E", lineToParse, ref ePosition);

                        lastPrinterPosition = attemptedDestination;
                        lastEPosition       = ePosition;
                    }
                    else if (lineToParse.StartsWith("G92"))
                    {
                        double ePosition = 0;
                        if (GetFirstNumberAfter("E", lineToParse, ref ePosition))
                        {
                            lastEPosition = ePosition;
                        }
                    }

                    readLineCount++;
                }
            }

            return(readLinesRingBuffer[index % MaxLinesToBuffer]);
        }
コード例 #2
0
 public PrinterMachineInstruction(string Line, PrinterMachineInstruction copy, bool clientInsertion = false)
     : this(Line)
 {
     xyzPosition          = copy.xyzPosition;
     FeedRate             = copy.FeedRate;
     EPosition            = copy.EPosition;
     MovementType         = copy.MovementType;
     SecondsToEndFromHere = copy.SecondsToEndFromHere;
     ToolIndex            = copy.ToolIndex;
 }
コード例 #3
0
 public PrinterMachineInstruction(string Line, PrinterMachineInstruction copy, bool clientInsertion = false)
     : this(Line)
 {
     xyzPosition          = copy.xyzPosition;
     feedRate             = copy.feedRate;
     ePosition            = copy.ePosition;
     movementType         = copy.movementType;
     secondsToEndFromHere = copy.secondsToEndFromHere;
     ExtruderIndex        = copy.ExtruderIndex;
     this.clientInsertion = clientInsertion;
 }
コード例 #4
0
        public void Insert(int insertIndex, PrinterMachineInstruction printerMachineInstruction)
        {
            for (int i = 0; i < IndexOfLayerStart.Count; i++)
            {
                if (insertIndex < IndexOfLayerStart[i])
                {
                    IndexOfLayerStart[i]++;
                }
            }

            GCodeCommandQueue.Insert(insertIndex, printerMachineInstruction);
        }
コード例 #5
0
        public override double GetFilamentUsedMm(double filamentDiameter)
        {
            if (filamentUsedMmCache == 0 || filamentDiameter != diameterOfFilamentUsedMmCache)
            {
                double lastEPosition = 0;
                double filamentMm    = 0;
                for (int i = 0; i < gCodeCommandQueue.Count; i++)
                {
                    PrinterMachineInstruction instruction = gCodeCommandQueue[i];
                    // filamentMm += instruction.EPosition;

                    string lineToParse = instruction.Line;
                    if (lineToParse.StartsWith("G0") || lineToParse.StartsWith("G1"))
                    {
                        double ePosition = lastEPosition;
                        if (GetFirstNumberAfter("E", lineToParse, ref ePosition))
                        {
                            if (instruction.XyzeMovementType == PrinterMachineInstruction.MovementTypes.Relative ||
                                instruction.ExtuderRelativeOverride)
                            {
                                filamentMm += ePosition;
                            }
                            else
                            {
                                double deltaEPosition = ePosition - lastEPosition;
                                filamentMm += deltaEPosition;
                            }

                            lastEPosition = ePosition;
                        }
                    }
                    else if (lineToParse.StartsWith("G92"))
                    {
                        double ePosition = 0;
                        if (GetFirstNumberAfter("E", lineToParse, ref ePosition))
                        {
                            lastEPosition = ePosition;
                        }
                    }
                }

                filamentUsedMmCache           = filamentMm;
                diameterOfFilamentUsedMmCache = filamentDiameter;
            }

            return(filamentUsedMmCache);
        }
コード例 #6
0
 public void Add(PrinterMachineInstruction printerMachineInstruction)
 {
     Insert(LineCount, printerMachineInstruction);
 }
コード例 #7
0
        private void ParseGLine(string lineString, PrinterMachineInstruction processingMachineState)
        {
            // take off any comments before we check its length
            int commentIndex = lineString.IndexOf(';');

            if (commentIndex != -1)
            {
                lineString = lineString.Substring(0, commentIndex);
            }

            string[] splitOnSpace = lineString.Split(' ');
            string   onlyNumber   = splitOnSpace[0].Substring(1).Trim();

            switch (onlyNumber)
            {
            case "0":
                goto case "1";

            case "4":
            case "04":
                // wait a given number of milliseconds
                break;

            case "1":
                // get the x y z to move to
            {
                double ePosition = processingMachineState.EPosition;
                var    position  = processingMachineState.Position;
                if (processingMachineState.MovementType == PrinterMachineInstruction.MovementTypes.Relative)
                {
                    position  = Vector3.Zero;
                    ePosition = 0;
                }

                GCodeFile.GetFirstNumberAfter("X", lineString, ref position.X);
                GCodeFile.GetFirstNumberAfter("Y", lineString, ref position.Y);
                GCodeFile.GetFirstNumberAfter("Z", lineString, ref position.Z);
                GCodeFile.GetFirstNumberAfter("E", lineString, ref ePosition);

                double feedrate = 0;
                if (GCodeFile.GetFirstNumberAfter("F", lineString, ref feedrate))
                {
                    processingMachineState.FeedRate = (float)feedrate;
                }

                if (processingMachineState.MovementType == PrinterMachineInstruction.MovementTypes.Absolute)
                {
                    processingMachineState.Position  = position;
                    processingMachineState.EPosition = (float)ePosition;
                }
                else
                {
                    processingMachineState.Position  += position;
                    processingMachineState.EPosition += (float)ePosition;
                }
            }

                if (!gcodeHasExplicitLayerChangeInfo)
                {
                    if (processingMachineState.Z != parsingLastZ || IndexOfLayerStart.Count == 0)
                    {
                        // if we changed z or there is a movement and we have never started a layer index
                        IndexOfLayerStart.Add(GCodeCommandQueue.Count);
                    }
                }
                parsingLastZ = processingMachineState.Position.Z;
                break;

            case "10":                     // firmware retract
                break;

            case "11":                     // firmware unretract
                break;

            case "21":
                // set to metric
                break;

            case "28":
                // G28  Return to home position (machine zero, aka machine reference point)
                break;

            case "29":
                // G29 Probe the z-bed in 3 places
                break;

            case "30":
                // G30 Probe z in current position
                break;

            case "90":                     // G90 is Absolute Distance Mode
                processingMachineState.MovementType = PrinterMachineInstruction.MovementTypes.Absolute;
                break;

            case "91":                     // G91 is Incremental Distance Mode
                processingMachineState.MovementType = PrinterMachineInstruction.MovementTypes.Relative;
                break;

            case "92":
            {
                // set current head position values (used to reset origin)
                double value = 0;
                if (GCodeFile.GetFirstNumberAfter("X", lineString, ref value))
                {
                    processingMachineState.PositionSet |= PositionSet.X;
                    processingMachineState.X            = value;
                }
                if (GCodeFile.GetFirstNumberAfter("Y", lineString, ref value))
                {
                    processingMachineState.PositionSet |= PositionSet.Y;
                    processingMachineState.Y            = value;
                }
                if (GCodeFile.GetFirstNumberAfter("Z", lineString, ref value))
                {
                    processingMachineState.PositionSet |= PositionSet.Z;
                    processingMachineState.Z            = value;
                }
                if (GCodeFile.GetFirstNumberAfter("E", lineString, ref value))
                {
                    processingMachineState.PositionSet |= PositionSet.E;
                    processingMachineState.EPosition    = (float)value;
                }
            }
            break;

            case "130":
                //Set Digital Potentiometer value
                break;

            case "161":
                // home x,y axis minimum
                break;

            case "162":
                // home z axis maximum
                break;

            default:
                break;
            }
        }
コード例 #8
0
        private void ParseMLine(string lineString, PrinterMachineInstruction processingMachineState)
        {
            // take off any comments before we check its length
            int commentIndex = lineString.IndexOf(';');

            if (commentIndex != -1)
            {
                lineString = lineString.Substring(0, commentIndex);
            }

            string[] splitOnSpace = lineString.Split(' ');
            switch (splitOnSpace[0].Substring(1).Trim())
            {
            case "01":
                // show a message?
                break;

            case "6":
                // wait for tool to heat up (wait for condition?)
                break;

            case "101":
                // extrude on, forward
                break;

            case "18":
                // turn off steppers
                break;

            case "42":
                // Stop on material exhausted / Switch I/O pin
                break;

            case "72":
                // makerbot, Play tone or song
                break;

            case "73":
                // makerbot, Manually set build percentage
                break;

            case "82":
                // set extruder to absolute mode
                break;

            case "83":
                //Set extruder to relative mode
                break;

            case "84":
                // lineString = "M84     ; disable motors\r"
                break;

            case "92":
                // set steps per mm
                break;

            case "102":
                // extrude on reverse
                break;

            case "103":
                // extrude off
                break;

            case "104":
                // set extruder temperature
                break;

            case "105":
                // M105 Custom code for temperature reading. (Not used)
                break;

            case "106":
                // turn fan on
                break;

            case "107":
                // turn fan off
                break;

            case "108":
                // set extruder speed
                break;

            case "109":
                // set heated platform temperature
                break;

            case "114":
                break;

            case "117":
                // in Marlin: Display Message
                break;

            case "126":
                // enable fan (makerbot)
                break;

            case "127":
                // disable fan (makerbot)
                break;

            case "132":
                // recall stored home offsets for axis xyzab
                break;

            case "133":
                // MakerBot wait for toolhead to heat
                break;

            case "134":
                // MakerBot wait for platform to reach target temp
                break;

            case "135":
                // MakerBot change toolhead
                break;

            case "140":
                // set bed temperature
                break;

            case "190":
                // wait for bed temperature to be reached
                break;

            case "200":
                // M200 sets the filament diameter.
                break;

            case "201":
                // set axis acceleration
                break;

            case "204":                     // - Set default acceleration
                break;

            case "207":                     // M207: calibrate z axis by detecting z max length
                break;

            case "208":                     // M208: set axis max travel
                break;

            case "209":                     // M209: enable automatic retract
                break;

            case "210":                     // Set homing rate
                break;

            case "226":                     // user request pause
                break;

            case "227":                     // Enable Automatic Reverse and Prime
                break;

            case "301":
                break;

            case "400":                     // Wait for current moves to finish
                break;

            case "565":                     // M565: Set Z probe offset
                break;

            case "1200":                    //M1200 Makerbot Fake gCode command for start build notification
                break;

            case "1201":                    //M1201 Makerbot Fake gCode command for end build notification
                break;

            case "1202":                    //M1202 Makerbot Fake gCode command for reset board
                break;

            default:
                break;
            }
        }
コード例 #9
0
        private void AnalyzeGCodeLines(CancellationToken cancellationToken, Action <double, string> progressReporter,
                                       Vector4 maxAccelerationMmPerS2,
                                       Vector4 maxVelocityMmPerS,
                                       Vector4 velocitySameAsStopMmPerS,
                                       Vector4 speedMultiplier)
        {
            double  feedRateMmPerMin    = 0;
            Vector3 lastPrinterPosition = new Vector3();
            double  lastEPosition       = 0;

            Stopwatch maxProgressReport = new Stopwatch();

            maxProgressReport.Start();

            for (int lineIndex = 0; lineIndex < GCodeCommandQueue.Count; lineIndex++)
            {
                PrinterMachineInstruction instruction = GCodeCommandQueue[lineIndex];
                string  line = instruction.Line;
                Vector3 deltaPositionThisLine  = new Vector3();
                double  deltaEPositionThisLine = 0;
                string  lineToParse            = line.ToUpper().Trim();
                if (lineToParse.StartsWith("G0") || lineToParse.StartsWith("G1"))
                {
                    double newFeedRateMmPerMin = 0;
                    if (GetFirstNumberAfter("F", lineToParse, ref newFeedRateMmPerMin))
                    {
                        feedRateMmPerMin = newFeedRateMmPerMin;
                    }

                    Vector3 attemptedDestination = lastPrinterPosition;
                    GetFirstNumberAfter("X", lineToParse, ref attemptedDestination.X);
                    GetFirstNumberAfter("Y", lineToParse, ref attemptedDestination.Y);
                    GetFirstNumberAfter("Z", lineToParse, ref attemptedDestination.Z);

                    double ePosition = lastEPosition;
                    GetFirstNumberAfter("E", lineToParse, ref ePosition);

                    deltaPositionThisLine  = attemptedDestination - lastPrinterPosition;
                    deltaEPositionThisLine = Math.Abs(ePosition - lastEPosition);

                    lastPrinterPosition = attemptedDestination;
                    lastEPosition       = ePosition;
                }
                else if (lineToParse.StartsWith("G92"))
                {
                    double ePosition = 0;
                    if (GetFirstNumberAfter("E", lineToParse, ref ePosition))
                    {
                        lastEPosition = ePosition;
                    }
                }

                if (feedRateMmPerMin > 0)
                {
                    var timeForE = Estimator.GetSecondsForMovement(deltaEPositionThisLine,
                                                                   feedRateMmPerMin / 60.0,
                                                                   maxAccelerationMmPerS2[3],
                                                                   maxVelocityMmPerS[3],
                                                                   velocitySameAsStopMmPerS[3],
                                                                   speedMultiplier[3]);

                    var timeForPosition = Estimator.GetSecondsForMovement(deltaPositionThisLine,
                                                                          feedRateMmPerMin / 60.0,
                                                                          new Vector3(maxAccelerationMmPerS2),
                                                                          new Vector3(maxVelocityMmPerS),
                                                                          new Vector3(velocitySameAsStopMmPerS),
                                                                          new Vector3(speedMultiplier));

                    instruction.SecondsThisLine = (float)Math.Max(timeForE, timeForPosition);
                }

                if (progressReporter != null && maxProgressReport.ElapsedMilliseconds > 200)
                {
                    progressReporter(((double)lineIndex / GCodeCommandQueue.Count / 2) + .5, "");
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    maxProgressReport.Restart();
                }
            }

            double accumulatedTime = 0;

            for (int i = GCodeCommandQueue.Count - 1; i >= 0; i--)
            {
                PrinterMachineInstruction line = GCodeCommandQueue[i];
                accumulatedTime          += line.SecondsThisLine;
                line.SecondsToEndFromHere = (float)accumulatedTime;
            }
        }
コード例 #10
0
        private static GCodeMemoryFile ParseFileContents(string gCodeString,
                                                         Vector4 maxAccelerationMmPerS2,
                                                         Vector4 maxVelocityMmPerS,
                                                         Vector4 velocitySameAsStopMmPerS,
                                                         Vector4 speedMultiplier,
                                                         CancellationToken cancellationToken, Action <double, string> progressReporter)
        {
            if (gCodeString == null)
            {
                return(null);
            }

            Stopwatch loadTime = Stopwatch.StartNew();

            Stopwatch maxProgressReport = new Stopwatch();

            maxProgressReport.Start();
            PrinterMachineInstruction machineInstructionForLine = new PrinterMachineInstruction("None");

            bool gcodeHasExplicitLayerChangeInfo = false;

            if (gCodeString.Contains("LAYER:") ||
                gCodeString.Contains("; layer"))
            {
                gcodeHasExplicitLayerChangeInfo = true;
            }

            PrinterMachineInstruction previousInstruction = null;
            var speeds = new HashSet <float>();

            GCodeMemoryFile loadedGCodeFile = new GCodeMemoryFile(gcodeHasExplicitLayerChangeInfo);

            // Add the first start index (of 0)
            loadedGCodeFile.IndexOfLayerStart.Add(0);

            int crCount   = CountNumLines(gCodeString);
            int lineIndex = 0;

            foreach (string outputString in CustomSplit(gCodeString, '\n'))
            {
                string lineString = outputString.Trim();
                machineInstructionForLine = new PrinterMachineInstruction(lineString, machineInstructionForLine, false);

                if (lineString.Length > 0)
                {
                    switch (lineString[0])
                    {
                    case 'G':
                        loadedGCodeFile.ParseGLine(lineString, machineInstructionForLine);
                        break;

                    case 'M':
                        loadedGCodeFile.ParseMLine(lineString, machineInstructionForLine);
                        break;

                    case 'T':
                        double extruderIndex = 0;
                        if (GetFirstNumberAfter("T", lineString, ref extruderIndex))
                        {
                            machineInstructionForLine.ExtruderIndex = (int)extruderIndex;
                        }
                        break;

                    case ';':
                        if (gcodeHasExplicitLayerChangeInfo && IsLayerChange(lineString))
                        {
                            // The first "layer" statement in the gcode file is after the start gcode and we ignore
                            // it because we already added a marker for the start of the file (before start gcode)
                            if (!loadedGCodeFile.foundFirstLayerMarker)
                            {
                                loadedGCodeFile.foundFirstLayerMarker = true;
                            }
                            else
                            {
                                loadedGCodeFile.IndexOfLayerStart.Add(loadedGCodeFile.GCodeCommandQueue.Count);
                            }
                        }
                        else if (lineString.StartsWith("; LAYER_HEIGHT:"))
                        {
                            double layerWidth = 0;
                            if (GetFirstNumberAfter("LAYER_HEIGHT:", lineString, ref layerWidth, 0, ""))
                            {
                                loadedGCodeFile.layerHeights.Add(layerWidth);
                            }
                        }
                        break;

                    case '@':
                        break;

                    default:
#if DEBUG
                        throw new NotImplementedException();
#else
                        break;
#endif
                    }
                }

                loadedGCodeFile.GCodeCommandQueue.Add(machineInstructionForLine);

                // Accumulate speeds for extruded moves
                if (previousInstruction != null &&
                    machineInstructionForLine.EPosition > previousInstruction.EPosition &&
                    (machineInstructionForLine.Line.IndexOf('X') != -1 || machineInstructionForLine.Line.IndexOf('Y') != -1))
                {
                    speeds.Add((float)machineInstructionForLine.FeedRate);
                }

                if (progressReporter != null && maxProgressReport.ElapsedMilliseconds > 200)
                {
                    progressReporter((double)lineIndex / crCount / 2, "");

                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(null);
                    }

                    maxProgressReport.Restart();
                }

                previousInstruction = machineInstructionForLine;

                lineIndex++;
            }

            loadedGCodeFile.AnalyzeGCodeLines(cancellationToken, progressReporter,
                                              maxAccelerationMmPerS2,
                                              maxVelocityMmPerS,
                                              velocitySameAsStopMmPerS,
                                              speedMultiplier);

            loadedGCodeFile.Speeds = speeds;

            loadTime.Stop();
            Console.WriteLine("Time To Load Seconds: {0:0.00}".FormatWith(loadTime.Elapsed.TotalSeconds));

            return(loadedGCodeFile);
        }