mirror of
https://git.mirrors.martin98.com/https://github.com/petaflot/pygcode
synced 2025-08-14 04:56:01 +08:00
gcodes sortable by linuxcnc execution order
This commit is contained in:
parent
3a5dec14f0
commit
cf5f9a17cd
@ -21,7 +21,32 @@ class Block(object):
|
||||
self.text = text
|
||||
|
||||
self.words = list(iter_words(self.text))
|
||||
self.gcodes = list(words_to_gcodes(self.words))
|
||||
(self.gcodes, self.modal_params) = words_to_gcodes(self.words)
|
||||
|
||||
self._assert_gcodes()
|
||||
|
||||
# TODO: gcode verification
|
||||
# - gcodes in the same modal_group raises exception
|
||||
|
||||
def _assert_gcodes(self):
|
||||
modal_groups = set()
|
||||
code_words = set()
|
||||
for gc in self.gcodes:
|
||||
# Assert all gcodes are not repeated in the same block
|
||||
if gc.word in code_words:
|
||||
raise AssertionError("%s cannot be in the same block" % ([
|
||||
x for x in self.gcodes
|
||||
if x.modal_group == gc.modal_group
|
||||
]))
|
||||
code_words.add(gc.word)
|
||||
# Assert all gcodes are from different modal groups
|
||||
if gc.modal_group is not None:
|
||||
if gc.modal_group in modal_groups:
|
||||
raise AssertionError("%s cannot be in the same block" % ([
|
||||
x for x in self.gcodes
|
||||
if x.modal_group == gc.modal_group
|
||||
]))
|
||||
modal_groups.add(gc.modal_group)
|
||||
|
||||
def __getattr__(self, k):
|
||||
if k in WORD_MAP:
|
||||
|
@ -64,6 +64,34 @@ from .words import Word
|
||||
# Override Switches (Group 9) M48, M49
|
||||
# User Defined (Group 10) M100-M199
|
||||
#
|
||||
# Execution Order
|
||||
# Order taken http://linuxcnc.org/docs/html/gcode/overview.html#_g_code_order_of_execution
|
||||
# (as of 2017-07-03)
|
||||
# 010: O-word commands (optionally followed by a comment but no other words allowed on the same line)
|
||||
# 020: Comment (including message)
|
||||
# 030: Set feed rate mode (G93, G94).
|
||||
# 040: Set feed rate (F).
|
||||
# 050: Set spindle speed (S).
|
||||
# 060: Select tool (T).
|
||||
# 070: HAL pin I/O (M62-M68).
|
||||
# 080: Change tool (M6) and Set Tool Number (M61).
|
||||
# 090: Spindle on or off (M3, M4, M5).
|
||||
# 100: Save State (M70, M73), Restore State (M72), Invalidate State (M71).
|
||||
# 110: Coolant on or off (M7, M8, M9).
|
||||
# 120: Enable or disable overrides (M48, M49,M50,M51,M52,M53).
|
||||
# 130: User-defined Commands (M100-M199).
|
||||
# 140: Dwell (G4).
|
||||
# 150: Set active plane (G17, G18, G19).
|
||||
# 160: Set length units (G20, G21).
|
||||
# 170: Cutter radius compensation on or off (G40, G41, G42)
|
||||
# 180: Cutter length compensation on or off (G43, G49)
|
||||
# 190: Coordinate system selection (G54, G55, G56, G57, G58, G59, G59.1, G59.2, G59.3).
|
||||
# 200: Set path control mode (G61, G61.1, G64)
|
||||
# 210: Set distance mode (G90, G91).
|
||||
# 220: Set retract mode (G98, G99).
|
||||
# 230: Go to reference location (G28, G30) or change coordinate system data (G10) or set axis offsets (G92, G92.1, G92.2, G94).
|
||||
# 240: Perform motion (G0 to G3, G33, G38.x, G73, G76, G80 to G89), as modified (possibly) by G53.
|
||||
# 250: Stop (M0, M1, M2, M30, M60).
|
||||
|
||||
|
||||
class GCode(object):
|
||||
@ -77,6 +105,9 @@ class GCode(object):
|
||||
# Modal Group
|
||||
modal_group = None
|
||||
|
||||
# Execution Order
|
||||
exec_order = 999 # if not otherwise specified, run last
|
||||
|
||||
def __init__(self, word, *params):
|
||||
assert isinstance(word, Word), "invalid gcode word %r" % code_word
|
||||
self.word = word
|
||||
@ -87,13 +118,16 @@ class GCode(object):
|
||||
self.add_parameter(param)
|
||||
|
||||
def __repr__(self):
|
||||
return "<{class_name}: {gcode}{{{word_list}}}>".format(
|
||||
class_name=self.__class__.__name__,
|
||||
gcode=self.word,
|
||||
word_list=', '.join([
|
||||
param_str = ''
|
||||
if self.params:
|
||||
param_str = "{%s}" % (', '.join([
|
||||
"{}".format(self.params[k])
|
||||
for k in sorted(self.params.keys())
|
||||
]),
|
||||
]))
|
||||
return "<{class_name}: {gcode}{params}>".format(
|
||||
class_name=self.__class__.__name__,
|
||||
gcode=self.word,
|
||||
params=param_str,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
@ -106,6 +140,10 @@ class GCode(object):
|
||||
]),
|
||||
)
|
||||
|
||||
# Sort by exec_order
|
||||
def __lt__(self, other):
|
||||
return self.exec_order < other.exec_order
|
||||
|
||||
def add_parameter(self, word):
|
||||
assert isinstance(word, Word), "invalid parameter class: %r" % word
|
||||
assert word.letter in self.param_letters, "invalid parameter for %s: %s" % (self.__class__.__name__, str(word))
|
||||
@ -113,6 +151,7 @@ class GCode(object):
|
||||
self.params[word.letter] = word
|
||||
|
||||
def __getattr__(self, key):
|
||||
# Return parameter values (if valid parameter for gcode)
|
||||
if key in self.param_letters:
|
||||
if key in self.params:
|
||||
return self.params[key].value
|
||||
@ -124,6 +163,10 @@ class GCode(object):
|
||||
key=key
|
||||
))
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
return self.__doc__
|
||||
|
||||
|
||||
# ======================= Motion =======================
|
||||
# (X Y Z A B C U V W apply to all motions)
|
||||
@ -143,7 +186,7 @@ class GCode(object):
|
||||
class GCodeMotion(GCode):
|
||||
param_letters = set('XYZABCUVW')
|
||||
modal_group = 1
|
||||
|
||||
exec_order = 241
|
||||
|
||||
class GCodeRapidMove(GCodeMotion):
|
||||
"""G0: Rapid Move"""
|
||||
@ -175,6 +218,7 @@ class GCodeDwell(GCodeMotion):
|
||||
param_letters = GCodeMotion.param_letters | set('P')
|
||||
word_key = Word('G', 4)
|
||||
modal_group = None # one of the few motion commands that isn't modal
|
||||
exec_order = 140
|
||||
|
||||
|
||||
class GCodeCublcSpline(GCodeMotion):
|
||||
@ -238,6 +282,7 @@ class GCodeCancelCannedCycle(GCodeMotion):
|
||||
class GCodeCannedCycle(GCode):
|
||||
param_letters = set('XYZUVW')
|
||||
modal_group = 1
|
||||
exec_order = 241
|
||||
|
||||
class GCodeDrillingCycle(GCodeCannedCycle):
|
||||
"""G81: Drilling Cycle"""
|
||||
@ -289,7 +334,7 @@ class GCodeThreadingCycle(GCodeCannedCycle):
|
||||
# G8 Lathe Radius Mode
|
||||
|
||||
class GCodeDistanceMode(GCode):
|
||||
pass
|
||||
exec_order = 210
|
||||
|
||||
|
||||
class GCodeAbsoluteDistanceMode(GCodeDistanceMode):
|
||||
@ -333,7 +378,7 @@ class GCodeLatheRadiusMode(GCodeDistanceMode):
|
||||
|
||||
class GCodeFeedRateMode(GCode):
|
||||
modal_group = 5
|
||||
|
||||
exec_order = 30
|
||||
|
||||
class GCodeInverseTimeMode(GCodeFeedRateMode):
|
||||
"""G93: Inverse Time Mode"""
|
||||
@ -357,25 +402,25 @@ class GCodeUnitsPerRevolution(GCodeFeedRateMode):
|
||||
# G96, G97 S D Spindle Control Mode
|
||||
|
||||
class GCodeSpindle(GCode):
|
||||
pass
|
||||
exec_order = 90
|
||||
|
||||
|
||||
class GCodeStartSpindleCW(GCodeSpindle):
|
||||
"""M3: Start Spindle Clockwise"""
|
||||
param_letters = set('S')
|
||||
#param_letters = set('S') # S is it's own gcode, makes no sense to be here
|
||||
word_key = Word('M', 3)
|
||||
modal_group = 7
|
||||
|
||||
class GCodeStartSpindleCCW(GCodeSpindle):
|
||||
"""M4: Start Spindle Counter-Clockwise"""
|
||||
param_letters = set('S')
|
||||
#param_letters = set('S') # S is it's own gcode, makes no sense to be here
|
||||
word_key = Word('M', 4)
|
||||
modal_group = 7
|
||||
|
||||
|
||||
class GCodeStopSpindle(GCodeSpindle):
|
||||
"""M5: Stop Spindle"""
|
||||
param_letters = set('S')
|
||||
#param_letters = set('S') # S is it's own gcode, makes no sense to be here
|
||||
word_key = Word('M', 5)
|
||||
modal_group = 7
|
||||
|
||||
@ -406,6 +451,7 @@ class GCodeSpindleRPMMode(GCodeSpindle):
|
||||
|
||||
class GCodeCoolant(GCode):
|
||||
modal_group = 8
|
||||
exec_order = 110
|
||||
|
||||
|
||||
class GCodeCoolantMistOn(GCodeCoolant):
|
||||
@ -432,6 +478,7 @@ class GCodeCoolantOff(GCodeCoolant):
|
||||
|
||||
class GCodeToolLength(GCode):
|
||||
modal_group = 8
|
||||
exec_order = 180
|
||||
|
||||
|
||||
class GCodeToolLengthOffset(GCodeToolLength):
|
||||
@ -464,7 +511,7 @@ class GCodeCancelToolLengthOffset(GCodeToolLength):
|
||||
|
||||
class GCodeProgramControl(GCode):
|
||||
modal_group = 4
|
||||
|
||||
exec_order = 250
|
||||
|
||||
class GCodePauseProgram(GCodeProgramControl):
|
||||
"""M0: Program Pause"""
|
||||
@ -497,6 +544,7 @@ class GCodePalletChangePause(GCodeProgramControl):
|
||||
|
||||
class GCodeUnit(GCode):
|
||||
modal_group = 6
|
||||
exec_order = 160
|
||||
|
||||
|
||||
class GCodeUseInches(GCodeUnit):
|
||||
@ -516,6 +564,7 @@ class GCodeUseMillimeters(GCodeUnit):
|
||||
|
||||
class GCodePlaneSelect(GCode):
|
||||
modal_group = 2
|
||||
exec_order = 150
|
||||
|
||||
|
||||
class GCodeSelectZYPlane(GCodePlaneSelect):
|
||||
@ -556,6 +605,7 @@ class GCodeSelectVWPlane(GCodePlaneSelect):
|
||||
|
||||
class GCodeCutterRadiusComp(GCode):
|
||||
modal_group = 7
|
||||
exec_order = 170
|
||||
|
||||
|
||||
class GCodeCutterRadiusCompOff(GCodeCutterRadiusComp):
|
||||
@ -594,6 +644,7 @@ class GCodeDynamicCutterCompRight(GCodeCutterRadiusComp):
|
||||
|
||||
class GCodePathControlMode(GCode):
|
||||
modal_group = 13
|
||||
exec_order = 200
|
||||
|
||||
|
||||
class GCodeExactPathMode(GCodePathControlMode):
|
||||
@ -618,6 +669,7 @@ class GCodePathBlendingMode(GCodePathControlMode):
|
||||
|
||||
class GCodeCannedReturnMode(GCode):
|
||||
modal_group = 10
|
||||
exec_order = 220
|
||||
|
||||
|
||||
class GCodeCannedCycleReturnLevel(GCodeCannedReturnMode):
|
||||
@ -646,10 +698,12 @@ class GCodeFeedRate(GCodeOtherModal):
|
||||
@classmethod
|
||||
def word_matches(cls, w):
|
||||
return w.letter == 'F'
|
||||
# Modal Group n/a:
|
||||
# Modal Group :
|
||||
# although this sets the machine's state, there are no other codes to
|
||||
# group with this one, so although it's modal, it has no group.
|
||||
#modal_group = n/a
|
||||
# group with this one, so although it's modal, it usually has no group.
|
||||
# However,
|
||||
modal_group = 101
|
||||
exec_order = 40
|
||||
|
||||
|
||||
class GCodeSpindleSpeed(GCodeOtherModal):
|
||||
@ -657,10 +711,9 @@ class GCodeSpindleSpeed(GCodeOtherModal):
|
||||
@classmethod
|
||||
def word_matches(cls, w):
|
||||
return w.letter == 'S'
|
||||
# Modal Group n/a:
|
||||
# although this sets the machine's state, there are no other codes to
|
||||
# group with this one, so although it's modal, it has no group.
|
||||
#modal_group = n/a
|
||||
# Modal Group: (see description in GCodeFeedRate)
|
||||
modal_group = 102
|
||||
exec_order = 50
|
||||
|
||||
|
||||
class GCodeSelectTool(GCodeOtherModal):
|
||||
@ -668,46 +721,51 @@ class GCodeSelectTool(GCodeOtherModal):
|
||||
@classmethod
|
||||
def word_matches(cls, w):
|
||||
return w.letter == 'T'
|
||||
# Modal Group n/a:
|
||||
# although this sets the machine's state, there are no other codes to
|
||||
# group with this one, so although it's modal, it has no group.
|
||||
#modal_group = n/a
|
||||
# Modal Group: (see description in GCodeFeedRate)
|
||||
modal_group = 103
|
||||
exec_order = 60
|
||||
|
||||
|
||||
class GCodeSpeedAndFeedOverrideOn(GCodeOtherModal):
|
||||
"""M48: Speed and Feed Override Control On"""
|
||||
word_key = Word('M', 48)
|
||||
modal_group = 9
|
||||
exec_order = 120
|
||||
|
||||
|
||||
class GCodeSpeedAndFeedOverrideOff(GCodeOtherModal):
|
||||
"""M49: Speed and Feed Override Control Off"""
|
||||
word_key = Word('M', 49)
|
||||
modal_group = 9
|
||||
exec_order = 120
|
||||
|
||||
|
||||
class GCodeFeedOverride(GCodeOtherModal):
|
||||
"""M50: Feed Override Control"""
|
||||
param_letters = set('P')
|
||||
word_key = Word('M', 50)
|
||||
exec_order = 120
|
||||
|
||||
|
||||
class GCodeSpindleSpeedOverride(GCodeOtherModal):
|
||||
"""M51: Spindle Speed Override Control"""
|
||||
param_letters = set('P')
|
||||
word_key = Word('M', 51)
|
||||
exec_order = 120
|
||||
|
||||
|
||||
class GCodeAdaptiveFeed(GCodeOtherModal):
|
||||
"""M52: Adaptive Feed Control"""
|
||||
param_letters = set('P')
|
||||
word_key = Word('M', 52)
|
||||
exec_order = 120
|
||||
|
||||
|
||||
class GCodeFeedStop(GCodeOtherModal):
|
||||
"""M53: Feed Stop Control"""
|
||||
param_letters = set('P')
|
||||
word_key = Word('M', 53)
|
||||
exec_order = 120
|
||||
|
||||
|
||||
class GCodeSelectCoordinateSystem(GCodeOtherModal):
|
||||
@ -726,6 +784,7 @@ class GCodeSelectCoordinateSystem(GCodeOtherModal):
|
||||
def word_matches(cls, w):
|
||||
return (w.letter == 'G') and (w.value in [54, 55, 56, 57, 58, 59, 59.1, 59.2, 59.3])
|
||||
modal_group = 12
|
||||
exec_order = 190
|
||||
|
||||
|
||||
# ======================= Flow-control Codes =======================
|
||||
@ -750,7 +809,7 @@ class GCodeSelectCoordinateSystem(GCodeOtherModal):
|
||||
# M68 T Analog Output, Immediate
|
||||
|
||||
class GCodeIO(GCode):
|
||||
pass
|
||||
exec_order = 70
|
||||
|
||||
|
||||
class GCodeDigitalOutput(GCodeIO):
|
||||
@ -824,18 +883,21 @@ class GCodeToolChange(GCodeNonModal):
|
||||
"""M6: Tool Change"""
|
||||
param_letters = set('T')
|
||||
word_key = Word('M', 6)
|
||||
exec_order = 80
|
||||
|
||||
|
||||
class GCodeToolSetCurrent(GCodeNonModal):
|
||||
"""M61: Set Current Tool"""
|
||||
param_letters = set('Q')
|
||||
word_key = Word('M', 61)
|
||||
exec_order = 80
|
||||
|
||||
|
||||
class GCodeSet(GCodeNonModal):
|
||||
"""G10: Set stuff"""
|
||||
param_letters = set('LPQR')
|
||||
word_key = Word('G', 10)
|
||||
exec_order = 230
|
||||
|
||||
|
||||
class GCodeGotoPredefinedPosition(GCodeNonModal):
|
||||
@ -843,6 +905,7 @@ class GCodeGotoPredefinedPosition(GCodeNonModal):
|
||||
@classmethod
|
||||
def word_matches(cls, w):
|
||||
return (w.letter == 'G') and (w.value in [28, 30])
|
||||
exec_order = 230
|
||||
|
||||
|
||||
class GCodeSetPredefinedPosition(GCodeNonModal):
|
||||
@ -850,16 +913,19 @@ class GCodeSetPredefinedPosition(GCodeNonModal):
|
||||
@classmethod
|
||||
def word_matches(cls, w):
|
||||
return (w.letter == 'G') and (w.value in [28.1, 30.1])
|
||||
exec_order = 230
|
||||
|
||||
|
||||
class GCodeMoveInMachineCoords(GCodeNonModal):
|
||||
"""G53: Move in Machine Coordinates"""
|
||||
word_key = Word('G', 53)
|
||||
exec_order = 240
|
||||
|
||||
|
||||
class GCodeCoordSystemOffset(GCodeNonModal):
|
||||
"""G92: Coordinate System Offset"""
|
||||
word_key = Word('G', 92)
|
||||
exec_order = 230
|
||||
|
||||
|
||||
class GCodeResetCoordSystemOffset(GCodeNonModal):
|
||||
@ -867,11 +933,13 @@ class GCodeResetCoordSystemOffset(GCodeNonModal):
|
||||
@classmethod
|
||||
def word_matches(cls, w):
|
||||
return (w.letter == 'G') and (w.value in [92.1, 92.2])
|
||||
exec_order = 230
|
||||
|
||||
|
||||
class GCodeRestoreCoordSystemOffset(GCodeNonModal):
|
||||
"""G92.3: Restore Coordinate System Offset"""
|
||||
word_key = Word('G', 92.3)
|
||||
exec_order = 230
|
||||
|
||||
|
||||
class GCodeUserDefined(GCodeNonModal):
|
||||
@ -881,6 +949,7 @@ class GCodeUserDefined(GCodeNonModal):
|
||||
#@classmethod
|
||||
#def word_matches(cls, w):
|
||||
# return (w.letter == 'M') and (101 <= w.value <= 199)
|
||||
exec_order = 130
|
||||
|
||||
|
||||
# ======================= Utilities =======================
|
||||
|
@ -44,3 +44,27 @@ class AbstractMachine(object):
|
||||
def process_line(self, line):
|
||||
"""Change machine's state based on the given gcode line"""
|
||||
pass # TODO
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
class Axes(object):
|
||||
pass
|
||||
|
||||
class MyMachineState(MachineState):
|
||||
axes_state_class = AxesState
|
||||
pass
|
||||
|
||||
class MyMachine(AbstractMachine):
|
||||
available_axes = set('xyz')
|
||||
state_class = MyMachineState
|
||||
|
||||
|
||||
m = MyMachine(
|
||||
state=MyMachineState(
|
||||
absolute_position=
|
||||
),
|
||||
)
|
||||
|
||||
"""
|
||||
|
@ -4,12 +4,12 @@ import six
|
||||
|
||||
from .exceptions import GCodeBlockFormatError
|
||||
|
||||
|
||||
FLOAT_REGEX = re.compile(r'^-?(\d+\.?\d*|\.\d+)') # testcase: ..tests.test_words.WordValueMatchTests.test_float
|
||||
INT_REGEX = re.compile(r'^-?\d+')
|
||||
POSITIVEINT_REGEX = re.compile(r'^\d+')
|
||||
CODE_REGEX = re.compile(r'^\d+(\.\d)?') # similar
|
||||
|
||||
|
||||
WORD_MAP = {
|
||||
# Descriptions copied from wikipedia:
|
||||
# https://en.wikipedia.org/wiki/G-code#Letter_addresses
|
||||
@ -163,87 +163,6 @@ WORD_MAP = {
|
||||
}
|
||||
|
||||
|
||||
ORDER_LINUXCNC_LETTER_MAP = {
|
||||
'O': 10,
|
||||
'F': 40,
|
||||
'S': 50,
|
||||
'T': 60,
|
||||
}
|
||||
|
||||
_v_csv = lambda v, ks: [(k, v) for k in ks.split(',')]
|
||||
|
||||
ORDER_LINUXCNC_LETTERVALUE_MAP = dict(itertools.chain.from_iterable([
|
||||
_v_csv(30, 'G93,G94'),
|
||||
_v_csv(70, 'M62,M63,M64,M65,M66,M67,M68'),
|
||||
_v_csv(80, 'M6,M61'),
|
||||
_v_csv(90, 'M3,M4,M5'),
|
||||
_v_csv(100, 'M71,M73,M72,M71'),
|
||||
_v_csv(110, 'M7,M8,M9'),
|
||||
_v_csv(120, 'M48,M49,M50,M51,M52,M53'),
|
||||
[('G4', 140)],
|
||||
_v_csv(150, 'G17,G18,G19'),
|
||||
_v_csv(160, 'G20,G21'),
|
||||
_v_csv(170, 'G40,G41,G42'),
|
||||
_v_csv(180, 'G43,G49'),
|
||||
_v_csv(190, 'G54,G55,G56,G57,G58,G59,G59.1,G59.2,G59.3'),
|
||||
_v_csv(200, 'G61,G61.1,G64'),
|
||||
_v_csv(210, 'G90,G91'),
|
||||
_v_csv(220, 'G98,G99'),
|
||||
_v_csv(230, 'G28,G30,G10,G92,G92.1,G92.2,G94'),
|
||||
_v_csv(240, 'G0,G1,G2,G3,G33,G73,G76,G80,G81,G82,G83,G84,G85,G86,G87,G88,G89'),
|
||||
_v_csv(250, 'M0,M1,M2,M30,M60'),
|
||||
]))
|
||||
|
||||
def _word_order_linuxcnc(word):
|
||||
'''
|
||||
Order taken http://linuxcnc.org/docs/html/gcode/overview.html#_g_code_order_of_execution
|
||||
(as of 2017-07-03)
|
||||
010: O-word commands (optionally followed by a comment but no other words allowed on the same line)
|
||||
N/A: Comment (including message)
|
||||
030: Set feed rate mode (G93, G94).
|
||||
040: Set feed rate (F).
|
||||
050: Set spindle speed (S).
|
||||
060: Select tool (T).
|
||||
070: HAL pin I/O (M62-M68).
|
||||
080: Change tool (M6) and Set Tool Number (M61).
|
||||
090: Spindle on or off (M3, M4, M5).
|
||||
100: Save State (M70, M73), Restore State (M72), Invalidate State (M71).
|
||||
110: Coolant on or off (M7, M8, M9).
|
||||
120: Enable or disable overrides (M48, M49,M50,M51,M52,M53).
|
||||
130: User-defined Commands (M100-M199).
|
||||
140: Dwell (G4).
|
||||
150: Set active plane (G17, G18, G19).
|
||||
160: Set length units (G20, G21).
|
||||
170: Cutter radius compensation on or off (G40, G41, G42)
|
||||
180: Cutter length compensation on or off (G43, G49)
|
||||
190: Coordinate system selection (G54, G55, G56, G57, G58, G59, G59.1, G59.2, G59.3).
|
||||
200: Set path control mode (G61, G61.1, G64)
|
||||
210: Set distance mode (G90, G91).
|
||||
220: Set retract mode (G98, G99).
|
||||
230: Go to reference location (G28, G30) or change coordinate system data (G10) or set axis offsets (G92, G92.1, G92.2, G94).
|
||||
240: Perform motion (G0 to G3, G33, G38.x, G73, G76, G80 to G89), as modified (possibly) by G53.
|
||||
250: Stop (M0, M1, M2, M30, M60).
|
||||
900 + letter val: (else)
|
||||
'''
|
||||
if word.letter in ORDER_LINUXCNC_LETTER_MAP:
|
||||
return ORDER_LINUXCNC_LETTER_MAP[word.letter]
|
||||
letter_value = str(word)
|
||||
if letter_value in ORDER_LINUXCNC_LETTERVALUE_MAP:
|
||||
return ORDER_LINUXCNC_LETTERVALUE_MAP[letter_value]
|
||||
|
||||
# special cases
|
||||
if (word.letter == 'M') and (100 <= int(word.value) <= 199):
|
||||
return 130
|
||||
if (word.letter == 'G') and (38 < float(word.value) < 39):
|
||||
return 240
|
||||
|
||||
# otherwise, sort last, in alphabetic order
|
||||
return (900 + (ord(word.letter) - ord('A')))
|
||||
|
||||
def by_linuxcnc_order(word):
|
||||
return word.orderval_linuxcnc
|
||||
|
||||
|
||||
class Word(object):
|
||||
def __init__(self, letter, value):
|
||||
self.letter = letter.upper()
|
||||
@ -302,7 +221,7 @@ class Word(object):
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
return WORD_MAP[self.letter]['description']
|
||||
return "%s: %s" % (self.letter, WORD_MAP[self.letter]['description'])
|
||||
|
||||
NEXT_WORD = re.compile(r'^.*?(?P<letter>[%s])' % ''.join(WORD_MAP.keys()), re.IGNORECASE)
|
||||
|
||||
@ -336,3 +255,11 @@ def iter_words(block_text):
|
||||
remainder = block_text[index:]
|
||||
if remainder and re.search(r'\S', remainder):
|
||||
raise GCodeBlockFormatError("block code remaining '%s'" % remainder)
|
||||
|
||||
|
||||
def str2word(word_str):
|
||||
words = list(iter_words(word_str))
|
||||
if words:
|
||||
assert len(words) <= 1, "more than one word given"
|
||||
return words[0]
|
||||
return None
|
||||
|
Loading…
x
Reference in New Issue
Block a user