Skip to main content
Topic: gcmc - G-code preprocessor/meta-language (Read 21397 times) previous topic - next topic

gcmc - G-code preprocessor/meta-language

Hi all,

Every time I need to create G-code for a CNC mill I get quite annoyed with the ancient syntax and hopeless format. Especially when I need to have dimensions in both mil and mm, to match PCB designs, it becomes a mess very quickly. I looked for a meta-language/preprocessor/compiler, but came up with nothing.

Time to create one!

I created a small compiler with a context-free grammar and procedural format, which runs scripts to make G-code for a CNC mill. It supports variables and advanced math (scalars, vectors and vector-lists) including mil/mm unit-conversions. You can find the code at my git-repo: https://gitorious.org/gcmc/gcmc

A bit more complex example:
Code: [Select]
SAVEZ = 5.0;
HOME = [0, 0, SAFEZ];
feedrate(100.0);      // Set the feedrate (F) to 100mm/min
goto([100mil, 100mm]); // go to (G0) location x=100.0*0.254mm, y=100mm
move([-,-,-10]);      // move to (G1) location Z=-10mm
move([-,-,SAFEZ]);    // move to (G1) location Z=5mm
goto(HOME);            // go to (G0) home position
The compiler code is far from finished. All it currently can do is generate G[014] codes. Arcs are yet to be implemented. However, there are quite a few built-in functions to support programming (trigonometric, standard math, unit conversion). Documentation is non-existent as of yet. The below example should help a bit for now. The grammar is designed to be familiar (very much C-like).

Please let me know any comments you may have.

An example is attached:
[attachment=1]
[attachment=0]

Re: gcmc - G-code preprocessor/meta-language

Reply #1
I have been improving the gcmc compiler for a while and I think it is very powerful now. The grammar is done and a very rich set of built-in functions support easy creation of very complex designs. Gcmc's syntax and built-in functions are now also documented at gcmc's home page http://http://www.vagrearg.org/content/gcmc, which links to syntax and function reference.

Next up is to start working on a standard library of script-space functions to do high-level common operations. However, this will take some more time. In the meantime, I hope some of you find gcmc useful for CNC milling or other uses I have not yet though about.

Some examples:
[attachment=3]
[attachment=1]
[attachment=2]
[attachment=0]

Re: gcmc - G-code preprocessor/meta-language

Reply #2
I guess it depends on what flavour you're dealing with, but I don't have any real issues with G-Code, though some controls are easier than others.

A couple of minor correction to the code above -
G0 isn't 'go to', it's 'Rapid' - i.e. move at Rapid velocity.
G1 isn't 'move' to, it's 'Feed to' - i.e. move at the commanded Feed velocity

It looks a little odd compared to the G-Code I'm used to, I'm also not use to seeing what appear to be placeholders for the other axes -
e.g. move([-,-,-10]);

that's usually just G1Z-10.

I don't really have an issue with swapping between Metric and Imperial, though generally you try to avoid it if you can, so that you don't accidentally get caught out. Of course there are exceptions like the PCB related stuff you mention. What I usually try to do in those cases is do all the metric stuff in one section, then the imperial in another section or another program. On the controls I deal with it's just a simple selection of G70 or G71 to swap, so I don't really see it as messy, though plenty of people who try to convert a lot of precise numbers to metric and then it can get messy.

Re: gcmc - G-code preprocessor/meta-language

Reply #3
[quote author="Sleepwalker3"]I guess it depends on what flavour you're dealing with, but I don't have any real issues with G-Code, though some controls are easier than others.[/quote]
Well, gcode is archaic. It hurts my brain and makes my eyes bleed ;-)

The point being, nobody is forced to use anything. Gcmc was started because I wanted to write things easier. If you love gcode, you should certainly continue to use it directly.

Quote
A couple of minor correction to the code above -
G0 isn't 'go to', it's 'Rapid' - i.e. move at Rapid velocity.
G1 isn't 'move' to, it's 'Feed to' - i.e. move at the commanded Feed velocity
That is a matter of perspective. You are right in the sense of machining, but gcmc is on top of that. G0 simply moves at the highest speed to the point you want and G1 moves at the specified speed or feedrate to the specified point. If you don't like them to be called goto/move, the you can make a couple of functions:
Code: [Select]
 function rapid(v) { goto(v); }
function feed_to(v) { move(v); }

Quote
It looks a little odd compared to the G-Code I'm used to, I'm also not use to seeing what appear to be placeholders for the other axes -
e.g. move([-,-,-10]);
that's usually just G1Z-10.
They are not placeholders, but "undefined" values. The reason is quite simple. The argument is a vector. The vector entries correspond to XYZABCUVW. Undefined entries are there to enable selective moves and still being able to to vector-mathematics.

