1. Вступ

GStat — це клас Python, який використовується для надсилання повідомлень з LinuxCNC до інших програм Python. Він використовує GObject для доставки повідомлень, що полегшує прослуховування конкретної інформації. Це називається подієвим програмуванням, яке є більш ефективним, ніж одночасне опитування LinuxCNC кожною програмою. GladeVCP, Gscreen, Gmoccapy та QtVCP широко використовують GStat. GStat знаходиться в модулі hal_glib.

Огляд
  • Спочатку програма імпортує модуль hal_glib та створює екземпляр GStat.

  • Потім він «підключається» до повідомлень, які хоче відстежувати.

  • GStat перевіряє стан LinuxCNC кожні 100 мс, і якщо є відмінності від останньої перевірки, він надсилає повідомлення зворотного виклику всім підключеним програмам з поточним станом.

  • Коли GStat викликає зареєстровану функцію, вона надсилає об’єкт GStat разом із будь-якими кодами повернення з повідомлення.

Типові підписи коду:

GSTAT.connect('MESSGAE-TO-LISTEN-FOR', FUNCTION_TO_CALL)

def FUNCTION_TO_CALL(gstat_object, return_codes):

Часто LAMBDA використовується для видалення об’єкта GSTAT та маніпулювання кодами повернення:

GSTAT.connect('MESSGAE-TO-LISTEN-FOR', lambda o, return: FUNCTION_TO_CALL(not return))

def FUNCTION_TO_CALL(return_codes):

2. Зразок коду GStat

Існує кілька основних схем використання GStat, залежно від того, в якій бібліотеці ви їх використовуєте. Якщо ви використовуєте GStat з GladeVCP, Gscreen або QtVCP, бібліотека GObject не потрібна, оскільки ці набори інструментів вже налаштовані для роботи з GObject.

2.1. Зразок шаблону коду компонента HAL

Ця програма створює два виводи HAL, які виводять стан G20/G21.

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import GObject
from gi.repository import GLib
import hal
from hal_glib import GStat
GSTAT = GStat()

# зворотний виклик для зміни стану виводу HAL
def mode_changed(obj, data):
        h['g20'] = not data
        h['g21'] = data

# Зробіть компонент і виводи
h = hal.component("metric_status")
h.newpin("g20", hal.HAL_BIT, hal.HAL_OUT)
h.newpin("g21", hal.HAL_BIT, hal.HAL_OUT)
h.ready()

# підключити повідомлення GSTAT до функції зворотного виклику
GSTAT.connect("metric-mode-changed",mode_changed)

# примусити GSTAT ініціалізувати стани
GSTAT.forced_update()

# петля до виходу
try:
    GLib.MainLoop().run()
except KeyboardInterrupt:
    raise SystemExit

Це можна завантажити за допомогою команди loadusr python PATH-TO-FILE/FILENAME.py або, якщо потрібно дочекатися створення контактів, перш ніж продовжувати:
loadusr python -Wn metric_status PATH-TO-FILE/FILENAME.py
Контакти будуть такими: metric_status.g20 та metric_status.g21.

2.2. Шаблон коду розширення Python GladeVCP

У цьому файлі припускається, що є три мітки GTK з такими назвами:

  • state_label

  • e_state_label

  • interp_state_label

#!/usr/bin/env python3

from hal_glib import GStat
GSTAT = GStat()

class HandlerClass:

    def __init__(self, halcomp, builder, useropts):
        self.builder = builder

        GSTAT.connect("state-estop",lambda w: self.update_estate_label('ESTOP'))
        GSTAT.connect("state-estop-reset",lambda w: self.update_estate_label('RESET'))

        GSTAT.connect("state-on",lambda w: self.update_state_label('MACHINE ON'))
        GSTAT.connect("state-off",lambda w: self.update_state_label('MACHINE OFF'))

        GSTAT.connect("interp-paused",lambda w: self.update_interp_label('Paused'))
        GSTAT.connect("interp-run",lambda w: self.update_interp_label('Run'))
        GSTAT.connect("interp-idle",lambda w: self.update_interp_label('Idle'))

    def update_state_label(self,text):
        self.builder.get_object('state_label').set_label("State: %s" % (text))

    def update_estate_label(self,text):
        self.builder.get_object('e_state_label').set_label("E State: %s" % (text))

    def update_interp_label(self,text):
        self.builder.get_object('interp_state_label').set_label("Interpreter State: %s" % (text))

