Merge pull request #1 from emorybarlow/master

emorybarlow/pygcode
This commit is contained in:
engrenage 2024-03-08 12:38:18 +01:00 committed by GitHub
commit 6319e963bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 337 additions and 24 deletions

View File

@ -11,11 +11,7 @@ for python.
Installation
============
Install using ``pip``
``pip install pygcode``
or `download directly from PyPi <https://pypi.python.org/pypi/pygcode>`__
python3 setup.py install
Documentation

View File

@ -54,7 +54,7 @@ __all__ = [
'GCodeArcMoveCW',
'GCodeBoringCycleDwellFeedOut',
'GCodeBoringCycleFeedOut',
'GCodeCancelCannedCycle',
#'GCodeCancelCannedCycle',
'GCodeCancelToolLengthOffset',
'GCodeCannedCycle',
'GCodeCannedCycleReturnPrevLevel',
@ -336,7 +336,7 @@ from .gcodes import (
GCodeArcMoveCW,
GCodeBoringCycleDwellFeedOut,
GCodeBoringCycleFeedOut,
GCodeCancelCannedCycle,
#GCodeCancelCannedCycle,
GCodeCancelToolLengthOffset,
GCodeCannedCycle,
GCodeCannedCycleReturnPrevLevel,

View File

@ -8,6 +8,7 @@ __all__ = [
# dialects
'linuxcnc',
'reprap',
'prusa',
]
@ -18,9 +19,10 @@ from .mapping import word_dialect
# Dialects
from . import linuxcnc
from . import reprap
from . import prusa
_DEFAULT = 'linuxcnc'
_DEFAULT = 'prusa'
def get_default():

View File

@ -0,0 +1,202 @@
import re
from .utils import WordType
# ======================== WORDS ========================
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):
if value < 10:
return "0%g" % value
return "%g" % value
CLEAN_NONE = lambda v: v
CLEAN_FLOAT = lambda v: "{0:g}".format(round(v, 3))
CLEAN_CODE = _clean_codestr
CLEAN_INT = lambda v: "%g" % v
WORD_MAP = {
# Descriptions copied from wikipedia:
# https://en.wikipedia.org/wiki/G-code#Letter_addresses
# Rotational Axes
'A': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Absolute or incremental position of A axis (rotational axis around X axis)",
clean_value=CLEAN_FLOAT,
),
'B': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Absolute or incremental position of B axis (rotational axis around Y axis)",
clean_value=CLEAN_FLOAT,
),
'C': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Absolute or incremental position of C axis (rotational axis around Z axis)",
clean_value=CLEAN_FLOAT,
),
'D': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Defines diameter or radial offset used for cutter compensation. D is used for depth of cut on lathes. It is used for aperture selection and commands on photoplotters.",
clean_value=CLEAN_FLOAT,
),
# Feed Rates
'E': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Precision feedrate for threading on lathes",
clean_value=CLEAN_FLOAT,
),
'F': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Feedrate",
clean_value=CLEAN_FLOAT,
),
# G-Codes
'G': WordType(
cls=float,
value_regex=REGEX_CODE,
description="Address for preparatory commands",
clean_value=CLEAN_CODE,
),
# Tool Offsets
'H': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Defines tool length offset; Incremental axis corresponding to C axis (e.g., on a turn-mill)",
clean_value=CLEAN_FLOAT,
),
# Arc radius center coords
'I': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Defines arc center in X axis for G02 or G03 arc commands. Also used as a parameter within some fixed cycles.",
clean_value=CLEAN_FLOAT,
),
'J': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Defines arc center in Y axis for G02 or G03 arc commands. Also used as a parameter within some fixed cycles.",
clean_value=CLEAN_FLOAT,
),
'K': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Defines arc center in Z axis for G02 or G03 arc commands. Also used as a parameter within some fixed cycles, equal to L address.",
clean_value=CLEAN_FLOAT,
),
# Loop Count
'L': WordType(
cls=int,
value_regex=REGEX_POSITIVEINT,
description="Fixed cycle loop count; Specification of what register to edit using G10",
clean_value=CLEAN_INT,
),
# Miscellaneous Function
'M': WordType(
cls=float,
value_regex=REGEX_CODE,
description="Miscellaneous function",
clean_value=CLEAN_CODE,
),
# Line Number
'N': WordType(
cls=int,
value_regex=REGEX_POSITIVEINT,
description="Line (block) number in program; System parameter number to change using G10",
clean_value=CLEAN_INT,
),
# Program Name
'O': WordType(
cls=str,
value_regex=re.compile(r'^.+$'), # all the way to the end
description="Program name",
clean_value=CLEAN_NONE,
),
# Parameter (arbitrary parameter)
'P': WordType(
cls=str, # parameter is often an integer, but can be a float
value_regex=re.compile(r'^.+$'), # all the way to the end
description="Checks the parameters of the printer and gcode and performs compatibility check",
clean_value=CLEAN_NONE,
),
# Peck increment
'Q': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Depth to increase on each peck; Peck increment in canned cycles",
clean_value=CLEAN_FLOAT,
),
# Arc Radius
'R': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Defines size of arc radius, or defines retract height in milling canned cycles",
clean_value=CLEAN_FLOAT,
),
# Spindle speed
'S': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Defines speed, either spindle speed or surface speed depending on mode",
clean_value=CLEAN_FLOAT,
),
# Tool Selecton
'T': WordType(
cls=str,
value_regex=REGEX_POSITIVEINT, # tool string may have leading '0's, but is effectively an index (integer)
description="Tool selection",
clean_value=CLEAN_NONE,
),
# Incremental axes
'U': WordType(
cls=str,
value_regex=re.compile(r'^.*$'), # all the way to the end
description="todo",
clean_value=CLEAN_NONE,
),
'V': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Incremental axis corresponding to Y axis",
clean_value=CLEAN_FLOAT,
),
'W': WordType(
cls=str,
value_regex=re.compile(r'^.*$'), # all the way to the end
description="When used with G28 just specifies without bed leveling, when used with M900 specifies width",
clean_value=CLEAN_NONE,
),
# Linear Axes
'X': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Absolute or incremental position of X axis.",
clean_value=CLEAN_FLOAT,
),
'Y': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Absolute or incremental position of Y axis.",
clean_value=CLEAN_FLOAT,
),
'Z': WordType(
cls=float,
value_regex=REGEX_FLOAT,
description="Absolute or incremental position of Z axis.",
clean_value=CLEAN_FLOAT,
),
}
# ======================== G-CODES ========================

