2016-08-02 8 views
2

Я хочу прочитать файл g-кода по строкам и, исходя из комментария в конце, выполнить его. Код g выходит из Slic3r. Некоторые примеры строки в произвольном порядке выглядеть следующим образом:Редактировать код G Строка по строке

G1 Z0.242 F7800.000 ; move to next layer (0) 
G1 E-2.00000 F2400.00000 ; retract 
G1 X0.000 Y30.140 F7800.000 ; move to first skirt point 
G1 E0.00000 F2400.00000 ; unretract 
G1 X-53.493 Y30.140 E2.14998 F1800.000 ; skirt 
G1 X57.279 Y-37.776 E22.65617 ; perimeter 
G1 X-52.771 Y-38.586 E56.83128 ; infill 

Комментарий всегда начинается точкой с запятой, а также использует постоянные термины, такие как периметр или засыпка. В идеале сценарий будет читать строку, искать конкретный случай, выполнять действие на основе этого, а затем обновлять файл, а затем перейти к следующей строке. Я немного новичок в python, поэтому я знаю, что это будет сделано с помощью цикла for с вложенными операциями if, однако я не уверен, как настроить архитектуру на основе этих ключевых терминов.

ответ

1

Я не уверен, что вы хотите точно изменить, поэтому я решил добавить слово '(up)' перед комментарием, указывающим на отвод, и '(down)' перед комментарием, который указывает на нерасторжение.

file_name = "file.gcode" # put your filename here 

with open(file_name, 'r+') as f: 

    new_code = ""   # where the new modified code will be put 
    content = f.readlines() # gcode as a list where each element is a line 

    for line in content: 
     gcode, comment = line.strip('\n').split(";") # seperates the gcode from the comments 
     if 'unretract' in comment: 
      comment = ' (down) ' + comment 
     elif 'retract' in comment: 
      comment = ' (up)' + comment 

     new_code += gcode + ';' + comment + '\n' # rebuild the code from the modified pieces 

    f.seek(0)   # set the cursor to the beginning of the file 
    f.write(new_code) # write the new code over the old one 

Содержимое файла сейчас будет:

G1 Z0.242 F7800.000 ; move to next layer (0) 
G1 E-2.00000 F2400.00000 ; (up) retract 
G1 X0.000 Y30.140 F7800.000 ; move to first skirt point 
G1 E0.00000 F2400.00000 ; (down) unretract 
G1 X-53.493 Y30.140 E2.14998 F1800.000 ; skirt 
G1 X57.279 Y-37.776 E22.65617 ; perimeter 
G1 X-52.771 Y-38.586 E56.83128 ; infill 

Если вы хотите изменить GCode вместо этого, позволяет сказать, заменить первую букву на 'U', если комментарий указывает на втягивание, и 'D' если комментарий указывает unretraction, вы просто должны заменить это:

if 'unretract' in comment: 
    comment = ' (down) ' + comment 
elif 'retract' in comment: 
    comment = ' (up)' + comment 

к этому:

if 'unretract' in comment: 
    gcode = 'D' + gcode[1:] 
elif 'retract' in comment: 
    gcode = 'U' + gcode[1:] 

Нового содержимое файла:

G1 Z0.242 F7800.000 ; move to next layer (0) 
U1 E-2.00000 F2400.00000 ; retract 
G1 X0.000 Y30.140 F7800.000 ; move to first skirt point 
D1 E0.00000 F2400.00000 ; unretract 
G1 X-53.493 Y30.140 E2.14998 F1800.000 ; skirt 
G1 X57.279 Y-37.776 E22.65617 ; perimeter 
G1 X-52.771 Y-38.586 E56.83128 ; infill 

Я надеюсь, что это помогает!


EDIT

Чтобы ответить на ваш запрос, чтобы получить X, Y и F значения, здесь обновленный скрипт для сохранения этих значений:

file_name = "file.gcode" # put your filename here 

    with open(file_name, 'r+') as f: 

     coordinates = [] 
     content = f.readlines() # gcode as a list where each element is a line 

     for line in content: 
      gcode, comment = line.strip('\n').split(";") 
      coordinate_set = {} 
      if 'retract' not in comment and 'layer' not in comment: 
       for num in gcode.split()[1:]: 
        coordinate_set[num[:1]] = float(num[1:]) 
       coordinates.append(coordinate_set) 

Если вы print(coordinates) вас получить:

