LinuxCNC Documentation

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
[HAL_PREFIX]
    NAME= Yourname

Це дозволяє змінити префікс виводів HAL з «panelui» на довільну назву.

Налаштування повідомлень ZMQ
[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. Довідник внутрішніх команд

Існує кілька внутрішніх команд, які ви можете використовувати.

home_selected
  • обов’язковий аргумент: номер осі (ціле число)

unhome_selected
  • обов’язковий аргумент: номер осі (ціле число)

spindle_forward_adjust
  • необов’язковий аргумент: початкове число RPM (ціле число) - за замовчуванням 100

  • Опис: Якщо шпиндель зупинено, він почне обертатися вперед. Якщо він вже працює, швидкість обертання збільшиться або зменшиться залежно від напрямку обертання шпинделя.

spindle_forward
  • необов’язковий аргумент: початкове число RPM (ціле число) - за замовчуванням 100

spindle_reverse
  • необов’язковий аргумент: початкове число RPM (ціле число) - за замовчуванням 100

spindle_reverse_adjust
  • необов’язковий аргумент: початкове число RPM (ціле число) - за замовчуванням 100

  • Опис: Якщо шпиндель зупинено, він почне обертатися у зворотному напрямку. Якщо він вже працює, швидкість обертання збільшиться або зменшиться залежно від напрямку обертання шпинделя.

spindle_faster
  • Опис: збільшує швидкість шпинделя на 100 об/хв

spindle_slower
  • Опис: зменшує швидкість шпинделя на 100 об/хв, доки об/хв не досягне 100

set_linear_jog_velocity
  • обов’язковий аргумент: швидкість у дюймах за хвилину (число з плаваючою комою)

  • опис: встановлює швидкість штовхання по осях 0,1,2,6,7,8 (X,Y,Z,U,V,W)

set_angular_jog_velocity
  • обов’язковий аргумент: швидкість у градусах за хвилину (число з плаваючою комою)

  • опис: встановлює швидкість штовхання на осях 3, 4, 5 (A.B.C)

continuous_jog
  • обов’язкові аргументи: номер осі (ціле число), напрямок (ціле число)

incremental_jog
  • обов’язкові аргументи: номер осі (ціле число), напрямок (ціле число), відстань (число з плаваючою комою)

quill_up
  • додаткові аргументи: абсолютне положення осі Z машини (число з плаваючою комою)

  • Опис: Перемістити вісь Z у задану позицію верстата

feed_hold
  • обов’язковий аргумент: стан (bool 0 або 1)

feed_override
  • обов’язковий аргумент: ставка (число з плаваючою комою)

rapid_override
  • обов’язковий аргумент: rate (float 0-1)

spindle_override
  • обов’язковий аргумент: ставка (число з плаваючою комою)

max_velocity
  • обов’язковий аргумент: ставка (число з плаваючою комою)

optional_stop
  • обов’язковий аргумент: стан (bool 0 або 1)

block_delete
  • обов’язковий аргумент: стан (bool 0 або 1)

single_block
  • обов’язковий аргумент: стан (bool 0 або 1)

smart_cycle_start
  • Опис: У режимі очікування запускає програму G-коду, якщо призупинено, виконується один рядок.

re_start line
  • обов’язковий аргумент: номер рядка (ціле число)

mdi_and_return
  • обов’язковий аргумент: команда(и) G-коду

  • Опис: записує поточний режим, викликає команди та повертається до цього режиму.

mdi
  • обов’язковий аргумент: команда(и) 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)