def get_handlers(halcomp,builder,useropts):
    return [HandlerClass(halcomp,builder,useropts)]

2.3. Шаблон коду розширення Python QtVCP

QtVCP розширює GStat, тому його потрібно завантажувати по-різному, але всі повідомлення доступні в QtVCP.
Цей файл обробника припускає, що є три QLabel з такими назвами:

  • state_label

  • e_state_label

  • interp_state_label

#!/usr/bin/env python3

з імпорту qtvcp.core Стан
GSTAT = Status()

class HandlerClass:

    def __init__(self, halcomp,widgets,paths):
        self.w = widgets

        GSTAT.connect("state-estop",lambda w: self.update_estate_label('ESTOP'))
        GSTAT.connect("state-estop-reset",lambda w: self.update_estate_label('RESET'))

        GSTAT.connect("state-on",lambda w: self.update_state_label('MACHINE ON'))
        GSTAT.connect("state-off",lambda w: self.update_state_label('MACHINE OFF'))

        GSTAT.connect("interp-paused",lambda w: self.update_interp_label('Paused'))
        GSTAT.connect("interp-run",lambda w: self.update_interp_label('Run'))
        GSTAT.connect("interp-idle",lambda w: self.update_interp_label('Idle'))

    def update_state_label(self,text):
        self.w.state_label.setText("State: %s" % (text))

    def update_estate_label(self,text):
        self.w.e_state_label.setText("E State: %s" % (text))

    def update_interp_label(self,text):
        self.winterp_state_label.setText("Interpreter State: %s" % (text))

def get_handlers(halcomp,builder,useropts):
    return [HandlerClass(halcomp,widgets,paths)]

3. Повідомлення

periodic

«(нічого не повертає)» – надсилається кожні 100 мс.

state-estop

(returns nothing) - Надсилається, коли LinuxCNC переходить у режим estop.

state-estop-reset

(returns nothing) - Надсилається, коли LinuxCNC виходить з режиму estop.

state-on

(returns nothing) - Надсилається, коли LinuxCNC перебуває у стані «машина ввімкнена».

state-off

(returns nothing) - Надсилається, коли LinuxCNC вимкнено.

homed

(returns string) - Надсилається, коли кожен джоін переводиться в хоум-код.

all-homed

(returns nothing) - Надсилається, коли всі визначені з’єднання переведені в вихідне положення.

not-all-homed

(returns string) - Надсилає список суглобів, які наразі не є хоум-ранами.

override_limits_changed

(returns string) - Надсилається, якщо LinuxCNC було наказано перевизначити свої обмеження.

hard-limits-tripped

(returns bool, Python List) - Надсилається, коли спрацьовує будь-яке жорстке обмеження. bool вказує, що якщо спрацьовує будь-яке обмеження, список показує поточні граничні значення всіх доступних з’єднань.

mode-manual

(returns nothing) - Надсилається, коли LinuxCNC перемикається в ручний режим.

mode-mdi

(returns nothing) - Надсилається, коли LinuxCNC перемикається в режим MDI.

mode-auto

(returns nothing) - Надсилається, коли LinuxCNC перемикається в автоматичний режим.

command-running

(returns nothing) - Надсилається під час запуску програми або MDI

command-stopped

(returns nothing) - Надсилається, коли програма або MDI зупинені

command-error

(returns nothing) - Надсилається, коли виникає помилка команди

interp-run

(returns nothing) - Надсилається, коли інтерпретатор LinuxCNC виконує MDI або програму.

interp-idle

(returns nothing) - Надсилається, коли інтерпретатор LinuxCNC неактивний.

interp-paused

(returns nothing) - Надсилається, коли інтерпретатор LinuxCNC призупинено.

interp-reading

(returns nothing) - Надсилається, коли інтерпретатор LinuxCNC читає.

interp-waiting

(returns nothing) - Надсилається, коли інтерпретатор LinuxCNC очікує.

jograte-changed

