示例#1
0
def list(args, gcodes, clearance_height):
  m = Machine()
  print("The line numbers where a cut is possible are:")
  for gcode in gcodes:
    m.process_gcodes(gcode['gcode'])
    if clearance_height == m.pos._value['Z']:
      print("  {:7} at {:6.2f}% in {}".format(gcode["line_no"], gcode["line_no"]*100/gcodes[-1]["line_no"],m.pos))
示例#2
0
def getClearanceHeight(gcodes):
  m = Machine()  
  last = m.pos
  clearance_height = m.pos._value['Z']
  for gcode in gcodes:
    m.process_gcodes(gcode['gcode'])
    if clearance_height < m.pos._value['Z']: clearance_height = m.pos._value['Z']
  return clearance_height
示例#3
0
def get_positions(data):
    t1 = dt.now()
    machine = Machine()
    positions = []
    last = []
    for i in data.split('\n'):
        line = Line(i)
        block = line.block.gcodes
        for g in block:
            machine.process_gcodes(g)
            keys = []
            for key in machine.pos.values.keys():

                keys.append(machine.pos.values[key])
            #positions.append(keys)
            position = machine.pos.values
            if position != last:
                positions.append(position)
            last = position
    timer(t1, "processing gcode")


    return positions
示例#4
0
def cut(args, gcodes, clearance_height):
  non_motion = []
  
  # Select where to cut
  m = Machine()
  last = m.pos
  checkpoint = {'gcode': None, 'pos': m.pos, 'mode': m.mode.distance}
  for idx, gcode in enumerate(gcodes):
    m.process_gcodes(gcode['gcode'])
    if gcode["line_no"] > args.line:
      break
    if m.pos == last: non_motion.append(gcode)
    last = m.pos
    if clearance_height == m.pos._value['Z']:
      checkpoint = {'idx': idx, 'gcode': gcode, 'pos': m.pos, 'mode': m.mode.distance}
      
  #print("Checkpoint at {}".format(checkpoint))
  
  # If the user wants to cut before the first clearance height, do nothing
  if checkpoint['gcode'] is None:
    print("The provided line is not a valid one, use list subcommand for more info. Exiting")
    return
    
  # Dump the non motion commands first
  for gcode in non_motion:
   # if not isinstance(gcode['gcode'], GCodeFeedRate):  # Ignore feedrates please
      print(FORMAT.format(str(gcode['gcode']), str(gcode['line_no']), gcode['gcode'].__class__.__name__), file=args.output)
   
  # Insert the travel until the checkpoint position
  gcode = GCodeAbsoluteDistanceMode()
  print(FORMAT.format(str(gcode), "Cut comp.", gcode.__class__.__name__), file=args.output)
  gcode = GCodeRapidMove(Z=clearance_height)
  print(FORMAT.format(str(gcode), "Cut comp.", gcode.__class__.__name__), file=args.output)
  gcode = GCodeRapidMove(X=checkpoint['pos']._value['X'], Y=checkpoint['pos']._value['Y'], Z=checkpoint['pos']._value['Z'])
  print(FORMAT.format(str(gcode), "Cut comp.", gcode.__class__.__name__), file=args.output)
  gcode = checkpoint['mode']
  print(FORMAT.format(str(gcode), "Cut comp.", gcode.__class__.__name__), file=args.output)
  print(CHECKPOINT_TAG, file=args.output)
      
  # Dump the rest of the codes from the original file (to preserve formatting)
  try: 
    args.input.seek(gcodes[checkpoint['idx']+1]['offset'])
    for line in args.input:
      print(line, file=args.output, end="")
  except: pass
  
  if args.verify:
    s = Machine()
    t = Machine()
    
    # Run input gcodes until the selected
    for gcode in gcodes[:checkpoint['idx']+1]:
      s.process_gcodes(gcode['gcode'])
    
    # Run output gcodes until checkpoint
    args.output.seek(0)
    line = args.output.readline()
    while line:
      if CHECKPOINT_TAG in line:
        break
      for gcode in Line(line).block.gcodes:
        t.process_gcodes(gcode)
      line = args.output.readline()

    args.input.seek(gcodes[checkpoint['idx']+1]['offset'])
    sline = args.output.readline()
    tline = args.input.readline()
    while sline and tline:
      for gcode in Line(sline).block.gcodes: s.process_gcodes(gcode)
      for gcode in Line(tline).block.gcodes: t.process_gcodes(gcode)
      if s.pos!=t.pos:
        print("\nOutput gcode not verified (source: {}, target: {})".format(s.pos, t.pos))
        return
      sline = args.output.readline()
      tline = args.input.readline()
        
    print("\nOutput gcode verified")
示例#5
0
class parse_gcode(object):

    def __init__(self, gcode):

        self.gcode = gcode
        # gcode stored in plain text or whatever

        self.all_positions = []
        # list of every xyz position the gcode contains, including 'strokes' and 'seeks'. without separating strokes and
        # seeks, the order of the self.all_positions cannot be changed

        self.machine = Machine()
        # Virtual machine that will simulate running the gcode and extract coordinates

        self.cities = []
        # in TSP parlance, each uninterrupted line to be drawn on the paper is considered a city
        # unlike usual TSP, our cities must have a different start and end rather than being a single point
        # therefore each city is a list coordinates.

        self.cities_lite = []
        # in order to find the best tour we only need the start and end points of each city.
        # we will need the whole city only when we come to output new gcode one day.
        # so to keep it lite we strip all the in between coordinates plus the z values
        # also format the data as a simple array for numpy reasons
        # format is [startX, startY, endX, endY]

        self.seek_threshold = self.guess_seek_threshold()
        print('seek threshold is', self.seek_threshold)
        # if the Z position of the pen is above this value, we will assume it's a seek (flight), not a stroke (city)

        # self.original_tour = [x for x in range(len(self.cities_lite))]
        # in TSP parlance the tour is the order in which we visit the cities, ie the whole thing we want to find
        # we keep the original order of strokes for reference

        self.parse()

    def parse(self):
        # use the machine to populate the all_positions variable with xyz coordinates
        t1 = dt.now()

        previous_position = []

        for i in self.gcode.split('\n'):
            line = Line(i)
            block = line.block.gcodes
            for g in block:
                self.machine.process_gcodes(g)
                keys = []
                for key in self.machine.pos.values.keys():
                    keys.append(self.machine.pos.values[key])
                this_position = self.machine.pos.values
                if this_position != previous_position:
                    self.all_positions.append(this_position)

                previous_position = this_position
        timer(t1, 'parsing')
        self.get_cities()
        return self.all_positions

    def guess_seek_threshold(self):

        minZ = 0
        maxZ = 0
        for i in self.all_positions:
            if "Z" in i.keys():
                minZ = min(minZ, i["Z"])
                maxZ = max(maxZ, i["Z"])
        return (minZ + maxZ) / 2

    def get_cities(self):

        this_city = []

        for x, this_position in enumerate(self.all_positions):
            if x == 0:
                pass
                # current_pos = self.all_positions[0]
                #
                # if current_pos['Z'] <= self.seek_threshold:
                #     this_city.append(this_position)
            else:
                if this_position['Z'] <= self.seek_threshold:
                    this_city.append(this_position)
                else:
                    if this_city:
                        self.cities.append(this_city)
                        this_city = []

        self.cities_lite = [[i[0]['X'], i[0]['Y'], i[-1]['X'], i[-1]['Y']] for i in self.cities]

        return self.cities