updates to support more varied file formats

This commit is contained in:
Peter Boin 2017-08-22 15:02:48 +10:00
parent 209ee305ea
commit 21fb37293c
21 changed files with 217 additions and 149 deletions

View File

@ -341,6 +341,44 @@ class GCode(object):
pass
# ======================= Non Operational =======================
# CODE PARAMETERS DESCRIPTION
# N# Define line number (oldschool)
# O<name> Define program name
class GCodeDefinition(GCode):
pass
class GCodeLineNumber(GCodeDefinition):
"""N: Line Number"""
word_letter = 'N'
word_value_configurable = True
exec_order = 0
@classmethod
def word_matches(cls, w):
return w.letter == 'N'
@property
def number(self):
return self.word.value
class GCodeProgramName(GCodeDefinition):
"""O: Program Name"""
word_letter = 'O'
word_value_configurable = True
exec_order = 1
@classmethod
def word_matches(cls, w):
return w.letter == 'O'
@property
def name(self):
return self.word.value
# ======================= Motion =======================
# (X Y Z A B C U V W apply to all motions)
@ -360,7 +398,7 @@ class GCode(object):
class GCodeMotion(GCode):
param_letters = set('XYZABCUVW')
modal_group = MODAL_GROUP_MAP['motion']
exec_order = 241
exec_order = 242
def _process(self, machine):
machine.move_to(**self.get_param_dict(letters=machine.axes))
@ -474,6 +512,18 @@ class GCodeRigidTapping(GCodeMotion):
class GCodeCancelCannedCycle(GCodeMotion):
"""G80: Cancel Canned Cycle"""
word_key = Word('G', 80)
# Modal Group
# Technically G80 belongs to the motion modal group, however it's often
# expressed in the same line as another motion command.
# This is alowed, but executed just prior to any other motion command
# eg: G00 G80
# will leave the machine in rapid motion mode
# Just running G80 will leave machine with no motion mode.
modal_group = None
exec_order = 241
def _process(self, machine):
machine.mode.motion = None
# ======================= Canned Cycles =======================
@ -490,7 +540,7 @@ class GCodeCancelCannedCycle(GCodeMotion):
class GCodeCannedCycle(GCode):
param_letters = set('XYZUVW')
modal_group = MODAL_GROUP_MAP['motion']
exec_order = 241
exec_order = 242
def _process(self, machine):
moveto_coords = self.get_param_dict(letters=machine.axes)
@ -1390,7 +1440,7 @@ def word_gcode_class(word, exhaustive=False):
build_maps()
# quickly eliminate parameters
if (not exhaustive) and (word.letter not in 'GMFST'):
if (not exhaustive) and (word.letter not in 'GMFSTNO'):
return None
# by Word Map (faster)

View File

@ -410,20 +410,37 @@ class Machine(object):
if not modal_params:
return None
if self.mode.motion is None:
raise MachineInvalidState("unable to assign modal parameters when no motion mode is set")
params = copy(self.mode.motion.params) # dict
params.update(dict((w.letter, w) for w in modal_params)) # override retained modal parameters
(modal_gcodes, unasigned_words) = words2gcodes(
[self.mode.motion.word] + list(params.values())
)
unasigned_words = modal_params
# forces exception to be raised in next step
else:
params = copy(self.mode.motion.params) # dict
params.update(dict((w.letter, w) for w in modal_params)) # override retained modal parameters
(modal_gcodes, unasigned_words) = words2gcodes(
[self.mode.motion.word] + list(params.values())
)
if unasigned_words:
raise MachineInvalidState("modal parameters '%s' cannot be assigned when in mode: %r" % (
' '.join(str(x) for x in unasigned_words), self.mode
))
# Can't process with unknown words on the same line...
# raising: MachineInvalidState
plausable_codes = [w for w in unasigned_words if w.letter in set('GM')]
if plausable_codes:
# words in list are probably valid, but unsupported, G-Codes
# raise exception with a more helpfull message
raise MachineInvalidState("unsupported gcode(s): '%s' (machine mode: %r)" % (
' '.join(str(x) for x in unasigned_words), self.mode
))
else:
# words don't look like gcodes, assuming they're misplaced motion parameters
raise MachineInvalidState("modal parameters '%s' cannot be assigned when in mode: %r" % (
' '.join(str(x) for x in unasigned_words), self.mode
))
if modal_gcodes:
assert len(modal_gcodes) == 1, "more than 1 modal code found"
return modal_gcodes[0]
return None
def block_modal_gcodes(self, block):

