Пример #1
0
	def __init__(self):
		if(platform.system() == 'Linux'):
			self.serial = serial.Serial ("/dev/ttyAMA0", self.BAUDRATE, timeout=1)	# open the serial "/dev/ttyAMA0"
		
		self.svg2plt = SVG2PLT()
		self.plt = PLT()
		
		self.home()
Пример #2
0
class Cutter:

    # PLT and SVG
    plt = None
    svg = None

    # CONSTANTS
    MAX_X = 10000  # maximum distance on the X axis
    MAX_Y = 10000  # maximum distance on the Y axis
    BAUDRATE = 57600  # baudrate for the serial port comms

    # The current location of the head on the x, y axis
    current_x = 0
    current_y = 0

    step_size = 100  # the number of positions to move with user control

    passes = 1  # the number of times to cut the shape
    scale = 1.0

    # Up speed - speed that the machine moves while up
    # us <1-40>
    up_speed = 40

    # Down speed - speed that the machine moves while down
    # ds <1-40>
    down_speed = 40

    # Plunge speed - speed at which the tool is lowered
    # ps <1-40>
    plunge_speed = 40

    # Lift speed - speed at which the tool is raised
    # ls <1-40>
    lift_speed = 40

    # Depth - default tool depth while down
    # dp <1-670>
    cutting_depth = 300

    # Up lift - Lift tool by an extra amount while up (for special cases)
    # ul <0-300>
    up_lift = 0

    # Up/down state - Value is 1 if up, 0 if down
    # returned: up=<0/1>;
    up = None

    # Tool - Value is 0 for left tool or 1 for right tool
    # tool <0/1>
    # returned: tool=<0/1>;
    current_tool = 0

    serial = None

    # CONSTRUCTOR
    def __init__(self):
        if (platform.system() == 'Linux'):
            self.serial = False
            #self.serial = serial.Serial ("/dev/ttyAMA0", self.BAUDRATE, timeout=1)	# open the serial "/dev/ttyAMA0"

        self.svg2plt = SVG2PLT()
        self.plt = PLT()

        self.home()

    def __del__(self):
        if (platform.system() == 'Linux' and self.serial != False):
            self.serial.close()

    # home the cutter location
    def home(self):
        self.current_x = 0
        self.current_y = 0
        self.move(self.current_x, self.current_y)

    # change a setting variable
    def change_setting(self, setting, value):
        setattr(self, setting, float(value))
        print(setting + ":" + value)

    # load a file
    def load_file(self, filename='./static/svg/pattern.svg'):
        self.svg2plt.load_file(filename)
        self.svg2plt.parse()

        self.plt = self.svg2plt.plt  # TODO: i'm not completely happy with this idea
        self.plt.reset_settings()

        output = self.display_dimensions()
        return (json.dumps(output))

    # send the PLT to the cutter
    def cut(self):
        self.plt.scale = self.scale
        output = self.plt.build()
        print(output)

        for line in output:
            response = self.send(line)

    def move_direction(self, direction):
        if (direction == 'N'):
            self.move((self.step_size * -1), 0)
        elif (direction == 'S'):
            self.move(self.step_size, 0)
        elif (direction == 'E'):
            self.move(0, (self.step_size * -1))
        elif (direction == 'W'):
            self.move(0, self.step_size)

    def move(self, x, y):
        next_x = self.current_x + x
        next_y = self.current_y + y

        if (next_x < 0):
            next_x = 0
        elif (next_x > self.MAX_X):
            next_x = self.MAX_X

        if (next_y < 0):
            next_y = 0
        elif (next_y > self.MAX_Y):
            next_y = self.MAX_Y

        command = Coord('U', next_x, next_y)
        response = self.send(str(command))
        if (response):
            self.current_x = next_x
            self.current_y = next_y

            self.plt.x_offset = self.current_x  # TODO: I'm not sure this is the right place to do this.
            self.plt.y_offset = self.current_y

    # send a string to the serial port and read the response
    def send(self, command):
        if (platform.system() == 'Linux' and self.serial != False):
            response = self.serial.write(command.encode('utf-8'))
        else:
            response = 1
        return (response)

    def display_dimensions(self):
        if (self.plt.display_units == "mm"):
            output = {
                "width": format(self.plt.display_width * 25.4, '.1f'),
                "height": format(self.plt.display_height * 25.4, '.1f'),
                "units": self.plt.display_units
            }
        else:
            output = {
                "width": self.plt.display_width,
                "height": self.plt.display_height,
                "units": self.plt.display_units
            }
        return (json.dumps(output))