View File

@ -508,22 +508,24 @@ class GCodeRigidTapping(GCodeMotion):
param_letters = GCodeMotion.param_letters | set('K')
word_key = Word('G', 33.1)
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
#
# Conflicts with prusa command
#
#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 =======================
@ -1299,6 +1301,7 @@ class GCodeSet(GCodeNonModal):
class GCodeGotoPredefinedPosition(GCodeNonModal):
"""G28,G30: Goto Predefined Position (rapid movement)"""
param_letters = set('W')
@classmethod
def word_matches(cls, w):
return (w.letter == 'G') and (w.value in [28, 30])
@ -1308,6 +1311,7 @@ class GCodeGotoPredefinedPosition(GCodeNonModal):
class GCodeSetPredefinedPosition(GCodeNonModal):
"""G28.1,G30.1: Set Predefined Position""" # redundancy in language there, but I'll let it slide
param_letters = set('W')
@classmethod
def word_matches(cls, w):
return (w.letter == 'G') and (w.value in [28.1, 30.1])
@ -1356,6 +1360,115 @@ class GCodeUserDefined(GCodeNonModal):
exec_order = 130
modal_group = MODAL_GROUP_MAP['user_defined']
# ======================= Prusa =======================
# CODE PARAMETERS DESCRIPTION
# M862.1 P Q Nozzle Diameter
# M862.2 P Q Model Code
# M862.3 P Q Model Name
# M862.4 P Q Firmware Version
# M862.5 P Q GCode Level
# M115 V U Firmware info
# M73 P R Q S C D Set/Get print progress
# M205 S T B X Y Z E Set advanced settings
# M104 S Set extruder temperature
# M109 B R S Wait for extruder temperature
# M140 S Set bed temperature
# M190 R S Wait for bed temperature
# M204 S T Acceleration settings
# M221 S T Set extrude factor override percentage
# M106 S Set fan speed
# G80 N R V L R F B Mesh-based Z probe
class GCodePrintChecking(GCode):
exec_order = 999
modal_group = MODAL_GROUP_MAP['user_defined']
param_letters = set('PQ')
class GCodeNozzleDiameterPrintChecking(GCodePrintChecking):
"""M862.1: Nozzle Diameter"""
word_key = Word('M', 862.1)
class GCodeModelCodePrintChecking(GCodePrintChecking):
"""M862.2: Model Code"""
word_key = Word('M', 862.2)
class GCodeModelNamePrintChecking(GCodePrintChecking):
"""M862.3: Model Name"""
word_key = Word('M', 862.3)
class GCodeFirmwareVersionPrintChecking(GCodePrintChecking):
"""M862.4: Firmware Version"""
word_key = Word('M', 862.4)
class GCodeGcodeLevelPrintChecking(GCodePrintChecking):
"""M862.5: Gcode Level"""
word_key = Word('M', 862.5)
class GCodeFirmwareInfo(GCode):
exec_order = 999
modal_group = MODAL_GROUP_MAP['user_defined']
param_letters = set('VU')
word_key = Word('M', 115)
class GCodePrintProgress(GCode):
exec_order = 999
modal_group = MODAL_GROUP_MAP['user_defined']
param_letters = set('PRQSCD')
word_key = Word('M', 73)
class GCodeSetAdvancedSettings(GCode):
exec_order = 999
modal_group = MODAL_GROUP_MAP['user_defined']
param_letters = set('STBXYZE')
word_key = Word('M', 205)
class GCodeSetExtruderTemperature(GCode):
exec_order = 999
modal_group = MODAL_GROUP_MAP['user_defined']
param_letters = set('S')
word_key = Word('M', 104)
class GCodeWaitForExtruderTemperature(GCode):
exec_order = 999
modal_group = MODAL_GROUP_MAP['user_defined']
param_letters = set('BRS')
word_key = Word('M', 109)
class GCodeSetBedTemperature(GCode):
exec_order = 999
modal_group = MODAL_GROUP_MAP['user_defined']
param_letters = set('S')
word_key = Word('M', 140)
class GCodeWaitForBedTemperature(GCode):
exec_order = 999
modal_group = MODAL_GROUP_MAP['user_defined']
param_letters = set('RS')
word_key = Word('M', 190)
class GCodeAccelerationSettings(GCode):
exec_order = 999
modal_group = MODAL_GROUP_MAP['user_defined']
param_letters = set('ST')
word_key = Word('M', 204)
class GCodeSetExtrudeFactorOverridePercentage(GCode):
exec_order = 999
modal_group = MODAL_GROUP_MAP['user_defined']
param_letters = set('ST')
word_key = Word('M', 221)
class GCodeSetFanSpeed(GCode):
exec_order = 999
modal_group = MODAL_GROUP_MAP['user_defined']
param_letters = set('S')
word_key = Word('M', 106)
class GCodeMeshBasedZProbe(GCode):
exec_order = 999
modal_group = MODAL_GROUP_MAP['user_defined']
param_letters = set('NRVLRFB')
word_key = Word('G', 80)
# ======================= Utilities =======================