Перевернуть ось 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