start of switchable dialect

This commit is contained in:
Peter Boin 2018-04-18 15:39:28 +10:00
parent 2dd1a1d974
commit 71d3e02261
7 changed files with 176 additions and 4 deletions

View File

@ -8,8 +8,16 @@ class Block(object):
def __init__(self, text=None, verify=True):
"""
Block Constructor
:param A-Z: gcode parameter values
:param comment: comment text
:param text: gcode line content (including comments) as string
:type text: :class:`str`
:param verify: verify given codes (modal & non-modal are not repeated)
:type verify: :class:`bool`
.. note::
State & machine specific codes cannot be verified at this point;
they must be processed by a virtual machine to be fully verified.
"""
self._raw_text = None

40
src/pygcode/dialect.py Normal file
View File

@ -0,0 +1,40 @@
def gcode_dialect(*names):
"""
GCode class dialect registration decorator
:param names: name of relevant dialects
:type names: :class:`list` of :class:`str` instances
For example::
from pygcode.dialect import gcode_dialect as dialect
from pygcode.gcodes import GCode
@dialect('linuxcnc')
class GCodeRapidMove(GCode):
word_key = Word('G', 0)
def _process(self, machine):
params = self.get_param_dict(letters=machine.axes)
machine.move_to(rapid=True, **params)
@dialect('reprap')
clsas GCodeRapidMove2(GCode): # name changed because scope is the same
word_key = Word('G', 0)
def _process(self, machine):
params = self.get_param_dict(letters=machine.axes)
params = {k: -v for (k, v) in params.items()} # negate parameters
machine.move_to(rapid=True, **params)
When processing a ``linuxcnc`` dialect, the machine coordintes would be
positive. Conversely the coordintes would be negated if processed in the
``reprap`` dialect.
"""
# TODO
def word_dialect(*names):
"""
"""

View File

@ -0,0 +1,14 @@
__all__ = [
'DEFAULT',
# registration decorators
'gcode_dialect',
'word_dialect',
]
DEFAULT = 'linuxcnc'
# Registration decorators
from .mapping import gcode_dialect
from .mapping import word_dialect

View File

@ -0,0 +1,18 @@
"""
LinuxCNC
The linuxcnc gcode dialect is typically used for subtractive fabrication, such
as milling.
This dialect is the basis for all other dialects; GCodes and Words in other
dialects either inherit, or directly reference these classes.
**Specification:** http://www.linuxcnc.org
TODO: verify above info before publishing
"""
# ======================== WORDS ========================
# ======================== G-CODES ========================

View File

@ -0,0 +1,47 @@
# ---------------- Registration Decorators ----------------
def gcode_dialect(*names):
"""
GCode class dialect registration decorator
:param names: name of relevant dialects
:type names: :class:`list` of :class:`str` instances
For example::
from pygcode.dialect import gcode_dialect as dialect
from pygcode.gcodes import GCode
@dialect('linuxcnc')
class GCodeRapidMove(GCode):
word_key = Word('G', 0)
def _process(self, machine):
params = self.get_param_dict(letters=machine.axes)
machine.move_to(rapid=True, **params)
@dialect('reprap')
clsas GCodeRapidMove2(GCode): # name changed because scope is the same
word_key = Word('G', 0)
def _process(self, machine):
params = self.get_param_dict(letters=machine.axes)
params = {k: -v for (k, v) in params.items()} # negate parameters
machine.move_to(rapid=True, **params)
When processing a ``linuxcnc`` dialect, the machine coordintes would be
positive. Conversely the coordintes would be negated if processed in the
``reprap`` dialect.
"""
# TODO
def word_dialect(*names):
"""
"""
# TODO
# ---------------- Dialect ----------------

View File

View File

@ -1440,6 +1440,7 @@ def word_gcode_class(word, exhaustive=False):
build_maps()
# quickly eliminate parameters
# TODO: get valid world letters from dialect
if (not exhaustive) and (word.letter not in 'GMFSTNO'):
return None
@ -1457,9 +1458,16 @@ def word_gcode_class(word, exhaustive=False):
def words2gcodes(words):
"""
Group words into g-codes (includes both G & M codes)
:param words: list of Word instances
Group words into GCodes
:param words: list of :class:`Word <pygcode.words.Word>` instances
:type words: :class:`list`
:return: tuple([<GCode>, <GCode>, ...], list(<unused words>))
:rtype: :class:`tuple`
Returns a 2-tuple:
- list of :class:`GCode <pygocde.gcodes.GCode>` instances
-
"""
gcodes = []
@ -1536,8 +1544,45 @@ def split_gcodes(gcode_list, splitter_class, sort_list=True):
"""
Splits a list of GCode instances into 3, the center list containing the splitter_class gcode
:param gcode_list: list of GCode instances to split
:type gcode_list: :class:`list`
:param splitter_class: class of gcode identifying split from left to right
:type splitter_class: :class:`GCode`
:param sort_list: if ``False``, gcodes list is not sorted before processing
:type sort_list: :class:`bool`
:return: list of: [[<gcodes before splitter>], [<splitter instance>], [<gcodes after splitter>]]
:rtype: :class:`list`
Returns a list with 3 elements
- gcodes before splitter (may be empty)
- splitter instance (list with a single element)
- gcodes after splitter (may be empty)
For example:
.. doctest::
>>> from pygcode import Block
>>> from pygcode.gcodes import split_gcodes, GCodeCoolantOff
>>> block = Block('G1 X1 Y2 M9 F100 S200')
>>> (a, b, c) = split_gcodes(block.gcodes, GCodeCoolantOff)
>>> a
[<GCodeFeedRate: F100>, <GCodeSpindleSpeed: S200>]
>>> b
[<GCodeCoolantOff: M09>]
>>> c
[<GCodeLinearMove: G01{X1, Y2}>]
>>> # Line with the M09 code removed
>>> a + c
[<GCodeFeedRate: F100>, <GCodeSpindleSpeed: S200>, <GCodeLinearMove: G01{X1, Y2}>]
.. note::
The above example is sorted in execution order by default, set
``sort_list=False`` to override this behaviour.
"""
# for example:
# g_list = sorted([g1, g2, g3, g4])