Skip to content

Commit

Permalink
replace some errors with warnings in gcode parser
Browse files Browse the repository at this point in the history
  • Loading branch information
martin2250 committed Dec 24, 2018
1 parent e9eabf1 commit f559415
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 41 deletions.
26 changes: 24 additions & 2 deletions OpenCNCPilot/GCode/GCodeFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,26 @@ class GCodeFile
public double TravelDistance { get; private set; } = 0;
public TimeSpan TotalTime { get; private set; } = TimeSpan.Zero;

public List<string> Warnings = new List<string>();

private GCodeFile(List<Command> toolpath)
{
for (int i = 0; i < toolpath.Count; i++)
{
Command c = toolpath[i];

if (c is Motion)
{
Motion m = (Motion)c;

if (m.Start == m.End)
{
Warnings.Add($"ignoring empty move at position {i} (not equal to line number)");
toolpath.RemoveAt(i--);
}
}
}

Toolpath = new ReadOnlyCollection<Command>(toolpath);

Vector3 min = Vector3.MaxValue, max = Vector3.MinValue;
Expand Down Expand Up @@ -99,15 +117,19 @@ public static GCodeFile Load(string path)
GCodeParser.Reset();
GCodeParser.ParseFile(path);

return new GCodeFile(GCodeParser.Commands) { FileName = path.Substring(path.LastIndexOf('\\') + 1) };
GCodeFile gcodeFile = new GCodeFile(GCodeParser.Commands) { FileName = path.Substring(path.LastIndexOf('\\') + 1) };
gcodeFile.Warnings.InsertRange(0, GCodeParser.Warnings);
return gcodeFile;
}

public static GCodeFile FromList(IEnumerable<string> file)
{
GCodeParser.Reset();
GCodeParser.Parse(file);

return new GCodeFile(GCodeParser.Commands) { FileName = "output.nc" };
GCodeFile gcodeFile = new GCodeFile(GCodeParser.Commands) { FileName = "output.nc" };
gcodeFile.Warnings.InsertRange(0, GCodeParser.Warnings);
return gcodeFile;
}

public static GCodeFile Empty
Expand Down
58 changes: 20 additions & 38 deletions OpenCNCPilot/GCode/GCodeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ struct Word
{
public char Command;
public double Parameter;

public override string ToString()
{
return $"{Command}{Parameter}";
}
}

static class GCodeParser
Expand All @@ -57,11 +62,13 @@ static class GCodeParser
private static string ValidWords = "GMXYZIJKFRSP";
private static string IgnoreAxes = "ABC";
public static List<Command> Commands;
public static List<string> Warnings;

public static void Reset()
{
State = new ParserState();
Commands = new List<Command>(); //don't reuse, might be used elsewhere
Warnings = new List<string>();
}

static GCodeParser()
Expand Down Expand Up @@ -145,7 +152,9 @@ static void Parse(string line, int lineNumber)

if (!ValidWords.Contains(Words[i].Command))
{
throw new ParseException($"unknown word (letter): \"{Words[i].Command} {Words[i].Parameter}\"", lineNumber);
Warnings.Add($"ignoring unknown word (letter): \"{Words[i]}\" in line {lineNumber}");
Words.RemoveAt(i--);
continue;
}

if (Words[i].Command != 'F')
Expand Down Expand Up @@ -179,9 +188,9 @@ static void Parse(string line, int lineNumber)
double param = Words[i].Parameter;

if (param < 0)
throw new ParseException("Spindle Speed must be positive", lineNumber);
Warnings.Add($"Spindle Speed must be positive in line {lineNumber}");

Commands.Add(new Spindle() { Speed = param });
Commands.Add(new Spindle() { Speed = Math.Abs(param) });

Words.RemoveAt(i);
i--;
Expand Down Expand Up @@ -261,25 +270,18 @@ static void Parse(string line, int lineNumber)
if (Words.Count >= 2 && Words[i + 1].Command == 'P')
{
if (Words[i + 1].Parameter < 0)
throw new ParseException("Negative dwell time", lineNumber);
Warnings.Add($"Dwell time must be positive in line {lineNumber}");

Commands.Add(new Dwell() { Seconds = Words[i + 1].Parameter });
Commands.Add(new Dwell() { Seconds = Math.Abs(Words[i + 1].Parameter) });
Words.RemoveAt(i + 1);
Words.RemoveAt(i);
i--;
continue;
}
}

