2

I'm trying to extract data from a line of gcode which can look like ANY of the following:

G01 X10. Y20. Z3.0 F15.
G00X.500Y-10.
G01 Y10.X20.150

Now I already created my regular expression that matches this perfectly with groups:

(G|M|X|Y|Z|I|J|K|F)(?<val>-?\d*\.?\d+\.?)

and that seems to be working great. I get three groups of data out for each result, example:

G01 X10. Y20. Z3.0 F15.
G01  |  G  |  01
X10. |  X  |  10.
Y20. |  Y  |  20.
Z3.0 |  Z  |  3.0
F15. |  F  |  15.

What I'd like to do is be able to check which values are in the input string so I can extract the data and make positional commands. Take the above example, I'd like to extract just the X, Y, and Z values so I can create a Vector of them. This is easy to do when I have all 3 values, but how can I check if a value exists in the first group if the input string is G01 X10. Y5.0?

Xander Luciano
  • 3,753
  • 7
  • 32
  • 53

2 Answers2

2

In order to do this, I decided to iterate through each regex match, then I checked if the first group was either X, Y, or Z, and using a switch statement, changed the value of my 3D vector. Here's the code in case anyone else would like to produce something similar:

public static void ExtractAll(string gcode)
{
    dataPos = Vector3.zero;

    var match = Regex.Matches(gcode, @"(G|M|X|Y|Z|I|J|K|F)(?<val>-?\d*\.?\d+\.?)");
    for (int i = 0; i < match.Count; i++)
    {
        switch (match[i].Groups[1].Value)
        {
            case "X":
                dataPos.x = float.Parse(match[i].Groups["val"].Value);
                break;
            case "Y":
                dataPos.y = float.Parse(match[i].Groups["val"].Value);
                break;
            case "Z":
                dataPos.z = float.Parse(match[i].Groups["val"].Value);
                break;
        }
    }
    print(dataPos);
}

Note to use regex you need to include it's namespace: using System.Text.RegularExpressions;

Xander Luciano
  • 3,753
  • 7
  • 32
  • 53
2

I just started a GCode parsing library that would help extract information: https://github.com/chrismiller7/GCodeNet

You could use it like the following:

var cmd = Command.Parse("G01 X10. Y20. Z3.0 F15.");
var X = cmd.GetParameterValue(ParameterType.X);
var Y = cmd.GetParameterValue(ParameterType.Y);
var Z = cmd.GetParameterValue(ParameterType.Z);

Additionally, you could read an entire gcode file:

var gcodeFile = new GCodeFile(File.ReadAllText("file.gcode"));
foreach (var cmd in gcodeFile.Commands)
{
   var X = cmd.GetParameterValue(ParameterType.X);
   var Y = cmd.GetParameterValue(ParameterType.Y);
   var Z = cmd.GetParameterValue(ParameterType.Z);
}

The GCodeFile class will handle comments, CRC checks, line numbers, and multiple commands on a single line.