private void ExecuteExtendedFunction(string line) { var lineParts = line.Split(':'); string functionName = lineParts[0].ToUpper(); string parameters = lineParts.Length > 1 ? lineParts[1] : ""; switch (functionName) { case "!Z-TOP": _machine.MoveZServo(_machine.Settings.ZServoTopPosition); _machine.SendDwell(500); break; case "!Z-BOTTOM": _machine.MoveZServo(_machine.Settings.ZServoBottomPosition, true); break; case "!Z-LOAD": _machine.MoveZServo(_machine.Settings.ZServoLoadPosition); _machine.SendDwell(500); break; case "!END": ProgramFinished = true; break; case "!EXEC": ExecuteCode(GCodeFunctions.ExecuteGCodeFile(parameters), true); break; default: throw new Exception("Invalid extended function"); } }
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); } }