/// <summary> /// Converts block X, Y and Z params into a Coordinate, substituting current machine locations for those that don't /// have values supplied in the block /// </summary> private Coordinate GetMoveTargetCoordinate(GCodeBlock block) { var coordinate = new Coordinate(); Coordinate machineLocation = _machine.GetWorkingLocation(); if (block.X.HasValue) { coordinate.X = (double)block.X; } else { if (AbsoluteMode) { coordinate.X = machineLocation.X; } else { coordinate.X = 0; } } if (block.Y.HasValue) { coordinate.Y = (double)block.Y; } else { if (AbsoluteMode) { coordinate.Y = machineLocation.Y; } else { coordinate.Y = 0; } } if (block.Z.HasValue) { coordinate.Z = (double)block.Z; } else { if (AbsoluteMode) { coordinate.Z = machineLocation.Z; } else { coordinate.Z = 0; } } return(coordinate); }
public static List<GCodeBlock> Parse(string blockLine) { var words = blockLine.ToUpper().Split(' '); var newBlocks = new List<GCodeBlock>(); var newBlock = new GCodeBlock(); newBlocks.Add(newBlock); foreach (string word in words) { if (word.Length < 2) continue; double value; string wordType = word.Substring(0, 1); if (!double.TryParse(word.Substring(1), out value)) value = 0; // Another G word on the same line as a previous G word, starts a new block if (wordType == "G" && newBlock.G.HasValue) { newBlock = new GCodeBlock(); newBlocks.Add(newBlock); } // Another M word on the same line as a previous M word, starts a new block if (wordType == "M" && newBlock.M.HasValue) { newBlock = new GCodeBlock(); newBlocks.Add(newBlock); } switch (wordType) { case "G": newBlock.G = value; break; case "M": newBlock.M = value; break; case "X": newBlock.X = value; break; case "Y": newBlock.Y = value; break; case "Z": newBlock.Z = value; break; case "I": newBlock.I = value; break; case "J": newBlock.J = value; break; case "F": newBlock.F = value; break; case "T": newBlock.T = value; break; case "P": newBlock.P = value; break; case "Q": newBlock.Q = value; break; case "R": newBlock.R = value; break; case "S": newBlock.S = value; break; } } return newBlocks; }
public static List <GCodeBlock> Parse(string blockLine) { var words = blockLine.ToUpper().Split(' '); var newBlocks = new List <GCodeBlock>(); var newBlock = new GCodeBlock(); newBlocks.Add(newBlock); foreach (string word in words) { if (word.Length < 2) { continue; } double value; string wordType = word.Substring(0, 1); if (!double.TryParse(word.Substring(1), out value)) { value = 0; } // Another G word on the same line as a previous G word, starts a new block if (wordType == "G" && newBlock.G.HasValue) { newBlock = new GCodeBlock(); newBlocks.Add(newBlock); } // Another M word on the same line as a previous M word, starts a new block if (wordType == "M" && newBlock.M.HasValue) { newBlock = new GCodeBlock(); newBlocks.Add(newBlock); } switch (wordType) { case "G": newBlock.G = value; break; case "M": newBlock.M = value; break; case "X": newBlock.X = value; break; case "Y": newBlock.Y = value; break; case "Z": newBlock.Z = value; break; case "I": newBlock.I = value; break; case "J": newBlock.J = value; break; case "F": newBlock.F = value; break; case "T": newBlock.T = value; break; case "P": newBlock.P = value; break; case "Q": newBlock.Q = value; break; case "R": newBlock.R = value; break; case "S": newBlock.S = value; break; } } return(newBlocks); }
public void ExecuteCode(List <string> gCode, bool nestedCall = false) { int linesParsed = 0; int linesToParse = gCode.Count; bool cancel = false; SetMachineWorkingOffset(); // Header File if (!nestedCall && _machine.Settings.ExecHeaderFile.Length > 0) { ExecuteCode(GCodeFunctions.ExecuteGCodeFile(_machine.Settings.ExecHeaderFile), true); } foreach (string line in gCode) { if (ProgramFinished) { break; } string normalizedLine = line.Split('/')[0]; // The '/' signifies a remark to the end of the line normalizedLine = normalizedLine.Split('(')[0]; // The '(' signifies an inline/multiline remark in standard Gcode, but we're only treating it as a line comment or end of line comment normalizedLine = normalizedLine.Trim(); // Raise event to notify caller of progress linesParsed++; if (!nestedCall && OnProgressNotify != null) { OnProgressNotify(string.Format("Parsing G-Code: {0} of {1}", linesParsed, linesToParse), out cancel); } if (cancel) { break; } if (normalizedLine.Length == 0) { continue; } // --- Extended (non-gcode) functions begin with a '!' if (normalizedLine.StartsWith("!")) { ExecuteExtendedFunction(normalizedLine); } // --- Everything else is gcode else { var blocks = GCodeBlock.Parse(normalizedLine); foreach (var block in blocks) { if (block.G.HasValue || block.T.HasValue) { ExecuteGBlock(block); } if (block.M.HasValue) { ExecuteMBlock(block); } } } } // Footer File if (!nestedCall && _machine.Settings.ExecFooterFile.Length > 0) { ExecuteCode(GCodeFunctions.ExecuteGCodeFile(_machine.Settings.ExecFooterFile), true); } }
private void ExecuteGBlock(GCodeBlock block) { // Remember sticky words for subsequent operations if (block.F.HasValue) { G1FeedRate = (int)Math.Floor((double)block.F); } if (block.Q.HasValue) { _drillDepthIncrement = (double)block.Q; } if (block.R.HasValue) { _drillSurfaceStart = (double)block.R; } if (block.P.HasValue) { _dwellDurationMS = (int)Math.Abs((Math.Floor((double)block.P))); } // Set Absolute coordinate mode if (block.G == 90) { AbsoluteMode = true; } // Set Incremental coordinate mode if (block.G == 91) { AbsoluteMode = false; } // Causes next G0, G1, G2, or G3 to use Machine coordinate system - only applies once if (block.G == 53) { _oneTimeMachineCoordinateSystem = true; } // G49 cancels G43 if (block.G == 49) { ToolLengthCompensation = false; SetMachineWorkingOffset(); } // G43 - Sets tool length compensation if (block.G == 43) { ToolLengthCompensation = true; SetMachineWorkingOffset(); } // G53 - G59 -- Working Coordinate System change if (block.G >= 54 && block.G <= 59) { SetWorkspaceOffset((double)block.G); } if (block.T >= 1 && block.T <= 9) { SetToolOffset((double)block.T); } // G00 - Rapid Traverse if (block.G == 0) { BeforeMoveSetMCS(); _machine.MoveTo(GetMoveTargetCoordinate(block), !AbsoluteMode, false, _machine.Settings.FeedRateMaximum); AfterMoveRevertMCS(); } // G01 - Line to if (block.G == 1) { BeforeMoveSetMCS(); _machine.MoveTo(GetMoveTargetCoordinate(block), !AbsoluteMode, true, G1FeedRate); AfterMoveRevertMCS(); } // G02/G03 - Arc clockwise/counter-clockwise to a point (Does not currently support Incremental mode) if (block.G == 2 || block.G == 3) { bool clockwise = block.G == 2; if (!block.I.HasValue) { block.I = 0; } if (!block.J.HasValue) { block.J = 0; } if (block.I == 0 && block.J == 0) { throw new Exception("I and J may not both be zero for a g02/g03"); } var machineLocation = _machine.GetWorkingLocation(); var finish = GetMoveTargetCoordinate(block); var center = new Coordinate(machineLocation.X + (double)block.I, machineLocation.Y + (double)block.J, machineLocation.Z); //TODO: make sure this supports incremental mode (which I don't think it does now) BeforeMoveSetMCS(); ExecuteCode(GCodeFunctions.GenerateArc(machineLocation, finish, center, clockwise), true); AfterMoveRevertMCS(); } // G4 - Pause in milliseconds. EG: G04 P250 -- P is sticky if (block.G == 4) { _machine.SendDwell(_dwellDurationMS); } // G83 - Drilling cycle with pecks: Accepts X, Y, Z, P (Depth increment), Q (Dwell time in ms) and R (Work surface Z) values // P, Q and R are sticky if (block.G == 83 || block.G == 82 || block.G == 81) { _oneTimeMachineCoordinateSystem = false; // Not supported for G83 var location = GetMoveTargetCoordinate(block); ExecuteCode(GCodeFunctions.GeneratePeckingDrillCycle(location, _drillDepthIncrement, _dwellDurationMS, _drillSurfaceStart), true); } }
private void ExecuteMBlock(GCodeBlock block) { }
/// <summary> /// Converts block X, Y and Z params into a Coordinate, substituting current machine locations for those that don't /// have values supplied in the block /// </summary> private Coordinate GetMoveTargetCoordinate(GCodeBlock block) { var coordinate = new Coordinate(); Coordinate machineLocation = _machine.GetWorkingLocation(); if (block.X.HasValue) { coordinate.X = (double)block.X; } else { if (AbsoluteMode) coordinate.X = machineLocation.X; else coordinate.X = 0; } if (block.Y.HasValue) { coordinate.Y = (double)block.Y; } else { if (AbsoluteMode) coordinate.Y = machineLocation.Y; else coordinate.Y = 0; } if (block.Z.HasValue) { coordinate.Z = (double)block.Z; } else { if (AbsoluteMode) coordinate.Z = machineLocation.Z; else coordinate.Z = 0; } return coordinate; }
private void ExecuteGBlock(GCodeBlock block) { // Remember sticky words for subsequent operations if (block.F.HasValue) G1FeedRate = (int)Math.Floor((double)block.F); if (block.Q.HasValue) _drillDepthIncrement = (double)block.Q; if (block.R.HasValue) _drillSurfaceStart = (double)block.R; if (block.P.HasValue) _dwellDurationMS = (int)Math.Abs((Math.Floor((double)block.P))); // Set Absolute coordinate mode if (block.G == 90) { AbsoluteMode = true; } // Set Incremental coordinate mode if (block.G == 91) { AbsoluteMode = false; } // Causes next G0, G1, G2, or G3 to use Machine coordinate system - only applies once if (block.G == 53) { _oneTimeMachineCoordinateSystem = true; } // G49 cancels G43 if (block.G == 49) { ToolLengthCompensation = false; SetMachineWorkingOffset(); } // G43 - Sets tool length compensation if (block.G == 43) { ToolLengthCompensation = true; SetMachineWorkingOffset(); } // G53 - G59 -- Working Coordinate System change if (block.G >= 54 && block.G <= 59) { SetWorkspaceOffset((double)block.G); } if (block.T >= 1 && block.T <= 9) { SetToolOffset((double)block.T); } // G00 - Rapid Traverse if (block.G == 0) { BeforeMoveSetMCS(); _machine.MoveTo(GetMoveTargetCoordinate(block), !AbsoluteMode, false, _machine.Settings.FeedRateMaximum); AfterMoveRevertMCS(); } // G01 - Line to if (block.G == 1) { BeforeMoveSetMCS(); _machine.MoveTo(GetMoveTargetCoordinate(block), !AbsoluteMode, true, G1FeedRate); AfterMoveRevertMCS(); } // G02/G03 - Arc clockwise/counter-clockwise to a point (Does not currently support Incremental mode) if (block.G == 2 || block.G == 3) { bool clockwise = block.G == 2; if (!block.I.HasValue) block.I = 0; if (!block.J.HasValue) block.J = 0; if (block.I == 0 && block.J == 0) throw new Exception("I and J may not both be zero for a g02/g03"); var machineLocation = _machine.GetWorkingLocation(); var finish = GetMoveTargetCoordinate(block); var center = new Coordinate(machineLocation.X + (double)block.I, machineLocation.Y + (double)block.J, machineLocation.Z); //TODO: make sure this supports incremental mode (which I don't think it does now) BeforeMoveSetMCS(); ExecuteCode(GCodeFunctions.GenerateArc(machineLocation, finish, center, clockwise), true); AfterMoveRevertMCS(); } // G4 - Pause in milliseconds. EG: G04 P250 -- P is sticky if (block.G == 4) { _machine.SendDwell(_dwellDurationMS); } // G83 - Drilling cycle with pecks: Accepts X, Y, Z, P (Depth increment), Q (Dwell time in ms) and R (Work surface Z) values // P, Q and R are sticky if (block.G == 83) { _oneTimeMachineCoordinateSystem = false; // Not supported for G83 var location = GetMoveTargetCoordinate(block); ExecuteCode(GCodeFunctions.GeneratePeckingDrillCycle(location, _drillDepthIncrement, _dwellDurationMS, _drillSurfaceStart), true); } }