ПОМОГИТЕ Gcode поиск точки FluidNC

klot

МЕСТНЫЙ
Регистрация
01.05.2023
Сообщения
0
Реакции
2
Баллы
22
Город
SPB
Всем здравствуйте, прошу помощи.
у меня есть Gcode такого типа

G1 F1000 Z1.0
G0 X-162.4 Y244.65
G1 F1000 Z-2.0
G1 F1000 Z1.0
G1 F1000 Z-2.5
G1 F1000 Z1.0
G1 F1000 Z-2.5
G1 F1000 Z1.0
G1 F1000 Z-3.0
G1 F1000 Z1.0
G1 F1000 Z-3.0
G1 F1000 Z1.0
G1 F1000 Z-3.5
G1 F1000 Z1.0
G0 X-161.0 Y244.65
G1 F1000 Z-2.0
G1 F1000 Z1.0
G1 F1000 Z-2.5
G1 F1000 Z1.0
G1 F1000 Z-2.5
G1 F1000 Z1.0
G1 F1000 Z-3.0
G1 F1000 Z1.0
G1 F1000 Z-3.0
G1 F1000 Z1.0
G1 F1000 Z-3.5
G1 F1000 Z1.0
G0 X-159.6 Y244.65
G1 F1000 Z-2.0
G1 F1000 Z1.0
G1 F1000 Z-2.5
G1 F1000 Z1.0
G1 F1000 Z-2.5
G1 F1000 Z1.0
G1 F1000 Z-3.0
G1 F1000 Z1.0
G1 F1000 Z-3.0
G1 F1000 Z1.0
G1 F1000 Z-3.5
G1 F1000 Z1.0
G0 X-159.6 Y242.55
G1 F1000 Z-2.0
G1 F1000 Z1.0
G1 F1000 Z-2.5
G1 F1000 Z1.0
G1 F1000 Z-2.5
G1 F1000 Z1.0
G1 F1000 Z-3.0
G1 F1000 Z1.0
G1 F1000 Z-3.0
G1 F1000 Z1.0
G1 F1000 Z-3.5
G1 F1000 Z1.0
G0 X-162.4 Y242.55

и таких точек около 40 000 и где-то сломалось сверло,(у меня на глазах) обломок торчит, я жму паузу, станок работает на FluidNC

в консоли FluidNC такие строки

<Run|MPos:286.998,330.356,-4.767|FS:600,0|WCO:290.500,276.800,-1.500|SD:39.57,/sd/opt777.ngc>
<Run|MPos:286.998,330.356,-1.340|FS:243,0|Ov:100,100,100|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.704,329.062,-0.500|FS:288,0|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.591,328.949,-2.711|FS:225,0|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.591,328.949,-2.973|FS:720,0|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.591,328.949,-0.512|FS:240,0|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.591,328.949,-2.662|FS:387,0|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.591,328.949,-3.791|FS:600,0|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.591,328.949,-0.832|FS:27,0|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.591,328.949,-1.569|FS:657,0|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.591,328.949,-4.000|FS:330,0|WCO:290.500,276.800,-1.500|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.591,328.949,-1.596|FS:297,0|Ov:100,100,100|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.591,328.949,-0.822|FS:660,0|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.591,328.949,-4.074|FS:77,0|SD:39.57,/sd/opt777.ngc>
<Run|MPos:285.591,328.949,-3.576|FS:797,0|SD:39.57,/sd/opt777.ngc>

надо сменить сверло не потерять ноль и запустить работу с точки поломки, в консоли координаты на которой сломалось сверло нет

и вот я например рассчитываю координаты для этой строки:

<Run|MPos:272.308,323.358,-0.681|FS:570,0|WCO:290.500,276.800,-1.500|SD:39.60,/sd/opt777.ngc>


MPos (Machine Position):

X = 272.308

Y = 323.358

Z = -0.681

WCO (Work Coordinate Offset):

X = 290.500

Y = 276.800

Z = -1.500

