Cleaned up G-code parser. Fixed dwell command. Fixes #184.
This commit is contained in:
parent
6136afe84c
commit
d1442a4900
|
@ -1038,6 +1038,11 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
||||||
self.export_gcode(filename, preamble=preamble, postamble=postamble)
|
self.export_gcode(filename, preamble=preamble, postamble=postamble)
|
||||||
|
|
||||||
def dwell_generator(self, lines):
|
def dwell_generator(self, lines):
|
||||||
|
"""
|
||||||
|
Inserts "G4 P..." instructions after spindle-start
|
||||||
|
instructions (M03 or M04).
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
log.debug("dwell_generator()...")
|
log.debug("dwell_generator()...")
|
||||||
|
|
||||||
|
@ -1060,7 +1065,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
||||||
# If start spindle, buffer a G4.
|
# If start spindle, buffer a G4.
|
||||||
if m3m4re.search(line):
|
if m3m4re.search(line):
|
||||||
log.debug("Found M03/4")
|
log.debug("Found M03/4")
|
||||||
bufline = "G4 {}\n".format(self.options['dwelltime'])
|
bufline = "G4 P{}\n".format(self.options['dwelltime'])
|
||||||
|
|
||||||
yield line
|
yield line
|
||||||
|
|
||||||
|
@ -1070,10 +1075,13 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
||||||
|
|
||||||
lines = StringIO(self.gcode)
|
lines = StringIO(self.gcode)
|
||||||
|
|
||||||
|
## Post processing
|
||||||
|
# Dwell?
|
||||||
if self.options['dwell']:
|
if self.options['dwell']:
|
||||||
log.debug("Will add G04!")
|
log.debug("Will add G04!")
|
||||||
lines = self.dwell_generator(lines)
|
lines = self.dwell_generator(lines)
|
||||||
|
|
||||||
|
## Write
|
||||||
with open(filename, 'w') as f:
|
with open(filename, 'w') as f:
|
||||||
f.write(preamble + "\n")
|
f.write(preamble + "\n")
|
||||||
|
|
||||||
|
|
82
camlib.py
82
camlib.py
|
@ -9,6 +9,7 @@
|
||||||
#from scipy import optimize
|
#from scipy import optimize
|
||||||
#import traceback
|
#import traceback
|
||||||
|
|
||||||
|
from cStringIO import StringIO
|
||||||
from numpy import arctan2, Inf, array, sqrt, pi, ceil, sin, cos, dot, float32, \
|
from numpy import arctan2, Inf, array, sqrt, pi, ceil, sin, cos, dot, float32, \
|
||||||
transpose
|
transpose
|
||||||
from numpy.linalg import solve, norm
|
from numpy.linalg import solve, norm
|
||||||
|
@ -3024,67 +3025,25 @@ class CNCjob(Geometry):
|
||||||
self.gcode += "G00 X0Y0\n"
|
self.gcode += "G00 X0Y0\n"
|
||||||
self.gcode += "M05\n" # Spindle stop
|
self.gcode += "M05\n" # Spindle stop
|
||||||
|
|
||||||
def pre_parse(self, gtext):
|
@staticmethod
|
||||||
|
def codes_split(gline):
|
||||||
"""
|
"""
|
||||||
Separates parts of the G-Code text into a list of dictionaries.
|
Parses a line of G-Code such as "G01 X1234 Y987" into
|
||||||
Used by ``self.gcode_parse()``.
|
a dictionary: {'G': 1.0, 'X': 1234.0, 'Y': 987.0}
|
||||||
|
|
||||||
:param gtext: A single string with g-code
|
:param gline: G-Code line string
|
||||||
|
:return: Dictionary with parsed line.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
log.debug("pre_parse()")
|
command = {}
|
||||||
|
|
||||||
# Units: G20-inches, G21-mm
|
match = re.search(r'^\s*([A-Z])\s*([\+\-\.\d\s]+)', gline)
|
||||||
units_re = re.compile(r'^G2([01])')
|
while match:
|
||||||
|
command[match.group(1)] = float(match.group(2).replace(" ", ""))
|
||||||
|
gline = gline[match.end():]
|
||||||
|
match = re.search(r'^\s*([A-Z])\s*([\+\-\.\d\s]+)', gline)
|
||||||
|
|
||||||
# TODO: This has to be re-done
|
return command
|
||||||
gcmds = []
|
|
||||||
lines = gtext.split("\n") # TODO: This is probably a lot of work!
|
|
||||||
for line in lines:
|
|
||||||
# Clean up
|
|
||||||
line = line.strip()
|
|
||||||
|
|
||||||
# Remove comments
|
|
||||||
# NOTE: Limited to 1 bracket pair
|
|
||||||
op = line.find("(")
|
|
||||||
cl = line.find(")")
|
|
||||||
#if op > -1 and cl > op:
|
|
||||||
if cl > op > -1:
|
|
||||||
#comment = line[op+1:cl]
|
|
||||||
line = line[:op] + line[(cl+1):]
|
|
||||||
|
|
||||||
# Units
|
|
||||||
match = units_re.match(line)
|
|
||||||
if match:
|
|
||||||
self.units = {'0': "IN", '1': "MM"}[match.group(1)]
|
|
||||||
|
|
||||||
# Parse GCode
|
|
||||||
# 0 4 12
|
|
||||||
# G01 X-0.007 Y-0.057
|
|
||||||
# --> codes_idx = [0, 4, 12]
|
|
||||||
codes = "NMGXYZIJFPST"
|
|
||||||
codes_idx = []
|
|
||||||
i = 0
|
|
||||||
for ch in line:
|
|
||||||
if ch in codes:
|
|
||||||
codes_idx.append(i)
|
|
||||||
i += 1
|
|
||||||
n_codes = len(codes_idx)
|
|
||||||
if n_codes == 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Separate codes in line
|
|
||||||
parts = []
|
|
||||||
for p in range(n_codes - 1):
|
|
||||||
parts.append(line[codes_idx[p]:codes_idx[p+1]].strip())
|
|
||||||
parts.append(line[codes_idx[-1]:].strip())
|
|
||||||
|
|
||||||
# Separate codes from values
|
|
||||||
cmds = {}
|
|
||||||
for part in parts:
|
|
||||||
cmds[part[0]] = float(part[1:])
|
|
||||||
gcmds.append(cmds)
|
|
||||||
return gcmds
|
|
||||||
|
|
||||||
def gcode_parse(self):
|
def gcode_parse(self):
|
||||||
"""
|
"""
|
||||||
|
@ -3098,10 +3057,6 @@ class CNCjob(Geometry):
|
||||||
# Results go here
|
# Results go here
|
||||||
geometry = []
|
geometry = []
|
||||||
|
|
||||||
# TODO: Merge into single parser?
|
|
||||||
gobjs = self.pre_parse(self.gcode)
|
|
||||||
|
|
||||||
log.debug("gcode_parse(): pre_parse() done.")
|
|
||||||
# Last known instruction
|
# Last known instruction
|
||||||
current = {'X': 0.0, 'Y': 0.0, 'Z': 0.0, 'G': 0}
|
current = {'X': 0.0, 'Y': 0.0, 'Z': 0.0, 'G': 0}
|
||||||
|
|
||||||
|
@ -3110,7 +3065,14 @@ class CNCjob(Geometry):
|
||||||
path = [(0, 0)]
|
path = [(0, 0)]
|
||||||
|
|
||||||
# Process every instruction
|
# Process every instruction
|
||||||
for gobj in gobjs:
|
for line in StringIO(self.gcode):
|
||||||
|
|
||||||
|
gobj = self.codes_split(line)
|
||||||
|
|
||||||
|
## Units
|
||||||
|
if 'G' in gobj and (gobj['G'] == 20.0 or gobj['G'] == 21.0):
|
||||||
|
self.units = {20.0: "IN", 21.0: "MM"}[gobj['G']]
|
||||||
|
continue
|
||||||
|
|
||||||
## Changing height
|
## Changing height
|
||||||
if 'Z' in gobj:
|
if 'Z' in gobj:
|
||||||
|
|
Loading…
Reference in New Issue