1. Вступ
Panelui is a non-realtime component to interface buttons to LinuxCNC or HAL:
-
Він декодує коди сканування ключів у стилі MESA 7I73 та викликає відповідну процедуру.
-
Він отримує вхідні дані від компонента реального часу — семплера. Семплер отримує вхідні дані або від компонента MESA 7I73, або від компонента sim_matrix_kb.
-
Panelui можна налаштувати за допомогою текстового файлу у стилі INI для визначення типів кнопок, типів контактів HAL та/або команд.
-
Його можна розширити за допомогою файлу-обробника на основі Python для додавання функцій.
Хоча фактичні кнопки введення повинні бути миттєвими, Panelui використовуватиме цей вхід для створення виводу перемикання, радіо або миттєвої кнопки.
2. Команди завантаження
Команда, що використовується для завантаження panelui (з необов’язковим параметром debug -d):
loadusr -W panelui -d
Це ініціалізує panelui, який шукатиме INI-файл panelui.ini в папці config або папці користувача.
Перевірити INI-файл можна за допомогою цієї команди:
loadusr pyui
Ця програма зчитає, спробує виправити, а потім збереже файл panelui.ini. Якщо будуть знайдені помилки, програма виведе їх у термінал.
У типовому HAL-файлі додаються такі команди:
# команди, необхідні для завантаження панелі
#
# семплер потрібен для panelui
# cfg= завжди має бути u для panelui. depth встановлює доступний буфер
loadrt sampler cfg=u depth=1025
#розкоментувати для перевірки INI-файлу panelui
#loadusr pyui
# -d = налагодження, -v = детальне налагодження
# -d покаже вам ідентифікацію натискання клавіш та викликані команди
# -v призначено для інформації розробника
loadusr -W panelui -d
# використання імітації кнопок замість плати MESA 7I73
# тому ми завантажуємо компонент sim_matrix_kb для перетворення контактів HAL у коди сканування клавіш
loadrt sim_matrix_kb
# з'єднати компоненти разом.
# семплер взаємодіє з panelui внутрішньо
net key-scan sim-matrix-kb.0.out
net key-scan sampler.0.pin.0
# додати компоненти panelui до потоку
addf sim-matrix-kb.0 servo-thread
addf sampler.0 servo-thread
3. Посилання на файл panelui.ini
-
KEY= Використовується для позначення клавіші, на яку реагує кнопка. Це може бути NONE або номер ROW та номер стовпця, наприклад, R1C2. Рядок та стовпець можна використовувати лише один раз.
-
OUTPUT= This sets the Button’s output type, eg SINT, UINT, REAL, BOOL, NONE, COMMAND, ZMQ.
-
ЗА ЗАМОВЧАННЯМ= Це встановлює початковий вихід групи або кнопки.
-
GROUP= У радіокнопках позначає групу, з якою взаємодіє кнопка.
-
GROUP_OUTPUT= встановлює вихідний сигнал групового контакту, якщо ця кнопка активна.
-
STATUS_PIN= Якщо значення TRUE (ІСТИНА), буде додано HAL-пін, який відображає поточний стан кнопки.
-
TRUE_STATE= встановлює вихідний сигнал на виводі HAL, якщо button має значення TRUE.
-
FALSE_STATE= встановлює ВИХІД, який матиме вивід HAL, якщо кнопка має значення FALSE.
-
TRUE_COMMAND= встановлює команду та аргументи, які будуть викликані, коли кнопка має значення TRUE.
-
FALSE_COMMAND= встановлює команду та аргументи, які будуть викликані, коли кнопка має значення FALSE.
-
TRUE_FUNCTION= встановлює функцію повідомлення ZMQ та аргументи, які будуть викликані, коли кнопка має значення TRUE.
-
FALSE_FUNCTION= встановлює функцію повідомлення ZMQ та аргументи, які будуть викликані, коли кнопка має значення FALSE.
[HAL_PREFIX]
NAME= Yourname
Це дозволяє змінити префікс виводів HAL з «panelui» на довільну назву.
[ZMQ_SETUP]
TOPIC = 'QTVCP'
SOCKET = 'tcp://127.0.0.1:5690'
ENABLE = True
Це налаштовує та активує обмін повідомленнями на основі ZMQ. TOPIC та SOCKET повинні відповідати програмі прослуховування.
Радіокнопки дозволяють активувати одночасно тільки одну кнопку в групі. Кожна група має власний вихідний контакт, окремий від кожної кнопки в групі. Визначення радіокнопок починаються з тексту «RADIO_BUTTON» в одинарних дужках.
[RADIO_BUTTONS]
# The double bracket section(s) define the group(s) of radio buttons.
# The group name must be unique and is case sensitive.
# Groups output is controlled by what button is active not directly by keycode.
# DEFAULT references a button in the group by name and is case sensitive.
[[group1_name]]
KEY = NONE
OUTPUT = REAL
DEFAULT = small
# The triple bracket sections define the buttons in this group.
# button names must be unique and are case sensitive.
# There must be at least two buttons in a group.
#
# This button, named 'small'is controller by the row 0 column 1 key.
# It will cause the group output to be .0001 when it is pressed.
# It has no output of its own, but has a status
# pin which will follow its current state.
# since this button is in a group, DEFAULT has no bearing.
# since OUTPUT in not 'COMMAND' _COMMAND entries are ignored.
[[[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
# This button, named 'large' is controller by the row 0 column 2 key.
# It will cause the group output to be 1000 when it is pressed.
# It has a SINT output of its own, will be 20 on true and 0 on false.
# It also has a status pin which will follow its current state.
# since this button is in a group, DEFAULT has no bearing.
# since OUTPUT in not 'COMMAND' _COMMAND entries are ignored.
[[[large]]]
KEY = R0C2
GROUP = group1_name
GROUP_OUTPUT = 1000
OUTPUT = SINT
STATUS_PIN = True
TRUE_STATE = 20
TRUE_COMMAND = NONE, NONE
FALSE_COMMAND = NONE, NONE
FALSE_STATE = 0
DEFAULT = false
Кнопки-перемикачі змінюють стан лише при кожному натисканні кнопки. Визначення кнопок-перемикачів починаються з тексту «TOGGLE_BUTTON» в одинарних дужках.
[TOGGLE_BUTTONS]
# Each button name inside double brackets, must be unique and is case sensitive.
# This button, named 'tool_change'is controller by the row 2 column 5 key.
# It has a BOOL output, will output 1 on true state and 0 on false state.
# It also has a status pin which will follow its current state.
# DEFAULT sets this to true when first initialized.
# The _COMMAND are not used since OUTPUT is not set to COMMAND but validation will
# add the lines regardless
[[tool_change]]
KEY = R2C5
OUTPUT = BOOL
TRUE_COMMAND = NONE, NONE
FALSE_COMMAND = NONE, NONE
STATUS_PIN = True
DEFAULT = TRUE
TRUE_STATE = 1
FALSE_STATE = 0
Миттєві кнопки мають значення true при натисканні та false при відпусканні. Визначення миттєвих кнопок починаються з тексту MOMENTARY_BUTTON в одинарних дужках.
[MOMENTARY_BUTTONS]
# Кожна назва кнопки в подвійних дужках повинна бути унікальною і чутливою до регістру.
# Ця кнопка, названа «spindle_rev», керується клавішею рядка 2 стовпця 3.
# Вона має вихід COMMAND, тому буде використовувати TRUE_COMMAND і FALSE_COMMAND.
# Вона також має контакт стану, який буде слідувати за її поточним станом.
# COMMANDs матиме ім'я команди, а потім будь-які необхідні аргументи.
# Ця TRUE_COMMAND викликає внутрішню команду для запуску шпинделя в зворотному напрямку зі швидкістю 200 об/хв.
# Якщо шпиндель вже запущений, швидкість обертання збільшиться.
# DEFAULT не використовується з миттєвими кнопками.
# _STATE не використовуються, оскільки OUTPUT встановлено на COMMAND, але перевірка
# додасть рядки незалежно від цього.
[[spindle_rev]]
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. Довідник внутрішніх команд
Існує кілька внутрішніх команд, які ви можете використовувати.
-
обов’язковий аргумент: номер осі (ціле число)
-
обов’язковий аргумент: номер осі (ціле число)
-
необов’язковий аргумент: початкове число RPM (ціле число) - за замовчуванням 100
-
Опис: Якщо шпиндель зупинено, він почне обертатися вперед. Якщо він вже працює, швидкість обертання збільшиться або зменшиться залежно від напрямку обертання шпинделя.
-
необов’язковий аргумент: початкове число RPM (ціле число) - за замовчуванням 100
-
необов’язковий аргумент: початкове число RPM (ціле число) - за замовчуванням 100
-
необов’язковий аргумент: початкове число RPM (ціле число) - за замовчуванням 100
-
Опис: Якщо шпиндель зупинено, він почне обертатися у зворотному напрямку. Якщо він вже працює, швидкість обертання збільшиться або зменшиться залежно від напрямку обертання шпинделя.
-
Опис: збільшує швидкість шпинделя на 100 об/хв
-
Опис: зменшує швидкість шпинделя на 100 об/хв, доки об/хв не досягне 100
-
обов’язковий аргумент: швидкість у дюймах за хвилину (число з плаваючою комою)
-
опис: встановлює швидкість штовхання по осях 0,1,2,6,7,8 (X,Y,Z,U,V,W)
-
обов’язковий аргумент: швидкість у градусах за хвилину (число з плаваючою комою)
-
опис: встановлює швидкість штовхання на осях 3, 4, 5 (A.B.C)
-
обов’язкові аргументи: номер осі (ціле число), напрямок (ціле число)
-
обов’язкові аргументи: номер осі (ціле число), напрямок (ціле число), відстань (число з плаваючою комою)
-
додаткові аргументи: абсолютне положення осі Z машини (число з плаваючою комою)
-
Опис: Перемістити вісь Z у задану позицію верстата
-
обов’язковий аргумент: стан (bool 0 або 1)
-
обов’язковий аргумент: ставка (число з плаваючою комою)
-
обов’язковий аргумент: rate (float 0-1)
-
обов’язковий аргумент: ставка (число з плаваючою комою)
-
обов’язковий аргумент: ставка (число з плаваючою комою)
-
обов’язковий аргумент: стан (bool 0 або 1)
-
обов’язковий аргумент: стан (bool 0 або 1)
-
обов’язковий аргумент: стан (bool 0 або 1)
-
Опис: У режимі очікування запускає програму G-коду, якщо призупинено, виконується один рядок.
-
обов’язковий аргумент: номер рядка (ціле число)
-
обов’язковий аргумент: команда(и) G-коду
-
Опис: записує поточний режим, викликає команди та повертається до цього режиму.
-
обов’язковий аргумент: команда(и) G-коду
-
Опис: встановлює режим MDI, викликає команди.
5. Повідомлення ZMQ
Panelui може надсилати повідомлення на основі ZMQ при натисканні кнопок.
Таким чином, panelui може взаємодіяти з іншими програмами, такими як екрани QtVCP.
[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
Ось приклад програми, яка отримає повідомлення та виведе його на термінал.
import zmq
import json
# ZeroMQ Context
context = zmq.Context()
# Визначте сокет за допомогою "Контексту"
sock = context.socket(zmq.SUB)
# Визначте підписку та повідомлення з темою для прийняття.
topic = "" # всі теми
sock.setsockopt(zmq.SUBSCRIBE, topic)
sock.connect("tcp://127.0.0.1:5690")
поки True:
topic, message = sock.recv_multipart()
print('{} sent message:{}'.format(topic,json.loads(message)))
6. Розширення файлу обробника
Спеціальний файл можна використовувати для додавання власного коду Python, який буде доступний як команди. panelui_handler.py повинен бути написаний на Python і розміщений у папці конфігурації. Якщо panelui знайде там файл, він додасть його виклики функцій до доступних команд. Ось приклад файлу обробника, який додає дві функції — hello_world і cycle_mode:
# стандартний виклик обробника - це завжди буде обов'язковим
def get_handlers(linuxcnc_stat, linucnc_cmd, commands, master):
return [HandlerClass(linuxcnc_stat, linucnc_cmd, commands, master)]
# Також обов'язковий - клас обробника класу HandlerClass:
# Це буде досить стандартним для отримання доступу до всього.
# linuxcnc_stat: це екземпляр стану Python для LinuxCNC.
# linuxcnc_cmd: це екземпляр команди Python для LinuxCNC.
# commands: це екземпляр команди, за допомогою якого можна викликати внутрішні процедури.
# master: надає доступ до основних функцій/даних.
def __init__(self, linuxcnc_stat, linuxcnc_cmd, commands, master):
self.parent = commands
self.current_mode = 0
# Команди повинні мати такий вигляд:
# def some_name(self, widget_instance, arguments from widget):
# widget_instance надає доступ до функції/даних викликуючим віджетом.
# arguments може бути списком аргументів, одним аргументом або None,
# залежно від того, що було вказано в INI-файлі panelui.
def hello_world(self, wname, m):
# вивести на термінал, щоб ми знали, що все працює
print('\nHello world\n')
print(m) # вивести аргумент(и)
print(wname.metadata) # вивести внутрішні метадані викликуючих віджетів (з файлу конфігурації)
# Викликайте команду mdi для друку повідомлення в LinuxCNC.
# Для цього потрібно, щоб LinuxCNC був встановлений, але це не перевіряється.
# Батьківські команди очікують widget_instance - замінюється None.
self.parent.mdi(None,'(MSG, Hello Linuxcnc World!)')
# Кожен виклик цієї функції циклічно змінюватиме режим LinuxCNC.
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)
# Код котла, часто потрібен
def __getitem__(self, item):
return getattr(self, item)
def __setitem__(self, item, value):
return setattr(self, item, value)