Open maculata opened 6 years ago
@maculata
No, you're not missing anything, the current version of pygcode
doesn't support this.
Do you have some sample gcode you could post here? Also: is there an online specification you can link.
I'd imagine this would be done by pre-processing the gcode, which may be out of scope of pygcode
, but I'll look into it.
linuxcnc specs:
(Mill - generated: Sat Apr 7 22:26:21 2018 ) (Version: 2.0.2) (Description = engrave02) (Material = Aluminum : -any-)
(Units = G20 inches) (Work Offset = G54) (Tool Number = 101) (Tool Description = Drag Knife) (Tool Diameter = 0.0010 inches) (Spindle RPM = 0) (Text to engrave = 0123) (Font = FONT.TTF) (Font height = 0.5000) (Scale = 0.000117564072419) (X Base Location = 0.0000) (Justification Setting = left) (Y Base Location = 1.3500) (Feed Rate = 20.0 inches/minute)
(Z Clear Location = 0.0800) (Z Start Location = 0.0250)
(Z Depth of Cut = 0.0300) (Ammend Serial Number = no)
(----- Start of G-code -----)
(
G17 G90 (XY Plane, Absolute Distance Mode)
G64 P 0.0050 Q 0.0000 (Path Blending)
(font: FONT.TTF) (text: 0123)
(Fill Line Scale = 24) (Fill = 0)
G17 (set current plane to XY) G90 (set Absolute Distance Mode) G20 (set units to inches) G54 (set current work offset)
G30 (move to preset G30) T101 M6 G43 H101 M5 (0 RPM. turn off spindle) M8 (set coolant to ON)
G00 X [#5] Y [#6] G00 Z [#1+#7] (start of symbol 0) (starting X offset: 0) G00 Z [#1+#7] G00 X [1393#3+#5] Y [2077#3+#6] (moveto) G01 Z [0-#2+#7] F#4 G5.1 X[1577#3+#5] Y[1716#3+#6] I[139#3] J[-156#3] G5.1 X[1597#3+#5] Y[1159#3+#6] I[20#3] J[-90#3] G5.1 X[1602#3+#5] Y[991#3+#6] I[0#3] J[-69#3] G5.1 X[1602#3+#5] Y[815#3+#6] I[4#3] J[-90#3] G5.1 X[1585#3+#5] Y[655#3+#6] I[-5#3] J[-106#3] G5.1 X[1307#3+#5] Y[180#3+#6] I[-69#3] J[-299#3] G5.1 X[795#3+#5] Y[4#3+#6] I[-209#3] J[-176#3] G5.1 X[313#3+#5] Y[176#3+#6] I[-271#3] J[0#3] G5.1 X[37#3+#5] Y[614#3+#6] I[-211#3] J[172#3] G5.1 X[12#3+#5] Y[807#3+#6] I[-21#3] J[82#3] G5.1 X[12#3+#5] Y[1016#3+#6] I[-4#3] J[86#3] G5.1 X[16#3+#5] Y[1221#3+#6] I[4#3] J[139#3] G5.1 X[29#3+#5] Y[1647#3+#6] I[0#3] J[335#3] G5.1 X[164#3+#5] Y[2007#3+#6] I[28#3] J[213#3] G5.1 X[721#3+#5] Y[2331#3+#6] I[217#3] J[299#3] G5.1 X[1393#3+#5] Y[2077#3+#6] I[418#3] J[28#3] G00 Z [#1+#7] G00 X [365#3+#5] Y [1520#3+#6] (moveto) G01 Z [0-#2+#7] F#4 G5.1 X[360#3+#5] Y[1212#3+#6] I[-5#3] J[-54#3] G5.1 X[373#3+#5] Y[721#3+#6] I[0#3] J[-417#3] G5.1 X[530#3+#5] Y[436#3+#6] I[28#3] J[-172#3] G5.1 X[831#3+#5] Y[328#3+#6] I[129#3] J[-112#3] G5.1 X[975#3+#5] Y[365#3+#6] I[54#3] J[0#3] G5.1 X[1253#3+#5] Y[811#3+#6] I[246#3] J[98#3] G01 X [1253#3+#5] Y [1126#3+#6] (lineto) G5.1 X[1225#3+#5] Y[1647#3+#6] I[0#3] J[398#3] G5.1 X[897#3+#5] Y[1995#3+#6] I[-70#3] J[295#3] G5.1 X[717#3+#5] Y[2003#3+#6] I[-123#3] J[24#3] G5.1 X[365#3+#5] Y[1520#3+#6] I[-324#3] J[-98#3] (symbol extents: X = 365 to 1393, Y = 1126 to 2077) (symbol advance: X = 1815, Y = 0) (start of symbol 1) (starting X offset: 1815) G00 Z [#1+#7] G00 X [2761#3+#5] Y [2236#3+#6] (moveto) G01 Z [0-#2+#7] F#4 G5.1 X[2802#3+#5] Y[1884#3+#6] I[41#3] J[-65#3] G01 X [2802#3+#5] Y [918#3+#6] (lineto) G5.1 X[2798#3+#5] Y[766#3+#6] I[0#3] J[-41#3] G5.1 X[2798#3+#5] Y[606#3+#6] I[-4#3] J[-98#3] G5.1 X[2962#3+#5] Y[332#3+#6] I[12#3] J[-217#3] G5.1 X[3105#3+#5] Y[315#3+#6] I[20#3] J[-4#3] G01 X [3212#3+#5] Y [307#3+#6] (lineto) G5.1 X[3404#3+#5] Y[193#3+#6] I[164#3] J[-16#3] G5.1 X[3392#3+#5] Y[94#3+#6] I[17#3] J[-58#3] G5.1 X[3265#3+#5] Y[12#3+#6] I[-33#3] J[-61#3] G5.1 X[2933#3+#5] Y[0#3+#6] I[-57#3] J[-12#3] G01 X [2352#3+#5] Y [0#3+#6] (lineto) G5.1 X[1938#3+#5] Y[8#3+#6] I[-295#3] J[0#3] G5.1 X[1852#3+#5] Y[53#3+#6] I[-49#3] J[4#3] G5.1 X[1819#3+#5] Y[143#3+#6] I[-37#3] J[41#3] G5.1 X[1962#3+#5] Y[295#3+#6] I[8#3] J[123#3] G5.1 X[2192#3+#5] Y[307#3+#6] I[58#3] J[12#3] G5.1 X[2261#3+#5] Y[319#3+#6] I[20#3] J[0#3] G5.1 X[2417#3+#5] Y[492#3+#6] I[119#3] J[46#3] G5.1 X[2438#3+#5] Y[733#3+#6] I[21#3] J[69#3] G01 X [2438#3+#5] Y [1094#3+#6] (lineto) G5.1 X[2425#3+#5] Y[1507#3+#6] I[0#3] J[364#3] G5.1 X[2327#3+#5] Y[1651#3+#6] I[-20#3] J[82#3] G5.1 X[2192#3+#5] Y[1831#3+#6] I[-135#3] J[110#3] G5.1 X[2433#3+#5] Y[2253#3+#6] I[0#3] J[192#3] G5.1 X[2597#3+#5] Y[2331#3+#6] I[82#3] J[78#3] G5.1 X[2761#3+#5] Y[2236#3+#6] I[107#3] J[0#3] (symbol extents: X = 2352 to 3212, Y = 0 to 2236) (symbol advance: X = 1741, Y = 0) (start of symbol 2) (starting X offset: 3556) G00 Z [#1+#7] G00 X [4994#3+#5] Y [1982#3+#6] (moveto) G01 Z [0-#2+#7] F#4 G5.1 X[5088#3+#5] Y[1573#3+#6] I[114#3] J[-180#3] G5.1 X[4949#3+#5] Y[1237#3+#6] I[-16#3] J[-201#3] G5.1 X[4650#3+#5] Y[1016#3+#6] I[-82#3] J[-90#3] G5.1 X[4375#3+#5] Y[852#3+#6] I[-140#3] J[-82#3] G5.1 X[4121#3+#5] Y[655#3+#6] I[-155#3] J[-98#3] G5.1 X[3998#3+#5] Y[446#3+#6] I[-123#3] J[-123#3] G5.1 X[4371#3+#5] Y[299#3+#6] I[0#3] J[-147#3] G01 X [4551#3+#5] Y [299#3+#6] (lineto) G5.1 X[4658#3+#5] Y[303#3+#6] I[-20#3] J[0#3] G5.1 X[4736#3+#5] Y[303#3+#6] I[0#3] J[0#3] G5.1 X[5104#3+#5] Y[205#3+#6] I[315#3] J[0#3] G5.1 X[5104#3+#5] Y[94#3+#6] I[29#3] J[-53#3] G5.1 X[4871#3+#5] Y[-4#3+#6] I[-45#3] J[-86#3] G5.1 X[4719#3+#5] Y[-4#3+#6] I[-58#3] J[-4#3] G5.1 X[4572#3+#5] Y[0#3+#6] I[-102#3] J[4#3] G01 X [3998#3+#5] Y [0#3+#6] (lineto) G5.1 X[3646#3+#5] Y[33#3+#6] I[-282#3] J[0#3] G5.1 X[3544#3+#5] Y[250#3+#6] I[-115#3] J[53#3] G5.1 X[4007#3+#5] Y[999#3+#6] I[37#3] J[450#3] G5.1 X[4285#3+#5] Y[1188#3+#6] I[127#3] J[91#3] G5.1 X[4568#3+#5] Y[1356#3+#6] I[57#3] J[37#3] G5.1 X[4740#3+#5] Y[1622#3+#6] I[164#3] J[123#3] G5.1 X[4649#3+#5] Y[1867#3+#6] I[8#3] J[139#3] G5.1 X[4408#3+#5] Y[1999#3+#6] I[-98#3] J[107#3] G5.1 X[4129#3+#5] Y[1946#3+#6] I[-156#3] J[24#3] G5.1 X[3978#3+#5] Y[1815#3+#6] I[-8#3] J[-4#3] G5.1 X[3810#3+#5] Y[1729#3+#6] I[-98#3] J[-86#3] G5.1 X[3728#3+#5] Y[1757#3+#6] I[-41#3] J[0#3] G5.1 X[3671#3+#5] Y[1905#3+#6] I[-74#3] J[53#3] G5.1 X[4064#3+#5] Y[2277#3+#6] I[37#3] J[229#3] G5.1 X[4244#3+#5] Y[2327#3+#6] I[110#3] J[45#3] G5.1 X[4994#3+#5] Y[1982#3+#6] I[512#3] J[32#3] (symbol extents: X = 3998 to 4994, Y = 0 to 1982) (symbol advance: X = 1753, Y = 0) (start of symbol 3) (starting X offset: 5309) G00 Z [#1+#7] G00 X [6206#3+#5] Y [2277#3+#6] (moveto) G01 Z [0-#2+#7] F#4 G5.1 X[6607#3+#5] Y[2003#3+#6] I[250#3] J[-69#3] G5.1 X[6759#3+#5] Y[1536#3+#6] I[152#3] J[-205#3] G5.1 X[6685#3+#5] Y[1217#3+#6] I[0#3] J[-197#3] G5.1 X[6587#3+#5] Y[1061#3+#6] I[-49#3] J[-78#3] (this line fails) G5.1 X[6554#3+#5] Y[885#3+#6] I[-45#3] J[-90#3] G5.1 X[6648#3+#5] Y[705#3+#6] I[4#3] J[-33#3] G5.1 X[6722#3+#5] Y[541#3+#6] I[45#3] J[-74#3] G5.1 X[6767#3+#5] Y[70#3+#6] I[45#3] J[-144#3] G5.1 X[6743#3+#5] Y[-344#3+#6] I[0#3] J[-275#3] G5.1 X[6587#3+#5] Y[-692#3+#6] I[-37#3] J[-209#3] G5.1 X[5964#3+#5] Y[-971#3+#6] I[-238#3] J[-279#3] G5.1 X[5399#3+#5] Y[-725#3+#6] I[-348#3] J[0#3] G5.1 X[5305#3+#5] Y[-537#3+#6] I[-94#3] J[107#3] G5.1 X[5346#3+#5] Y[-430#3+#6] I[0#3] J[62#3] G5.1 X[5448#3+#5] Y[-385#3+#6] I[41#3] J[45#3] G5.1 X[5612#3+#5] Y[-463#3+#6] I[62#3] J[0#3] G5.1 X[5760#3+#5] Y[-586#3+#6] I[74#3] J[-61#3] G5.1 X[6022#3+#5] Y[-647#3+#6] I[114#3] J[-65#3] G5.1 X[6165#3+#5] Y[-602#3+#6] I[53#3] J[0#3] G5.1 X[6390#3+#5] Y[-303#3+#6] I[172#3] J[82#3] G5.1 X[6423#3+#5] Y[86#3+#6] I[33#3] J[131#3] G5.1 X[6407#3+#5] Y[356#3+#6] I[0#3] J[193#3] G5.1 X[6288#3+#5] Y[594#3+#6] I[-25#3] J[123#3] G5.1 X[6149#3+#5] Y[692#3+#6] I[-45#3] J[53#3] G5.1 X[5973#3+#5] Y[762#3+#6] I[-135#3] J[45#3] G5.1 X[5854#3+#5] Y[893#3+#6] I[-107#3] J[53#3] G5.1 X[5973#3+#5] Y[1081#3+#6] I[-21#3] J[123#3] G5.1 X[6206#3+#5] Y[1167#3+#6] I[118#3] J[41#3] G5.1 X[6411#3+#5] Y[1540#3+#6] I[205#3] J[115#3] G5.1 X[6218#3+#5] Y[1917#3+#6] I[0#3] J[238#3] G5.1 X[5985#3+#5] Y[1991#3+#6] I[-102#3] J[74#3] G5.1 X[5706#3+#5] Y[1892#3+#6] I[-160#3] J[0#3] G5.1 X[5518#3+#5] Y[1737#3+#6] I[-61#3] J[-61#3] G5.1 X[5456#3+#5] Y[1724#3+#6] I[-33#3] J[-13#3] G5.1 X[5356#3+#5] Y[1763#3+#6] I[-57#3] J[0#3] G5.1 X[5313#3+#5] Y[1860#3+#6] I[-43#3] J[39#3] G5.1 X[5420#3+#5] Y[2064#3+#6] I[0#3] J[86#3] G5.1 X[5604#3+#5] Y[2212#3+#6] I[90#3] J[103#3] G5.1 X[5870#3+#5] Y[2306#3+#6] I[164#3] J[82#3] G5.1 X[6206#3+#5] Y[2277#3+#6] I[156#3] J[21#3]
G0 Z [#1+#7]
M9 (stop coolant) M5 (stop spindle)
G30 Z [#1+#7] (move in Z only to preset G30) G30 (move to preset G30) M30 (end program)
@maculata
That looks quite simple, you're not using any dynamic variables like #<_rpm>
, so you can pre-process the file to remove parameters.
I think this does the job:
#!/usr/bin/env python
import sys
import re
filename = sys.argv[1]
regex_paramset = re.compile(r'^#(?P<name>\w+)=(?P<value>[^\s\(]+)')
regex_expression = re.compile(r'\[(?P<exp>[^\]]+)\]')
regex_param = re.compile(r'#(?P<name>\w+)')
params = {}
with open(filename, 'r') as fh:
for line in fh:
# parameter set
match = regex_paramset.search(line)
if match:
params[match.group('name')] = float(match.group('value'))
sys.stdout.write("(%s)\n" % line.rstrip('\n'))
continue # don't print line
# evaluate expressions (with parameter substitution)
for match in reversed(list(regex_expression.finditer(line))):
exp_str = match.group('exp')
for m in reversed(list(regex_param.finditer(exp_str))):
exp_str = exp_str[:m.start()] + ("%g" % params[m.group('name')]) + exp_str[m.end():]
exp_result = eval(exp_str)
line = line[:match.start()] + ("%g" % exp_result) + line[match.end():]
sys.stdout.write(line)
so if the content you've pasted above is in a file called input.g
, we can create a pre-processed file called output.g
with:
./pre-process.py input.g > output.g
I haven't tested it, and it has limits, but it should do the trick for now as a workaround.
To clarify:
I agree with @maculata ; parameters should be deciphered by pygcode
interpreter where possible, and shouldn't need pre-processing.
Furthermore, the pre-processing done by the above script is something pygcode
should do, namely a new feature for pygcode-norm
I'm currently planning dialects for pygcode
, variables and expressions will be a part of that.
stuff to think about, mostly brain-storming
Variables in different Dialects
#<_rpm>
, #<_x>
)Expressions in different Dialects
{}
brackets as opposed to []
, (TODO: research)Line Processor Idea
Ideas welcome
Good day folks!
This is quite the conundrum.... And is why G-code files are not universal and cannot be shared across most machines. I program CNC machines in an industrial manufacturing environment, and this was very disappointing when I first learned it. Every machine controller can have different capabilities and can choose to interpret g-code files in it's own way. This is why your CAM software of choice requires a "Post" file to help it generate a G-code file that is compatible with your machine. Many times, the only way to utilize some features of the controller is to hand edit the G-code file yourself (or write your own plug-in for your CAM software). The machine I use at work uses an Osai 10 Series controller which interprets code differently than a Haas machine would, for example. It's easy for a hobbyist to assume that G-Code files are all interchangeable because most of them use the same software (Linux CNC or Mach 3) in their controllers, but this is not the case in the rest of the CNC world.
Basically, the "dialects" you speak of will be a configuration file of sorts to help pygcode emulate certain controllers, is that right? Or perhaps you could choose to emulate a LINUX CNC or MACH 3 based machine with the dialects being different post file configurations? I look forward to see how this goes!
This appears to be missing.... did I miss something? Thanks