Перевернуть ось X файла G-код
У меня есть несколько нарезанных моделей, которые представляют правосторонние руки и ноги робота. Я действительно доволен тем, как они напечатаны, поэтому теперь я хотел бы напечатать руки и ноги с левой стороны.
Я думал, что было бы довольно тривиально проанализировать файл G-кода с помощью Python и изменить значение всех команд Xn с n на 2*h - n, где h находится в середине стола, скажем, 110 или 120 мм для Ender 3.
Прежде чем я запущу свою любимую IDE, есть ли какие-либо серьезные проблемы, с которыми я могу столкнуться из-за такого наивного подхода к отображению G-кода, подобного этому? Я изначально нарезал в Cura 4.9.1.
@Ron Jensen, 👍3
Обсуждение3 ответа
Лучший ответ:
Если в вашем слайсере нет операции зеркального отображения или шкалы, допускающей отрицательные значения, то зеркальное отображение в G-коде должно быть простым.
До тех пор, пока на вашем принтере нет определенных конкретных изменений инструмента, наведения или очистки, которые выполняются в G-коде, вы можете просто преобразовать его, в противном случае вы захотите пропустить эти разделы и просто выполнить данные модели (это должно быть очевидно, глядя на код, с которого начинаются данные модели).
Для того, чтобы отразить его нужно просто поменять координаты X в G-код, если (0,0) находится центр вашего стола, как это часто (но не всегда) чехол для дельта принтеров вы просто хотите отменяет Х, так Г1 Х30 М-3 З2 становится Г1 х-30 г-3 З2. Если ваши координаты имеют (0,0) в углу (часто это относится к ортогональным принтерам), то вы хотите вычесть X из максимального значения X. например, если ширина вашего стола составляет 250 мм, то в G1 X30 Y10 Z3 X30 становится X(250-30) или G1 X220 Y10 Z3.
Есть только одно предостережение: некоторые слайсеры переключаются на относительное перемещение, используя G91 для определенных операций, а затем возвращаются к абсолютному с помощью G90, поэтому вам нужно будет обратить на это внимание. Между G91 и G90 вы захотите отменить X, независимо от того, где находится источник вашего принтера.
При написании вашего сценария я бы отслеживал встречающиеся минимальные и максимальные значения, а также новые минимальные и максимальные значения и распечатывал их в конце в качестве проверки на вменяемость, чтобы вы могли увидеть, если что-то не так.
Основываясь на исчерпывающем ответе @John Mecham, я быстро представил доказательство концепции. На изображении ниже стрелка влево (вверху) является оригиналом, а стрелка вправо (внизу) - перевернутым клоном. Cura действительно генерирует небольшой код относительного смещения в конце, я думаю, что справился с этим правильно.