Расчёт WPos (Work Position):

𝑋 WPos = 272.308 − 290.500 = −18.192

𝑌 WPos = 323.358 − 276.800 = 46.558

𝑍 WPos = −0.681 −(−1.500) = 0.819

Таким образом, координаты последней обработанной точки в рабочих координатах (WPos) составляют:

𝑋 WPos = −18.192

𝑌 WPos = 46.558

что визуально похоже на правду
Но такой точки в моём Gcode нет!
пробовал скрипт на питоне написать, с подбором ближайших координат, но понимаю, что изобретаю колесо
вероятно тут есть знающие люди, которые подскажут как можно узнать с какой точки перезапустить Gcode,
удалив из него уже сделанную работу.
 
klot, А нельзя просто снова запустить программу , без сверла и когда шпиндель придет в точку поломки, вы увидите строку. Или запустить в NC corrector и так определить строку?. Думаю это по любому будет быстрее, чем искать питоном...не пойми чего.
 
Но такой точки в моём Gcode нет!
Это просто какое-то промежуточное значение, оно не обязано быть в G-коде - управляющий софт периодически опрашивает плату "ты как там и где", вот она и отвечает...

Можете попробовать найти ближайшую нужную точку визуально - например, загрузите УП в Кэндл. В Кэндл, перемещаясь клавишами курсора или тыкая мышом в строчки УП будет виден результат - пройденная траектория подсвечивается сероватым, цветом, а текущее положение точкой такого же цвета. Можно начать работу "с чуть пораньше", что бы наверняка, удалив команды, которые уже выполнились, только обязательно проверить, что бы и высота по Z, подача и состояние шпинделя были указаны.
Bilderman 2025.02.07 15-03-55.png

<Run|MPos:285.591,328.949,-1.569|FS:657,0
Прикольно - статус " в работе", подача 657, а шпиндель "по нулям". Это оно выключенным шпинделем сверлило? :)
 
спасибо! Я просто думал, что в каждой прошивке уже заложена возможность сохранять лог работы и я это просто найти не могу
Это просто какое-то промежуточное значение, оно не обязано быть в G-коде - управляющий софт периодически опрашивает плату "ты как там и где", вот она и отвечает...

Можете попробовать найти ближайшую нужную точку визуально - например, загрузите УП в Кэндл. В Кэндл, перемещаясь клавишами курсора или тыкая мышом в строчки УП будет виден результат - пройденная траектория подсвечивается сероватым, цветом, а текущее положение точкой такого же цвета. Можно начать работу "с чуть пораньше", что бы наверняка, удалив команды, которые уже выполнились, только обязательно проверить, что бы и высота по Z, подача и состояние шпинделя были указаны.
Bilderman 2025.02.07 15-03-55.png


Прикольно - статус " в работе", подача 657, а шпиндель "по нулям". Это оно выключенным шпинделем сверлило? :)

шпиндель отдельно включается.) написал себе скрипт на питоне визуально можно отмотать с конца или с начала файла и на нужной строке сохранить нужную часть Gcode, а то у меня специфическая работа бывает иногда по 300 000 точек в файле.(если нужен могу поделиться)
Просьба размещать длинный текст под спойлер.
Код:
import tkinter as tk
from tkinter import filedialog
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk

def open_gcode_file():
    file_path = filedialog.askopenfilename(filetypes=[("G-code files", "*.ngc")])
    if file_path:
        with open(file_path, 'r') as file:
            lines = file.readlines()
        return lines
    return []

def parse_gcode(lines):
    red_segments = []
    current_segment = []
    for line in lines:
        if line.startswith('G0') or line.startswith('G00'):
            parts = line.split()
            x = None
            y = None
            for part in parts:
                if part.startswith('X'):
                    x = float(part[1:])
                elif part.startswith('Y'):
                    y = float(part[1:])
            if x is not None and y is not None:
                current_segment.append((x, y))

    if current_segment:
        red_segments.append(current_segment)
   
    return red_segments

