# -*- coding: utf-8 -*- from __future__ import division import serial import time import math class Command: inicoms= ("IN", "SP", "LT") scalecoms=("PA", "PD", "PR", "PU", "CI" ) movecoms=("PA", "PD", "PR", "PU" ) def __init__(self, name, *args): self.name = name # hpgl Command name e.g. PU, PA, self.args = args # list of Position args @property def scalable(self): return True \ if self.name in Command.scalecoms and self.args else \ False @property def movable(self): return True \ if self.name in Command.movecoms and self.args else \ False @property def x(self): return self.args[0] \ if self.movable else\ None @property def y(self): return self.args[1] \ if self.movable else\ None def __len__(self): return len(str(self)) def __str__(self): return self.name + ",".join(str(arg) for arg in self.args) + ";" def __mul__(self, factor): if not self.scalable: return self if type(factor) == type(0) or type(factor) == type(0.0): factor = (factor, factor) return Command(self.name, int(self.args[0] * factor[0]), int(self.args[1] * factor[1])) \ if len(self.args)>1 else\ Command(self.name,int(self.args[0]*factor[0]) ) def __add__(self, addend): if not self.movable: return self if type(addend) == type(0) or type(addend) == type(0.0): addend = (addend, addend) return Command(self.name, int(self.x + addend[0]), int(self.y + addend[1])) def __sub__(self, addend): if type(addend) == type(0) or type(addend) == type(0.0): addend = (addend, addend) return self + (-addend[0], -addend[1]) def rotate(self, angl): if not self.movable: return self cosa=math.cos(angl*math.pi/180) sina=math.sin(angl*math.pi/180) return Command(self.name,int(self.x*cosa-self.y*sina),int(self.y*cosa+self.x*sina)) def flip(self): if not self.movable: return self return Command(self.name,self.y,-self.x) class Program: def __init__(self, commands=[]): self.commands = commands def parsefile(self, filename): with open(filename) as file: self.parse( file.read()) def parse(self, code): for command in code.strip().split(";")[:-1]: name, args = command[:2], command[2:] args = [int(arg) for arg in args.split(",")] if args else [] #print name , args self.commands.append(Command(name, *args)) def __str__(self): return "".join(str(command) for command in self.commands) def __mul__(self, arg): return Program([command * arg for command in self.commands]) def __add__(self, arg): return Program([command + arg for command in self.commands]) def __sub__(self, arg): return Program([command - arg for command in self.commands]) def __len__(self): return len(str(self)) def rotate(self, angl): return Program([command.rotate(angl) for command in self.commands]) def flip(self): return Program([command.flip() for command in self.commands]) @property def xmax(self): return max(command.x for command in self.commands if command.x and command.movable) @property def xmin(self): return min(command.x for command in self.commands if command.x and command.movable) @property def ymax(self): return max(command.y for command in self.commands if command.y and command.movable) @property def ymin(self): return min(command.y for command in self.commands if command.y and command.movable) @property def center(self): #return 42 return int((self.xmin+self.xmax)/2),int((self.ymin+self.ymax)/2) @property def size(self): return self.xmax-self.xmin , self.yax - self.ymin @property def winsize(self): return self.xmax-self.xmin , self.ymax - self.ymin def centralize(self): return self-self.center @property def oob(self, pltr): return (self.xmax > pltr.xmax or self.xmin < pltr.xmin or self.ymin < pltr.ymin or self.ymax > pltr.ymax) def full(self,pltr): arg = min(pltr.winsize[0]/self.winsize[0],pltr.winsize[1]/self.winsize[1]) return self*arg class Plotter: def __init__(self): try: print 'try to open Serial' self.ser = serial.Serial('/dev/ttyUSB0', 9600,serial.EIGHTBITS,serial.PARITY_NONE,serial.STOPBITS_ONE,15) print ' sending: OW;' self.ser.write('OW;') print 'OW; sent, start reading' s = [] while True: x = self.ser.read() if x == "\x0d": break s.append(x) if not s: print 'I/O Fehler ist der Plotter bereit' print 'Gerät sagt:' + str(s) self.__boundaries = tuple(int(x) for x in "".join(s).split(",")) except OSError: self.__boundaries = -2000,-2000,2000,2000 self.ser=None print "No such file or directory: '/dev/ttyUSB0'" @property def xmin(self): return self.__boundaries[0] @property def ymin(self): return self.__boundaries[1] @property def xmax(self): return self.__boundaries[2] @property def ymax(self): return self.__boundaries[3] @property def center(self): return (self.xmin + self.xmax)/2, (self.ymin + self.ymax)/2 def write(self,programm): self.ser.write(str(programm)) @property def winsize(self): return self.xmax-self.xmin , self.ymax - self.ymin def oob(self,p): return (p.xmax > self.xmax or p.xmin < self.xmin or p.ymin < self.ymin or p.ymax > self.ymax) @property def ready(self): try: print 'try to get Status' if not self.ser: return False self.ser.write('OS;') print 'OW; sent, start reading' s = [] while True: x = self.ser.read() if x == "\x0d": break s.append(x) if not s: return False print s return True except OSError: return False def plot(self,prog): if (not self.oob(prog)) and self.ready: self.write(prog) plt=Plotter() print "p" p=Program() #print plt.winsize print "parsefile" p.parsefile("sign") #p=p.rotate(15) #print str(p) p=p*(-0.2,0.2) #p=p.flip() #p=p.full(plt) p=p.centralize() #print str(p) plt.plot(p) print p.winsize print len(p) #print str(p)