[{'X': 0.0, 'F': 7800.0, 'Y': 30.14}, {'E': 2.14998, 'X': -53.493, 'F': 1800.0, 'Y': 30.14}, {'E': 22.65617, 'X': 57.279, 'Y': -37.776}, {'E': 56.83128, 'X': -52.771, 'Y': -38.586}] 

EDIT 2

Сценарий 1:

file_name = "file.gcode" 

with open(file_name, 'r+') as f: 

    new_code = ""    
    content = f.readlines() 

    for line in content: 
     if ';' in line: 
      try: 
       gcode, comment = line.strip('\n').split(";") 
      except: 
       print('ERROR\n', line) 
     else: # when there are no comments 
      gcode = line.strip('\n') 
      comment = "" 

     if 'unretract' in comment: 
      comment = ' (down) ' + comment 
     elif 'retract' in comment: 
      comment = ' (up)' + comment 

     if comment != "": 
      new_code += gcode + ';' + comment + '\n' 
     else: # when there are no comments 
      new_code += gcode + '\n' 

    f.seek(0)   
    f.write(new_code) 

Сценарий 2:

file_name = "file.gcode" 

with open(file_name, 'r+') as f: 

    coordinates = [] 
    content = f.readlines() 

    for line in content: 
     if ';' in line: 
      try: 
       gcode, comment = line.strip('\n').split(";") 
      except: 
       print(' ERROR \n', line, '\n') 
     else: 
      gcode = line.strip('\n') 
      comment = "" 

     coordinate_set = {} 
     if 'retract' not in comment and 'layer' not in comment and gcode: 
      for num in gcode.split()[1:]: 
       coordinate_set[num[:1]] = float(num[1:]) 
      coordinates.append(coordinate_set) 

Некоторые линии, где Slic3r делает некоторые странные тексты не работают, это то, что ERROR печатная вещь есть. Кроме того, я рекомендую вам не попробовать и print все координаты, так как это привело к сбою Python.Если вы хотите, чтобы увидеть всю совокупность координат, вы можете вставить их на отдельном .txt файла, как например:

with ('coordinates.txt', 'w') as f2: 
    f2.write(coordinates) 

EDIT 3

Обновленные скрипты для работы с комментариями в скобках ,

Сценарий 1:

file_name = "file.gcode" 

with open(file_name, 'r+') as f: 

    new_code = "" 
    content = f.readlines() 

    for line in content: 
     if ';' in line: 
      try: 
       gcode, comment = line.strip('\n').split(";") 
      except: 
       print('ERROR\n', line) 
     else: # when there are no comments 
      gcode = line.strip('\n') 
      comment = "" 

     if 'unretract' in comment: 
      comment = ' (down) ' + comment 
     elif 'retract' in comment: 
      comment = ' (up)' + comment 

     if comment != "": 
      new_code += gcode + ';' + comment + '\n' 
     else: # when there are no comments 
      new_code += gcode + '\n' 

    f.seek(0) 
    f.write(new_code) 

Сценарий 2:

file_name = "3Samples_0skin_3per.gcode" # put your filename here 

with open(file_name, 'r+') as f: 

    coordinates = [] 
    content = f.readlines() 

    for line in content: 
     if ';' in line: 
      try: 
       gcode, comment = line.strip('\n').split(";") 
      except: 
       print(' ERROR 1: \n', line, '\n') 
     elif '(' in line: 
      try: 
       gcode, comment = line.strip('\n').strip(')').split("(") 
      except: 
       print('ERROR 2: \n', line, '\n') 
     else: 
      gcode = line.strip('\n') 
      comment = "" 

     coordinate_set = {} 
     if 'retract' not in comment and 'layer' not in comment and gcode: 
      for num in gcode.split()[1:]: 
       if len(num) > 1: 
        try: 
         coordinate_set[num[:1]] = float(num[1:]) 
        except: 
         print('ERROR 3: \n', gcode, '\n') 
      coordinates.append(coordinate_set) 
+0

Это очень полезно, спасибо. Мне придётся обходиться с этим, чтобы все это выяснилось, но это именно те рамки, которые мне нужно для начала. Один из вопросов, который у меня есть, - как я могу захватить значения подачи X, Y и экструдера, чтобы выполнить некоторую математику? – paperstsoap

+0

Вы можете разделить gcode между пробелами, а затем удалить буквы спереди и преобразовать их в float. Я отредактирую ответ так, чтобы его яснее. – TrakJohnson

+0

Это имеет смысл для меня. Мой последний вопрос: когда вы передаете файл gcode в цикл for, обрабатывает ли он его как строку? – paperstsoap