(returns float) - Відправляється, коли швидкість ручного переміщення змінилася.
LinuxCNC не має внутрішньої швидкості ручного переміщення.
Це внутрішня швидкість ручного переміщення GStat.
Очікується, що вона буде вказана в одиницях виміру, властивих для даної машини, незалежно від поточного режиму одиниць виміру.

jograte-angular-changed

(returns float) - Відправляється, коли змінюється кутова швидкість переміщення.
LinuxCNC не має внутрішньої кутової швидкості переміщення.
Це внутрішня швидкість переміщення GStat.
Очікується, що вона буде вказана в одиницях виміру, властивих для даної машини, незалежно від поточного режиму одиниць виміру.

jogincrement-changed

(returns float, text) - Відправляється, коли змінюється приріст кроку.
LinuxCNC не має внутрішнього приросту кроку.
Це внутрішній приріст кроку GStat.
Очікується, що він буде в нативних одиницях виміру машини, незалежно від поточного режиму одиниць виміру.

jogincrement-angular-changed

(returns float, text) - Відправляється, коли змінюється кутовий крок переміщення.
LinuxCNC не має внутрішнього кутового кроку переміщення.
Це внутрішній кутовий крок переміщення GStat.
Очікується, що він буде в нативних одиницях виміру машини, незалежно від поточного режиму одиниць виміру.

program-pause-changed

(returns bool) - Надсилається, коли програма призупинена/відновлена.

optional-stop-changed

(returns bool) - Надсилається, коли встановлено/знято необов’язкову зупинку

block-delete-changed

(returns bool) - надсилається, коли встановлено/скасовано видалення блоку.

file-loaded

(returns string) - Надсилається, коли LinuxCNC завантажує файл

reload-display

(returns nothing) - Надсилається, коли є запит на перезавантаження дисплея

line-changed

(returns integer) - Надсилається, коли LinuxCNC зчитує новий рядок.
LinuxCNC не оновлює це для кожного типу рядка.

tool-in-spindle-changed

(returns integer) - Надсилається, коли інструмент змінюється.

tool-info-changed

(returns Python object) - Надсилається, коли змінюється інформація про поточний інструмент.

current-tool-offset

(returns Python object) - Надсилається, коли змінюються поточні зміщення інструменту.

motion-mode-changed

(returns integer) - Надсилається, коли режим руху змінюється

spindle-control-changed

(returns integer, bool, integer, bool) - (номер шпинделя, стан шпинделя ввімкнено, запитуваний напрямок і швидкість шпинделя, стан на швидкості)
Надсилається, коли змінюється напрямок або стан роботи шпинделя, або змінюється швидкість.

current-feed-rate

(returns float) - Надсилається, коли змінюється поточна швидкість подачі.

current-x-rel-position

(повертає число з плаваючою комою) – Надсилається кожні 100 мс.

current-position

(returns pyobject, pyobject, pyobject, pyobject) - Надсилається кожні 100 мс.
Повертає кортежі позиції, відносної позиції, відстані до переміщення та фактичної позиції суглоба. Перед поверненням до початкової точки, на осях з кількома суглобами, дійсним є лише положення суглоба.

current-z-rotation

(returns float) - Надсилається, коли змінюється поточний кут повороту навколо осі Z

requested-spindle-speed-changed

(returns float) - Надсилається, коли змінюється поточний запитуваний RPM

actual-spindle-speed-changed

(returns float) - Надсилається, коли фактична швидкість обертання змінюється на основі даних виводу HAL spindle.0.speed-in.

spindle-override-changed

(returns float) - Надсилається, коли змінюється значення корекції шпинделя
у відсотках

feed-override-changed

(returns float) - Надсилається, коли значення перевизначення каналу змінюється
у відсотках

rapid-override-changed

(returns float) - Надсилається, коли змінюється значення швидкого перевизначення
у відсотках (0-100)

max-velocity-override-changed

(returns float) - Надсилається, коли змінюється значення максимальної швидкості
в одиницях за хвилину

feed-hold-enabled-changed

(returns bool) - Надсилається, коли змінюється стан затримки каналу

itime-mode

(returns bool) - Надсилається, коли змінюється стан G93
(режим зворотного часу)

fpm-mode

(returns bool) - Надсилається, коли змінюється стан G94
(режим подачі за хвилину)

fpr-mode

