config class and support for feedrate and moverate

This commit is contained in:
Hendrik Schutter 2022-06-14 15:28:00 +02:00
parent f459e7abcc
commit cdfea7b211
3 changed files with 137 additions and 83 deletions

View File

@ -1,23 +1,82 @@
"""Bed width in mm"""
bed_max_x = 376
import argparse
import sys
class Config:
"""G-code emitted at the start of processing the SVG file"""
preamble = "G90 ;Absolute programming\nG21 ;Programming in millimeters (mm)\nM5 ;Disable laser\n"
"""G-code emitted at the end of processing the SVG file"""
postamble = "G1 X0.0 Y0.0; Display printbed\nM02 ;End of program\n"
gcode_file_path = " "
svg_file_path = " "
feedrate = 0
moverate = 0
passes = 0
laserpower = 0.0
bedsizex = 0
bedsizey = 0
smoothness = 0.0
def parse_arguments(self):
parser = argparse.ArgumentParser(description='Generate gcode from vector graphics.')
parser.add_argument("-i", "--input", dest='inputfile', metavar='image.svg', help="path to vector graphic file", required=True)
parser.add_argument("-o", "--output", dest='outputfile', metavar='data.gcode', help="path to file for generated gcode", required=True)
parser.add_argument("-fr", "--feedrate", dest='feedrate', metavar=300, default=300, help="rate while laser is on", required=False)
parser.add_argument("-mr", "--moverate", dest='moverate', metavar=1200, default=1200, help="rate while laser is off", required=False)
parser.add_argument("-p", "--passes", dest='passes', metavar=1, default=1, help="number of passes (for deeper cutting)", required=False)
parser.add_argument("-lp", "--laserpower", dest='laserpower', metavar="0%", default="0%", help="laser power in %%", required=False)
parser.add_argument("-bx", "--bedsizex", dest='bedsizex', default="376", help="x size of bed in mm", required=False)
parser.add_argument("-by", "--bedsizey", dest='bedsizey', default="315", help="y size of bed in mm", required=False)
parser.add_argument("-s", "--smoothness", dest='smoothness', metavar=0.2, default=0.2, help="Used to control the smoothness/sharpness of the curves.\nSmaller the value greater the sharpness.\nMake sure the value is greater than 0.1", required=False)
args = parser.parse_args()
self.svg_file_path = args.inputfile
self.gcode_file_path = args.outputfile
self.feedrate = int(args.feedrate)
self.moverate = int(args.moverate)
self.passes = int(args.passes)
self.laserpower = ((float(args.laserpower.split("%")[0])/100.0))
self.bedsizex = int(args.bedsizex)
self.bedsizey = int(args.bedsizey)
self.smoothness = float(args.smoothness)
if(self.laserpower > 1):
print("[config] argument describing laser power is greater 100%")
sys.exit(1)
elif (self.laserpower < 0):
print("[config] argument describing laser power is lower 0%")
sys.exit(1)
if (self.feedrate < 1):
print("[config] argument describing feedrate is lower 1")
sys.exit(1)
if (self.moverate < 1):
print("[config] argument describing moverate is lower 1")
sys.exit(1)
if (self.passes < 1):
print("[config] argument describing passes is lower 1")
sys.exit(1)
if (self.bedsizex < 1):
print("[config] argument describing bedsizex is lower 1")
sys.exit(1)
if (self.bedsizey < 1):
print("[config] argument describing bedsizey is lower 1")
sys.exit(1)
"""Bed height in mm"""
bed_max_y = 315
"""X/Y speed in mm/minute"""
xy_speed = 50
"""G-code emitted at the start of processing the SVG file"""
preamble = "G90 ;Absolute programming\nG21 ;Programming in millimeters (mm)\nM5 ;Disable laser\n"
"""G-code emitted at the end of processing the SVG file"""
postamble = "G1 X0.0 Y0.0; Display printbed\nM02 ;End of program\n"
"""
Used to control the smoothness/sharpness of the curves.
Smaller the value greater the sharpness. Make sure the
value is greater than 0.1
"""
smoothness = 0.2

View File

