mirror of
https://git.mirrors.martin98.com/https://github.com/petaflot/pygcode
synced 2025-08-12 02:19:02 +08:00
updates to support more varied file formats
This commit is contained in:
parent
209ee305ea
commit
21fb37293c
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -1,6 +1,6 @@
|
||||
( Colt )
|
||||
N100G00G21G17G90G40G49G80
|
||||
N110G71G91.1
|
||||
N110G91.1
|
||||
N120T1M06
|
||||
N130(ENGRAVING - 20 DEG TIP 0.1)
|
||||
N140G00G43Z6H1
|
||||
|
@ -5,7 +5,7 @@
|
||||
( T1 = End Mill 4 mm )
|
||||
()
|
||||
N100G00G21G17G90G40G49G80
|
||||
N110G71G91.1
|
||||
N110G91.1
|
||||
N120T1M06
|
||||
N130
|
||||
N140G00G43Z6.001H1
|
||||
|
@ -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)
|
||||
(****DB 25 Pin****)
|
||||
M6 T7(TOOL DIA. 3)
|
||||
@ -12,7 +12,7 @@ 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
|
||||
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
|
||||
@ -39,7 +39,7 @@ 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
|
||||
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
|
||||
@ -66,7 +66,7 @@ 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
|
||||
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
|
||||
|
@ -1,6 +1,6 @@
|
||||
(Tweakie.CNC)
|
||||
G00G21G17G90G40G49G80
|
||||
G71G91.1
|
||||
G91.1
|
||||
T1M06
|
||||
G00G43Z10H1
|
||||
S12000M03
|
||||
|
@ -1,6 +1,6 @@
|
||||
( Horse )
|
||||
N100G00G21G17G90G40G49G80
|
||||
N110G71G91.1
|
||||
N110G91.1
|
||||
N120T1M06
|
||||
N130(ENGRAVING - 20 DEG TIP 0.1)
|
||||
N140G00G43Z6H1
|
||||
|
@ -1,6 +1,6 @@
|
||||
( Horse2 )
|
||||
N100G00G21G17G90G40G49G80
|
||||
N110G71G91.1
|
||||
N110G91.1
|
||||
N120T1M06
|
||||
N130(ENGRAVING - 20 DEG TIP 0.1)
|
||||
N140G00G43Z6H1
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
G49 G40 G17 G80 G50 G90 G21
|
||||
G49 G40 G17 G80 G90 G21
|
||||
M04 S12000
|
||||
G90 G90.1
|
||||
G00 Z6
|
||||
|
@ -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
|
||||
|
@ -1,6 +1,6 @@
|
||||
( Snow White )
|
||||
N100G20G17G90G40G49G80
|
||||
N110G70G91.1
|
||||
N110G91.1
|
||||
N120T1M06
|
||||
N140G00G43Z0.5H1
|
||||
N150S12000M03
|
||||
|
@ -1,6 +1,6 @@
|
||||
(Tweakie.CNC)
|
||||
G00G21G17G90G40G49G80
|
||||
G71G91.1
|
||||
G91.1
|
||||
T1M06
|
||||
S12000M03
|
||||
G94 M63P1 F1016.0
|
||||
|
@ -5,29 +5,29 @@ 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
|
||||
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
|
||||
@ -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
|
||||
%
|
||||
|
@ -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
|
||||
|
@ -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>)
|
||||
|
@ -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
|
||||
|
@ -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', '.']
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user