mirror of
https://git.mirrors.martin98.com/https://github.com/petaflot/pygcode
synced 2025-06-04 11:25:20 +08:00
commit
75022b63fe
@ -1 +0,0 @@
|
|||||||
theme: jekyll-theme-hacker
|
|
@ -178,9 +178,11 @@ to make sure it's sane
|
|||||||
|
|
||||||
# Deployment in Git
|
# Deployment in Git
|
||||||
|
|
||||||
merge deployed branch to `master`
|
merge deployed branch to `master`, then...
|
||||||
|
|
||||||
```
|
```
|
||||||
|
git checkout master
|
||||||
|
git pull
|
||||||
git tag ${version} -m "<change description>"
|
git tag ${version} -m "<change description>"
|
||||||
git push --tags origin master
|
git push --tags origin master
|
||||||
```
|
```
|
||||||
|
15
dist/README.md
vendored
Normal file
15
dist/README.md
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Change History
|
||||||
|
|
||||||
|
## 0.1.2
|
||||||
|
|
||||||
|
Changes to accommodate implementation of [grbl-stream](https://github.com/fragmuffin/grbl-stream)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
- added `NullMachine`, `NullState`, and `NullMode` (not assuming any machine state)
|
||||||
|
- `Block` length is the number of gcodes + 1 if modal parameters exists
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- `%` enclosed lines are considered to be _macros_ when parsing
|
||||||
|
- added axes `ABCXYZ` as valid parameters for `G10` (eg: `G10 L20 X0 Y0 Z0`)
|
BIN
dist/pygcode-0.1.1.tar.gz
vendored
BIN
dist/pygcode-0.1.1.tar.gz
vendored
Binary file not shown.
Binary file not shown.
BIN
dist/pygcode-0.1.2.tar.gz
vendored
Normal file
BIN
dist/pygcode-0.1.2.tar.gz
vendored
Normal file
Binary file not shown.
@ -4,3 +4,7 @@
|
|||||||
Screenshots of arc linearizing methods for the `pygcode-norm` script.
|
Screenshots of arc linearizing methods for the `pygcode-norm` script.
|
||||||
|
|
||||||
credit to _nraynaud_ for [this awesome online gcode interpreter](https://nraynaud.github.io/webgcode/)
|
credit to _nraynaud_ for [this awesome online gcode interpreter](https://nraynaud.github.io/webgcode/)
|
||||||
|
|
||||||
|
## `grbl-stream-*.png`
|
||||||
|
|
||||||
|
Screenshots of the `grbl-stream` script at work
|
||||||
|
4
scripts/.gitignore
vendored
Normal file
4
scripts/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# GCode files (dropped into this folder during development)
|
||||||
|
*.gcode
|
||||||
|
*.ngc
|
||||||
|
*.g
|
@ -203,7 +203,7 @@ omit_redundant_modes = utils.omit_redundant_modes
|
|||||||
if args.full:
|
if args.full:
|
||||||
omit_redundant_modes = lambda gcode_iter: gcode_iter # bypass
|
omit_redundant_modes = lambda gcode_iter: gcode_iter # bypass
|
||||||
|
|
||||||
def write(gcodes, modal_params=tuple(), comment=None):
|
def write(gcodes, modal_params=tuple(), comment=None, macro=None):
|
||||||
"""
|
"""
|
||||||
Write to output, while enforcing the flags:
|
Write to output, while enforcing the flags:
|
||||||
args.singles
|
args.singles
|
||||||
@ -234,6 +234,8 @@ def write(gcodes, modal_params=tuple(), comment=None):
|
|||||||
line_list.append(block_str)
|
line_list.append(block_str)
|
||||||
if comment:
|
if comment:
|
||||||
line_list.append(str(comment))
|
line_list.append(str(comment))
|
||||||
|
if macro:
|
||||||
|
line_list.append(str(macro))
|
||||||
line_str = ' '.join(line_list)
|
line_str = ' '.join(line_list)
|
||||||
if line_str or not args.rm_blanks:
|
if line_str or not args.rm_blanks:
|
||||||
print(line_str)
|
print(line_str)
|
||||||
@ -309,7 +311,7 @@ for line_str in args.infile.readlines():
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
if args.full:
|
if args.full:
|
||||||
write(effective_gcodes, comment=line.comment)
|
write(effective_gcodes, comment=line.comment, macro=line.macro)
|
||||||
else:
|
else:
|
||||||
write(line.block.gcodes, modal_params=line.block.modal_params, comment=line.comment)
|
write(line.block.gcodes, modal_params=line.block.modal_params, comment=line.comment, macro=line.macro)
|
||||||
machine.process_block(line.block)
|
machine.process_block(line.block)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Metadata-Version: 1.1
|
Metadata-Version: 1.1
|
||||||
Name: pygcode
|
Name: pygcode
|
||||||
Version: 0.1.1
|
Version: 0.1.2
|
||||||
Summary: Basic g-code parser, interpreter, and encoder library.
|
Summary: Basic g-code parser, interpreter, and encoder library.
|
||||||
Home-page: https://github.com/fragmuffin/pygcode
|
Home-page: https://github.com/fragmuffin/pygcode
|
||||||
Author: Peter Boin
|
Author: Peter Boin
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# 1.x - Development Status :: 5 - Production/Stable
|
# 1.x - Development Status :: 5 - Production/Stable
|
||||||
# <any above>.y - developments on that version (pre-release)
|
# <any above>.y - developments on that version (pre-release)
|
||||||
# <any above>*.dev* - development release (intended purely to test deployment)
|
# <any above>*.dev* - development release (intended purely to test deployment)
|
||||||
__version__ = "0.1.1"
|
__version__ = "0.1.2"
|
||||||
|
|
||||||
__title__ = "pygcode"
|
__title__ = "pygcode"
|
||||||
__description__ = "Basic g-code parser, interpreter, and encoder library."
|
__description__ = "Basic g-code parser, interpreter, and encoder library."
|
||||||
@ -24,7 +24,10 @@ __copyright__ = "Copyright (c) 2017 {0}".format(__author__)
|
|||||||
# =========================== Imports ===========================
|
# =========================== Imports ===========================
|
||||||
__all__ = [
|
__all__ = [
|
||||||
# Machine
|
# Machine
|
||||||
'Machine', 'Position', 'CoordinateSystem', 'State', 'Mode',
|
'Machine', 'State', 'Mode',
|
||||||
|
'NullMachine', 'NullState', 'NullMode',
|
||||||
|
'Position', 'CoordinateSystem',
|
||||||
|
|
||||||
# Line
|
# Line
|
||||||
'Line',
|
'Line',
|
||||||
# Block
|
# Block
|
||||||
@ -165,8 +168,8 @@ __all__ = [
|
|||||||
# Machine
|
# Machine
|
||||||
from .machine import (
|
from .machine import (
|
||||||
Position, CoordinateSystem,
|
Position, CoordinateSystem,
|
||||||
State, Mode,
|
Machine, State, Mode,
|
||||||
Machine,
|
NullMachine, NullState, NullMode,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Line
|
# Line
|
||||||
|
@ -76,6 +76,16 @@ class Block(object):
|
|||||||
key=k
|
key=k
|
||||||
))
|
))
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
"""
|
||||||
|
Block length = number of identified gcodes (+ 1 if any modal parameters are defined)
|
||||||
|
:return: block length
|
||||||
|
"""
|
||||||
|
length = len(self.gcodes)
|
||||||
|
if self.modal_params:
|
||||||
|
length += 1
|
||||||
|
return length
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
return bool(self.words)
|
return bool(self.words)
|
||||||
|
|
||||||
|
@ -1210,8 +1210,8 @@ class GCodeAnalogOutputImmediate(GCodeAnalogOutput):
|
|||||||
# G10 L1 P Q R Set Tool Table
|
# G10 L1 P Q R Set Tool Table
|
||||||
# G10 L10 P Set Tool Table
|
# G10 L10 P Set Tool Table
|
||||||
# G10 L11 P Set Tool Table
|
# G10 L11 P Set Tool Table
|
||||||
# G10 L2 P R Set Coordinate System
|
# G10 L2 P R ABCXYZ Set Coordinate System
|
||||||
# G10 L20 P Set Coordinate System
|
# G10 L20 P ABCXYZ Set Coordinate System
|
||||||
# G28, G28.1 Go/Set Predefined Position
|
# G28, G28.1 Go/Set Predefined Position
|
||||||
# G30, G30.1 Go/Set Predefined Position
|
# G30, G30.1 Go/Set Predefined Position
|
||||||
# G53 Move in Machine Coordinates
|
# G53 Move in Machine Coordinates
|
||||||
@ -1242,7 +1242,7 @@ class GCodeToolSetCurrent(GCodeNonModal):
|
|||||||
|
|
||||||
class GCodeSet(GCodeNonModal):
|
class GCodeSet(GCodeNonModal):
|
||||||
"""G10: Set stuff"""
|
"""G10: Set stuff"""
|
||||||
param_letters = set('LPQR')
|
param_letters = set('LPQRABCXYZ')
|
||||||
word_key = Word('G', 10)
|
word_key = Word('G', 10)
|
||||||
exec_order = 230
|
exec_order = 230
|
||||||
|
|
||||||
|
@ -1,17 +1,28 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
from .comment import split_line
|
from .comment import split_line
|
||||||
from .block import Block
|
from .block import Block
|
||||||
|
|
||||||
class Line(object):
|
class Line(object):
|
||||||
|
|
||||||
|
line_regex = re.compile(r'^(?P<block_and_comment>.*?)?(?P<macro>%.*%?)?\s*$')
|
||||||
|
|
||||||
def __init__(self, text=None):
|
def __init__(self, text=None):
|
||||||
self._text = text
|
self._text = text
|
||||||
|
|
||||||
# Initialize
|
# Initialize
|
||||||
self.block = None
|
self.block = None
|
||||||
self.comment = None
|
self.comment = None
|
||||||
|
self.macro = None
|
||||||
|
|
||||||
# Split line into block text, and comments
|
# Split line into block text, and comments
|
||||||
if text is not None:
|
if text is not None:
|
||||||
(block_str, comment) = split_line(text)
|
match = self.line_regex.search(text)
|
||||||
|
|
||||||
|
block_and_comment = match.group('block_and_comment')
|
||||||
|
self.macro = match.group('macro')
|
||||||
|
|
||||||
|
(block_str, comment) = split_line(block_and_comment)
|
||||||
self.block = Block(block_str)
|
self.block = Block(block_str)
|
||||||
if comment:
|
if comment:
|
||||||
self.comment = comment
|
self.comment = comment
|
||||||
@ -28,4 +39,4 @@ class Line(object):
|
|||||||
return self.block.gcodes
|
return self.block.gcodes
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return ' '.join([str(x) for x in [self.block, self.comment] if x])
|
return ' '.join([str(x) for x in [self.block, self.comment, self.macro] if x])
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import re
|
||||||
from copy import copy, deepcopy
|
from copy import copy, deepcopy
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
@ -290,9 +291,12 @@ class Mode(object):
|
|||||||
def __init__(self, set_default=True):
|
def __init__(self, set_default=True):
|
||||||
self.modal_groups = defaultdict(lambda: None)
|
self.modal_groups = defaultdict(lambda: None)
|
||||||
|
|
||||||
# Initialize
|
# Initialize (from multiline self.default_mode)
|
||||||
if set_default:
|
if set_default:
|
||||||
self.set_mode(*Line(self.default_mode).block.gcodes)
|
gcodes = []
|
||||||
|
for m in re.finditer(r'\s*(?P<line>.*)\s*\n?', self.default_mode):
|
||||||
|
gcodes += Line(m.group('line')).block.gcodes
|
||||||
|
self.set_mode(*gcodes)
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
obj = self.__class__(set_default=False)
|
obj = self.__class__(set_default=False)
|
||||||
@ -499,3 +503,16 @@ class Machine(object):
|
|||||||
new_pos = self.pos
|
new_pos = self.pos
|
||||||
new_pos.update(**coords) # only change given coordinates
|
new_pos.update(**coords) # only change given coordinates
|
||||||
self.pos = new_pos
|
self.pos = new_pos
|
||||||
|
|
||||||
|
|
||||||
|
# Null Machine
|
||||||
|
# A machine that presumes nothing
|
||||||
|
class NullMode(Mode):
|
||||||
|
default_mode = ''
|
||||||
|
|
||||||
|
class NullState(State):
|
||||||
|
pass # no change (yet)
|
||||||
|
|
||||||
|
class NullMachine(Machine):
|
||||||
|
MODE_CLASS = NullMode
|
||||||
|
STATE_CLASS = NullState
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
import sys
|
|
||||||
import os
|
|
||||||
import inspect
|
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
# Add relative pygcode to path
|
# Add relative pygcode to path
|
||||||
@ -27,3 +23,29 @@ class LineCommentTests(unittest.TestCase):
|
|||||||
line = Line('G02 X10.75 (x coord) Y47.44 (y coord) I-0.11 J-1.26 F70 (eol)')
|
line = Line('G02 X10.75 (x coord) Y47.44 (y coord) I-0.11 J-1.26 F70 (eol)')
|
||||||
self.assertEqual(line.comment.text, 'x coord. y coord. eol')
|
self.assertEqual(line.comment.text, 'x coord. y coord. eol')
|
||||||
self.assertEqual(len(line.block.words), 6)
|
self.assertEqual(len(line.block.words), 6)
|
||||||
|
|
||||||
|
def test_line_macros(self):
|
||||||
|
# (blank)
|
||||||
|
line = Line('')
|
||||||
|
self.assertIsNone(line.macro)
|
||||||
|
|
||||||
|
# (no macro)
|
||||||
|
line = Line('G02 X10.75 Y47.44 I-0.11 J-1.26 F70 (blah blah)')
|
||||||
|
self.assertIsNone(line.macro)
|
||||||
|
|
||||||
|
# %
|
||||||
|
line = Line('%')
|
||||||
|
self.assertEqual(str(line.macro), '%')
|
||||||
|
|
||||||
|
# %%
|
||||||
|
line = Line('%%')
|
||||||
|
self.assertEqual(str(line.macro), '%%')
|
||||||
|
|
||||||
|
# % blah blah %
|
||||||
|
line = Line('% blah blah %')
|
||||||
|
self.assertEqual(str(line.macro), '% blah blah %')
|
||||||
|
|
||||||
|
# Combined at end of line (not sure if this is legit)
|
||||||
|
line = Line('G02 X10.75 Y2 ; abc %something%')
|
||||||
|
self.assertEqual(line.comment.text.strip(), 'abc')
|
||||||
|
self.assertEqual(line.macro, '%something%')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user