@ -4,7 +4,6 @@ from __future__ import absolute_import
from __future__ import print_function
import sys
import os
import argparse
import xml.etree.ElementTree as ET
import shapes as shapes_pkg
from shapes import point_generator
@ -13,7 +12,7 @@ from config import *
debug = True
example_usage = "-i test_data/Test_H.svg -o test_data/test.gcode -fr 300 -mr 1200 -p 1 -lp 20%"
svg_shapes = set(['rect', 'circle', 'ellipse', 'line', 'polyline', 'polygon', 'path'])
gcode_file_path = " "
global conf
def gcode_write(gcode_file, gcode):
if (debug):
@ -26,26 +25,11 @@ def close_on_failure():
os.remove(gcode_file_path)
sys.exit(1)
def parse_arguments():
parser = argparse.ArgumentParser(description='Generate gcode from vector graphics.')
parser.add_argument("-i", "--input", dest='inputfile', metavar='image.svg', help="path to vector graphic file", required=True)
parser.add_argument("-o", "--output", dest='outputfile', metavar='data.gcode', help="path to file for generated gcode", required=True)
parser.add_argument("-fr", "--feedrate", dest='feedrate', metavar=300, default=300, help="rate while laser is on", required=False)
parser.add_argument("-mr", "--moverate", dest='moverate', metavar=1200, default=1200, help="rate while laser is off", required=False)
parser.add_argument("-p", "--passes", dest='passes', metavar=1, default=1, help="number of passes (for deeper cutting)", required=False)
parser.add_argument("-lp", "--laserpower", dest='laserpower', metavar="0%", default="0%", help="laser power in %%", required=False)
parser.add_argument("-bx", "--bedsizex", dest='bedsizex', default="376", help="x size of bed in mm", required=False)
parser.add_argument("-by", "--bedsizey", dest='bedsizey', default="315", help="y size of bed in mm", required=False)
parser.add_argument("-s", "--smoothness", dest='smoothness', metavar=0.2, default=0.2, help="Used to control the smoothness/sharpness of the curves.\nSmaller the value greater the sharpness.\nMake sure the value is greater than 0.1", required=False)
args = parser.parse_args()
return [args.inputfile, args.outputfile, int(args.feedrate), int(args.moverate), int(args.passes), ((float(args.laserpower.split("%")[0])/100.0)), int(args.bedsizex), int(args.bedsizey), float(args.smoothness) ]
def laserpower_to_pwm(percent):
if (percent <= 1):
return int(percent*255)
else:
return 0
def read_input_file(svg_file_path):
try:
tree = ET.parse(svg_file_path)
@ -71,7 +55,7 @@ def generate_gcode(svg_file_root_tree, gcode_file):
print("[SVG loaded] With:" + str(width) + "mm Height:" + str(height) + "mm")
#generate start cmds's
gcode_write(gcode_file, preamble)
gcode_write(gcode_file, conf.preamble)
for elem in svg_file_root_tree.iter():
@ -84,18 +68,19 @@ def generate_gcode(svg_file_root_tree, gcode_file):
shape_obj = shape_class(elem)
obj_path = shape_obj.d_path()
obj_trans_matrix = shape_obj.transformation_matrix()
gcode_write(gcode_file, "G0 F" + str(conf.moverate) + " set the moverate to " + str(conf.moverate) + "mm/min;\n")
if obj_path:
gcode_write(gcode_file, "; == Start of " + tag_suffix + " ==\n")
points = point_generator(obj_path, obj_trans_matrix, smoothness)
points = point_generator(obj_path, obj_trans_matrix, conf.smoothness)
num_points = 0
for x,y in points:
if (debug): print("[Point] X: " + str(x) + " Y: " + str(y))
if x > 0 and x < bed_max_x and y > 0 and y < bed_max_y:
if x > 0 and x < conf.bedsizex and y > 0 and y < conf.bedsizey:
gcode_write(gcode_file, "G1 X%0.001f Y%0.001f\n" % (x, y))
num_points += 1
if (num_points == 1):
gcode_write(gcode_file, "M3 I S15 ;start laser\n")
gcode_write(gcode_file, "G0 F" + str(conf.feedrate) + " set the feedrate to " + str(conf.feedrate) + "mm/min;\n")
gcode_write(gcode_file, "M3 I S" + str(laserpower_to_pwm(conf.laserpower)) + " ;start laser\n")
elif (debug):
print("\n; Coordinates out of range:", "G1 X%0.01f Y%0.01f" % (x, y))
print("; Raw:", str(x), str(y), "\nScaled:", str(x), str(y), "\n")
@ -103,28 +88,17 @@ def generate_gcode(svg_file_root_tree, gcode_file):
gcode_write(gcode_file, "M5 ;stop laser\n")
gcode_write(gcode_file, "; == End of " + tag_suffix + " ==\n")
generated_points_count += num_points
gcode_write(gcode_file, postamble)
gcode_write(gcode_file, "G0 F" + str(conf.moverate) + " set the moverate to " + str(conf.moverate) + "mm/min;\n")
gcode_write(gcode_file, conf.postamble)
print("\nGenerated", generated_points_count, "points")
if __name__ == "__main__":
sys.setrecursionlimit(20000) #needed for svg's with more indepented paths
svg_file_path, gcode_file_path, feedrate, moverate, passes, laserpower, bedsizex, bedsizey, smoothness = parse_arguments()
print("inputfile: " + str(svg_file_path))
print("outputfile: " + str(gcode_file_path))
print("feedrate: " + str(feedrate))
print("moverate: " + str(moverate))
print("passes: " + str(passes))
print("laserpower: " + str(laserpower))
print("bedsizex: " + str(bedsizex))
print("bedsizey: " + str(bedsizey))
print("smoothness: " + str(smoothness))
conf = Config()
conf.parse_arguments()
try:
with open(gcode_file_path, 'w') as gcode_file:
generate_gcode(read_input_file(svg_file_path),gcode_file)
with open(conf.gcode_file_path, 'w') as gcode_file:
generate_gcode(read_input_file(conf.svg_file_path),gcode_file)
except Exception as e:
print("unable to create gcode file: \n" + str(e))
close_on_failure()

