1. Einführung
Panelui ist eine Nicht-Echtzeit-Komponente zur Anbindung von Schaltflächen an LinuxCNC oder HAL:
-
Es dekodiert MESA 7I73-artige Key-Scan-Codes und ruft die entsprechende Routine auf.
-
Die Eingabe erfolgt über eine Echtzeitkomponente - Sampler. Der Sampler erhält seine Eingaben entweder von der Komponente MESA 7I73 oder sim_matrix_kb.
-
Panelui kann mithilfe einer INI-Textdatei konfiguriert werden, um Schaltflächentypen, HAL-Pin-Typen und/oder Befehle zu definieren.
-
Sie kann mit einer Python-basierten "Handler"-Datei um Funktionen erweitert werden.
Während die eigentlichen Eingabetasten träge sein müssen, verwendet Panelui diese Eingabe für die Ausgabe von Toggle-, Radio- oder Tasterschaltungen.
2. Laden von Befehlen
Der Befehl zum Laden von panelui (mit optionalem Schalter -d debug):
loadusr -W panelui -d
Dadurch wird panelui initialisiert, das im Konfigurations- oder Benutzerordner nach der INI-Datei panelui.ini sucht.
Mit diesem Befehl kann man die INI-Datei validieren:
loadusr pyui
Damit wird die Datei panelui.ini gelesen, versucht zu korrigieren und dann gespeichert. Eventuelle Fehler werden diese auf dem Terminal ausgegeben.
Einer typischen HAL-Datei werden diese Befehle hinzugefügt:
# Befehle, die für das Laden von Panelui benötigt werden # # sampler wird für panelui benötigt # cfg= muss für panelui immer u sein. depth legt den verfügbaren Puffer fest loadrt sampler cfg=u depth=1025 #unkommentiert, um die panelui INI-Datei zu validieren #loadusr pyui # -d = Fehlersuche, -v = ausführliche Fehlersuche # -d zeigt Ihnen die Tastenkennzeichnung und die aufgerufenen Befehle # -v ist für Informationen über den Entwickler loadusr -W panelui -d # mit simulierten Tasten anstelle der MESA 7I73-Karte # also laden wir die Komponente sim_matrix_kb, um die HAL-Pins in Keyscan-Codes umzuwandeln loadrt sim_matrix_kb # Verbinden Sie die Komponenten miteinander. # sampler spricht intern mit panelui net key-scan sim-matrix-kb.0.out net key-scan sampler.0.pin.0 # panelui Komponenten zu einem Thread hinzufügen addf sim-matrix-kb.0 servo-thread addf sampler.0 servo-thread
3. panelui.ini Dateireferenz
-
KEY= Hier wird die Taste angegeben, auf die der Button reagiert. Es kann KEINE oder eine Zeilennummer und eine Spaltennummer sein, z. B. R1C2. Eine Zeile und Spalte kann nur einmal verwendet werden.
-
OUTPUT= Hier wird der Ausgabetyp der Schaltfläche festgelegt, z. B. S32, U32, FLOAT, BIT, NONE, COMMAND, ZMQ.
-
DEFAULT= Hiermit wird die Startausgabe der Gruppe oder der Schaltfläche festgelegt.
-
GROUP= Bezeichnet bei Radiobuttons die Gruppe, mit innerhalb welcher der Button interagiert.
-
GROUP_OUTPUT= legt den Ausgang fest, den der Gruppenpin hat, wenn dieser Button aktiv ist.
-
STATUS_PIN= Wenn TRUE, wird ein HAL-Pin hinzugefügt, der den aktuellen Zustand des Button wiedergibt.
-
TRUE_STATE= legt den Ausgang fest, den der HAL-Pin hat, wenn der Button TRUE ist.
-
FALSE_STATE= legt den OUTPUT fest, den der HAL-Pin erhält, wenn die Taste FALSE ist.
-
TRUE_COMMAND= legt den Befehl und die Argumente fest, die aufgerufen werden, wenn der Button TRUE ist.
-
FALSE_COMMAND= legt den Befehl und die Argumente fest, die aufgerufen werden, wenn der Button FALSE ist.
-
TRUE_FUNCTION= legt die ZMQ-Nachrichtenfunktion und Argumente fest, die aufgerufen werden sollen, wenn der Button TRUE ist.
-
FALSE_FUNCTION= legt die ZMQ-Nachrichtenfunktion und die Argumente fest, die aufgerufen werden sollen, wenn der Button FALSE ist.
[HAL_PREFIX] NAME= IhrName
Damit kann man den Präfix der HAL-Pins von panelui auf einen beliebigen Namen ändern.
[ZMQ_SETUP] TOPIC = 'QTVCP' SOCKET = 'tcp://127.0.0.1:5690' ENABLE = True
Damit wird das ZMQ-basierte Messaging eingerichtet und aktiviert. TOPIC und SOCKET müssen mit dem empfangenden Programm übereinstimmen.
Bei Radiobutons kann jeweils nur eine Taste in der Gruppe aktiv sein. Jede Gruppe hat ihren eigenen Ausgangspin, der von jeder Taste in der Gruppe getrennt ist. Radiobutton-Definitionen beginnen mit dem Text "RADIO_BUTTON" in einfachen Klammern.
[RADIO_BUTTONS] # Die doppelte(n) Klammer(n) definieren die Gruppe(n) von Optionsschaltflächen. # Der Gruppenname muss eindeutig sein und Groß- und Kleinschreibung wird beachtet. # Die Ausgabe der Gruppe wird durch die aktive Schaltfläche gesteuert, nicht direkt durch den Keycode. # DEFAULT verweist auf eine Schaltfläche in der Gruppe durch den Namen und unterscheidet zwischen Groß- und Kleinschreibung. [[group1_name]] KEY = NONE OUTPUT = FLOAT DEFAULT = small # Die dreifachen Klammerabschnitte definieren die Schaltflächen in dieser Gruppe. # Die Namen der Schaltflächen müssen eindeutig sein und Groß- und Kleinschreibung wird beachtet. # Es muss mindestens zwei Schaltflächen in einer Gruppe geben. # # Diese Schaltfläche mit dem Namen 'small' wird durch die Taste Zeile 0 Spalte 1 gesteuert. # Sie bewirkt, dass der Gruppenausgang .0001 ist, wenn sie gedrückt wird. # Sie hat keinen eigenen Ausgang, aber einen Status # Pin, der den aktuellen Zustand der Taste anzeigt. # Da diese Taste in einer Gruppe ist, hat DEFAULT keine Bedeutung. # da OUTPUT nicht 'COMMAND' ist, werden _COMMAND-Einträge ignoriert. [[[small]]] KEY = R0C1 GROUP = group1_name GROUP_OUTPUT = .0001 OUTPUT = NONE STATUS_PIN = True TRUE_STATE = TRUE FALSE_STATE = FALSE TRUE_COMMAND = NONE, NONE FALSE_COMMAND = NONE, NONE DEFAULT = false # Diese Schaltfläche mit dem Namen 'large' wird von der Taste Zeile 0 Spalte 2 gesteuert. # Sie bewirkt, dass der Gruppenausgang 1000 ist, wenn sie gedrückt wird. # Er hat einen eigenen S32-Ausgang, der bei true 20 und bei false 0 ist. # Sie hat auch einen Status-Pin, der ihren aktuellen Zustand anzeigt. # Da diese Taste in einer Gruppe ist, hat DEFAULT keine Bedeutung. # Da OUTPUT nicht 'COMMAND' ist, werden _COMMAND-Einträge ignoriert.. [[[large]]] KEY = R0C2 GROUP = group1_name GROUP_OUTPUT = 1000 OUTPUT = S32 STATUS_PIN = True TRUE_STATE = 20 TRUE_COMMAND = NONE, NONE FALSE_COMMAND = NONE, NONE FALSE_STATE = 0 DEFAULT = false
Togglebuttons ändern ihren Zustand nur bei jedem Drücken der Taste. Toggle-Button-Definitionen beginnen mit dem Text "TOGGLE_BUTTON" in einfachen Klammern.
[TOGGLE_BUTTONS] # Jeder Button-Name in doppelten Klammern muss eindeutig sein und Groß- und Kleinschreibung wird unterschieden. # Diese Schaltfläche mit dem Namen 'tool_change' wird von der Taste in Zeile 2 Spalte 5 gesteuert. # Sie hat einen BIT-Ausgang, der bei einem wahren Zustand 1 und bei einem falschen Zustand 0 ausgibt. # Er hat auch einen Status-Pin, der seinen aktuellen Zustand anzeigt. # DEFAULT setzt diesen bei der ersten Initialisierung auf true. # Die _COMMAND werden nicht verwendet, da OUTPUT nicht auf COMMAND gesetzt ist, aber die Validierung wird # die Zeilen dennoch hinzufügen. [[tool_change]] KEY = R2C5 OUTPUT = BIT TRUE_COMMAND = NONE, NONE FALSE_COMMAND = NONE, NONE STATUS_PIN = True DEFAULT = TRUE TRUE_STATE = 1 FALSE_STATE = 0
Momentane Buttons sind wahr, wenn sie gedrückt werden, und falsch, wenn sie losgelassen werden. Button-Definitionen beginnen mit dem Text "MOMENTARY_BUTTON" in einfachen Klammern.
[MOMENTARY_BUTTONS] # Jeder Tastenname in doppelten Klammern muss eindeutig sein und Groß- und Kleinschreibung wird unterschieden. # Diese Taste mit dem Namen 'spindle_rev' wird von der Taste in Zeile 2 Spalte 3 gesteuert. # Sie hat einen COMMAND-Ausgang, verwendet also TRUE_COMMAND und FALSE_COMMAND. # Er hat auch einen Status-Pin, der seinen aktuellen Zustand anzeigt. # COMMANDs haben einen Befehlsnamen und dann alle erforderlichen Argumente. # Dieser TRUE_COMMAND ruft einen internen Befehl zum Starten der Spindel im Rückwärtsgang mit 200 U/min auf. # Wenn die Spindel bereits gestartet ist, wird die Drehzahl erhöht. # DEFAULT wird nicht mit Momentary-Buttons verwendet. # Die _STATE werden nicht verwendet, da OUTPUT auf COMMAND gesetzt ist, aber die Validierung wird # die Zeilen dennoch hinzufügen. [[spindel_drehzahl]] KEY = R2C3 OUTPUT = COMMAND TRUE_COMMAND = SPINDLE_REVERSE_INCREASE, 200 FALSE_COMMAND = None, NONE STATUS_PIN = True DEFAULT = FALSE TRUE_STATE = 1 FALSE_STATE = 0
4. Übersicht zu Internen Anweisungen
Es gibt eine Reihe von internen Befehlen, die Sie verwenden können.
-
erforderliches Argument: Achsennummer (int)
-
erforderliches Argument: Achsennummer (int)
-
optionales Argument: Anfangsdrehzahl (int) - Standardwert 100
-
Beschreibung: Wenn die Spindel angehalten ist, startet sie in Vorwärtsrichtung. Wenn sie bereits läuft, erhöht oder verringert sie die Drehzahl, je nachdem, in welche Richtung die Spindel läuft.
-
optionales Argument: Anfangsdrehzahl (int) - Standardwert 100
-
optionales Argument: Anfangsdrehzahl (int) - Standardwert 100
-
optionales Argument: Anfangsdrehzahl (int) - Standardwert 100
-
Beschreibung: Wenn die Spindel angehalten wird, startet sie in umgekehrter Richtung. Wenn sie bereits läuft, erhöht oder verringert sie die Drehzahl, je nachdem, in welche Richtung die Spindel läuft.
-
Beschreibung: erhöht die Spindeldrehzahl um 100 RPM
-
Beschreibung: Verringert die Spindeldrehzahl um 100 RPM, bis die Drehzahl 100 beträgt.
-
erforderliches Argument: Geschwindigkeit in Zoll pro Minute (Float)
-
Beschreibung: setzt die Jog-Geschwindigkeit auf den Achsen 0,1,2,6,7,8 (X,Y,Z,U,V,W)
-
erforderliches Argument: Geschwindigkeit in Grad pro Minute (Float)
-
Beschreibung: Setzt die Jog-Geschwindigkeit auf Achse 3,4,5 (A.B.C)
-
erforderliche Argumente: Achsennummer (int), Richtung (int)
-
erforderliche Argumente: Achsennummer (int), Richtung (int), Abstand (float)
-
optionale Argumente: absolute Position der Z-Achse der Maschine (Float)
-
Beschreibung: Z-Achse auf die angegebene Maschinenposition fahren
-
Erforderliches Argument: Zustand (bool 0 oder 1)
-
erforderliches Argument: Rate (float)
-
erforderliches Argument: Rate (float 0-1)
-
erforderliches Argument: Rate (float)
-
erforderliches Argument: Rate (float)
-
Erforderliches Argument: Zustand (bool 0 oder 1)
-
Erforderliches Argument: Zustand (bool 0 oder 1)
-
Erforderliches Argument: Zustand (bool 0 oder 1)
-
Beschreibung: Wenn im Leerlauf, startet G-Code-Programm, wenn angehalten wird eine Zeile ausgeführt.
-
erforderliches Argument: Zeilennummer (int)
-
erforderliches Argument: G-Code-Befehl(e)
-
Beschreibung: Zeichnet den aktuellen Modus auf, ruft Befehle auf und kehrt dann zum Modus zurück.
-
erforderliches Argument: G-Code-Befehl(e)
-
Beschreibung: Setzt den Modus auf MDI, ruft Befehle auf.
5. ZMQ-Nachrichten
Panelui kann ZMQ-basierte Nachrichten beim Drücken von Tasten senden.
Auf diese Weise kann panelui mit anderen Programmen wie QtVCP-Bildschirmen interagieren.
[TOGGLE_BUTTONS] [[zmq_test]] KEY = R2C3 OUTPUT = ZMQ TRUE_FUNCTION = ZMQ_BUTTON, 200 FALSE_FUNCTION = ZMQ_BUTTON, 0 STATUS_PIN = False DEFAULT = FALSE TRUE_STATE = 1 FALSE_STATE = 0
Hier ist ein Beispielprogramm, das die Nachricht empfängt und auf dem Terminal ausgibt.
import zmq import json # ZeroMQ Context context = zmq.Context() # Definition des Sockets mit Hilfe des "Context". sock = context.socket(zmq.SUB) # Definieren des Abonnements und der zu akzeptierenden Nachrichten ohne Einschränkung der Themen. topic = "" # alle Themen sock.setsockopt(zmq.SUBSCRIBE, topic) sock.connect("tcp://127.0.0.1:5690") while True: topic, message = sock.recv_multipart() print('{} sent message:{}'.format(topic,json.loads(message)))
6. Handler Dateierweiterung
Eine spezielle Datei kann verwendet werden, um benutzerdefinierten Python-Code hinzuzufügen, der als Befehle verfügbar ist. panelui_handler.py muss in Python geschrieben und im Konfigurationsordner abgelegt werden. Wenn panelui dort eine Datei findet, fügt es deren Funktionsaufrufe zu den verfügbaren Befehlen hinzu. Hier ist ein Beispiel für eine Handler-Datei, die zwei Funktionen hinzufügt - hello_world und cycle_mode:
# standard handler call - This will always be required def get_handlers(linuxcnc_stat, linucnc_cmd, commands, master): return [HandlerClass(linuxcnc_stat, linucnc_cmd, commands, master)] # Ebenfalls erforderlich - Handler-Klassenklasse HandlerClass: # Dies wird ein ziemlicher Standard sein, um Zugriff auf alles zu erhalten. # linuxcnc_stat: ist die Python-Status-Instanz von LinuxCNC # linuxcnc_cmd: ist die Python-Befehlsinstanz von LinuxCNC # commands: ist die Befehlsinstanz, damit man die internen Routinen aufrufen kann # master: ermöglicht den Zugriff auf die Master-Funktionen/Daten def __init__(self, linuxcnc_stat, linuxcnc_cmd, commands, master): self.parent = commands self.current_mode = 0 # command functions are expected to have this layout: # def some_name(self, widget_instance, arguments from widget): # widget_instance gives access to the calling widget's function/data # arguments can be a list of arguments, a single argument, or None # depending on what was given in panelui's INI file. def hello_world(self, wname, m): # print to terminal so we know it worked print('\nHello world\n') print(m) # print the argument(s) print(wname.metadata) # Print the calling widgets internal metadata (from config file) # Aufruf eines MDI-Befehls zum Drucken einer Nachricht in LinuxCNC. # Dies setzt voraus, dass LinuxCNC referenziert ist, aber das wird nicht überprüft. # übergeordnete Befehle erwarten eine widget_instance - None wird ersetzt self.parent.mdi(None,'(MSG, Hallo Linuxcnc Welt!)') # Jeder Aufruf dieser Funktion schaltet den Modus von LinuxCNC um. def cycle_mode(self, wname, m): if self.current_mode == 0: self.current_mode = 1 self.parent.set_mdi_mode() elif self.current_mode == 1: self.current_mode = 2 self.parent.set_auto_mode() else: self.current_mode = 0 self.parent.set_manual_mode() print(self.current_mode) # Boiler code, braucht man oft def __getitem__(self, item): return getattr(self, item) def __setitem__(self, item, value): return setattr(self, item, value)