if (param == 54 || param == 94 || param == 40)
{
// discard Gxx words
Words.RemoveAt(i);
i--;
continue;
}

throw new ParseException($"G{param} is not supported", lineNumber);
Warnings.Add($"ignoring unknown command G{param} in line {lineNumber}");
Words.RemoveAt(i--);
#endregion
}
}
Expand Down Expand Up @@ -344,7 +346,7 @@ static void Parse(string line, int lineNumber)
if (MotionMode <= 1)
{
if (Words.Count > 0)
throw new ParseException("Motion Command must be last in line (unused Words in Block)", lineNumber);
Warnings.Add($"Motion Command must be last in line (ignoring unused Words {string.Join(" ", Words)} in Block) in line {lineNumber}");

Line motion = new Line();
motion.Start = State.Position;
Expand Down Expand Up @@ -487,29 +489,6 @@ static void Parse(string line, int lineNumber)
A -= U; //(AB) = vector from start to end of arc along the axes of the current plane
B -= V;

/*
double C = -B; //(UV) = vector perpendicular to (AB)
double D = A;
{ //normalize perpendicular vector
double perpLength = Math.Sqrt(C * C + D * D);
C /= perpLength;
D /= perpLength;
}
double PerpSquare = (Radius * Radius) - ((A * A + B * B) / 4);
if (PerpSquare < 0)
throw new ParseException("arc radius too small to reach both ends", lineNumber);
double PerpLength = Math.Sqrt(PerpSquare);
if (MotionMode == 3 ^ Radius < 0)
PerpLength = -PerpLength;
U += (A / 2) + C * (PerpLength);
V += (B / 2) + (D * PerpLength);
*/
//see grbl/gcode.c
double h_x2_div_d = 4.0 * (Radius * Radius) - (A * A + B * B);
if (h_x2_div_d < 0)
Expand All @@ -532,6 +511,9 @@ static void Parse(string line, int lineNumber)
}
#endregion

if (Words.Count > 0)
Warnings.Add($"Motion Command must be last in line (ignoring unused Words {string.Join(" ", Words)} in Block) in line {lineNumber}");

Arc arc = new Arc();
arc.Start = State.Position;
arc.End = EndPos;
Expand Down
4 changes: 4 additions & 0 deletions OpenCNCPilot/MainWindow.xaml.FileTab.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using OpenCNCPilot.Communication;
using OpenCNCPilot.GCode;
using System;
using System.Windows;

Expand All @@ -23,6 +24,9 @@ private void OpenFileDialogGCode_FileOk(object sender, System.ComponentModel.Can
if (machine.Mode == Machine.OperatingMode.SendFile)
return;

CurrentFileName = "";
ToolPath = GCodeFile.Empty;

try
{
machine.SetFile(System.IO.File.ReadAllLines(openFileDialogGCode.FileName));
Expand Down
10 changes: 9 additions & 1 deletion OpenCNCPilot/MainWindow.xaml.MachineStatus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,15 @@ private void Machine_FileChanged()
}
catch (Exception ex)
{
MessageBox.Show("Could not parse GCode File, no preview/editing available\nrun this file at your own risk\n" + ex.Message);
MessageBox.Show("Could not parse GCode File, no preview/editing available\nrun this file at your own risk\n" + ex.Message + "\n\n\ninternal:\n" + ex.StackTrace);
}

if (ToolPath.Warnings.Count > 0)
{
MessageBox.Show(@"Warning! There were some errors while parsing this file!
Do not use OpenCNCPilot's edit functions unless you are sure that these warnings can be ignored!
If you use edit functions, check the output file for errors before running the gcode!
Be aware that the affected lines will likely move when using edit functions" + "\n\n >" + string.Join("\n >", ToolPath.Warnings));
}

if (Properties.Settings.Default.EnableCodePreview)
Expand Down

0 comments on commit f559415

Please sign in to comment.