import re
data_start = re.compile('^;LAYER_COUNT:[0-9]+')
ifilename = 'c:/Users/jentron128/Downloads/ThingVerse/Tools/arrow.gcode'
ofilename = 'c:/Users/jentron128/Downloads/ThingVerse/Tools/rev_arrow.gcode'
new_data =[]
BEDX = float(235)
h = BEDX # Absolute Positioning is default
mode='Skip'
with open(ifilename, 'r') as ifp:
for d in ifp:
new_d = ''
tokens = d.split()
if len(tokens) == 0:
pass
elif mode == 'Skip':
new_d = d[0:-1]
if data_start .match(d):
mode = 'Go'
else:
if tokens[0] == 'G91': # Относительное расположение
h = 0
elif tokens[0] == 'G90':# Абсолютное позиционирование
h = BEDX
for t in tokens:
if t.startswith('X'):
if len(t) > 1:
x = h - float(t[1:])
t = 'X'+f'{x:.3f}'
new_d += t+' '
new_data.append(new_d)
with open(ofilename, 'w') as ofp:
for d in new_data:
ofp.write(d+'\n') # как линии записи не поддерживают разделитель строк?
`#!/usr/bin/env python3
импортировать повторно
из системного импорта argv
data_start = re.compile('^;LAYER_COUNT:[0-9]+')
имя_файла = argv[1];
offilename = ifilename.replace('.gcode', '-reversed.gcode');
`, @Onza
Я попытался прокомментировать, чтобы сделать его повторно используемым скриптом, который вы можете запускать для любого файла, но комментарий был искажен; в основном используйте sys для импорта argv и используйте argv[1] для имени файла :), @Onza
Тем не менее, у меня это не сработало, не с файлом, созданным prusa., @Onza
По крайней мере, в Windows я никогда не запускаю Python из командной строки. Если у вас есть (желательно небольшой) файл gcode prusa, я посмотрю, смогу ли я изменить код для работы с ним., @Ron Jensen
Я думаю, что нашел проблему, вы ищете заголовок, который, похоже, специфичен для Cura, я сделал новую версию на основе вашей, которая правильно работает с файлами слайсера prusa; Я взял всю математику, которую вы использовали в целом, теперь она работает правильно; честно говоря, я не уверен, я никогда не прикасался к gcode до сих пор, но я думаю, что G1 универсален., @Onza
Да, в мой код встроен конечный автомат, и кажется, что переключатель основан на конкретном комментарии Cura. Все, что предшествует первому комментарию «;LAYER:0», выводится как прочитанное, потому что это все настройки принтера, затем состояние переключается в режим «Go» и после этого обрабатывает ВСЕ директивы X, независимо от G-кода. Он обрабатывает G90/G91 отдельно, устанавливая h = 0 для ОТНОСИТЕЛЬНОГО позиционирования и h = ширину стола для АБСОЛЮТНОГО позиционирования., @Ron Jensen
Самый простой способ обойти это — просто изменить режим = «Пропустить» на режим = «Перейти», и тогда скрипт обработает все строки., @Ron Jensen
Однако мы (или, по крайней мере, я) не были уверены, что это правильное предположение, я просто взял весь вывод токена G1 и перевернул его, предполагая, что это инструкции; Я написал код ниже, как вы можете видеть., @Onza
Использование: python3 [имя файла.gcode] [ширина стола]
#!/usr/bin/env python3
import re
from sys import argv
#first arg is the file, second arg is the bed x width
ifilename = argv[1];
ofilename = ifilename.replace('.gcode', '-reversed.gcode');
new_data =[]
BEDX = float(argv[2])
h = BEDX # Absolute Positioning is default
with open(ifilename, 'r') as ifp:
for d in ifp:
new_d = ''
tokens = d.split()
if len(tokens) == 0:
pass
else:
if tokens[0] == 'G91': # Relative Positioning
h = 0
new_d += d
elif tokens[0] == 'G90':# Absolute Positioning
h = BEDX
new_d += d
elif tokens[0] == 'G1':
for t in tokens:
if t.startswith('X'):
if len(t) > 1:
x = h - float(t[1:])
t = 'X'+f'{x:.3f}'
new_d += t+' '
else:
new_d += d
new_data.append(new_d)
with open(ofilename, 'w') as ofp:
for d in new_data:
ofp.write(d+'\n') # how does writelines not support a line separator?
Для тех, у кого есть проблемы со сценарием выше, я думаю, что это исправит их.
Похоже, что существует ошибка, из-за которой G90 или G91 не пишется всякий раз, когда он их находит.
То, как вы генерируете ofilename, не очень безопасно. Если имя файла не оканчивается на .gcode (например, если оно оканчивается на .GCODE или .gco), замена будет неэффективной, и похоже, что вы перезапишете ввод., @R.. GitHub STOP HELPING ICE
Вы правы, сделайте третью версию или что-то в этом роде; Я быстро взломал это на месте, возможно, используя argv[2] для выходного имени., @Onza
- Как вы отправляете G-код с USB-порта с помощью Python?
- Отправка команд G-кода в систему Hyrel 30M с помощью python
- Получите команду M114 во время печати с помощью Printrun
- Есть ли G-код для ожидания?
- Для чего используется G92 в G-коде
- Написание G-кода : проведите пальцем в начале печати
- Используя автоматическое выравнивание стола, нужно ли инициировать G29 перед каждой печатью?
- Cura: установить z-смещение
Существуют визуализаторы g-кода, которые позволят вам открыть ваш недавно измененный файл, чтобы увидеть очевидные проблемы. Ваша ссылка на середину стола действительна? Я недостаточно изучил файл g-кода, чтобы заметить, является ли источник центром стола или определенным углом., @fred_dot_u
@fred_dot_u хороший момент, я полагаю, что я мог бы найти ограничивающую рамку печати, пока разбираю файл. По крайней мере, на эндере 3 домашняя позиция, кажется, находится на (0,0,0)., @Ron Jensen
часто вы можете масштабироваться со значением -1, чтобы отразить ось, если в срезе нет явного параметра зеркального отображения., @John Meacham