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
Hier ist ein sehr einfaches Beispiel für die Filtermechanik: Wenn ein Linucnc-Bildschirm, der Programmfilterung bietet, durchläuft, wird jede 100stel Sekunde eine Zeile G-Code erzeugt und auf die Standardausgabe geschrieben. Außerdem sendet es eine Fortschrittsmeldung an den UNIX-Standardfehler-Ausgabe. Wenn ein Fehler auftritt, gibt es eine Fehlermeldung aus und beendet sich mit dem Exitcode 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_() )