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)
|
||||
|
||||
def dwell_generator(self, lines):
|
||||
"""
|
||||
Inserts "G4 P..." instructions after spindle-start
|
||||
instructions (M03 or M04).
|
||||
|
||||
"""
|
||||
|
||||
log.debug("dwell_generator()...")
|
||||
|
||||
|
@ -1060,7 +1065,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
# If start spindle, buffer a G4.
|
||||
if m3m4re.search(line):
|
||||
log.debug("Found M03/4")
|
||||
bufline = "G4 {}\n".format(self.options['dwelltime'])
|
||||
bufline = "G4 P{}\n".format(self.options['dwelltime'])
|
||||
|
||||
yield line
|
||||
|
||||
|
@ -1070,10 +1075,13 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
|
||||
lines = StringIO(self.gcode)
|
||||
|
||||
## Post processing
|
||||
# Dwell?
|
||||
if self.options['dwell']:
|
||||
log.debug("Will add G04!")
|
||||
lines = self.dwell_generator(lines)
|
||||
|
||||
## Write
|
||||
with open(filename, 'w') as f:
|
||||
f.write(preamble + "\n")
|
||||
|
||||
|
|
84
camlib.py
84
camlib.py
|
@ -9,6 +9,7 @@
|
|||
#from scipy import optimize
|
||||
#import traceback
|
||||
|
||||
from cStringIO import StringIO
|
||||
from numpy import arctan2, Inf, array, sqrt, pi, ceil, sin, cos, dot, float32, \
|
||||
transpose
|
||||
from numpy.linalg import solve, norm
|
||||
|
@ -3024,67 +3025,25 @@ class CNCjob(Geometry):
|
|||
self.gcode += "G00 X0Y0\n"
|
||||
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.
|
||||
Used by ``self.gcode_parse()``.
|
||||
Parses a line of G-Code such as "G01 X1234 Y987" into
|
||||
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
|
||||
units_re = re.compile(r'^G2([01])')
|
||||
match = re.search(r'^\s*([A-Z])\s*([\+\-\.\d\s]+)', gline)
|
||||
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
|
||||
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
|
||||
return command
|
||||
|
||||
def gcode_parse(self):
|
||||
"""
|
||||
|
@ -3097,11 +3056,7 @@ class CNCjob(Geometry):
|
|||
|
||||
# Results go here
|
||||
geometry = []
|
||||
|
||||
# TODO: Merge into single parser?
|
||||
gobjs = self.pre_parse(self.gcode)
|
||||
|
||||
log.debug("gcode_parse(): pre_parse() done.")
|
||||
# Last known instruction
|
||||
current = {'X': 0.0, 'Y': 0.0, 'Z': 0.0, 'G': 0}
|
||||
|
||||
|
@ -3110,7 +3065,14 @@ class CNCjob(Geometry):
|
|||
path = [(0, 0)]
|
||||
|
||||
# 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
|
||||
if 'Z' in gobj:
|
||||
|
@ -3154,7 +3116,7 @@ class CNCjob(Geometry):
|
|||
center = [gobj['I'] + current['X'], gobj['J'] + current['Y']]
|
||||
radius = sqrt(gobj['I']**2 + gobj['J']**2)
|
||||
start = arctan2(-gobj['J'], -gobj['I'])
|
||||
stop = arctan2(-center[1]+y, -center[0]+x)
|
||||
stop = arctan2(-center[1] + y, -center[0] + x)
|
||||
path += arc(center, radius, start, stop,
|
||||
arcdir[current['G']],
|
||||
self.steps_per_circ)
|
||||
|
|
Loading…
Reference in New Issue