def plot_gcode(red_segments, x_min, x_max, y_min, y_max):
    plt.clf()
    for segment in red_segments:
        if len(segment) > 1:
            x_coords, y_coords = zip(*segment)
            plt.plot(x_coords, y_coords, marker='.', markersize=1, color='red', linewidth=0.5)

    plt.xlabel('X')
    plt.ylabel('Y')
    plt.title('G-code Path')
    plt.xlim(x_min, x_max)
    plt.ylim(y_min, y_max)
    plt.gca().set_aspect('equal', adjustable='datalim')
    canvas.draw()

def update_plot(val=None):
    start_index = start_slider.get()
    end_index = end_slider.get()
    x_min = float(x_min_entry.get())
    x_max = float(x_max_entry.get())
    y_min = float(y_min_entry.get())
    y_max = float(y_max_entry.get())
   
    visible_lines = lines[start_index:end_index]
    red_segments = parse_gcode(visible_lines)
   
    plot_gcode(red_segments, x_min, x_max, y_min, y_max)

def save_visible_gcode():
    start_index = start_slider.get()
    end_index = end_slider.get()
    visible_lines = lines[start_index:end_index]
    save_path = filedialog.asksaveasfilename(defaultextension=".ngc", filetypes=[("G-code files", "*.ngc")])
    if save_path:
        with open(save_path, 'w') as file:
            file.writelines(visible_lines)

def exit_program():
    root.quit()
    root.destroy()

def main():
    global red_segments, canvas, start_slider, end_slider, x_min_entry, x_max_entry, y_min_entry, y_max_entry, lines, root

    root = tk.Tk()
    root.withdraw()
    lines = open_gcode_file()
    if lines:
        red_segments = parse_gcode(lines)
        if red_segments:
            all_coords = [coord for segment in red_segments for coord in segment]
            x_coords = [coord[0] for coord in all_coords]
            y_coords = [coord[1] for coord in all_coords]

            plot_window = tk.Toplevel(root)
            plot_window.title("G-code Viewer")
            plot_window.geometry("1200x1000")

            fig = plt.figure(figsize=(12, 8))
            canvas = FigureCanvasTkAgg(fig, master=plot_window)
            canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

            toolbar = NavigationToolbar2Tk(canvas, plot_window)
            toolbar.update()
            toolbar.pack(side=tk.TOP, fill=tk.X)

            control_frame = tk.Frame(plot_window)
            control_frame.pack(side=tk.BOTTOM, fill=tk.X)

            start_slider = tk.Scale(control_frame, from_=0, to=len(lines)-1, orient=tk.HORIZONTAL, label="Start", command=update_plot)
            start_slider.pack(side=tk.TOP, fill=tk.X, expand=1)

            end_slider = tk.Scale(control_frame, from_=0, to=len(lines), orient=tk.HORIZONTAL, label="End", command=update_plot)
            end_slider.set(len(lines))
            end_slider.pack(side=tk.TOP, fill=tk.X, expand=1)

            coord_frame = tk.Frame(plot_window)
            coord_frame.pack(side=tk.BOTTOM, fill=tk.X)

            tk.Label(coord_frame, text="X min:").pack(side=tk.LEFT)
            x_min_entry = tk.Entry(coord_frame)
            x_min_entry.pack(side=tk.LEFT)
            x_min_entry.insert(0, str(min(x_coords)))

            tk.Label(coord_frame, text="X max:").pack(side=tk.LEFT)
            x_max_entry = tk.Entry(coord_frame)
            x_max_entry.pack(side=tk.LEFT)
            x_max_entry.insert(0, str(max(x_coords)))

            tk.Label(coord_frame, text="Y min:").pack(side=tk.LEFT)
            y_min_entry = tk.Entry(coord_frame)
            y_min_entry.pack(side=tk.LEFT)
            y_min_entry.insert(0, str(min(y_coords)))

            tk.Label(coord_frame, text="Y max:").pack(side=tk.LEFT)
            y_max_entry = tk.Entry(coord_frame)
            y_max_entry.pack(side=tk.LEFT)
            y_max_entry.insert(0, str(max(y_coords)))

            update_button = tk.Button(coord_frame, text="Update Plot", command=update_plot)
            update_button.pack(side=tk.LEFT)

            button_frame = tk.Frame(plot_window)
            button_frame.pack(side=tk.BOTTOM, fill=tk.X)

            save_button = tk.Button(button_frame, text="Save G-code", command=save_visible_gcode)
            save_button.pack(side=tk.LEFT)

            exit_button = tk.Button(button_frame, text="Exit", command=exit_program)
            exit_button.pack(side=tk.RIGHT)

            plot_gcode(red_segments, min(x_coords), max(x_coords), min(y_coords), max(y_coords))

            root.mainloop()