If you look at the examples, then you can see that the vector math is what is so valuable. Vector math combined with the vector lists is a powerful way to do calculations.

Quote
I don't really have an issue with swapping between Metric and Imperial, though generally you try to avoid it if you can, so that you don't accidentally get caught out. Of course there are exceptions like the PCB related stuff you mention. What I usually try to do in those cases is do all the metric stuff in one section, then the imperial in another section or another program. On the controls I deal with it's just a simple selection of G70 or G71 to swap, so I don't really see it as messy, though plenty of people who try to convert a lot of precise numbers to metric and then it can get messy.
The problem is not that big if you can redefine the units on the fly. The problem is when you have to do math on the values. Then you get into the mess of conversion. Gcode is not very readable when you start to do many calculations on the lines. It also gets messy quick when you need to know where/when/what  just happened and "what is my state now again"... Better to let the language handle the conversions and you can concentrate on the actual pattern designs.

Re: gcmc - G-code preprocessor/meta-language

Reply #4
Not knocking it, obviously a lot of work has been put into it and it looks good, it's simply that I'm not sure that I have a need for it, though no doubt plenty would benefit from a meta-language like this - especially those coming from a C background. Where I do like this is the simplicity in mixing Imperial and Metric, I can see that it would come in *really* handy for that sort of thing. Is it flexible for different 'flavours' of G-Code or are you going for one particular flavour, as 'standard' ISO G-code is nothing like 'standard' in the real world, as you probably know.


I brought up the 'Rapid' and 'Feed' (or Linear) points because I get a lot of people thinking G0 (G-Zero) is actually GO (G-Oh) as in "GO to this point", when really it's not about getting to any specific point, that particular part of the code is simply about the way it feeds and the rate at which it does it. It's an important distinction also in that in G1 the toolpath will be a straight line to a point, however G0 may not follow that and can just get to the final point in any given axis at whatever maximum rate it can, with no regard for the other axis - so they may not all arrive at the finishing point at the same time - I've seen that result in a few crashes!

It's quite an adventurous sort of project, how far do you think you'll take it? For example, do you expect you'll get into things like having adjustable plains for Circular Interpolation, etc?  There are many types of things that could get tricky with the many different versions of G-Code out there.

Re: gcmc - G-code preprocessor/meta-language

Reply #5
[quote author="Sleepwalker3"]Not knocking it, obviously a lot of work has been put into it and it looks good, it's simply that I'm not sure that I have a need for it, though no doubt plenty would benefit from a meta-language like this - especially those coming from a C background.[/quote]
Don't get me wrong, all comments are welcome. However, not all will like or require a new language or see the need for it, whereas I was simply trying to solve my own frustration, which became a bit more.

Quote
Where I do like this is the simplicity in mixing Imperial and Metric, I can see that it would come in *really* handy for that sort of thing.
That was one of the design parameters of the language because I regularly deal with both in one project. Parts are PCBs, in mils and the case/rest is in mm. It is a hell to keep track. Now I can just specify all values as is and I know it will fit.

Quote
Is it flexible for different 'flavours' of G-Code or are you going for one particular flavour, as 'standard' ISO G-code is nothing like 'standard' in the real world, as you probably know.
Yes, that was a thought that struck me when the first version was done. It is possible to create a flexible backend to generate the codes that are supported for a specific target. Especially the arcs in YZ and XZ planes are badly supported, which could be created in gcmc. However, my test-target is LinuxCNC at the moment and has many features implemented. More fine grained backend features will be something to implement when I get a request for it.

Quote
I brought up the 'Rapid' and 'Feed' (or Linear) points because I get a lot of people thinking G0 (G-Zero) is actually GO (G-Oh) as in "GO to this point", when really it's not about getting to any specific point, that particular part of the code is simply about the way it feeds and the rate at which it does it. It's an important distinction also in that in G1 the toolpath will be a straight line to a point, however G0 may not follow that and can just get to the final point in any given axis at whatever maximum rate it can, with no regard for the other axis - so they may not all arrive at the finishing point at the same time - I've seen that result in a few crashes!
You still need to know some basics and knowing CNC machining principles. Knowing basic gcode is a good thing before attempting to make anything (just like you should know assembly even though you program in C). I do know the difference between G0/G1 and any user should also know that or learn the hard way, like you ;-)