View File

@ -1,29 +1,50 @@
G90 ;Absolute programming
G21 ;Programming in millimeters (mm)
M5 ;Disable laser
; == Start of path ==
G1 X8.6 Y11.7
M3 I S15 ;start laser
G1 X8.6 Y11.7
G1 X29.4 Y9.7
G1 X41.5 Y22.1
G1 X35.3 Y35.3
G1 X34.7 Y37.4
G1 X33.9 Y38.9
G1 X32.5 Y40.3
G1 X30.4 Y41.0
G1 X27.6 Y40.8
G1 X23.7 Y39.4
G1 X18.8 Y36.2
G1 X14.9 Y33.0
G1 X12.3 Y30.3
G1 X10.6 Y27.9
G1 X9.7 Y26.1
G1 X9.4 Y24.6
G1 X9.4 Y23.3
G1 X9.6 Y23.0
G1 X8.6 Y11.7
G0 F1200 set the moverate to 1200mm/min;
; == Start of ellipse ==
G1 X5.0 Y10.0
G0 F300 set the feedrate to 300mm/min;
M3 I S2 ;start laser
G1 X5.0 Y10.4
G1 X5.3 Y11.7
G1 X5.9 Y12.9
G1 X6.8 Y13.8
G1 X7.9 Y14.5
G1 X9.1 Y14.9
G1 X10.4 Y15.0
G1 X11.7 Y14.7
G1 X12.9 Y14.1
G1 X13.8 Y13.2
G1 X14.5 Y12.1
G1 X14.9 Y10.9
G1 X15.0 Y9.6
G1 X14.7 Y8.3
G1 X14.1 Y7.1
G1 X13.2 Y6.2
G1 X12.1 Y5.5
G1 X10.9 Y5.1
G1 X9.6 Y5.0
G1 X8.3 Y5.3
G1 X7.1 Y5.9
G1 X6.2 Y6.8
G1 X5.5 Y7.9
G1 X5.1 Y9.1
G1 X5.0 Y10.0
M5 ;stop laser
; == End of path ==
; == End of ellipse ==
G0 F1200 set the moverate to 1200mm/min;
; == Start of rect ==
G1 X30.0 Y30.0
G0 F300 set the feedrate to 300mm/min;
M3 I S2 ;start laser
G1 X30.0 Y30.0
G1 X40.0 Y30.0
G1 X40.0 Y40.0
G1 X30.0 Y40.0
G1 X30.0 Y30.0
M5 ;stop laser
; == End of rect ==
G0 F1200 set the moverate to 1200mm/min;
G1 X0.0 Y0.0; Display printbed
M02 ;End of program