mirror of
https://git.mirrors.martin98.com/https://github.com/petaflot/pygcode
synced 2025-06-04 11:25:20 +08:00
added normalization func'
This commit is contained in:
parent
133fc30fa9
commit
9c2fae672c
@ -23,7 +23,7 @@ for pygcode_lib_type in ('installed_lib', 'relative_lib'):
|
|||||||
from pygcode.transform import linearize_arc, simplify_canned_cycle
|
from pygcode.transform import linearize_arc, simplify_canned_cycle
|
||||||
from pygcode.transform import ArcLinearizeInside, ArcLinearizeOutside, ArcLinearizeMid
|
from pygcode.transform import ArcLinearizeInside, ArcLinearizeOutside, ArcLinearizeMid
|
||||||
from pygcode.gcodes import _subclasses
|
from pygcode.gcodes import _subclasses
|
||||||
from pygcode.utils import omit_redundant_modes
|
from pygcode import utils
|
||||||
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import sys, os, inspect
|
import sys, os, inspect
|
||||||
@ -63,7 +63,7 @@ def arc_lin_method_type(value):
|
|||||||
|
|
||||||
return value_dict
|
return value_dict
|
||||||
|
|
||||||
def canned_codes_type(value):
|
def word_list_type(value):
|
||||||
"""
|
"""
|
||||||
:return: [Word('G73'), Word('G89'), ... ]
|
:return: [Word('G73'), Word('G89'), ... ]
|
||||||
"""
|
"""
|
||||||
@ -88,9 +88,15 @@ parser.add_argument(
|
|||||||
)
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--precision', '-p', dest='precision', type=float, default=DEFAULT_PRECISION,
|
'--singles', '-s', dest='singles',
|
||||||
help="maximum positional error when generating gcodes (eg: arcs to lines) "
|
action='store_const', const=True, default=False,
|
||||||
"(default: %g)" % DEFAULT_PRECISION,
|
help="only output one command per gcode line",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--full', '-f', dest='full',
|
||||||
|
action='store_const', const=True, default=False,
|
||||||
|
help="output full commands, any modal parameters will be acompanied with "
|
||||||
|
"the fully qualified gcode command",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Machine
|
# Machine
|
||||||
@ -104,7 +110,7 @@ group = parser.add_argument_group(
|
|||||||
"Arc Linearizing",
|
"Arc Linearizing",
|
||||||
"Converting arcs (G2/G3 codes) into linear interpolations (G1 codes) to "
|
"Converting arcs (G2/G3 codes) into linear interpolations (G1 codes) to "
|
||||||
"aproximate the original arc. Indistinguishable from an original arc when "
|
"aproximate the original arc. Indistinguishable from an original arc when "
|
||||||
"--precision is set low enough."
|
"--arc_precision is set low enough."
|
||||||
)
|
)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
'--arc_linearize', '-al', dest='arc_linearize',
|
'--arc_linearize', '-al', dest='arc_linearize',
|
||||||
@ -119,6 +125,18 @@ group.add_argument(
|
|||||||
"(default: '%s')" % DEFAULT_ARC_LIN_METHOD,
|
"(default: '%s')" % DEFAULT_ARC_LIN_METHOD,
|
||||||
metavar='{i,o,m}[,{i,o,m}]',
|
metavar='{i,o,m}[,{i,o,m}]',
|
||||||
)
|
)
|
||||||
|
group.add_argument(
|
||||||
|
'--arc_precision', '-alp', dest='arc_precision', type=float, default=DEFAULT_PRECISION,
|
||||||
|
help="maximum positional error when creating linear interpolation codes "
|
||||||
|
"(default: %g)" % DEFAULT_PRECISION,
|
||||||
|
)
|
||||||
|
|
||||||
|
#parser.add_argument(
|
||||||
|
# '--arc_alignment', '-aa', dest='arc_alignment', type=str, choices=('XYZ','IJK','R'),
|
||||||
|
# default=None,
|
||||||
|
# help="enforce precision on arcs, if XYZ the destination is altered to match the radius"
|
||||||
|
# "if IJK or R then the arc'c centre point is moved to assure precision",
|
||||||
|
#)
|
||||||
|
|
||||||
# Canned Cycles
|
# Canned Cycles
|
||||||
group = parser.add_argument_group(
|
group = parser.add_argument_group(
|
||||||
@ -133,16 +151,37 @@ group.add_argument(
|
|||||||
)
|
)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
'--canned_codes', '-cc', dest='canned_codes',
|
'--canned_codes', '-cc', dest='canned_codes',
|
||||||
type=canned_codes_type, default=DEFAULT_CANNED_CODES,
|
type=word_list_type, default=DEFAULT_CANNED_CODES,
|
||||||
help="List of canned gcodes to expand, (default is '%s')" % DEFAULT_CANNED_CODES,
|
help="List of canned gcodes to expand, (default is '%s')" % DEFAULT_CANNED_CODES,
|
||||||
)
|
)
|
||||||
|
|
||||||
#parser.add_argument(
|
# Removing non-functional content
|
||||||
# '--arc_alignment', '-aa', dest='arc_alignment', type=str, choices=('XYZ','IJK','R'),
|
group = parser.add_argument_group(
|
||||||
# default=None,
|
"Removing Content",
|
||||||
# help="enforce precision on arcs, if XYZ the destination is altered to match the radius"
|
"options for the removal of content"
|
||||||
# "if IJK or R then the arc'c centre point is moved to assure precision",
|
)
|
||||||
#)
|
group.add_argument(
|
||||||
|
'--rm_comments', '-rc', dest='rm_comments',
|
||||||
|
action='store_const', const=True, default=False,
|
||||||
|
help="remove all comments (non-functional)",
|
||||||
|
)
|
||||||
|
group.add_argument(
|
||||||
|
'--rm_blanks', '-rb', dest='rm_blanks',
|
||||||
|
action='store_const', const=True, default=False,
|
||||||
|
help="remove all empty lines (non-functional)",
|
||||||
|
)
|
||||||
|
group.add_argument(
|
||||||
|
'--rm_whitespace', '-rws', dest='rm_whitespace',
|
||||||
|
action='store_const', const=True, default=False,
|
||||||
|
help="remove all whitespace from gcode blocks (non-functional)",
|
||||||
|
)
|
||||||
|
group.add_argument(
|
||||||
|
'--rm_gcodes', '-rmg', dest='rm_gcodes',
|
||||||
|
type=word_list_type, default=[],
|
||||||
|
help="remove gcode (and it's parameters) with words in the given list "
|
||||||
|
"(eg: M6,G43) (note: only works for modal params with --full)",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# --- Parse Arguments
|
# --- Parse Arguments
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
@ -158,6 +197,46 @@ class MyMachine(Machine):
|
|||||||
machine = MyMachine()
|
machine = MyMachine()
|
||||||
|
|
||||||
# =================== Utility Functions ===================
|
# =================== Utility Functions ===================
|
||||||
|
omit_redundant_modes = utils.omit_redundant_modes
|
||||||
|
if args.full:
|
||||||
|
omit_redundant_modes = lambda gcode_iter: gcode_iter # bypass
|
||||||
|
|
||||||
|
def write(gcodes, modal_params=tuple(), comment=None):
|
||||||
|
"""
|
||||||
|
Write to output, while enforcing the flags:
|
||||||
|
args.singles
|
||||||
|
args.rm_comments
|
||||||
|
args.rm_blanks
|
||||||
|
args.rm_whitespace
|
||||||
|
:param obj: Line, Block, GCode or Comment instance
|
||||||
|
"""
|
||||||
|
assert not(args.full and modal_params), "with full specified, this should never be called with modal_params"
|
||||||
|
if args.singles and len(gcodes) > 1:
|
||||||
|
for g in sorted(gcodes):
|
||||||
|
write([g], comment=comment)
|
||||||
|
else:
|
||||||
|
# remove comments
|
||||||
|
if args.rm_comments:
|
||||||
|
comment = None
|
||||||
|
# remove particular gcodes
|
||||||
|
if args.rm_gcodes:
|
||||||
|
gcodes = [g for g in gcodes if g.word not in args.rm_gcodes]
|
||||||
|
|
||||||
|
# Convert to string & write to file (or stdout)
|
||||||
|
block_str = ' '.join(str(x) for x in (list(gcodes) + list(modal_params)))
|
||||||
|
if args.rm_whitespace:
|
||||||
|
block_str = re.sub(r'\s', '', block_str)
|
||||||
|
|
||||||
|
line_list = []
|
||||||
|
if block_str:
|
||||||
|
line_list.append(block_str)
|
||||||
|
if comment:
|
||||||
|
line_list.append(str(comment))
|
||||||
|
line_str = ' '.join(line_list)
|
||||||
|
if line_str or not args.rm_blanks:
|
||||||
|
print(line_str)
|
||||||
|
|
||||||
|
|
||||||
def gcodes2str(gcodes):
|
def gcodes2str(gcodes):
|
||||||
return ' '.join("%s" % g for g in gcodes)
|
return ' '.join("%s" % g for g in gcodes)
|
||||||
|
|
||||||
@ -171,20 +250,21 @@ def split_and_process(gcode_list, gcode_class, comment):
|
|||||||
:param comment: Comment instance, or None
|
:param comment: Comment instance, or None
|
||||||
"""
|
"""
|
||||||
(befores, (g,), afters) = split_gcodes(gcode_list, gcode_class)
|
(befores, (g,), afters) = split_gcodes(gcode_list, gcode_class)
|
||||||
# print & process those before gcode_class instance
|
# write & process those before gcode_class instance
|
||||||
if befores:
|
if befores:
|
||||||
print(gcodes2str(befores))
|
write(befores)
|
||||||
machine.process_gcodes(*befores)
|
machine.process_gcodes(*befores)
|
||||||
# yield, then process gcode_class instance
|
# yield, then process gcode_class instance
|
||||||
yield g
|
yield g
|
||||||
machine.process_gcodes(g)
|
machine.process_gcodes(g)
|
||||||
# print & process those after gcode_class instance
|
# write & process those after gcode_class instance
|
||||||
if afters:
|
if afters:
|
||||||
print(gcodes2str(afters))
|
write(afters)
|
||||||
machine.process_gcodes(*afters)
|
machine.process_gcodes(*afters)
|
||||||
# print comment (if given)
|
# write comment (if given)
|
||||||
if comment:
|
if comment:
|
||||||
print(str(line.comment))
|
write([], comment=line.comment)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# =================== Process File ===================
|
# =================== Process File ===================
|
||||||
@ -198,7 +278,7 @@ for line_str in args.infile.readlines():
|
|||||||
|
|
||||||
if args.arc_linearize and any(isinstance(g, GCodeArcMove) for g in effective_gcodes):
|
if args.arc_linearize and any(isinstance(g, GCodeArcMove) for g in effective_gcodes):
|
||||||
with split_and_process(effective_gcodes, GCodeArcMove, line.comment) as arc:
|
with split_and_process(effective_gcodes, GCodeArcMove, line.comment) as arc:
|
||||||
print(Comment("linearized arc: %r" % arc))
|
write([], comment=Comment("linearized arc: %r" % arc))
|
||||||
linearize_params = {
|
linearize_params = {
|
||||||
'arc_gcode': arc,
|
'arc_gcode': arc,
|
||||||
'start_pos': machine.pos,
|
'start_pos': machine.pos,
|
||||||
@ -206,15 +286,15 @@ for line_str in args.infile.readlines():
|
|||||||
'method_class': args.arc_lin_method[arc.word],
|
'method_class': args.arc_lin_method[arc.word],
|
||||||
'dist_mode': machine.mode.distance,
|
'dist_mode': machine.mode.distance,
|
||||||
'arc_dist_mode': machine.mode.arc_ijk_distance,
|
'arc_dist_mode': machine.mode.arc_ijk_distance,
|
||||||
'max_error': args.precision,
|
'max_error': args.arc_precision,
|
||||||
'decimal_places': 3,
|
'decimal_places': 3,
|
||||||
}
|
}
|
||||||
for linear_gcode in omit_redundant_modes(linearize_arc(**linearize_params)):
|
for linear_gcode in omit_redundant_modes(linearize_arc(**linearize_params)):
|
||||||
print(linear_gcode)
|
write([linear_gcode])
|
||||||
|
|
||||||
elif args.canned_expand and any((g.word in args.canned_codes) for g in effective_gcodes):
|
elif args.canned_expand and any((g.word in args.canned_codes) for g in effective_gcodes):
|
||||||
with split_and_process(effective_gcodes, GCodeCannedCycle, line.comment) as canned:
|
with split_and_process(effective_gcodes, GCodeCannedCycle, line.comment) as canned:
|
||||||
print(Comment("expanded: %r" % canned))
|
write([], comment=Comment("expanded: %r" % canned))
|
||||||
simplify_canned_params = {
|
simplify_canned_params = {
|
||||||
'canned_gcode': canned,
|
'canned_gcode': canned,
|
||||||
'start_pos': machine.pos,
|
'start_pos': machine.pos,
|
||||||
@ -223,8 +303,11 @@ for line_str in args.infile.readlines():
|
|||||||
'axes': machine.axes,
|
'axes': machine.axes,
|
||||||
}
|
}
|
||||||
for simplified_gcode in omit_redundant_modes(simplify_canned_cycle(**simplify_canned_params)):
|
for simplified_gcode in omit_redundant_modes(simplify_canned_cycle(**simplify_canned_params)):
|
||||||
print(simplified_gcode)
|
write([simplified_gcode])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print(str(line))
|
if args.full:
|
||||||
|
write(effective_gcodes, comment=line.comment)
|
||||||
|
else:
|
||||||
|
write(line.block.gcodes, modal_params=line.block.modal_params, comment=line.comment)
|
||||||
machine.process_block(line.block)
|
machine.process_block(line.block)
|
||||||
|
@ -87,7 +87,7 @@ class Position(object):
|
|||||||
return self._value == other._value
|
return self._value == other._value
|
||||||
else:
|
else:
|
||||||
x = copy(other)
|
x = copy(other)
|
||||||
x.set_unit(self._unit)
|
x.unit = self._unit
|
||||||
return self._value == x._value
|
return self._value == x._value
|
||||||
|
|
||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
@ -125,13 +125,17 @@ class Position(object):
|
|||||||
__truediv__ = __div__ # Python 3 division
|
__truediv__ = __div__ # Python 3 division
|
||||||
|
|
||||||
# Conversion
|
# Conversion
|
||||||
def set_unit(self, unit):
|
@property
|
||||||
if unit == self._unit:
|
def unit(self):
|
||||||
return
|
return self._unit
|
||||||
factor = UNIT_MAP[self._unit]['conversion_factor'][unit]
|
|
||||||
for k in [k for (k, v) in self._value.items() if v is not None]:
|
@unit.setter
|
||||||
self._value[k] *= factor
|
def unit(self, value):
|
||||||
self._unit = unit
|
if value != self._unit:
|
||||||
|
factor = UNIT_MAP[self._unit]['conversion_factor'][value]
|
||||||
|
for k in [k for (k, v) in self._value.items() if v is not None]:
|
||||||
|
self._value[k] *= factor
|
||||||
|
self._unit = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def words(self):
|
def words(self):
|
||||||
@ -202,8 +206,6 @@ class State(object):
|
|||||||
# Coordinate System selection:
|
# Coordinate System selection:
|
||||||
# - G54-G59: select coordinate system (offsets from machine coordinates set by G10 L2)
|
# - G54-G59: select coordinate system (offsets from machine coordinates set by G10 L2)
|
||||||
|
|
||||||
# TODO: Move this class into MachineState
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def coord_sys(self):
|
def coord_sys(self):
|
||||||
"""Current equivalent coordinate system, including all """
|
"""Current equivalent coordinate system, including all """
|
||||||
@ -328,7 +330,7 @@ class Machine(object):
|
|||||||
units_mode = getattr(self.mode, 'units', None)
|
units_mode = getattr(self.mode, 'units', None)
|
||||||
self.Position = type('Position', (Position,), {
|
self.Position = type('Position', (Position,), {
|
||||||
'default_axes': self.axes,
|
'default_axes': self.axes,
|
||||||
'default_unit': units_mode.unit_id if units_mode else UNIT_METRIC,
|
'default_unit': units_mode.unit_id if units_mode else Position.default_unit,
|
||||||
})
|
})
|
||||||
|
|
||||||
# Absolute machine position
|
# Absolute machine position
|
||||||
|
Loading…
x
Reference in New Issue
Block a user