1. Вступ

Конфігурація переходить від теорії до пристрою – тобто пристрою HAL. Для тих, хто хоч трохи знайомий з комп’ютерним програмуванням, цей розділ – це «Привіт, світе» HAL.

halrun може бути використаний для створення робочої системи. Це інструмент командного рядка або текстового файлу для конфігурації та налаштування. Наведені нижче приклади ілюструють його налаштування та роботу.

2. Halcmd

halcmd — це інструмент командного рядка для роботи з HAL. Більш повна сторінка довідки для halcmd існує і встановлюється разом з LinuxCNC, з вихідного коду або з пакета. Якщо LinuxCNC було скомпільовано як run-in-place, сторінка довідки не встановлюється, але доступна в головному каталозі LinuxCNC за допомогою наступної команди:

$ man -M docs/man halcmd

2.1. Нотація

У цьому підручнику команди для операційної системи зазвичай показані без підказки, що надається оболонкою UNIX, тобто зазвичай знака долара ($) або знака решітки/подвійного хрестика (#). При безпосередньому спілкуванні з HAL через halcmd або halrun підказки показані в прикладах. Вікно терміналу знаходиться в розділі «Програми/Аксесуари» головної панелі меню Ubuntu.

Приклад команди терміналу - підказки
me@computer:~linuxcnc$ halrun
(буде показано як у наступному рядку)
halrun

(запит halcmd: буде показано під час запуску HAL)
halcmd: loadrt counter
halcmd: show pin

2.2. Автозаповнення за допомогою клавіші Tab

Ваша версія halcmd може підтримувати автозавершення за допомогою клавіші Tab. Замість завершення імен файлів, як це робить оболонка, вона завершує команди за допомогою ідентифікаторів HAL. Вам потрібно буде ввести достатню кількість літер для унікального збігу. Спробуйте натиснути клавішу Tab після запуску команди HAL:

Автозаповнення за допомогою клавіші Tab
halcmd: loa<TAB>
halcmd: load
halcmd: loadrt
halcmd: loadrt cou<TAB>
halcmd: loadrt counter

2.3. Середовище RTAPI

RTAPI означає «інтерфейс програмування додатків у реальному часі». Багато компонентів HAL працюють у реальному часі, і всі компоненти HAL зберігають дані у спільній пам’яті, щоб компоненти реального часу могли отримати до них доступ. Звичайна Linux не підтримує програмування у реальному часі або тип спільної пам’яті, який потрібен HAL. На щастя, існують операційні системи реального часу (RTOS), які надають необхідні розширення для Linux. На жаль, кожна RTOS працює трохи по-різному.

Щоб вирішити ці проблеми, команда LinuxCNC розробила RTAPI, який забезпечує єдиний спосіб взаємодії програм з RTOS. Якщо ви програміст, який хоче працювати над внутрішніми компонентами LinuxCNC, вам може бути корисно вивчити файл «linuxcnc/src/rtapi/rtapi.h», щоб зрозуміти API. Але якщо ви звичайна людина, все, що вам потрібно знати про RTAPI, це те, що він (і RTOS) повинен бути завантажений в пам’ять вашого комп’ютера, перш ніж ви почнете працювати з HAL.

3. Простий приклад

3.1. Завантаження компонента

Для цього підручника ми будемо вважати, що ви успішно встановили Live CD і, якщо використовуєте RIP
[Run In Place, коли вихідні файли завантажені в каталог користувача і компілюються та виконуються безпосередньо звідти.]
, запустіть скрипт «rip-environment» для підготовки вашої оболонки. У цьому випадку все, що вам потрібно зробити, це завантажити необхідні модулі RTOS і RTAPI в пам’ять. Просто виконайте наступну команду з терміналу:

Завантаження HAL
cd linuxcnc
halrun
halcmd:

Завантаживши ОС реального часу та RTAPI, ми можемо перейти до першого прикладу. Зверніть увагу, що тепер командний рядок відображається як «halcmd:». Це пов’язано з тим, що наступні команди будуть інтерпретуватися як команди HAL, а не команди оболонки.

Для першого прикладу ми будемо використовувати компонент HAL під назвою «siggen», який є простим генератором сигналів. Повний опис компонента «siggen» можна знайти в розділі SigGen цього посібника. Це компонент реального часу. Щоб завантажити компонент «siggen», використовуйте команду HAL loadrt.

Завантаження знаку
halcmd: loadrt siggen

3.2. Вивчення HAL

Тепер, коли модуль завантажено, настав час представити halcmd, інструмент командного рядка, що використовується для налаштування HAL. У цьому підручнику буде представлено лише деякі функції halcmd. Більш повний опис можна знайти в man halcmd або в розділі HAL Commands цього документа. Першою функцією halcmd є команда «show». Ця команда відображає інформацію про поточний стан HAL. Щоб показати всі встановлені компоненти:

Показати компоненти з halrun/halcmd
halcmd: show comp

    Завантажені компоненти HAL:
    ID     Type  Name                                PID   State
    3      RT    siggen                                    ready
    2      User  halcmd2177                          2177  ready

Оскільки halcmd сам по собі також є компонентом HAL, він завжди буде відображатися у списку. Число після «halcmd» у списку компонентів є ідентифікатором процесу UNIX. Можна запустити декілька копій halcmd одночасно (наприклад, у різних вікнах терміналу), тому PID додається в кінець імені, щоб зробити його унікальним. У списку також відображається компонент «siggen», який ми встановили на попередньому кроці. «RT» під «Тип» вказує, що «siggen» є компонентом реального часу. «Користувач» під «Тип» вказує, що це компонент нереального часу.

Далі, давайте подивимося, які піни пропонує siggen:

Показати піни
halcmd: show pin

Виводи компонентів:
Owner   Type   Dir        Value  Name
     3  float  IN             1  siggen.0.amplitude
     3  bit    OUT        FALSE  siggen.0.clock
     3  float  OUT            0  siggen.0.cosine
     3  float  IN             1  siggen.0.frequency
     3  float  IN             0  siggen.0.offset
     3  float  OUT            0  siggen.0.sawtooth
     3  float  OUT            0  siggen.0.sine
     3  float  OUT            0  siggen.0.square
     3  float  OUT            0  siggen.0.triangle

Ця команда відображає всі контакти в поточному HAL. Складна система може мати десятки або сотні контактів. Але зараз є тільки дев’ять контактів. З них вісім є плаваючими, а один — бітовим (булевим). Шість передають дані з компонента «siggen», а три використовуються для передачі налаштувань у компонент. Оскільки ми ще не виконали код, що міститься в компоненті, деякі контакти мають значення нуль.

Наступний крок – це перевірка параметрів:

Показати параметри
halcmd: show param

Параметри:
Owner   Type  Dir        Value   Name
     3  s32   RO             0   siggen.0.update.time
     3  s32   RW             0   siggen.0.update.tmax

Команда «show param» показує всі параметри в HAL. На даний момент кожен параметр має значення за замовчуванням, яке було задано під час завантаження компонента. Зверніть увагу на стовпець із назвою «Dir». Параметри з позначкою «-W» є параметрами, що записуються, які ніколи не змінюються самим компонентом, а призначені для зміни користувачем з метою керування компонентом. Пізніше ми побачимо, як це зробити. Параметри з позначкою «R-» є параметрами тільки для читання. Вони можуть бути змінені тільки компонентом. Нарешті, параметри з позначкою «RW» є параметрами для читання і запису. Це означає, що вони змінюються компонентом, але також можуть бути змінені користувачем. Примітка: Параметри siggen.0.update.time і siggen.0.update.tmax призначені для налагодження і не будуть розглядатися в цьому розділі.

Більшість компонентів реального часу експортують одну або декілька функцій для фактичного запуску коду реального часу, який вони містять. Давайте подивимося, які функції експортував «siggen»:

Показати функції за допомогою halcmd`
halcmd: show funct

Експортовані функції:
Owner   CodeAddr  Arg       FP   Users  Name
00003   f801b000  fae820b8  YES      0  siggen.0.update

The siggen component exported a single function. It is not currently linked to any threads, so users is zero
[CodeAddr and Arg fields were used during development and should probably disappear.]
.

3.3. Запуск коду в реальному часі

Щоб фактично запустити код, що міститься у функції siggen.0.update, нам потрібен потік реального часу. Компонент під назвою «threads» використовується для створення нового потоку. Створимо потік під назвою «test-thread» з періодом 1 мс (1000 мкс або 1000000 нс):

halcmd: loadrt threads name1=test-thread period1=1000000

Давайте подивимося, чи це спрацювало:

Показати теми
halcmd: show thread

Теми в реальному часі:
     Period  FP     Name               (     Time, Max-Time )
     999855  YES    test-thread        (        0,        0 )

It did. The period is not exactly 1,000,000 ns because of hardware limitations, but we have a thread that runs at approximately the correct rate. The next step is to connect the function to the thread:

Додати функцію
halcmd: addf siggen.0.update test-thread

До цього часу ми використовували halcmd тільки для перегляду HAL. Однак цього разу ми використали команду addf (додати функцію), щоб фактично змінити щось у HAL. Ми наказали halcmd додати функцію siggen.0.update до потоку test-thread, і якщо ми знову подивимося на список потоків, то побачимо, що це вдалося:

halcmd: show thread

Теми в реальному часі:
     Period  FP     Name                (     Time, Max-Time )
     999855  YES    test-thread         (        0,        0 )
                  1 siggen.0.update

Перед тим, як компонент «siggen» почне генерувати сигнали, потрібно виконати ще один крок. При першому запуску HAL потоки фактично не працюють. Це дозволяє повністю налаштувати систему перед запуском коду реального часу. Коли ви будете задоволені налаштуваннями, можете запустити код реального часу таким чином:

halcmd: start

Тепер генератор сигналів працює. Давайте розглянемо його вихідні контакти:

halcmd: show pin

Виводи компонентів:
Owner   Type  Dir         Value  Name
     3  float IN              1  siggen.0.amplitude
     3  bit   OUT         FALSE  siggen.0.clock
     3  float OUT    -0.1640929  siggen.0.cosine
     3  float IN              1  siggen.0.frequency
     3  float IN              0  siggen.0.offset
     3  float OUT    -0.4475303  siggen.0.sawtooth
     3  float OUT     0.9864449  siggen.0.sine
     3  float OUT            -1  siggen.0.square
     3  float OUT    -0.1049393  siggen.0.triangle

І давайте ще раз подивимося:

halcmd: show pin

Виводи компонентів:
Owner   Type  Dir         Value  Name
     3  float IN              1  siggen.0.amplitude
     3  bit   OUT         FALSE  siggen.0.clock
     3  float OUT     0.0507619  siggen.0.cosine
     3  float IN              1  siggen.0.frequency
     3  float IN              0  siggen.0.offset
     3  float OUT     -0.516165  siggen.0.sawtooth
     3  float OUT     0.9987108  siggen.0.sine
     3  float OUT            -1  siggen.0.square
     3  float OUT    0.03232994  siggen.0.triangle

Ми швидко послідовно виконали дві команди «show pin», і ви можете бачити, що вихідні дані більше не дорівнюють нулю. Вихідні дані синуса, косинуса, пилкоподібної хвилі та трикутника постійно змінюються. Вихідні дані квадратної хвилі також працюють, однак вони просто перемикаються з +1,0 на -1,0 кожного циклу.

3.4. Зміна параметрів

Справжня сила HAL полягає в тому, що ви можете змінювати значення. Наприклад, ми можемо використовувати команду setp для встановлення значення параметра. Давайте змінимо амплітуду генератора сигналів з 1,0 до 5,0:

Встановити PIN-код
halcmd: setp siggen.0.amplitude 5
Ще раз перевірте параметри та контакти
halcmd: show param

Параметри:
Owner   Type  Dir         Value  Name
     3  s32   RO           1754  siggen.0.update.time
     3  s32   RW          16997  siggen.0.update.tmax

halcmd: show pin

Виводи компонентів:
Owner   Type  Dir         Value  Name
     3  float IN              5  siggen.0.amplitude
     3  bit   OUT         FALSE  siggen.0.clock
     3  float OUT     0.8515425  siggen.0.cosine
     3  float IN              1  siggen.0.frequency
     3  float IN              0  siggen.0.offset
     3  float OUT      2.772382  siggen.0.sawtooth
     3  float OUT     -4.926954  siggen.0.sine
     3  float OUT             5  siggen.0.square
     3  float OUT      0.544764  siggen.0.triangle

Зверніть увагу, що значення параметра siggen.0.amplitude змінилося на 5, і що тепер значення виводів більші.

3.5. Збереження конфігурації HAL

Більшість того, що ми робили з halcmd до цього моменту, полягало просто в перегляді елементів за допомогою команди «show». Однак дві з команд фактично змінили ситуацію. У міру того, як ми будемо проектувати більш складні системи за допомогою HAL, ми будемо використовувати багато команд для налаштування елементів саме так, як нам потрібно. HAL має пам’ять слона і збереже цю конфігурацію, поки ми її не вимкнемо. Але що буде наступного разу? Ми не хочемо вручну вводити купу команд щоразу, коли хочемо використовувати систему.

Збереження конфігурації всього HAL однією командою.
halcmd: save

# компоненти
loadrt threads name1=test-thread period1=1000000
loadrt siggen
# псевдоніми виводів
# сигнали
# мережі
# значення параметрів
setp siggen.0.update.tmax 14687
# посилання на потоки/функції в реальному часі
addf siggen.0.update test-thread

Результатом виконання команди save є послідовність команд HAL. Якщо ви почнете з порожнього HAL і виконаєте всі ці команди, ви отримаєте конфігурацію, яка існувала на момент виконання команди «save». Щоб зберегти ці команди для подальшого використання, ми просто перенаправимо вихідні дані у файл:

Збережіть конфігурацію у файл за допомогою halcmd
halcmd: save all saved.hal

3.6. Вихід з Халруна

Коли ви закінчите сеанс HAL, введіть exit у командному рядку "halcmd:". Це поверне вас до системного командного рядка і закриє сеанс HAL. Не закривайте вікно терміналу, не завершивши сеанс HAL.

Вихід з HAL
halcmd: exit

3.7. Відновлення конфігурації HAL

Щоб відновити конфігурацію HAL, збережену у файлі «saved.hal», нам потрібно виконати всі ці команди HAL. Для цього ми використовуємо «-f _<ім'я файлу>_», яке зчитує команди з файлу, та «-I» (велика літера i), яке показує командний рядок halcmd після виконання команд:

Запуск збереженого файлу
halrun -I -f saved.hal

Зверніть увагу, що у файлі saved.hal немає команди "start". Потрібно виконати її ще раз (або відредагувати файл saved.hal, щоб додати її туди).

3.8. Вилучення HAL з пам’яті

Якщо відбувається неочікуване завершення сеансу HAL, можливо, доведеться вивантажити HAL, перш ніж зможе розпочатися інший сеанс. Для цього введіть таку команду у вікні терміналу.

Вилучення HAL
halrun -U

4. Приклад Stepgen

До цього моменту ми завантажили лише один компонент HAL. Але основна ідея HAL полягає в тому, щоб дозволити вам завантажувати та підключати низку простих компонентів для створення складної системи. У наступному прикладі буде використано два компоненти.

Перш ніж приступити до створення цього нового прикладу, ми хочемо почати з чистого аркуша. Якщо ви щойно завершили один із попередніх прикладів, нам потрібно видалити всі компоненти та перезавантажити бібліотеки RTAPI та HAL.

halcmd: exit

4.1. Встановлення компонентів

Тепер ми завантажимо компонент генератора імпульсів. Детальний опис цього компонента дивіться в розділі stepgen посібника Integrator Manual. У цьому прикладі ми будемо використовувати тип управління StepGen «velocity». Наразі ми можемо пропустити деталі і просто виконати наступні команди.

У цьому прикладі ми використовуватимемо тип керування velocity з компонента stepgen.

halrun
halcmd: loadrt stepgen step_type=0,0 ctrl_type=v,v
halcmd: loadrt siggen
halcmd: loadrt threads name1=fast period1=50000 name2=slow period2=1000000

The first command loads two step generators, both configured to generate stepping type 0. The second command loads our old friend siggen, and the third one creates two threads, a fast one with a period of 50 microseconds (µs) and a slow one with a period of 1 millisecond (ms).

Note
The fp1= parameter is deprecated and ignored. All threads now unconditionally support floating point.

Як і раніше, ми можемо використовувати halcmd show, щоб переглянути HAL. Цього разу у нас набагато більше виводів та параметрів, ніж раніше:

halcmd: show pin

Виводи компонентів:
Owner   Type  Dir         Value  Name
     4  float IN              1  siggen.0.amplitude
     4  bit   OUT         FALSE  siggen.0.clock
     4  float OUT             0  siggen.0.cosine
     4  float IN              1  siggen.0.frequency
     4  float IN              0  siggen.0.offset
     4  float OUT             0  siggen.0.sawtooth
     4  float OUT             0  siggen.0.sine
     4  float OUT             0  siggen.0.square
     4  float OUT             0  siggen.0.triangle
     3  s32   OUT             0  stepgen.0.counts
     3  bit   OUT         FALSE  stepgen.0.dir
     3  bit   IN          FALSE  stepgen.0.enable
     3  float OUT             0  stepgen.0.position-fb
     3  bit   OUT         FALSE  stepgen.0.step
     3  float IN              0  stepgen.0.velocity-cmd
     3  s32   OUT             0  stepgen.1.counts
     3  bit   OUT         FALSE  stepgen.1.dir
     3  bit   IN          FALSE  stepgen.1.enable
     3  float OUT             0  stepgen.1.position-fb
     3  bit   OUT         FALSE  stepgen.1.step
     3  float IN              0  stepgen.1.velocity-cmd

halcmd: show param

Параметри:
Owner   Type  Dir         Value  Name
     4  s32   RO              0  siggen.0.update.time
     4  s32   RW              0  siggen.0.update.tmax
     3  u32   RW     0x00000001  stepgen.0.dirhold
     3  u32   RW     0x00000001  stepgen.0.dirsetup
     3  float RO              0  stepgen.0.frequency
     3  float RW              0  stepgen.0.maxaccel
     3  float RW              0  stepgen.0.maxvel
     3  float RW              1  stepgen.0.position-scale
     3  s32   RO              0  stepgen.0.rawcounts
     3  u32   RW     0x00000001  stepgen.0.steplen
     3  u32   RW     0x00000001  stepgen.0.stepspace
     3  u32   RW     0x00000001  stepgen.1.dirhold
     3  u32   RW     0x00000001  stepgen.1.dirsetup
     3  float RO              0  stepgen.1.frequency
     3  float RW              0  stepgen.1.maxaccel
     3  float RW              0  stepgen.1.maxvel
     3  float RW              1  stepgen.1.position-scale
     3  s32   RO              0  stepgen.1.rawcounts
     3  u32   RW     0x00000001  stepgen.1.steplen
     3  u32   RW     0x00000001  stepgen.1.stepspace
     3  s32   RO              0  stepgen.capture-position.time
     3  s32   RW              0  stepgen.capture-position.tmax
     3  s32   RO              0  stepgen.make-pulses.time
     3  s32   RW              0  stepgen.make-pulses.tmax
     3  s32   RO              0  stepgen.update-freq.time
     3  s32   RW              0  stepgen.update-freq.tmax

4.2. З’єднання контактів із сигналами

У нас є двоступеневі генератори імпульсів і генератор сигналів. Тепер настав час створити кілька сигналів HAL для з’єднання двох компонентів. Ми будемо вважати, що двоступеневі генератори імпульсів керують осями X і Y машини. Ми хочемо переміщати стіл по колу. Для цього ми будемо надсилати косинусний сигнал на вісь X і синусний сигнал на вісь Y. Модуль siggen створює синус і косинус, але нам потрібні «проводи», щоб з’єднати модулі між собою. У HAL «проводи» називаються сигналами. Нам потрібно створити два таких сигнали. Ми можемо назвати їх як завгодно, для цього прикладу це будуть «X-vel» і «Y-vel». Сигнал «X-vel» призначений для передачі від косинусного виходу генератора сигналів до входу швидкості першого імпульсного генератора. Першим кроком є підключення сигналу до виходу генератора сигналів. Для підключення сигналу до виводу ми використовуємо команду net.

мережева команда
halcmd: net X-vel <= siggen.0.cosine

Щоб побачити ефект команди net, ми знову покажемо сигнали.

halcmd: show sig

Сигнали:
Type          Value  Name     (linked to)
float             0  X-vel <== siggen.0.cosine

Коли сигнал підключений до одного або декількох виводів, команда show відображає список виводів, що йдуть відразу за назвою сигналу. «Стрілка» показує напрямок потоку даних — в даному випадку дані надходять від виводу siggen.0.cosine до сигналу X-vel. Тепер підключимо X-vel до входу швидкості генератора імпульсів.

halcmd: net X-vel => stepgen.0.velocity-cmd

Ми також можемо підключити сигнал осі Y Y-vel. Він призначений для передачі від синусоїдального виходу генератора сигналів до входу другого генератора імпульсів кроку. Наступна команда виконує в одному рядку те, що дві команди net виконували для X-vel.

halcmd: net Y-vel siggen.0.sine => stepgen.1.velocity-cmd

Тепер давайте остаточно розглянемо сигнали та підключені до них контакти.

halcmd: show sig

Сигнали:
Type          Value  Name     (linked to)
float             0  X-vel <== siggen.0.cosine
                           ==> stepgen.0.velocity-cmd
float             0  Y-vel <== siggen.0.sine
                           ==> stepgen.1.velocity-cmd

Команда «show sig» чітко показує, як саме дані проходять через HAL. Наприклад, сигнал «X-vel» надходить з виводу siggen.0.cosine і переходить на вивод stepgen.0.velocity-cmd.

4.3. Налаштування виконання в реальному часі - потоки та функції

Якщо уявити собі дані, що протікають по «дротах», то зрозуміти, що таке контакти і сигнали, досить просто. Трохи складніше з потоками і функціями. Функції містять комп’ютерні інструкції, які фактично виконують завдання. Потоки — це метод, за допомогою якого ці інструкції виконуються, коли це необхідно. Спочатку давайте розглянемо функції, які нам доступні.

halcmd: show funct

Експортовані функції:
Owner   CodeAddr  Arg       FP   Users  Name
 00004  f9992000  fc731278  YES      0   siggen.0.update
 00003  f998b20f  fc7310b8  YES      0   stepgen.capture-position
 00003  f998b000  fc7310b8  NO       0   stepgen.make-pulses
 00003  f998b307  fc7310b8  YES      0   stepgen.update-freq

Як правило, вам доведеться звертатися до документації по кожному компоненту, щоб дізнатися, що роблять його функції. У даному випадку функція siggen.0.update використовується для оновлення вихідних даних генератора сигналів. Кожного разу, коли вона виконується, вона обчислює значення синусоїдальних, косинусоїдальних, трикутних і квадратних вихідних даних. Щоб отримати плавні сигнали, вона повинна працювати з певними інтервалами.

Інші три функції пов’язані з генераторами крокових імпульсів.

Перший, stepgen.capture_position, використовується для зворотного зв’язку щодо положення. Він фіксує значення внутрішнього лічильника, який підраховує імпульси кроку в міру їх генерації. Припускаючи, що кроки не пропускаються, цей лічильник вказує положення двигуна.

The main function for the step pulse generator is stepgen.make_pulses. Every time make_pulses runs it decides if it is time to take a step, and if so sets the outputs accordingly. For smooth step pulses, it should run as frequently as possible. Because it needs to run so fast, make_pulses is highly optimized and performs only a few calculations.

Остання функція, stepgen.update-freq, відповідає за масштабування та деякі інші обчислення, які потрібно виконувати лише тоді, коли змінюється команда частоти.

Для нашого прикладу це означає, що ми хочемо запустити siggen.0.update з помірною швидкістю, щоб обчислити значення синуса і косинуса. Відразу після запуску siggen.0.update ми хочемо запустити stepgen.update_freq, щоб завантажити нові значення в генератор імпульсів. Нарешті, нам потрібно запустити stepgen.make_pulses якомога швидше для отримання рівномірних імпульсів. Оскільки ми не використовуємо зворотний зв’язок по положенню, нам взагалі не потрібно запускати stepgen.capture_position.

Ми запускаємо функції, додаючи їх до потоків. Кожен потік виконується з певною швидкістю. Давайте подивимося, які потоки у нас є.

halcmd: show thread

Realtime Threads:
     Period  FP     Name               (     Time, Max-Time )
     996980  YES                  slow (        0,        0 )
      49849  YES                  fast (        0,        0 )

The two threads were created when we loaded threads. The first one, slow, runs every millisecond. We will use it for siggen.0.update and stepgen.update_freq. The second thread is fast, which runs every 50 microseconds (µs). We will use it for stepgen.make_pulses. To connect the functions to the proper thread, we use the addf command. We specify the function first, followed by the thread.

halcmd: addf siggen.0.update slow
halcmd: addf stepgen.update-freq slow
halcmd: addf stepgen.make-pulses fast

Після того, як ми надамо ці команди, ми можемо знову виконати команду show thread, щоб побачити, що сталося.

halcmd: show thread

Теми в реальному часі:
     Period  FP     Name               (     Time, Max-Time )
     996980  YES                  slow (        0,        0 )
                  1 siggen.0.update
                  2 stepgen.update-freq
      49849  NO                   fast (        0,        0 )
                  1 stepgen.make-pulses

Тепер за кожним потоком йдуть імена функцій у порядку, в якому ці функції будуть виконуватися.

4.4. Налаштування параметрів

Ми майже готові запустити нашу систему HAL. Однак нам ще потрібно налаштувати кілька параметрів. За замовчуванням компонент siggen генерує сигнали, які коливаються від +1 до -1. Для нашого прикладу це підходить, ми хочемо, щоб швидкість столу змінювалася від +1 до -1 дюйма в секунду. Однак масштабування генератора імпульсів кроку не зовсім правильне. За замовчуванням він генерує вихідну частоту 1 крок на секунду при вхідному сигналі 1,0. Малоймовірно, що один крок на секунду дасть нам один дюйм на секунду руху столу. Припустимо, що ми маємо гвинт з 5 обертами на дюйм, підключений до крокового двигуна з 200 кроками на оберт і 10-кратним мікрокрокуванням. Отже, для одного оберту гвинта потрібно 2000 кроків, а для переміщення на один дюйм — 5 обертів. Це означає, що загальне масштабування становить 10000 кроків на дюйм. Нам потрібно помножити швидкість, що вводиться в генератор імпульсів кроку, на 10000, щоб отримати правильний результат. Саме для цього і призначений параметр stepgen.n.velocity-scale. У цьому випадку осі X і Y мають однакове масштабування, тому ми встановлюємо параметри масштабування для обох на 10000.

halcmd: setp stepgen.0.position-scale 10000
halcmd: setp stepgen.1.position-scale 10000
halcmd: setp stepgen.0.enable 1
halcmd: setp stepgen.1.enable 1

Це масштабування швидкості означає, що коли контакт stepgen.0.velocity-cmd дорівнює 1,0, генератор імпульсів буде генерувати 10000 імпульсів на секунду (10 кГц). З описаними вище двигуном і ходовим гвинтом це призведе до руху осі зі швидкістю рівно 1,0 дюйма на секунду. Це ілюструє ключову концепцію HAL — такі речі, як масштабування, виконуються на найнижчому можливому рівні, в даному випадку в генераторі імпульсів кроку. Внутрішній сигнал X-vel — це швидкість столу в дюймах на секунду, а інші компоненти, такі як siggen, взагалі не знають (і не дбають) про масштабування. Якщо ми змінимо ходовий гвинт або двигун, ми змінимо тільки параметр масштабування генератора імпульсів кроку.

4.5. Запустіть це!

Тепер у нас все налаштовано, і ми готові до запуску. Як і в першому прикладі, ми використовуємо команду start.

halcmd: start

Хоча зовні нічого не відбувається, всередині комп’ютера генератор імпульсів видає імпульси, що змінюються від 10 кГц вперед до 10 кГц назад і назад кожну секунду. Пізніше в цьому підручнику ми побачимо, як вивести ці внутрішні сигнали для запуску двигунів у реальному світі, але спочатку ми хочемо подивитися на них і побачити, що відбувається.

5. Півметра

Ви можете створювати дуже складні системи HAL, навіть не використовуючи графічний інтерфейс. Однак є щось приємне в тому, щоб бачити результат своєї роботи. Першим і найпростішим інструментом GUI для HAL є halmeter. Це дуже проста програма, яка є еквівалентом HAL зручного мультиметра (або аналогового вимірювача для старої гвардії).

Це дозволяє спостерігати за контактами, сигналами або параметрами, відображаючи поточне значення цих сутностей. Це дуже простий у використанні додаток для графічних середовищ. У консольному типі:

halmeter

З’являться два вікна. Вікно вибору є найбільшим і містить три вкладки:

  • В одному перераховані всі виводи, що наразі визначені в HAL,

  • один перераховує всі сигнали,

  • в одному перераховані всі параметри.

Клацніть на вкладку, а потім на один з елементів, щоб вибрати його. У невеликому вікні буде показано назву та значення вибраного елемента. Відображення оновлюється приблизно 10 разів на секунду. Щоб звільнити місце на екрані, вікно вибору можна закрити за допомогою кнопки Закрити. У невеликому вікні, прихованому під вікном вибору під час запуску програми, кнопка Вибрати знову відкриває вікно вибору, а кнопка Вийти зупиняє програму та закриває обидва вікна.

Можна запустити кілька halmeter одночасно, що дозволяє візуалізувати кілька елементів одночасно. Щоб відкрити halmeter і звільнити консоль, запустивши його у фоновому режимі, виконайте наступну команду:

halmeter &

Можна запустити halmeter і змусити його відразу відобразити елемент. Для цього додайте аргументи pin|sig|par[am] name у командному рядку. Він відобразить сигнал, контакт або параметр name відразу після запуску. Якщо вказаний елемент не існує, він запуститься у звичайному режимі.

Нарешті, якщо елемент призначений для відображення, можна додати -s перед pin|sig|param, щоб halmeter використовував ще менше вікно. Назва елемента буде відображатися в рядку заголовка, а не під значенням, і кнопка не буде відображатися. Це корисно для відображення великої кількості halmeterів на невеликому просторі.

Ми знову використаємо компонент siggen, щоб перевірити halmeter. Якщо ви щойно завершили попередній приклад, то ви можете завантажити siggen, використовуючи збережений файл. Якщо ні, ми можемо завантажити його так само, як ми робили раніше:

halrun
halcmd: loadrt siggen
halcmd: loadrt threads name1=test-thread period1=1000000
halcmd: addf siggen.0.update test-thread
halcmd: start
halcmd: setp siggen.0.amplitude 5

На цьому етапі компонент siggen завантажено та працює. Час запустити halmeter.

Початковий півметра
halcmd: loadusr halmeter

Перше вікно, яке ви побачите, це вікно «Вибір елемента для дослідження».

Вікно вибору Halmeter
Figure 1. Вікно вибору Halmeter

Це діалогове вікно має три вкладки. Перша вкладка відображає всі контакти HAL в системі. Друга вкладка відображає всі сигнали, а третя — всі параметри. Спочатку ми хочемо розглянути контакт siggen.0.cosine, тому клацніть на ньому, а потім натисніть кнопку «Закрити». Діалогове вікно вибору зонда закриється, а вимірювач буде виглядати приблизно так, як показано на малюнку нижче.

Півметрове вікно
Figure 2. Півметрове вікно

Щоб змінити відображення на лічильнику, натисніть кнопку «Вибрати», яка поверне вікно «Вибір елемента для вимірювання».

Ви повинні побачити зміну значення, коли siggen генерує свою косинусоподібну хвилю. Halmeter оновлює свій дисплей приблизно 5 разів на секунду.

Щоб вимкнути Halmeter, просто натисніть кнопку виходу.

Якщо ви хочете переглянути більше ніж один контакт, сигнал або параметр одночасно, ви можете просто запустити більше халметрів. Вікно халметра було навмисно зроблено дуже маленьким, щоб ви могли мати багато з них на екрані одночасно.

6. Галшоу

Скрипт halshow може допомогти вам зорієнтуватися в запущеному HAL. Він відображає вибрані значення HAL та постійно їх оновлює.

Це дуже спеціалізована система, яка повинна підключатися до працюючого HAL. Вона не може працювати автономно, оскільки покладається на здатність HAL «інтроспектувати» і повідомляти про себе через бібліотеку інтерфейсу halcmd. Коли конфігурація LinuxCNC змінюється, вивід halshow також буде іншим.

Як ми скоро побачимо, ця здатність HAL до самодокументування є одним із ключових моментів у створенні ефективної системи CNC.

6.1. Початок гри в Халшоу

Халшоу доступний

  • у меню AXIS у розділі Machine/Show HAL Configuration,

  • у меню TkLinuxCNC у розділі Скрипти/Показати HAL,

  • у GMOCCAPY на сторінці налаштувань.

halshow також можна запустити з командного рядка терміналу та вказати формати для цілочисельних та чисельних елементів з плаваючою комою (виводи або сигнали) та визначити збережений файл списку спостереження для використання:

$ halshow --help
Використання:
  halshow [Options] [watchfile]
  Опції:
           --help    (this help)
           --fformat format_string_for_float
           --iformat format_string_for_int
           --noprefs don't use preference file to save settings

Нотатки:
       Створіть файл спостереження в halshow за допомогою: «Файл/Зберегти список спостереження».
       Для автономного використання LinuxCNC має бути запущений.

Приклад обмеження кількості десяткових ком для чисел з плаваючою комою та використання файлу з назвою my.halshow у поточному каталозі:

$ halshow  --fformat "%.5f" ./my.halshow

Для отримання додаткової інформації щодо формату, будь ласка, зверніться до https://www.tcl.tk/man/tcl/TclCmd/format.html [сторінка довідки щодо формату Tcl].

Макет Халшоу
Figure 3. Макет Халшоу

Ліворуч від його дисплея, як показано на рисунку вище, розташоване деревоподібне подання, що нагадує те, що ви могли бачити у файлових браузерах. Праворуч знаходиться блокнот із вкладками для показу, перегляду та налаштувань.

6.2. Площа дерева HAL

Дерево фільтрів

За замовчуванням цей запис фільтрує дерево за назвами контактів або вузлами дерева за допомогою регулярного виразу. Наприклад, введення "lim-sw" відфільтрує дерево за таким параметром:

Дерево фільтрації для імен пінів з підрядком "lim-sw".
joint.0.neg-lim-sw-in
joint.0.pos-lim-sw-in
joint.1.neg-lim-sw-in
joint.1.pos-lim-sw-in
joint.2.neg-lim-sw-in
joint.3.pos-lim-sw-in

Якщо ви хочете відобразити всі елементи, пов’язані з joint.0, вам потрібно натиснути на піктограму налаштувань і вибрати «Повний шлях». Зверніть увагу на те, щоб уникнути спеціальних символів регулярного виразу, тому вам потрібно ввести «joint\.1\.», щоб явно вказати крапку і не знайти також joint 10.

Дерево

Дерево показує всі основні частини HAL. Перед кожною з них розташований невеликий знак плюс (+) або мінус (-) у прямокутнику, щоб розгорнути або згорнути відповідну частину дерева.

Ви також можете розгорнути або згорнути деревоподібне відображення за допомогою меню «Вигляд дерева» у верхньому лівому краю екрана.

У розділі «Дерево перегляду» ви знайдете: «Розгорнути все», «Згорнути все»; «Розгорнути шпильки», «Розгорнути параметри», «Розгорнути сигнали»; та «Перезавантажити дерево перегляду». «Перезавантажити дерево перегляду» корисно, коли під час виконання завантажуються нові компоненти, які потрібно відобразити.

6.3. Виставкова зона HAL

Halshow: Показати вкладку
Figure 4. Halshow: Показати вкладку

Натиснувши на ім’я вузла, наприклад «Компоненти» в дереві, ви побачите (на вкладці «Показати») всю інформацію, яку HAL має про вміст цього вузла. На малюнку Halshow Show Tab показано список, який ви побачите, натиснувши на ім’я «Компоненти». Інформація відображається точно так само, як у традиційних текстових інструментах аналізу HAL. Перевага тут полягає в тому, що ми маємо доступ за допомогою клацання мишею, який може бути настільки широким або вузьким, наскільки вам потрібно.

Якщо ми уважніше придивимося до дерева, то побачимо, що шість основних частин HAL можна розгорнути щонайменше на один рівень. У міру розгортання цих рівнів ви можете отримати більш конкретну відповідь, якщо клацнути на крайньому правому вузлі дерева. Ви побачите, що деякі контакти та параметри HAL показують більше ніж одну відповідь. Це пов’язано з особливостями пошукових процедур у самій програмі halcmd. Якщо ви шукаєте один контакт, ви можете отримати два, як показано нижче:

Виводи компонентів:
Owner  Type  Dir  Value  Name
06     bit    -W   TRUE  parport.0.pin-10-in
06     bit    -W  FALSE  parport.0.pin-10-in-not

Назва другого піна містить повну назву першого.

Нове у версії 2.9

Виділений текст у вкладці «Показати» можна скопіювати, клацнувши правою кнопкою миші або натиснувши CTRL-C.
В області «Показати» можна додати шпильки з виділеного тексту за допомогою контекстного меню. Усі дійсні шпильки, що містяться у виділенні, додаються до вкладки «Спостерігати».

6.4. Область вкладок годинника

При натисканні на вкладку «Спостереження» з’являється порожнє полотно. Ви можете додавати сигнали та контакти на це полотно і спостерігати за їхніми значеннями. Ви можете додавати сигнали або контакти, коли вкладка «Спостереження» відображається, натиснувши на її назву в дереві.

Нове у версії 2.9

Ви також можете додати всі піделементи цього вузла, вибравши їх у контекстному меню (див. малюнок Halshow Watch Tab).

На наступному малюнку показано це полотно з кількома шпильками.

Вкладка годинника Halshow
Figure 5. Вкладка: годинника Halshow

Watch відображає значення бітового типу (бінарні) за допомогою кольорових кіл, що представляють світлодіоди. Вони відображаються темно-червоним кольором, коли бітовий сигнал або контакт є хибним, і світло-жовтим кольором, коли цей сигнал є істинним. Якщо ви виберете контакт або сигнал, який не є сигналом бітового типу (бінарним), watch відобразить його як числове значення. Контакти відображаються чорним кольором, сигнали — синім, а параметри — коричневим.

Watch дозволить вам швидко протестувати перемикачі або побачити ефект змін, які ви вносите в LinuxCNC під час використання графічного інтерфейсу. Частота оновлення Watch є дещо повільною для перегляду імпульсів крокового двигуна, але ви можете використовувати її для цього, якщо рухаєте вісь дуже повільно або з дуже невеликими кроками відстані.

Нове у версії 2.9

Контакти та сигнали, які можна записувати, мають кнопки для маніпулювання з правого боку. Контакти, які пов’язані з сигналом, мають вимкнені кнопки. Щоб встановити ці значення, відповідний контакт потрібно від’єднати від сигналу. Це можна зробити, клацнувши правою кнопкою миші на назві сигналу та вибравши «Від’єднати контакт», див. Контекстне меню Watch Tach.

Список спостереження буде збережено автоматично після виходу. Якщо ви не хочете, щоб Halshow зберігав ваш список спостереження, цю функцію можна вимкнути в Налаштування.

Контекстне меню

Нове у версії 2.9

Контекстне меню дозволяє додатково:

  • Скопіюйте назву PIN-коду в буфер обміну

  • Встановити значення

  • Від’єднати пін (якщо він пов’язаний із сигналом)

  • Показувати шпильку в дереві (підсвічує шпильку, не прокручує до потрібної позиції)

  • Вилучити позначку зі списку

Halshow: Контекстне меню вкладки «Перегляд»
Figure 6. Halshow: Контекстне меню вкладки «Перегляд»

6.5. Введення команди

У нижній частині знаходиться поле введення для тестування команд HAL. Команди, які ви вводите тут, та їхній вплив на працюючий HAL не зберігаються. Вони залишатимуться активними, доки працює LinuxCNC, але зникнуть, щойно LinuxCNC буде вимкнено.

Нове у версії 2.9

Запис команди має історію, подібну до історії BASH (протягом сеансу), тому ви можете відновити вставлені команди за допомогою клавіші зі стрілкою вгору.

Поле введення з назвою «Команда HAL:» прийматиме будь-які команди, перелічені для halcmd. До них належать:

  • loadrt, unloadrt (завантаження/вивантаження модуля реального часу)

  • loadusr, unloadusr (завантаження/вивантаження компонента, що не працює в реальному часі)

  • addf, delf (додавання/видалення функції до/з потоку реального часу)

  • net (створити зв’язок між двома або більше елементами)

  • setp (встановити параметр (або pin) у значення)

Цей невеликий редактор вводитиме команду щоразу, коли ви натискатимете клавішу enter або кнопку виконання. Якщо ці команди сформовані неправильно, halcmd відображатиме повідомлення про помилку. Якщо ви не впевнені, як правильно налаштувати команду, вам потрібно буде ще раз прочитати документацію про halcmd та конкретні модулі, з якими ви працюєте.

6.6. Налаштування

Нове у версії 2.9

Геометрія вікна та налаштування зберігаються у файлі в каталозі конфігурації при виході. Якщо цей шлях не може бути визначений, вони зберігаються в домашньому каталозі. Шлях буде відображатися на сторінці налаштувань. Ви можете пропустити використання файлу налаштувань, викликавши halshow з аргументом командного рядка --no-prefs.
Подальші налаштування повинні бути зрозумілими без додаткових пояснень.

Налаштування Галшоу
Figure 7. Налаштування Галшоу

6.7. Приклад/Посібник

Давайте використаємо цей редактор, щоб додати диференційний модуль до HAL і підключити його до положення осі, щоб ми могли бачити швидкість зміни положення, тобто прискорення. Спочатку нам потрібно завантажити компонент HAL під назвою ddt, додати його до серво-потоку, а потім підключити до контакту положення шарніра. Після цього ми зможемо знайти вихід диференціатора в halscope. Тож давайте почнемо.

loadrt ddt

Тепер подивіться на вузол components, і ви десь там маєте побачити ddt.

Завантажені компоненти HAL:
ID Type        Name
10 User halcmd29800
09 User halcmd29374
08   RT         ddt
06   RT hal_parport
05   RT    scope_rt
04   RT     stepgen
03   RT      motmod
02 User   iocontrol

Звісно ж, ось він. Зверніть увагу, що його ідентифікатор — 08. Далі нам потрібно з’ясувати, які функції він пропонує, тому ми розглянемо функції:

Експортовані функції:
Owner  CodeAddr      Arg  FP Users Name
  08   E0B97630 E0DC7674 YES     0 ddt.0
  03   E0DEF83C 00000000 YES     1 motion-command-handler
  03   E0DF0BF3 00000000 YES     1 motion-controller
  06   E0B541FE E0DC75B8  NO     1 parport.0.read
  06   E0B54270 E0DC75B8  NO     1 parport.0.write
  06   E0B54309 E0DC75B8  NO     0 parport.read-all
  06   E0B5433A E0DC75B8  NO     0 parport.write-all
  05   E0AD712D 00000000  NO     0 scope.sample
  04   E0B618C1 E0DC7448 YES     1 stepgen.capture-position
  04   E0B612F5 E0DC7448  NO     1 stepgen.make-pulses
  04   E0B614AD E0DC7448 YES     1 stepgen.update-freq

Тут ми шукаємо власника № 08 і бачимо функцію з назвою ddt.0. Ми повинні мати можливість додати ddt.0 до серво-потоку, і вона буде виконувати свої обчислення кожного разу, коли серво-потік оновлюється. Ще раз переглядаємо команду addf і бачимо, що вона використовує три аргументи, як показано нижче:

addf <functname> <threadname> [<position>]

Ми вже знаємо functname=ddt.0, тому давайте визначимо ім’я потоку, розгорнувши вузол потоку в дереві. Тут ми бачимо два потоки: servo-thread і base-thread. Позиція ddt.0 у потоці не є критичною. Тому ми додаємо функцію ddt.0 до servo-thread:

addf ddt.0 servo-thread

Це лише для перегляду, тому ми залишаємо позицію порожньою та отримуємо останню позицію в потоці. На наступному рисунку показано стан halshow після виконання цієї команди.

Команда Addf
Figure 8. Команда Addf

Далі нам потрібно підключити ddt до чогось. Але як нам дізнатися, які піни доступні? Відповідь полягає в тому, щоб подивитися в розділі «піни». Там ми знаходимо ddt і бачимо це:

Виводи компонентів:
Owner Type  Dir Value       Name
08    float R-  0.00000e+00 ddt.0.in
08    float -W  0.00000e+00 ddt.0.out

Це виглядає досить легко зрозуміти, але який сигнал або контакт ми хочемо до нього підключити? Це може бути контакт осі, контакт ступінчастого генератора або сигнал. Ми бачимо це, коли дивимося на joint.0:

Виводи компонентів:
Owner Type  Dir Value       Name
03    float -W  0.00000e+00 joint.0.motor-pos-cmd ==> Xpos-cmd

Отже, схоже, що Xpos-cmd має бути гарним сигналом для використання. Повертаємося до редактора, де вводимо таку команду:

linksp Xpos-cmd ddt.0.in

Тепер, якщо ми подивимося на сигнал Xpos-cmd, використовуючи вузол дерева, ми побачимо, що ми зробили:

Сигнали:
Тип Значення Назва
float 0.00000e+00 Xpos-cmd
<== joint.0.motor-pos-cmd
==> ddt.0.in
==> stepgen.0.position-cmd

Ми бачимо, що цей сигнал надходить від joint.o.motor-pos-cmd і надходить як до ddt.0.in, так і до stepgen.0.position-cmd. Підключивши наш блок до сигналу, ми уникнули будь-яких ускладнень із нормальним потоком цієї команди руху.

Область HAL Show Area використовує halcmd для виявлення того, що відбувається в працюючому HAL. Вона надає повну інформацію про те, що було виявлено. Вона також оновлюється, коли ви видаєте команди з невеликої панелі редактора для модифікації цього HAL. Іноді вам може знадобитися відображення іншого набору елементів без усієї інформації, доступної в цій області. Саме в цьому випадку корисною є область HAL Watch Area.