Quote
It's quite an adventurous sort of project, how far do you think you'll take it? For example, do you expect you'll get into things like having adjustable plains for Circular Interpolation, etc?  There are many types of things that could get tricky with the many different versions of G-Code out there.
The current version supports setting the active plane (XY/XZ/YZ) and simply assumes that the target machine also understands these. But that will be a future feature to do interpolations in gcmc on demand. For example in the UVW planes. One of the difficult issues are the ABC axes, where there is no consensus how they are mounted and therefore not possible to make a generic mathematical model. Then there also is supporting polar coordinates in general. Those will be of future consideration.

As for adventurous, well, I like a challenge :-) Gcmc is an attempt to bring an archaic CNC language into the modern age with an easy and clear interface. All feedback I get flows back into its development. As for "how far do I take it" is funny because I got a similar  question on the LinuxCNC mailing list. Well, as far as it takes to make gcode programming obsolete.

Re: gcmc - G-code preprocessor/meta-language

Reply #6
Quote
I do know the difference between G0/G1 and any user should also know that or learn the hard way, like you ;-)
I was actually talking about others crashing it, not myself, I'm normally the one fixing things up after the crashes!

Quote
Well, as far as it takes to make gcode programming obsolete.
That I think is quite a high aspiration (though I realise it's a bit tongue-in-cheek). Whilst it does have limitations, it's served us well for a very long time. It's important to remember too, that it's a bit like BASIC. Many people knock BASIC as some kiddy langauge that has no structure, no speed, no good programming practices and is something only for beginners. It may have started out that way, but if you look at something like PowerBasic, you'll find just about all of those complaints have gone long ago and you have a really nice language that is quite comparable to C - and a hell of a lot easier to read!
G-Code is much the same, there are many things that some G-Code flavours can't do or don't handle well, other flavours will be fine. Some don't like you leaving out an axis move (kind of like where you put in the undefined values marker), others will happily realise it's not referencing those and work it all out. Some insist on G01, others will take G01 or G1. There are lots of variations and some are certainly better than others.

Re: gcmc - G-code preprocessor/meta-language

Reply #7
Also, remember G-code is the language that the CNC understand.... Think of it as some kind of machine code. Usually, anithing more complex than a series of holes is done with a CAM program. (In the las workshop where I worked, none of the machinists touched a single line of Gcode, or Heindenhain, all was done via CAM).

This preprocesor seems interesting for doing some procedural stuff, like what you can do with some modern Heidenhain CNCs. It could be interesting the ability to import toolpaths from a dxf file, or some "standard" vectorial graphics file,  and apply some transformations to it (repetitions, offsets, etc...). This could replace CAM programs for some "simple" tasks, like PCB machining.

Lookong forward to see how this development ends... And dreaming of my own CNC mill in my workshop.

Re: gcmc - G-code preprocessor/meta-language

Reply #8
[quote author="Baldor"]Also, remember G-code is the language that the CNC understand.... Think of it as some kind of machine code. Usually, anithing more complex than a series of holes is done with a CAM program. (In the las workshop where I worked, none of the machinists touched a single line of Gcode, or Heindenhain, all was done via CAM).[/quote]
G-code is the assembly of machining. Gcmc is an abstraction level above. The "old" machinist may never have written a line of code, but the modern hacker builds his own mill nowadays. CNC machining is no longer an exclusive domain of the mechanical engineers and gcmc is an attempt to bridge a gap.

Quote
This preprocesor seems interesting for doing some procedural stuff, like what you can do with some modern Heidenhain CNCs. It could be interesting the ability to import toolpaths from a dxf file, or some "standard" vectorial graphics file,  and apply some transformations to it (repetitions, offsets, etc...). This could replace CAM programs for some "simple" tasks, like PCB machining.
Lookong forward to see how this development ends... And dreaming of my own CNC mill in my workshop.
Gcmc is not meant to be an import-/export-facility for CAD/CAM conversion as such. I cannot see the value of gcmc reading DXF files, where there are many other conversion scripts/programs already available. It could be interesting to have the CAD packages export a gcmc compatible script; that would be a different world.

Re: gcmc - G-code preprocessor/meta-language

Reply #9
Quote
Gcmc is not meant to be an import-/export-facility for CAD/CAM conversion as such. I cannot see the value of gcmc reading DXF files, where there are many other conversion scripts/programs already available. It could be interesting to have the CAD packages export a gcmc compatible script; that would be a different world.

Maybe I doesn't explain well enough what I am proposing. Is not importing a file and then exporting the same in Gcode. Is importing to your meta-language, and then, apply the transformations you already doing. Like the star example you shown earlier in this thread. For example, import  an arbitrary closed shape, make offsets to the left until the enclosed area is less than the tool diameter. Is simply to avoid defining the shape by hand, it could became prety dificult and tiresome with complex shapes with thousand of points.

Just could be a pre-preprocesor to convert dxf to your meta-language.

Re: gcmc - G-code preprocessor/meta-language

Reply #10
Yes, it is possible to convert to gcmc script form, execute a program and then convert to any output you'd like.

The backend is currently geared towards G-code, but there are, in principle, many more flexible backends possible. Replacing the built-in function table with a new set of function implementations would accomplish that.

However, I do not see me implementing this without some more concrete problem to solve. Just creating a backend for the sake of creating it is not something I would want to do right now. If you have a concrete problem, then we could maybe discuss options.

Re: gcmc - G-code preprocessor/meta-language

Reply #11
I've been incrementally improving gcmc to support more functionality and generalizations. Gcmc is now capable of generating G-code, SVG and DXF output as of version 1.4.0. The multiple backends allow gcmc to be used not only for mills and lathes, but also for laser cutters and things I have not thought of yet.

A set of screenshots show three examples output in all three output formats from one and the same source:
http://www.vagrearg.org/content/gcmc#screenshots

Have a testdrive and let me know if there are any things you'd like to have added/changed (or find a bug).

Re: gcmc - G-code preprocessor/meta-language

Reply #12
A lot has happened since I started the gcmc project. It is currently at version 1.5.1 and the syntax has matured to a level where you can write many complex algorithms with only few lines of code.

LinuxCNC's ngcgui now has direct support for gcmc and you can create patters from withing ngcgui.

The latest release improves on the documentation, providing an introduction doc and also adds a couple of new examples:
[attachment=2]
[attachment=3]
[attachment=1]
[attachment=0]

Re: gcmc - G-code preprocessor/meta-language

Reply #13
Awesome! Thanks for doing this!  Was considering developing something similar (though more likely a library extension of an existing language, like Ruby) but now I don't have to :)

A few thoughts, if you don't mind:

It would be really nice to be able to access the vector components with '.' accessors, e.g. V[0] ==> V.x, V[1] ==> V.y, V[2] ==> V.z etc. do make the readability clearer.

Also, any hope of file read/write capability and string (parsing/tokenizing) functions?  It would be nice to read a pre-existing G-code program (some tool path output by cam software for instance) and parse it into a vector list, which can then be manipulated (scaled, rotated, repeated in a matrix, etc.) by gcmc.

Also, a few things I noticed:

The 'if' statement requires {} around single statement execution blocks, e.g.:

Code: [Select]
if position()[0] == start_x 
  move([end_x]);
else
  move([start_x]);

won't work.

Also, the compiler doesn't like this:

Code: [Select]
position()[0] == start_x ? move([end_x]) : move([start_x]);

as it complains that it doesn't do anything (e.g. no assignment.)  I'm not sure if the above was intentional, but it would be nice if this worked more like as expected in C.

But awesome work, thanks again!

Re: gcmc - G-code preprocessor/meta-language

Reply #14
[quote author="damon"]It would be really nice to be able to access the vector components with '.' accessors, e.g. V[0] ==> V.x, V[1] ==> V.y, V[2] ==> V.z etc. do make the readability clearer.[/quote]
That would be a nice addition. The first 9 indices (0..8) are XYZABCUVW if all 9 axes are enabled. Otherwise only the first 6 are active. I have to take a look how that would affect the parser to make it look "nice"...

[quote author="damon"]Also, any hope of file read/write capability and string (parsing/tokenizing) functions?  It would be nice to read a pre-existing G-code program (some tool path output by cam software for instance) and parse it into a vector list, which can then be manipulated (scaled, rotated, repeated in a matrix, etc.) by gcmc.[/quote]
That would be a hard thing to do because it requires a full G-code interpreter. That is not part of the goal(s) fot gcmc. G-code is the assembly of the machine and you want gcmc to de-compile the assembly into a high-level program. That is very hard to do.

String tokenizing and such is not a property that I encourage. The language is not a text-handling program, but a math description of a path. I'd like to keep that thought as much as possible.

[quote author="damon"]Also, a few things I noticed:
The 'if' statement requires {} around single statement execution blocks, e.g.:
{snip}[/quote]
That is intentional. The curly braces are mandatory. Mainly to prevent an empty statement (;) causing a lot of headaches.

[quote author="damon"]Also, the compiler doesn't like this:
Code: [Select]
position()[0] == start_x ? move([end_x]) : move([start_x]);
as it complains that it doesn't do anything (e.g. no assignment.)  I'm not sure if the above was intentional, but it would be nice if this worked more like as expected in C.[/quote]
If you write this as a single line statement as you do, then yes, the compiler will complain. Gcmc explicitly discourages expressions in non-assignment statements, even though there are function calls in there.
What is allowed in C is a guideline, not a template. It is a source of errors to allow expressions as statements that result in an unused value. Better safe than sorry.