View File

@ -4,10 +4,10 @@ import six
from .exceptions import GCodeBlockFormatError, GCodeWordStrError
REGEX_FLOAT = re.compile(r'^-?(\d+\.?\d*|\.\d+)') # testcase: ..tests.test_words.WordValueMatchTests.test_float
REGEX_INT = re.compile(r'^-?\d+')
REGEX_POSITIVEINT = re.compile(r'^\d+')
REGEX_CODE = re.compile(r'^\d+(\.\d)?') # similar
REGEX_FLOAT = re.compile(r'^\s*-?(\d+\.?\d*|\.\d+)') # testcase: ..tests.test_words.WordValueMatchTests.test_float
REGEX_INT = re.compile(r'^\s*-?\d+')
REGEX_POSITIVEINT = re.compile(r'^\s*\d+')
REGEX_CODE = re.compile(r'^\s*\d+(\.\d)?') # float, but can't be negative
# Value cleaning functions
def _clean_codestr(value):

View File

@ -1,6 +1,6 @@
( CHUCKS DEER{3} 7 X 5 )
N100G00G20G17G90G40G49G80
N110G70G91.1
N110G91.1
N120T1M06
N130(TOOL: V-BIT {90 DEG 0.5"})
N140G00G43Z0.8H1

View File

@ -1,8 +1,8 @@
(Code by Newfangled Wizard, 15/01/2017)
(Version 2.86)
(Program Posted for Aluminum )
G0 G49 G40.1 G17
G80 G50 G90 G98
G0 G49 G17
G80 G90 G98
G21 (mm)
(***** Circular Pocket *****)
(Xcen=0 Ycen=0 Dia=10)
@ -40,4 +40,4 @@ Y-1.5 X1.5 R1.5
G00 Z2
M5 M9
M30
%
%

View File

@ -1,6 +1,6 @@
( Colt )
N100G00G21G17G90G40G49G80
N110G71G91.1
N110G91.1
N120T1M06
N130(ENGRAVING - 20 DEG TIP 0.1)
N140G00G43Z6H1

View File

@ -5,7 +5,7 @@
( T1 = End Mill 4 mm )
()
N100G00G21G17G90G40G49G80
N110G71G91.1
N110G91.1
N120T1M06
N130
N140G00G43Z6.001H1

View File

@ -1,95 +1,95 @@
(Code by Newfangled Wizard, 15/01/2017)
(Version 2.86)
(Program Posted for Aluminum )
G0 G49 G40.1 G17
G80 G50 G90 G98
G0 G49 G17
G80 G90 G98
G21 (mm)
(****DB 25 Pin****)
M6 T7(TOOL DIA. 3)
G43 H7
M03 S4000
M7 (Mist On)
G0 X18.6665 Y-3.1674
X18.6665 Y-3.1674 Z2
G1 X18.6665 Y-3.1674 Z-1 F39.6
G41 P1.5 X20.4013 Y-3.9116 F79.2
G3 X21.0007 Y-2.3038 R2.46126
G1 X21.0007 Y-1.6002
X23.3959 Y-1.6002
G3 X24.9961 Y0 R1.6002
X23.3959 Y1.6002 R1.6002
G1 X21.0007 Y1.6002
X21.0007 Y2.3241
G3 X17.8257 Y5.4991 R3.175
G1 X-17.8257 Y5.4991
G3 X-21.0007 Y2.3241 R3.175
G1 X-21.0007 Y1.6002
X-23.3959 Y1.6002
G3 X-24.9961 Y0 R1.6002
X-23.3959 Y-1.6002 R1.6002
G1 X-21.0007 Y-1.6002
X-21.0007 Y-2.3241
G3 X-17.8257 Y-5.4991 R3.175
G1 X17.8257 Y-5.4991
G3 X21.0007 Y-2.3241 R3.175
G1 X21.0007 Y-1.6002
G3 X21.8491 Y-0.7772 R1.69672
G1 G40 X20.4241 Y-0.0178
G0 X20.4241 Y-0.0178 Z2
G0 X18.6665 Y-3.1674
X18.6665 Y-3.1674 Z2
G1 X18.6665 Y-3.1674 Z-2 F39.6
G41 P1.5 X20.4013 Y-3.9116 F79.2
G3 X21.0007 Y-2.3038 R2.46126
G1 X21.0007 Y-1.6002
X23.3959 Y-1.6002
G3 X24.9961 Y0 R1.6002
X23.3959 Y1.6002 R1.6002
G1 X21.0007 Y1.6002
X21.0007 Y2.3241
G3 X17.8257 Y5.4991 R3.175
G1 X-17.8257 Y5.4991
G3 X-21.0007 Y2.3241 R3.175
G1 X-21.0007 Y1.6002
X-23.3959 Y1.6002
G3 X-24.9961 Y0 R1.6002
X-23.3959 Y-1.6002 R1.6002
G1 X-21.0007 Y-1.6002
X-21.0007 Y-2.3241
G3 X-17.8257 Y-5.4991 R3.175
G1 X17.8257 Y-5.4991
G3 X21.0007 Y-2.3241 R3.175
G1 X21.0007 Y-1.6002
G3 X21.8491 Y-0.7772 R1.69672
G1 G40 X20.4241 Y-0.0178
G0 X20.4241 Y-0.0178 Z2
G0 X18.6665 Y-3.1674
X18.6665 Y-3.1674 Z2
G1 X18.6665 Y-3.1674 Z-3 F39.6
G41 P1.5 X20.4013 Y-3.9116 F79.2
G3 X21.0007 Y-2.3038 R2.46126
G1 X21.0007 Y-1.6002
X23.3959 Y-1.6002
G3 X24.9961 Y0 R1.6002
X23.3959 Y1.6002 R1.6002
G1 X21.0007 Y1.6002
X21.0007 Y2.3241
G3 X17.8257 Y5.4991 R3.175
G1 X-17.8257 Y5.4991
G3 X-21.0007 Y2.3241 R3.175
G1 X-21.0007 Y1.6002
X-23.3959 Y1.6002
G3 X-24.9961 Y0 R1.6002
X-23.3959 Y-1.6002 R1.6002
G1 X-21.0007 Y-1.6002
X-21.0007 Y-2.3241
G3 X-17.8257 Y-5.4991 R3.175
G1 X17.8257 Y-5.4991
G3 X21.0007 Y-2.3241 R3.175
G1 X21.0007 Y-1.6002
G3 X21.8491 Y-0.7772 R1.69672
G1 G40 X20.4241 Y-0.0178
G0 X20.4241 Y-0.0178 Z2
G0 X18.6665 Y-3.1674
X18.6665 Y-3.1674 Z2
G1 X18.6665 Y-3.1674 Z-1 F39.6
G41 D1.5 X20.4013 Y-3.9116 F79.2
G3 X21.0007 Y-2.3038 R2.46126
G1 X21.0007 Y-1.6002
X23.3959 Y-1.6002
G3 X24.9961 Y0 R1.6002
X23.3959 Y1.6002 R1.6002
G1 X21.0007 Y1.6002
X21.0007 Y2.3241
G3 X17.8257 Y5.4991 R3.175
G1 X-17.8257 Y5.4991
G3 X-21.0007 Y2.3241 R3.175
G1 X-21.0007 Y1.6002
X-23.3959 Y1.6002
G3 X-24.9961 Y0 R1.6002
X-23.3959 Y-1.6002 R1.6002
G1 X-21.0007 Y-1.6002
X-21.0007 Y-2.3241
G3 X-17.8257 Y-5.4991 R3.175
G1 X17.8257 Y-5.4991
G3 X21.0007 Y-2.3241 R3.175
G1 X21.0007 Y-1.6002
G3 X21.8491 Y-0.7772 R1.69672
G1 G40 X20.4241 Y-0.0178
G0 X20.4241 Y-0.0178 Z2
G0 X18.6665 Y-3.1674
X18.6665 Y-3.1674 Z2
G1 X18.6665 Y-3.1674 Z-2 F39.6
G41 D1.5 X20.4013 Y-3.9116 F79.2
G3 X21.0007 Y-2.3038 R2.46126
G1 X21.0007 Y-1.6002
X23.3959 Y-1.6002
G3 X24.9961 Y0 R1.6002
X23.3959 Y1.6002 R1.6002
G1 X21.0007 Y1.6002
X21.0007 Y2.3241
G3 X17.8257 Y5.4991 R3.175
G1 X-17.8257 Y5.4991
G3 X-21.0007 Y2.3241 R3.175
G1 X-21.0007 Y1.6002
X-23.3959 Y1.6002
G3 X-24.9961 Y0 R1.6002
X-23.3959 Y-1.6002 R1.6002
G1 X-21.0007 Y-1.6002
X-21.0007 Y-2.3241
G3 X-17.8257 Y-5.4991 R3.175
G1 X17.8257 Y-5.4991
G3 X21.0007 Y-2.3241 R3.175
G1 X21.0007 Y-1.6002
G3 X21.8491 Y-0.7772 R1.69672
G1 G40 X20.4241 Y-0.0178
G0 X20.4241 Y-0.0178 Z2
G0 X18.6665 Y-3.1674
X18.6665 Y-3.1674 Z2
G1 X18.6665 Y-3.1674 Z-3 F39.6
G41 D1.5 X20.4013 Y-3.9116 F79.2
G3 X21.0007 Y-2.3038 R2.46126
G1 X21.0007 Y-1.6002
X23.3959 Y-1.6002
G3 X24.9961 Y0 R1.6002
X23.3959 Y1.6002 R1.6002
G1 X21.0007 Y1.6002
X21.0007 Y2.3241
G3 X17.8257 Y5.4991 R3.175
G1 X-17.8257 Y5.4991
G3 X-21.0007 Y2.3241 R3.175
G1 X-21.0007 Y1.6002
X-23.3959 Y1.6002
G3 X-24.9961 Y0 R1.6002
X-23.3959 Y-1.6002 R1.6002
G1 X-21.0007 Y-1.6002
X-21.0007 Y-2.3241
G3 X-17.8257 Y-5.4991 R3.175
G1 X17.8257 Y-5.4991
G3 X21.0007 Y-2.3241 R3.175
G1 X21.0007 Y-1.6002
G3 X21.8491 Y-0.7772 R1.69672
G1 G40 X20.4241 Y-0.0178
G0 X20.4241 Y-0.0178 Z2
M5 M9
M30
%

View File

@ -1,6 +1,6 @@
(Tweakie.CNC)
G00G21G17G90G40G49G80
G71G91.1
G91.1
T1M06
G00G43Z10H1
S12000M03

View File

@ -1,6 +1,6 @@
( Horse )
N100G00G21G17G90G40G49G80
N110G71G91.1
N110G91.1
N120T1M06
N130(ENGRAVING - 20 DEG TIP 0.1)
N140G00G43Z6H1

View File

@ -1,6 +1,6 @@
( Horse2 )
N100G00G21G17G90G40G49G80
N110G71G91.1
N110G91.1
N120T1M06
N130(ENGRAVING - 20 DEG TIP 0.1)
N140G00G43Z6H1

View File

@ -1,4 +1,4 @@
G00 G49 G40 G17 G80 G50 G90 G21
G00 G49 G40 G17 G80 G90 G21
M04 S12000
G90 G90.1
G00 Z6
@ -72,4 +72,4 @@ G00 Z6
G00 X0 Y0
M05
M30
%
%

View File

@ -1,4 +1,4 @@
G49 G40 G17 G80 G50 G90 G21
G49 G40 G17 G80 G90 G21
M04 S12000
G90 G90.1
G00 Z6
@ -65,4 +65,4 @@ G00 Z6
G00 X0 Y0
M05
M30
%
%

View File

@ -3,7 +3,7 @@
( X= 89.500, Y= 120.000 )
( TOOL=ENGRAVE {20' 0.02" TIP DIA} )
N100G00G20G17G90G40G49G80
N110G71G91.1
N110G91.1
N120T1M06
N130
N140G00G43Z0.4H1

View File

@ -1,6 +1,6 @@
( Snow White )
N100G20G17G90G40G49G80
N110G70G91.1
N110G91.1
N120T1M06
N140G00G43Z0.5H1
N150S12000M03

View File

@ -1,6 +1,6 @@
(Tweakie.CNC)
G00G21G17G90G40G49G80
G71G91.1
G91.1
T1M06
S12000M03
G94 M63P1 F1016.0

View File

@ -5,30 +5,30 @@ G90.1 (set absolute distance mode for arc centers)
G17 (set active plane to XY)
G21 (set units to mm)
F600 (set feed-rate)
M10 P1 (turns laser OFF)
(turns laser OFF)
G0 X 65.8393 Y 49.0906
M11 P1 (turns laser ON)
(turns laser ON)
G3 Y 61.7398 I 65.8393 J 55.4203
G3 Y 49.0906 I 65.8393 J 55.4101
M10 P1
G0 X 93.3399 Y 36.7792
M11 P1
G3 Y 42.2783 I 93.3399 J 39.5300
G3 Y 36.7792 I 93.3399 J 39.5300
M10 P1
G0 X 38.3388
M11 P1
G3 Y 42.2783 I 38.3388 J 39.5300
G3 Y 36.7792 I 38.3388 J 39.5300
M10 P1
G0 X 65.8393 Y 84.4093
M11 P1
G3 Y 89.9084 I 65.8393 J 87.1601
G3 Y 84.4093 I 65.8393 J 87.1601
M10 P1
G0 X 93.3399 Y 103.0402
M11 P1
G1 X 86.9010
G1 X 86.9010
G3 X 82.5094 Y 98.3285 I 86.9010 J 98.6384
G3 X 111.3409 Y 48.3895 I 148.3411 J 103.0402
G3 X 117.6198 Y 49.8297 I 113.8098 J 52.0294
@ -58,7 +58,7 @@ G2 X 37.0103 Y 114.7801 I 38.9306 J 110.8202
G2 X 94.6709 I 65.8393 J 55.4101
G2 X 96.5606 Y 108.6206 I 92.7506 J 110.8202
G1 X 93.3399 Y 103.0402
M10 P1
G0 X 0.0000 Y 0.0000
M30
%

View File

@ -1,54 +1,54 @@
G00G21G17G90G40G49G80
G71G91.1
G91.1
S12000M03
G94 M10P1 F600.0
G94 F600.0
X0.000Y0.000
G00X76.918Y-10.288M10P1
G1X76.918Y-10.288M11P1
G00X76.918Y-10.288
G1X76.918Y-10.288
G1X83.317Y-10.288
G1X83.317Y-14.187
G1X76.918Y-14.187
G1X76.918Y-10.288
G00X76.918Y-10.288M10P1
G00X76.918Y-10.288
G00X98.918Y-10.288
G1X98.918Y-10.288M11P1
G1X98.918Y-10.288
G1X105.317Y-10.288
G1X105.317Y-14.187
G1X98.918Y-14.187
G1X98.918Y-10.288
G00X98.918Y-10.288M10P1
G00X98.918Y-10.288
G00X93.022Y5.812
G1X93.022Y5.812M11P1
G1X93.022Y5.812
G1X89.122Y5.812
G1X89.122Y13.712
G1X93.022Y13.712
G1X93.022Y5.812
G00X93.022Y5.812M10P1
G00X93.022Y5.812
G00X-75.607Y-10.288
G1X-75.607Y-10.288M11P1
G1X-75.607Y-10.288
G1X-75.607Y-14.187
G1X-82.006Y-14.187
G1X-82.006Y-10.288
G1X-75.607Y-10.288
G00X-75.607Y-10.288M10P1
G00X-75.607Y-10.288
G00X-97.607Y-10.288
G1X-97.607Y-10.288M11P1
G1X-97.607Y-10.288
G1X-97.607Y-14.187
G1X-104.006Y-14.187
G1X-104.006Y-10.288
G1X-97.607Y-10.288
G00X-97.607Y-10.288M10P1
G00X-97.607Y-10.288
G00X-91.836Y5.812
G1X-91.836Y5.812M11P1
G1X-91.836Y5.812
G1X-91.836Y13.712
G1X-87.937Y13.712
G1X-87.937Y5.812
G1X-91.836Y5.812
G00X-91.836Y5.812M10P1
G00X-91.836Y5.812
G00X-15.556Y7.900
G1X-15.556Y7.900M11P1
G1X-15.556Y7.900
G2X-36.650Y9.539I13.488J310.094
G2X-49.156Y11.364I21.153J188.675
G2X-59.846Y13.733I24.394J135.416
@ -122,8 +122,8 @@ G2X54.729Y12.209I-26.464J81.059
G2X39.610Y9.752I-40.016J198.475
G2X21.814Y8.147I-32.998J266.303
G2X-15.556Y7.900I-21.148J372.705
G00X-15.556Y7.900M10P1
M10P1
G00X-15.556Y7.900
G00X0.000Y0.000
M09
M30

View File

@ -6,7 +6,6 @@ We can however still deal with these, workarounds shown below
## Unsupported GCodes
When attempting to process unsupported gcode(s) via a `Machine` the following error (or similar) will be raised
MachineInvalidState: unsupported gcode(s): 'P1 M10' (machine mode: <Mode: G00 G17 G90 G90.1 G94 G21 G40 G49 G54 G61 G97 M05 M09 F600 S0 T0>)

View File

@ -38,7 +38,7 @@ class GCodeModalGroupTests(unittest.TestCase):
table_rows += '''
Non-modal codes (Group 0) G4,G10,G28,G30,G53,G92,G92.1,G92.2,G92.3
Motion (Group 1) G0,G1,G2,G3,G33,G38.2,G38.3,G38.4
Motion (Group 1) G38.5,G73,G76,G80,G81,G82,G83,G85,G89
Motion (Group 1) G38.5,G73,G76,G81,G82,G83,G85,G89
Plane selection (Group 2) G17, G18, G19, G17.1, G18.1, G19.1
Distance Mode (Group 3) G90, G91
Arc IJK Distance Mode (Group 4) G90.1, G91.1

View File

@ -54,10 +54,11 @@ class WordValueMatchTests(unittest.TestCase):
('1.2', '1.2'), ('1', '1'), ('200', '200'), ('0092', '0092'),
('1.', '1.'), ('.2', '.2'), ('-1.234', '-1.234'),
('-1.', '-1.'), ('-.289', '-.289'),
(' 1.2', ' 1.2'), # leading whitespace
# error cases (only detectable in gcode context)
('1.2e3', '1.2'),
],
negative_list=['.', ' 1.2']
negative_list=['.']
)
def test_code(self):
@ -67,8 +68,9 @@ class WordValueMatchTests(unittest.TestCase):
('1.2', '1.2'), ('1', '1'), ('10', '10'),
('02', '02'), ('02.3', '02.3'),
('1.', '1'), ('03 ', '03'),
(' 2', ' 2'), # leading whitespace
# error cases (only detectable in gcode context)
('30.12', '30.1'),
],
negative_list=['.2', '.', ' 2']
negative_list=['.2', '.']
)