if __name__ == "__main__":
    main()
 
Хорошо бы ещё разъяснить для тех, кто не в теме, что и как с этим скриптом делать...
Он ищет где начало и конец у окружности...это чтоб жизнь раем не казалась.:)
 
Пока вы жали паузу станок просто уехал с места поломки и в очете показаны текущие координаты. То, что управляется станок FluidNC это ниочем. По вашему листингу подача на сверлении 1000 (наверное мм/мин) для любых сверл это неприемлемо много, даже при оборотах 30000 об/мин. Судя по жтому же листингу смещение между сверлениями 1.400, а значит сверло не более 1.3мм, иначе поломка гарантирована.
 
у меня всё несколько кондово... сверло 0,8 мм , а "шпиндель" сделан из бормашинки для маникюра, подключается просто из розетки 220V , сверлю пластик, обороты на бормашинке подбирал на "выпуклый рыбацкий глаз"... дабы стружку не наматывало.
что делать со скриптом
установить питон и зависимости
Для установки необходимых зависимостей для этого скрипта, вам нужно установить пакет matplotlib, так как tkinter встроен в стандартную библиотеку Python и не требует установки.
Вот команда для установки matplotlib:
pip install matplotlib
сохранить скрипт как например you_name.py
запустить, откроется выбор файла, открыть нужный файл, откроется такое окно
в нём можно отрезать кусок кода с конца или с начала файла и сохранить, кнопки позволят увеличить и передвинуть поле с кодом.
мне весьма помогло
очень задумался на что поменять FluidNC, использовать начал так как код открытый, а я собрался в него свою кинематику дописать, но бесконечные обрывы связи по wifi, учитывая, что нотбук и плата управления находятся рядом сводят все плюсы на нет!(
спасибо за советы и помощь
пока писал этот ответ всё просто остановилось!!!:):)
пойду "курить мануалы"
 

Вложения

  • Screenshot_14.png
    Screenshot_14.png
    288.2 KB · Просмотры: 8
  • Screenshot_15.png
    Screenshot_15.png
    223.5 KB · Просмотры: 8
сверло 0,8 мм , а "шпиндель" сделан из бормашинки для маникюра,
И с таким "шпинделем" сверла не ломать? Не улыбайте мои тапочки. И уж подавно не на такой подаче.
 
что делать со скриптом
Ясно-понятно. Юзать скрипт могут не только лишь все, вернее, мало кто сможет это сделать :)
 
Сверху Снизу
Обнаружен блокировщик рекламы AdBlock

МЫ ДОГАДЫВАЕМСЯ, ЧТО РЕКЛАМА ВАС РАЗДРАЖАЕТ!

Конечно, Ваше программное обеспечение для блокировки рекламы отлично справляется с блокировкой рекламы на нашем сайте, но оно также блокирует полезные функции. Мы стараемся для Вас и не обязываем Вас донатить и скидывать денег на наши кошельки, чтобы пользоваться форумом, но реклама это единственное, что позволяет поддерживать проект и развивать его.

Спасибо за Ваше понимание!

Я отключил свой AdBlock    Нет, я не буду ничего отключать