mirror of
https://git.mirrors.martin98.com/https://github.com/petaflot/pygcode
synced 2025-04-22 22:00:30 +08:00
modal groups
This commit is contained in:
parent
e84901eccc
commit
3a5dec14f0
@ -2,14 +2,81 @@ from collections import defaultdict
|
|||||||
|
|
||||||
from .words import Word
|
from .words import Word
|
||||||
|
|
||||||
|
# Terminology of a "G-Code"
|
||||||
|
# For the purposes of this library, so-called "G" codes do not necessarily
|
||||||
|
# use the letter "G" in their word; other letters include M, F, S, and T
|
||||||
|
# Why?
|
||||||
|
# I've seen documentation thrown around using the term "gcode" interchangably
|
||||||
|
# for any word that triggers an action, or mode change. The fact that the
|
||||||
|
# entire language is called "gcode" obfuscates any other convention.
|
||||||
|
# Considering it's much easier for me to call everything GCode, I'm taking
|
||||||
|
# the lazy route, so sue me (but seriously, please don't sue me).
|
||||||
|
#
|
||||||
|
# Modality groups
|
||||||
|
# Modal GCodes:
|
||||||
|
# A machine's "mode" can be changed by any gcode with a modal_group.
|
||||||
|
# This state is retained by the machine in the blocks to follow until
|
||||||
|
# the "mode" is revoked, or changed.
|
||||||
|
# A typical example of this is units:
|
||||||
|
# G20
|
||||||
|
# this will change the machine's "mode" to treat all positions as
|
||||||
|
# millimeters; G20 does not have to be on every line, thus the machine's
|
||||||
|
# "mode" is in millimeters for that, and every block after it until G21
|
||||||
|
# is specified (changing units to inches).
|
||||||
|
#
|
||||||
|
# Modal Groups:
|
||||||
|
# Only one mode of each modal group can be active. That is to say, a
|
||||||
|
# modal g-code can only change the sate of a previously set mode if
|
||||||
|
# they're in the same group.
|
||||||
|
# For example:
|
||||||
|
# G20 (mm), and G21 (inches) are in group 6
|
||||||
|
# G1 (linear movement), and G2 (arc movement) are in group 1
|
||||||
|
# A machine can't use mm and inches at the same time, just as it can't
|
||||||
|
# move in a straight line, and move in an arc simultaneously.
|
||||||
|
#
|
||||||
|
# There are 15 groups:
|
||||||
|
# ref: http://linuxcnc.org/docs/html/gcode/overview.html#_modal_groups
|
||||||
|
#
|
||||||
|
# Table 5. G-Code Modal Groups
|
||||||
|
# MODAL GROUP MEANING MEMBER WORDS
|
||||||
|
# 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.x, G73, G76, G80, G81
|
||||||
|
# G82, G83, G84, G85, G86, G87, G88,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
|
||||||
|
# Feed Rate Mode (Group 5) G93, G94, G95
|
||||||
|
# Units (Group 6) G20, G21
|
||||||
|
# Cutter Diameter Compensation (Group 7) G40, G41, G42, G41.1, G42.1
|
||||||
|
# Tool Length Offset (Group 8) G43, G43.1, G49
|
||||||
|
# Canned Cycles Return Mode (Group 10) G98, G99
|
||||||
|
# Coordinate System (Group 12) G54, G55, G56, G57, G58, G59,
|
||||||
|
# G59.1, G59.2, G59.3
|
||||||
|
# Control Mode (Group 13) G61, G61.1, G64
|
||||||
|
# Spindle Speed Mode (Group 14) G96, G97
|
||||||
|
# Lathe Diameter Mode (Group 15) G7, G8
|
||||||
|
#
|
||||||
|
# Table 6. M-Code Modal Groups
|
||||||
|
# MODAL GROUP MEANING MEMBER WORDS
|
||||||
|
# Stopping (Group 4) M0, M1, M2, M30, M60
|
||||||
|
# Spindle (Group 7) M3, M4, M5
|
||||||
|
# Coolant (Group 8) (M7 M8 can both be on), M9
|
||||||
|
# Override Switches (Group 9) M48, M49
|
||||||
|
# User Defined (Group 10) M100-M199
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
class GCode(object):
|
class GCode(object):
|
||||||
# Defining Word
|
# Defining Word
|
||||||
word_key = None # Word instance to use in lookup
|
word_key = None # Word instance to use in lookup
|
||||||
word_matches = None # function (secondary)
|
word_matches = None # function (secondary)
|
||||||
|
|
||||||
# Parameters associated to this gcode
|
# Parameters associated to this gcode
|
||||||
param_letters = set()
|
param_letters = set()
|
||||||
|
|
||||||
|
# Modal Group
|
||||||
|
modal_group = None
|
||||||
|
|
||||||
def __init__(self, word, *params):
|
def __init__(self, word, *params):
|
||||||
assert isinstance(word, Word), "invalid gcode word %r" % code_word
|
assert isinstance(word, Word), "invalid gcode word %r" % code_word
|
||||||
self.word = word
|
self.word = word
|
||||||
@ -75,6 +142,7 @@ class GCode(object):
|
|||||||
|
|
||||||
class GCodeMotion(GCode):
|
class GCodeMotion(GCode):
|
||||||
param_letters = set('XYZABCUVW')
|
param_letters = set('XYZABCUVW')
|
||||||
|
modal_group = 1
|
||||||
|
|
||||||
|
|
||||||
class GCodeRapidMove(GCodeMotion):
|
class GCodeRapidMove(GCodeMotion):
|
||||||
@ -106,6 +174,7 @@ class GCodeDwell(GCodeMotion):
|
|||||||
"""G4: Dwell"""
|
"""G4: Dwell"""
|
||||||
param_letters = GCodeMotion.param_letters | set('P')
|
param_letters = GCodeMotion.param_letters | set('P')
|
||||||
word_key = Word('G', 4)
|
word_key = Word('G', 4)
|
||||||
|
modal_group = None # one of the few motion commands that isn't modal
|
||||||
|
|
||||||
|
|
||||||
class GCodeCublcSpline(GCodeMotion):
|
class GCodeCublcSpline(GCodeMotion):
|
||||||
@ -168,7 +237,7 @@ class GCodeCancelCannedCycle(GCodeMotion):
|
|||||||
|
|
||||||
class GCodeCannedCycle(GCode):
|
class GCodeCannedCycle(GCode):
|
||||||
param_letters = set('XYZUVW')
|
param_letters = set('XYZUVW')
|
||||||
|
modal_group = 1
|
||||||
|
|
||||||
class GCodeDrillingCycle(GCodeCannedCycle):
|
class GCodeDrillingCycle(GCodeCannedCycle):
|
||||||
"""G81: Drilling Cycle"""
|
"""G81: Drilling Cycle"""
|
||||||
@ -226,31 +295,36 @@ class GCodeDistanceMode(GCode):
|
|||||||
class GCodeAbsoluteDistanceMode(GCodeDistanceMode):
|
class GCodeAbsoluteDistanceMode(GCodeDistanceMode):
|
||||||
"""G90: Absolute Distance Mode"""
|
"""G90: Absolute Distance Mode"""
|
||||||
word_key = Word('G', 90)
|
word_key = Word('G', 90)
|
||||||
|
modal_group = 3
|
||||||
|
|
||||||
class GCodeIncrementalDistanceMode(GCodeDistanceMode):
|
class GCodeIncrementalDistanceMode(GCodeDistanceMode):
|
||||||
"""G91: Incremental Distance Mode"""
|
"""G91: Incremental Distance Mode"""
|
||||||
word_key = Word('G', 91)
|
word_key = Word('G', 91)
|
||||||
|
modal_group = 3
|
||||||
|
|
||||||
|
|
||||||
class GCodeAbsoluteArcDistanceMode(GCodeDistanceMode):
|
class GCodeAbsoluteArcDistanceMode(GCodeDistanceMode):
|
||||||
"""G90.1: Absolute Distance Mode for Arc IJK Parameters"""
|
"""G90.1: Absolute Distance Mode for Arc IJK Parameters"""
|
||||||
word_key = Word('G', 90.1)
|
word_key = Word('G', 90.1)
|
||||||
|
modal_group = 4
|
||||||
|
|
||||||
|
|
||||||
class GCodeIncrementalArcDistanceMode(GCodeDistanceMode):
|
class GCodeIncrementalArcDistanceMode(GCodeDistanceMode):
|
||||||
"""G91.1: Incremental Distance Mode for Arc IJK Parameters"""
|
"""G91.1: Incremental Distance Mode for Arc IJK Parameters"""
|
||||||
word_key = Word('G', 91.1)
|
word_key = Word('G', 91.1)
|
||||||
|
modal_group = 4
|
||||||
|
|
||||||
|
|
||||||
class GCodeLatheDiameterMode(GCodeDistanceMode):
|
class GCodeLatheDiameterMode(GCodeDistanceMode):
|
||||||
"""G7: Lathe Diameter Mode"""
|
"""G7: Lathe Diameter Mode"""
|
||||||
word_key = Word('G', 7)
|
word_key = Word('G', 7)
|
||||||
|
modal_group = 15
|
||||||
|
|
||||||
|
|
||||||
class GCodeLatheRadiusMode(GCodeDistanceMode):
|
class GCodeLatheRadiusMode(GCodeDistanceMode):
|
||||||
"""G8: Lathe Radius Mode"""
|
"""G8: Lathe Radius Mode"""
|
||||||
word_key = Word('G', 8)
|
word_key = Word('G', 8)
|
||||||
|
modal_group = 15
|
||||||
|
|
||||||
|
|
||||||
# ======================= Feed Rate Mode =======================
|
# ======================= Feed Rate Mode =======================
|
||||||
@ -258,7 +332,7 @@ class GCodeLatheRadiusMode(GCodeDistanceMode):
|
|||||||
# G93, G94, G95 Feed Rate Mode
|
# G93, G94, G95 Feed Rate Mode
|
||||||
|
|
||||||
class GCodeFeedRateMode(GCode):
|
class GCodeFeedRateMode(GCode):
|
||||||
pass
|
modal_group = 5
|
||||||
|
|
||||||
|
|
||||||
class GCodeInverseTimeMode(GCodeFeedRateMode):
|
class GCodeInverseTimeMode(GCodeFeedRateMode):
|
||||||
@ -290,18 +364,20 @@ class GCodeStartSpindleCW(GCodeSpindle):
|
|||||||
"""M3: Start Spindle Clockwise"""
|
"""M3: Start Spindle Clockwise"""
|
||||||
param_letters = set('S')
|
param_letters = set('S')
|
||||||
word_key = Word('M', 3)
|
word_key = Word('M', 3)
|
||||||
|
modal_group = 7
|
||||||
|
|
||||||
class GCodeStartSpindleCCW(GCodeSpindle):
|
class GCodeStartSpindleCCW(GCodeSpindle):
|
||||||
"""M4: Start Spindle Counter-Clockwise"""
|
"""M4: Start Spindle Counter-Clockwise"""
|
||||||
param_letters = set('S')
|
param_letters = set('S')
|
||||||
word_key = Word('M', 4)
|
word_key = Word('M', 4)
|
||||||
|
modal_group = 7
|
||||||
|
|
||||||
|
|
||||||
class GCodeStopSpindle(GCodeSpindle):
|
class GCodeStopSpindle(GCodeSpindle):
|
||||||
"""M5: Stop Spindle"""
|
"""M5: Stop Spindle"""
|
||||||
param_letters = set('S')
|
param_letters = set('S')
|
||||||
word_key = Word('M', 5)
|
word_key = Word('M', 5)
|
||||||
|
modal_group = 7
|
||||||
|
|
||||||
|
|
||||||
class GCodeOrientSpindle(GCodeSpindle):
|
class GCodeOrientSpindle(GCodeSpindle):
|
||||||
@ -313,12 +389,14 @@ class GCodeSpindleConstantSurfaceSpeedMode(GCodeSpindle):
|
|||||||
"""G96: Spindle Constant Surface Speed"""
|
"""G96: Spindle Constant Surface Speed"""
|
||||||
param_letters = set('DS')
|
param_letters = set('DS')
|
||||||
word_key = Word('G', 96)
|
word_key = Word('G', 96)
|
||||||
|
modal_group = 14
|
||||||
|
|
||||||
|
|
||||||
class GCodeSpindleRPMMode(GCodeSpindle):
|
class GCodeSpindleRPMMode(GCodeSpindle):
|
||||||
"""G97: Spindle RPM Speed"""
|
"""G97: Spindle RPM Speed"""
|
||||||
param_letters = set('D')
|
param_letters = set('D')
|
||||||
word_key = Word('G', 97)
|
word_key = Word('G', 97)
|
||||||
|
modal_group = 14
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -327,7 +405,7 @@ class GCodeSpindleRPMMode(GCodeSpindle):
|
|||||||
# M7, M8, M9 Coolant Control
|
# M7, M8, M9 Coolant Control
|
||||||
|
|
||||||
class GCodeCoolant(GCode):
|
class GCodeCoolant(GCode):
|
||||||
pass
|
modal_group = 8
|
||||||
|
|
||||||
|
|
||||||
class GCodeCoolantMistOn(GCodeCoolant):
|
class GCodeCoolantMistOn(GCodeCoolant):
|
||||||
@ -353,7 +431,7 @@ class GCodeCoolantOff(GCodeCoolant):
|
|||||||
# G49 Cancel Tool Length Compensation
|
# G49 Cancel Tool Length Compensation
|
||||||
|
|
||||||
class GCodeToolLength(GCode):
|
class GCodeToolLength(GCode):
|
||||||
pass
|
modal_group = 8
|
||||||
|
|
||||||
|
|
||||||
class GCodeToolLengthOffset(GCodeToolLength):
|
class GCodeToolLengthOffset(GCodeToolLength):
|
||||||
@ -385,7 +463,7 @@ class GCodeCancelToolLengthOffset(GCodeToolLength):
|
|||||||
# M60 Pallet Change Pause
|
# M60 Pallet Change Pause
|
||||||
|
|
||||||
class GCodeProgramControl(GCode):
|
class GCodeProgramControl(GCode):
|
||||||
pass
|
modal_group = 4
|
||||||
|
|
||||||
|
|
||||||
class GCodePauseProgram(GCodeProgramControl):
|
class GCodePauseProgram(GCodeProgramControl):
|
||||||
@ -418,12 +496,14 @@ class GCodePalletChangePause(GCodeProgramControl):
|
|||||||
# G20, G21 Units
|
# G20, G21 Units
|
||||||
|
|
||||||
class GCodeUnit(GCode):
|
class GCodeUnit(GCode):
|
||||||
pass
|
modal_group = 6
|
||||||
|
|
||||||
|
|
||||||
class GCodeUseInches(GCodeUnit):
|
class GCodeUseInches(GCodeUnit):
|
||||||
"""G20: use inches for length units"""
|
"""G20: use inches for length units"""
|
||||||
word_key = Word('G', 20)
|
word_key = Word('G', 20)
|
||||||
|
|
||||||
|
|
||||||
class GCodeUseMillimeters(GCodeUnit):
|
class GCodeUseMillimeters(GCodeUnit):
|
||||||
"""G21: use millimeters for length units"""
|
"""G21: use millimeters for length units"""
|
||||||
word_key = Word('G', 21)
|
word_key = Word('G', 21)
|
||||||
@ -435,7 +515,7 @@ class GCodeUseMillimeters(GCodeUnit):
|
|||||||
# G17 - G19.1 Plane Select
|
# G17 - G19.1 Plane Select
|
||||||
|
|
||||||
class GCodePlaneSelect(GCode):
|
class GCodePlaneSelect(GCode):
|
||||||
pass
|
modal_group = 2
|
||||||
|
|
||||||
|
|
||||||
class GCodeSelectZYPlane(GCodePlaneSelect):
|
class GCodeSelectZYPlane(GCodePlaneSelect):
|
||||||
@ -475,7 +555,7 @@ class GCodeSelectVWPlane(GCodePlaneSelect):
|
|||||||
# G41.1, G42.1 D L Dynamic Cutter Compensation
|
# G41.1, G42.1 D L Dynamic Cutter Compensation
|
||||||
|
|
||||||
class GCodeCutterRadiusComp(GCode):
|
class GCodeCutterRadiusComp(GCode):
|
||||||
pass
|
modal_group = 7
|
||||||
|
|
||||||
|
|
||||||
class GCodeCutterRadiusCompOff(GCodeCutterRadiusComp):
|
class GCodeCutterRadiusCompOff(GCodeCutterRadiusComp):
|
||||||
@ -513,7 +593,7 @@ class GCodeDynamicCutterCompRight(GCodeCutterRadiusComp):
|
|||||||
# G64 P Q Path Blending
|
# G64 P Q Path Blending
|
||||||
|
|
||||||
class GCodePathControlMode(GCode):
|
class GCodePathControlMode(GCode):
|
||||||
pass
|
modal_group = 13
|
||||||
|
|
||||||
|
|
||||||
class GCodeExactPathMode(GCodePathControlMode):
|
class GCodeExactPathMode(GCodePathControlMode):
|
||||||
@ -537,7 +617,7 @@ class GCodePathBlendingMode(GCodePathControlMode):
|
|||||||
# G98 Canned Cycle Return Level
|
# G98 Canned Cycle Return Level
|
||||||
|
|
||||||
class GCodeCannedReturnMode(GCode):
|
class GCodeCannedReturnMode(GCode):
|
||||||
pass
|
modal_group = 10
|
||||||
|
|
||||||
|
|
||||||
class GCodeCannedCycleReturnLevel(GCodeCannedReturnMode):
|
class GCodeCannedCycleReturnLevel(GCodeCannedReturnMode):
|
||||||
@ -566,12 +646,21 @@ class GCodeFeedRate(GCodeOtherModal):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def word_matches(cls, w):
|
def word_matches(cls, w):
|
||||||
return w.letter == 'F'
|
return w.letter == 'F'
|
||||||
|
# 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
|
||||||
|
|
||||||
|
|
||||||
class GCodeSpindleSpeed(GCodeOtherModal):
|
class GCodeSpindleSpeed(GCodeOtherModal):
|
||||||
"""S: Set Spindle Speed"""
|
"""S: Set Spindle Speed"""
|
||||||
@classmethod
|
@classmethod
|
||||||
def word_matches(cls, w):
|
def word_matches(cls, w):
|
||||||
return w.letter == 'S'
|
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
|
||||||
|
|
||||||
|
|
||||||
class GCodeSelectTool(GCodeOtherModal):
|
class GCodeSelectTool(GCodeOtherModal):
|
||||||
@ -579,16 +668,22 @@ class GCodeSelectTool(GCodeOtherModal):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def word_matches(cls, w):
|
def word_matches(cls, w):
|
||||||
return w.letter == 'T'
|
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
|
||||||
|
|
||||||
|
|
||||||
class GCodeSpeedAndFeedOverrideOn(GCodeOtherModal):
|
class GCodeSpeedAndFeedOverrideOn(GCodeOtherModal):
|
||||||
"""M48: Speed and Feed Override Control On"""
|
"""M48: Speed and Feed Override Control On"""
|
||||||
word_key = Word('M', 48)
|
word_key = Word('M', 48)
|
||||||
|
modal_group = 9
|
||||||
|
|
||||||
|
|
||||||
class GCodeSpeedAndFeedOverrideOff(GCodeOtherModal):
|
class GCodeSpeedAndFeedOverrideOff(GCodeOtherModal):
|
||||||
"""M49: Speed and Feed Override Control Off"""
|
"""M49: Speed and Feed Override Control Off"""
|
||||||
word_key = Word('M', 49)
|
word_key = Word('M', 49)
|
||||||
|
modal_group = 9
|
||||||
|
|
||||||
|
|
||||||
class GCodeFeedOverride(GCodeOtherModal):
|
class GCodeFeedOverride(GCodeOtherModal):
|
||||||
@ -630,6 +725,7 @@ class GCodeSelectCoordinateSystem(GCodeOtherModal):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def word_matches(cls, w):
|
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])
|
return (w.letter == 'G') and (w.value in [54, 55, 56, 57, 58, 59, 59.1, 59.2, 59.3])
|
||||||
|
modal_group = 12
|
||||||
|
|
||||||
|
|
||||||
# ======================= Flow-control Codes =======================
|
# ======================= Flow-control Codes =======================
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import inspect
|
import inspect
|
||||||
|
import re
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
# Units Under Test
|
# Units Under Test
|
||||||
@ -22,6 +22,62 @@ class TestGCodeWordMapping(unittest.TestCase):
|
|||||||
"conflict with %s and %s" % (fn_class, key_class)
|
"conflict with %s and %s" % (fn_class, key_class)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class TestGCodeModalGroups(unittest.TestCase):
|
||||||
|
def test_modal_groups(self):
|
||||||
|
# Modal groups taken (and slightly modified) from LinuxCNC documentation:
|
||||||
|
# link: http://linuxcnc.org/docs/html/gcode/overview.html#_modal_groups
|
||||||
|
table_rows = ''
|
||||||
|
# Table 5. G-Code Modal Groups
|
||||||
|
# MODAL GROUP MEANING MEMBER WORDS
|
||||||
|
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
|
||||||
|
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
|
||||||
|
Feed Rate Mode (Group 5) G93, G94, G95
|
||||||
|
Units (Group 6) G20, G21
|
||||||
|
Cutter Diameter Compensation (Group 7) G40, G41, G42, G41.1, G42.1
|
||||||
|
Tool Length Offset (Group 8) G43, G43.1, G49
|
||||||
|
Canned Cycles Return Mode (Group 10) G98
|
||||||
|
Coordinate System (Group 12) G54,G55,G56,G57,G58,G59,G59.1,G59.2,G59.3
|
||||||
|
Control Mode (Group 13) G61, G61.1, G64
|
||||||
|
Spindle Speed Mode (Group 14) G96, G97
|
||||||
|
Lathe Diameter Mode (Group 15) G7,G8
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Table 6. M-Code Modal Groups
|
||||||
|
# MODAL GROUP MEANING MEMBER WORDS
|
||||||
|
table_rows += '''
|
||||||
|
Stopping (Group 4) M0, M1, M2, M30, M60
|
||||||
|
Spindle (Group 7) M3, M4, M5
|
||||||
|
Coolant (Group 8) M7, M8, M9
|
||||||
|
Override Switches (Group 9) M48, M49
|
||||||
|
'''
|
||||||
|
|
||||||
|
for row in table_rows.split('\n'):
|
||||||
|
match = re.search(r'^\s*(?P<title>.*)\s*\(Group (?P<group>\d+)\)\s*(?P<words>.*)$', row, re.I)
|
||||||
|
if match:
|
||||||
|
for word_str in re.split(r'\s*,\s*', match.group('words')):
|
||||||
|
word = list(words.iter_words(word_str))[0]
|
||||||
|
gcode_class = gcodes.word_gcode_class(word)
|
||||||
|
# GCode class found for each word in the table
|
||||||
|
self.assertIsNotNone(gcode_class)
|
||||||
|
# GCode's modal group equals that defined in the table
|
||||||
|
expected_group = int(match.group('group'))
|
||||||
|
if expected_group == 0:
|
||||||
|
self.assertIsNone(
|
||||||
|
gcode_class.modal_group,
|
||||||
|
"%s modal_group: %s is not None" % (gcode_class, gcode_class.modal_group)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.assertEqual(
|
||||||
|
gcode_class.modal_group, expected_group,
|
||||||
|
"%s != %s (%r)" % (gcode_class.modal_group, expected_group, word)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestWordsToGCodes(unittest.TestCase):
|
class TestWordsToGCodes(unittest.TestCase):
|
||||||
def test_stuff(self): # FIXME: function name
|
def test_stuff(self): # FIXME: function name
|
||||||
line = 'G1 X82.6892 Y-38.6339 F1500'
|
line = 'G1 X82.6892 Y-38.6339 F1500'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user