Пример #3
0
class Cutter:

	# PLT and SVG
	plt = None
	svg = None

	# CONSTANTS
	MAX_X = 10000		# maximum distance on the X axis
	MAX_Y = 10000		# maximum distance on the Y axis
	BAUDRATE = 57600	# baudrate for the serial port comms

	# The current location of the head on the x, y axis
	current_x = 0
	current_y = 0
	
	step_size = 100		# the number of positions to move with user control
	
	passes = 1		# the number of times to cut the shape
	scale = 1.0
	
	# Up speed - speed that the machine moves while up
	# us <1-40> 
	up_speed = 40
	
	# Down speed - speed that the machine moves while down
	# ds <1-40> 
	down_speed = 40	

	# Plunge speed - speed at which the tool is lowered
	# ps <1-40> 	
	plunge_speed = 40
	
	# Lift speed - speed at which the tool is raised
	# ls <1-40> 	
	lift_speed = 40
	
	# Depth - default tool depth while down
	# dp <1-670>
	cutting_depth = 300

	# Up lift - Lift tool by an extra amount while up (for special cases)
	# ul <0-300>
	up_lift = 0
	
	# Up/down state - Value is 1 if up, 0 if down
	# returned: up=<0/1>;
	up = None
	
	# Tool - Value is 0 for left tool or 1 for right tool
	# tool <0/1>
	# returned: tool=<0/1>;
	current_tool = 0
	
	serial = None
	
	# CONSTRUCTOR
	def __init__(self):
		if(platform.system() == 'Linux'):
			self.serial = serial.Serial ("/dev/ttyAMA0", self.BAUDRATE, timeout=1)	# open the serial "/dev/ttyAMA0"
		
		self.svg2plt = SVG2PLT()
		self.plt = PLT()
		
		self.home()
	
	def __del__(self):	
		if(platform.system() == 'Linux'):
			self.serial.close()
	
	# home the cutter location
	def home(self):
		self.current_x = 0
		self.current_y = 0
		self.move(self.current_x, self.current_y)
	
	# change a setting variable
	def change_setting(self, setting, value):
		setattr(self, setting, float(value))
		print(setting+":"+value)
	
	# load a file
	def load_file(self, filename='./static/svg/pattern.svg'):
		self.svg2plt.load_file(filename)
		self.svg2plt.parse()
		
		self.plt = self.svg2plt.plt		# TODO: i'm not completely happy with this idea
		self.plt.reset_settings()
		
		output = self.display_dimensions()
		return(json.dumps(output))
		
	# send the PLT to the cutter
	def cut(self):
		self.plt.scale = self.scale
		output = self.plt.build()
		print(output)
		
		for line in output:
			response = self.send(line)
	
	def move_direction(self, direction):
		if(direction=='N'):
			self.move((self.step_size*-1), 0)
		elif(direction=='S'):
			self.move(self.step_size, 0)
		elif(direction=='E'):
			self.move(0, (self.step_size*-1))
		elif(direction=='W'):
			self.move(0, self.step_size)

	def move(self, x, y):
		next_x = self.current_x + x
		next_y = self.current_y + y
		
		if(next_x<0):
			next_x = 0
		elif(next_x>self.MAX_X):
			next_x = self.MAX_X
		
		if(next_y<0):
			next_y = 0
		elif(next_y>self.MAX_Y):
			next_y = self.MAX_Y
		
		command = Coord('U', next_x, next_y)
		response = self.send(str(command))
		if(response):
			self.current_x = next_x;
			self.current_y = next_y;
			
			self.plt.x_offset = self.current_x		# TODO: I'm not sure this is the right place to do this.
			self.plt.y_offset = self.current_y
	
	# send a string to the serial port and read the response
	def send(self, command):
		if(platform.system() == 'Linux'):
			response = self.serial.write(command.encode('utf-8'))
		else:
			response = 1
		return(response)
		
	def display_dimensions(self):
		if(self.plt.display_units == "mm"):
			output = {"width":format(self.plt.display_width*25.4, '.1f'),"height":format(self.plt.display_height*25.4, '.1f'),"units":self.plt.display_units}
		else:
			output = {"width":self.plt.display_width,"height":self.plt.display_height,"units":self.plt.display_units}
		return(json.dumps(output))
	
			
		