(returns bool) - Надсилається, коли змінюється стан G95
(режим подачі на оберт)

css-mode

(returns bool) - Надсилається, коли змінюється стан G96
(режим постійної подачі на поверхню)

rpm-mode

(returns bool) - Надсилається, коли змінюється стан G97
(режим постійних обертів)

radius-mode

(returns bool) - Надсилається, коли змінюється статус G8
відображати X у режимі радіуса

diameter-mode

(returns bool) - Надсилається, коли змінюється стан G7
відображати X у режимі діаметра

flood-changed

(returns bool) - Надсилається, коли змінюється стан охолоджувальної рідини.

mist-changed

(returns bool ) - Надсилається, коли змінюється стан охолоджувальної рідини туманом.

m-code-changed

(returns string) - Надсилається, коли змінюються активні M-коди

g-code-changed

(returns string) - Надсилається під час активної зміни G-коду

metric-mode-changed

(returns bool) - Надсилається, коли змінюється статус G21

user-system-changed

(returns string) - Надсилається, коли змінюється система опорних координат (G5x)

mdi-line-selected

(returns string, string) - призначено для надсилання, коли користувач вибирає рядок MDI.
Це залежить від використовуваних віджетів/бібліотек.

gcode-line-selected

(returns integer) - призначено для надсилання, коли користувач вибирає рядок G-коду.
Це залежить від використаних віджетів/бібліотек.

graphics-line-selected

(returns integer) - призначено для надсилання, коли користувач вибирає графічну лінію.
Це залежить від використаних віджетів/бібліотек.

graphics-loading-progress

(returns integer) - призначений для повернення відсотка виконання завантаження або запуску програми.
Це залежить від використаних віджетів/бібліотек.

graphics-gcode-error

(returns string) - призначено для надсилання, коли під час завантаження виявлено помилку G-коду.
Це залежить від використаних віджетів/бібліотек.

graphics-gcode-properties

(returns Python dict) - Надсилається під час завантаження G-коду.
Словник містить такі ключі:

  • name (string): Ім’я завантаженого файлу

  • size (string): Розмір у байтах та рядках

  • g0 (string): Загальна швидкісна дистанція

  • g1 (string): Загальна відстань подачі

  • run (string): Орієнтовний час виконання програми

  • toollist (list): Список використаних інструментів

  • x (string): X екстентів (меж) 1

  • x_zero_rxy (string): X-екстенції без обертання навколо z (межі) 1

  • y (string): Y екстентів (границь) 1

  • y_zero_rxy (string): Екстенти Y без обертання навколо z (межі) 1

  • z (string): Z-екстенти (межі) 1

  • z_zero_rxy (string): Z-екстенції без обертання навколо z (межі) 1

  • machine_unit_sys (string): Одиниці вимірювання (Метричні або Імперські)

  • gcode_units (string): Одиниці вимірювання у файлі G-коду (мм або дюйми)

    Note
    1. Дивіться зображення:images/gremlin_extents_non-rotated_link.png[align="left",link="images/gremlin_extents_non-rotated.png",alt="extends non-rotated"] and extends rotated 30 для кращого розуміння.

graphics-view-changed

(returns string, Python dict or None) - призначено для надсилання під час зміни графічного вигляду.
Це залежить від використаних віджетів/бібліотек.

mdi-history-changed

(returns None) - призначене для надсилання, коли потрібно перезавантажити історію MDI.
Це залежить від використаних віджетів/бібліотек.

machine-log-changed

(returns None) - призначено для надсилання, коли журнал машини змінився.
Це залежить від використаних віджетів/бібліотек.

update-machine-log

(returns string, string) - призначений для надсилання під час оновлення комп’ютера.
Це залежить від використовуваних віджетів/бібліотек.

move-text-lineup

(returns None) - призначене для надсилання під час переміщення курсора на один рядок вгору на дисплеї G-коду.
Це залежить від використовуваних віджетів/бібліотек.

move-text-linedown

(returns None) - призначене для надсилання під час переміщення курсора на один рядок вниз у відображенні G-коду.
Це залежить від використовуваного віджета/бібліотек.

dialog-request

