1. Einführung
Die meisten Bildschirme von LinuxCNC haben die Möglichkeit, geladene Dateien durch ein "Filterprogramm" zu senden oder das Filterprogramm zu verwenden, um G-Code zu machen. Ein solcher Filter kann jede gewünschte Aufgabe erledigen: Etwas so Einfaches wie sicherzustellen, dass die Datei mit M2 endet, oder etwas so Kompliziertes wie die Erzeugung von G-Code aus einem Bild.
2. Einrichten der INI für Programmfilter
Der Abschnitt [FILTER] der INI-Datei steuert, wie die Filter funktionieren. Schreiben Sie zunächst für jeden Dateityp eine PROGRAM_EXTENSION-Zeile. Dann geben Sie das Programm an, das für jeden Dateityp ausgeführt werden soll. Dieses Programm erhält den Namen der Eingabedatei als erstes Argument und muss rs274ngc-Code in die Standardausgabe schreiben. Diese Ausgabe ist das, was im Textbereich angezeigt wird, in der Vorschau im Anzeigebereich, und dann auch von LinuxCNC ausgeführt wird. Die folgenden Zeilen fügen Unterstützung für den in LinuxCNC enthaltenen "image-to-gcode" (engl. für Bild zu G-Code) -Konverter hinzu:
[FILTER] PROGRAM_EXTENSION = .png,.gif Greyscale Depth Image png = image-to-gcode gif = image-to-gcode
Es ist auch möglich, einen Interpreter anzugeben:
PROGRAM_EXTENSION = .py Python Script py = python
Auf diese Weise kann jedes Python-Skript geöffnet werden, und seine Ausgabe wird als G-Code behandelt. Ein solches Beispielskript ist unter "nc_files/holecircle.py" verfügbar. Dieses Skript erzeugt G-Code für das Bohren einer Reihe von Löchern entlang des Umfangs eines Kreises.
Wenn das Filterprogramm Zeilen in der folgenden Form an stderr sendet:
FILTER_PROGRESS=10
Sie setzt den Fortschrittsbalken des Bildschirms auf den angegebenen Prozentsatz (in diesem Fall 10). Diese Funktion sollte von jedem Filter verwendet werden, der lange läuft.
3. Erstellung von Filterprogrammen auf Python-Basis
Here is a very basic example of the filtering mechanics: When run through a Linucnc screen that offers program filtering, it will produce and write a line of G-code every 100th of a second to standard output. It also sends a progress message out to the UNIX standard error stream. If there was an error it would post an error message and exit with an exitcode of 1.
import time import sys for i in range(0,100): try: # Rechenzeit simulieren time.sleep(.1) # Ausgabe einer Zeile G-Code print('G0 X1', file=sys.stdout) # Fortschritt aktualisieren print('FILTER_PROGRESS={}'.format(i), file=sys.stderr) except: # Dies führt zu einer Fehlermeldung print('Fehler; Aber das war nur ein Test', file=sys.stderr) raise SystemExit(1)
Hier ist ein ähnliches Programm, aber es kann tatsächlich filtern. Es zeigt einen PyQt5-Dialog mit einer Abbruch-Schaltfläche an. Dann liest es das Programm Zeile für Zeile und gibt es an die Standardausgabe weiter. Während es weiterläuft, aktualisiert es jeden Prozess, der auf die Standardfehlerausgabe hört.
#!/usr/bin/env python3 import sys import os import time from PyQt5.QtWidgets import (QApplication, QDialog, QDialogButtonBox, QVBoxLayout,QDialogButtonBox) from PyQt5.QtCore import QTimer, Qt class CustomDialog(QDialog): def __init__(self, path): super(CustomDialog, self).__init__(None) self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint) self.setWindowTitle("Filter-with-GUI Test") QBtn = QDialogButtonBox.Cancel self.buttonBox = QDialogButtonBox(QBtn) self.buttonBox.rejected.connect(self.reject) self.layout = QVBoxLayout() self.layout.addWidget(self.buttonBox) self.setLayout(self.layout) self.line = 0 self._percentDone = 0 if not os.path.exists(path): print("Path: '{}' existiert nicht:".format(path), file=sys.stderr) raise SystemExit(1) self.infile = open(path, "r") self.temp = self.infile.readlines() # calculate percent update interval self.bump = 100/float(len(self.temp)) self._timer = QTimer() self._timer.timeout.connect(self.process) self._timer.start(100) def reject(self): # This provides an error message print('You asked to cancel before finished.', file=sys.stderr) raise SystemExit(1) def process(self): try: # nächste Codezeile erhalten codeLine = self.temp[self.line] # die Zeile irgendwie verarbeiten # Verarbeiteten Code ausgeben print(codeLine, file=sys.stdout) self.line +=1 # update progress self._percentDone += self.bump print('FILTER_PROGRESS={}'.format(int(self._percentDone)), file=sys.stderr) # if done Ende ohne Fehler/Fehlermeldung if self._percentDone >= 99: print('FILTER_PROGRESS=-1', file=sys.stderr) self.infile.close() raise SystemExit(0) except Exception as e: # Dies liefert eine Fehlermeldung print(('Something bad happened:',e), file=sys.stderr) # dies signalisiert, dass die Fehlermeldung angezeigt werden soll raise SystemExit(1) if __name__ == "__main__": if (len(sys.argv)>1): path = sys.argv[1] else: path = None app = QApplication(sys.argv) w = CustomDialog(path=path) w.show() sys.exit( app.exec_() )