Пример #4
0
class SVG2PLT:
	# the PLT object for operations and export
	plt = None
	
	# SVG path objects
	paths = None
	
	delimiter = 'z'		# path delimiter (mM -> zZ)
	
	divisions = 30.0 	# the number of point divisions on an element
	overcut = 0.2		# how much to overcut the next shape (TODO: units for now as percentage. could be a percentage of the line, could be mm?)	
		
	def __init__(self):
		self.paths = []
		self.plt = PLT()
		
	# open a file with name 'filename', extract the path elements
	def load_file(self, filename):
		#read the svg doc as a DOM to extract the XML <path> element
		doc = xml.dom.minidom.parse(filename)
		
		# determine the ratio of each pixel to real world units
		svg = doc.getElementsByTagName('svg')[0]
		
		#get the units for this file
		height = svg.getAttribute('height')
		width = svg.getAttribute('width')
		if(height.find("in")!=-1):
			self.display_units = "in"
		elif(height.find("mm")!=-1):
			self.display_units = "mm"
		elif(height.find("cm")!=-1):
			self.display_units = "cm"
		elif(height.find("px")!=-1):
			self.display_units = "px"
			
		height = height.replace(self.display_units, "")
		width = width.replace(self.display_units, "")

		viewbox = svg.getAttribute('viewBox').rsplit(" ")
		self.unit = (float(width)/float(viewbox[2]) + float(height)/float(viewbox[3]))/2
		
		self.plt.display_units = self.display_units
		
		# extract the path elements
		path_strings = [path.getAttribute('d') for path in doc.getElementsByTagName('path')]
		
		# iterate over each path that is found
		for path_string in path_strings:
			# break up each path shape into the individual lines (mM -> zZ)
			lines = re.split('z|Z', path_string)

			for line in lines:
				if(len(line)>2):
					line += self.delimiter
					item = parse_path(line) 		# convert the string to a path using svg.path library
					self.paths.append(item)		

	# load the file
	def parse(self):
		for path in self.paths:
			self.parse_path(path)
			
			if(path.closed==True):
				self.parse_overcut(path)
				
		self.plt.calc_bounding_box()
		
	# parse a path 
	def parse_path(self, path):
		first = True
		for item in path:
			self.parse_item(item, first)
			if(first):
				first = False;

	# parse an item (line, cubic, quadratic bezier)
	def parse_item(self, item, first):	
		for i in range(0, int(self.divisions)):
			loc = i/self.divisions
			point = item.point(loc)
			
			if(first and i==0):
				self.plt.add_coord('U', point.real, point.imag)
			
			self.plt.add_coord('D', point.real, point.imag)

	# parse a the first item in a path for overcut (line, cubic, quadratic bezier)
	def parse_overcut(self, path):
		item = path[0]
		
		for i in range(0, int(self.divisions*self.overcut)):
			loc = i/self.divisions
			point = item.point(loc)
			self.plt.add_coord('D', point.real, point.imag)
Пример #5
0
	def __init__(self):
		self.paths = []
		self.plt = PLT()