(returns Python dict) - призначено для надсилання під час запиту діалогу графічного інтерфейсу.
Для зв’язку використовується словник Python. Словник повинен містити таку пару ключів:

  • NAME: requested dialog name
    Словник зазвичай має кілька пар імен ключів — це залежить від діалогу.
    Діалоги повертають інформацію за допомогою загального повідомлення.
    Це залежить від використаного віджета/бібліотек.

focus-overlay-changed

(returns bool, string, Python object) - призначений для надсилання під час запиту на розміщення накладання поверх дисплея.
Це залежить від використаних віджетів/бібліотек.

play-sound

(returns string) - призначений для надсилання під час запиту відтворення певного звукового файлу.
Це залежить від використаного віджета/бібліотек.

virtual-keyboard

(returns string) - призначене для надсилання під час запиту екранної клавіатури.
Це залежить від використаного віджета/бібліотек.

dro-reference-change-request

(returns integer) - призначене для надсилання під час запиту віджета DRO на зміну його посилання.
0 = машина, 1 = відносна, 3 = залишкова відстань
Це залежить від використовуваного віджета/бібліотек.

show-preferences

(returns None) - призначене для надсилання під час запиту на відображення налаштувань екрана.
Це залежить від використовуваних віджетів/бібліотек.

shutdown

(returns None) - призначений для надсилання під час запиту на завершення роботи LinuxCNC.
Це залежить від використовуваних віджетів/бібліотек.

status-message

returns python dict (message), python dict (options) Призначено для екрана/панелі для отримання повідомлень про стан/журнал з віджетів, але може використовуватися загалом.
Очікується, що об’єкт прослуховування шукатиме та оброблятиме щонайменше такі записи:

Словник повідомлення міститиме:

  • TITLE: (рядок)

  • SHORTTEXT: (рядок)

  • DETAILS: (рядок)

Список опцій включатиме:

  • LEVEL: (ціле число)

  • LOG: (логічна змінна)

Об’єкт прослуховування може використовувати це для відображення інформації в текстовому рядку або діалоговому вікні повідомлення.
РІВЕНЬ вказує на терміновість 0 = ЗАЗВИЧАЙ 1 = ПОПЕРЕДЖЕННЯ 2 = КРИТИЧНИЙ
LOG вказує, чи слід записувати повідомлення у файл/на сторінку, якщо це можливо.
Передбачається, що повідомлення LOG використовують запис DETAILS.

Приклад того, як надіслати повідомлення:

mess = {'SHORTTEXT':'File Copy Failed',
        'TITLE':'FileManager',
        'DETAILS':'На диску недостатньо місця для копіювання файлу'}
opt = {'LOG':True,'LEVEL':2}
STATUS.emit('status-message',mess,opt)

Приклад об’єкта прослуховування:

# повідомити STATUS, що ми хочемо відповідати на будь-які надіслані повідомлення типу «status-message».
STATUS.connect('status-message', lambda w, d, o: self.add_external_status(m,o))

    def add_external_status(self, message, option):

        # вилучення та перехоплення помилок для очікуваних записів
        level = option.get('LEVEL', STATUS.DEFAULT)
        log = option.get("LOG", True)
        title = message.get('TITLE', '')
        mess = message.get('SHORTTEXT', '')
        logtext = message.get('DETAILS', '')

        # викликати функцію для виведення повідомлення в рядку стану:
        self.add_status(mess, level, noLog=True)

        # запит на оновлення файлу журналу
        if log:
            STATUS.emit('update-machine-log', "{}\n{}".format(title, logtext), 'TIME')
error

(returns integer, string) - призначено для надсилання, коли повідомляється про помилку.
ціле число представляє тип помилки. ERROR, TEXT або DISPLAY
рядок – це фактичне повідомлення про помилку.
Це залежить від використаних віджетів/бібліотек.

general

(returns Python dict) - призначений для відправлення, коли необхідно надіслати повідомлення, яке не охоплюється більш конкретним повідомленням.
Загальне повідомлення слід використовувати якомога рідше, оскільки всі об’єкти, пов’язані з ним, повинні будуть його розібрати.
Для комунікації використовується словник Python.
Словник повинен містити та перевірятися на наявність унікальної пари ідентифікатора та імені ключа:

  • ID: UNIQUE_ID_CODE
    У словнику зазвичай більше пар ключових слів — це залежить від реалізації.

forced-update

(returns None) - призначений для надсилання, коли потрібно ініціалізувати або довільно оновити об’єкт.
Це залежить від використовуваних віджетів/бібліотек.

progress

(returns integer, Python object) - призначений для надсилання для індикації прогресу програми фільтрації.
Це залежить від використаних віджетів/бібліотек.

following-error

(returns Python list) - повертає список усіх поточних суглобів після помилки.

4. Функції

Це зручні функції, які зазвичай використовуються в програмуванні.

set_jograte

(float) - LinuxCNC не має внутрішньої концепції швидкості переміщення - кожен графічний інтерфейс має свою власну. Це не завжди зручно.
Ця функція дозволяє встановити швидкість переміщення для всіх об’єктів, підключених до сигналу jograte-changed.
За замовчуванням вона становить 15.
GSTAT.set_jog_rate(10) встановить швидкість переміщення на 10 одиниць машини на хвилину і видасть сигнал jograte-changed.

get_jograte()

(Nothing) - x = GSTAT.get_jograte() поверне поточне внутрішнє значення jograte (число з плаваючою комою) GSTAT.

set_jograte_angular

(float) -

get_jograte_angular

(Жоден) -

set_jog_increment_angular

(float, string) -

get_jog_increment_angular

(Жоден) -

set_jog_increments

(float, string) -

get_jog_increments

(Жоден) -

is_all_homed

(nothing) - Це поверне поточний стан all_homed (BOOL).

machine_is_on

(nothing) - Це поверне поточний стан машини (BOOL).

estop_is_clear

(nothing) - Це поверне стан Estop (BOOL)

set_tool_touchoff

(tool,axis,value) - Ця команда буде

  1. запис поточного режиму,

  2. переключитися в режим MDI,

  3. викликати команду MDI: G10 L10 P[TOOL] [AXIS] [VALUE],

  4. зачекайте, поки це завершиться,

  5. викликати G43,

  6. зачекайте, поки це завершиться,

  7. повернутися до початкового режиму.

set_axis_origin

(axis,value) - Ця команда буде

  1. запис поточного режиму,

  2. переключитися в режим MDI,

  3. викликати команду MDI: G10 L20 P0 [AXIS] [VALUE],

  4. зачекайте, поки це завершиться,

  5. повернутися до початкового режиму,

  6. видавати сигнал «перезавантаження дисплея».

do_jog

(axis_number,direction, distance) - Це дозволить безперервно переміщувати вісь або переміщувати її на заданій відстані.
Для переміщення потрібно бути у відповідному режимі.

check_for_modes

(mode) - Ця функція перевіряє необхідний режим LinuxCNC.
Вона повертає кортеж Python (стан, режим)
режим буде встановлено на режим, у якому знаходиться система
стан буде встановлено на:

  • хибність, якщо режим дорівнює 0

  • false, якщо машина зайнята

  • true, якщо LinuxCNC перебуває в запитуваному режимі

  • Немає, якщо можливо змінити, але не в запитуваному режимі

get_current_mode

(nothing) - повертає ціле число: поточний режим LinuxCNC.

set_selected_joint

(integer) - записує номер вибраного з’єднання внутрішньо.
запитує вибір з’єднання, надсилаючи повідомлення
joint-selection-changed.

get_selected_joint

(None) - повертає ціле число, що представляє внутрішній вибраний номер суглоба.

set_selected_axis

(string) - записує вибрану літеру осі внутрішньо.
Запитує вибір осі, надсилаючи повідомлення axis-selection-changed.

get_selected_axis

(None) - повертає рядок, що представляє внутрішню вибрану літеру осі.

is_man_mode

(Жоден) -

is_mdi_mode

(Жоден) -

is_auto_mode

(Жоден) -

is_on_and_idle

(Жоден) -

is_auto_running

(Жоден) -

is_auto_paused

(Жоден) -

is_file_loaded

(Жоден) -

is_metric_mode

(Жоден) -

is_spindle_on

(Жоден) -

shutdown

(Жоден) -

5. Відомі проблеми

Деякі статусні точки повідомляються неправильно під час виконання програми, оскільки інтерпретатор працює попереду поточної позиції програми, що виконується. Сподіваємося, що ця проблема буде вирішена після об’єднання гілки state-tags.