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

Компонент siggen експортував одну функцію. Він вимагає плаваючої точки. Наразі він не пов’язаний з жодним потоком, тому users дорівнює нулю. Примітка: [Поля CodeAddr та Arg використовувалися під час розробки і, ймовірно, мають зникнути.].

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 )

Так, вийшло. Період не дорівнює точно 1000000 нс через обмеження апаратного забезпечення, але ми маємо потік, який працює з приблизно правильною швидкістю і може обробляти функції з плаваючою комою. Наступним кроком є підключення функції до потоку:

Додати функцію
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. Півметра

Ви можете створювати дуже складні системи 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, просто натисніть кнопку виходу.

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

5. Приклад Stepgen

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

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

halcmd: exit

5.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 fp1=0 period1=50000 name2=slow period2=1000000

Перша команда завантажує два генератори кроків, обидва налаштовані на генерацію кроків типу 0. Друга команда завантажує нашого старого знайомого siggen, а третя створює два потоки: швидкий з періодом 50 мікросекунд (мкс) і повільний з періодом 1 мілісекунди (мс). Швидкий потік не підтримує функції з плаваючою комою.

Як і раніше, ми можемо використовувати 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

5.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.

5.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, використовується для зворотного зв’язку щодо положення. Він фіксує значення внутрішнього лічильника, який підраховує імпульси кроку в міру їх генерації. Припускаючи, що кроки не пропускаються, цей лічильник вказує положення двигуна.

Основною функцією генератора імпульсів кроку є stepgen.make_pulses. Кожного разу, коли запускається «make_pulses», вона вирішує, чи настав час зробити крок, і якщо так, то відповідно встановлює виходи. Для плавних імпульсів кроку вона повинна працювати якомога частіше. Оскільки вона повинна працювати дуже швидко, «make_pulses» є високо оптимізованою і виконує лише кілька обчислень. На відміну від інших, він не потребує математичних операцій з плаваючою комою.

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

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

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

halcmd: show thread

Теми в реальному часі:
     Period  FP     Name               (     Time, Max-Time )
     996980  YES                  slow (        0,        0 )
      49849  NO                   fast (        0,        0 )

Два потоки були створені під час завантаження threads. Перший, «slow», працює кожну мілісекунду і здатний виконувати функції з плаваючою комою. Ми будемо використовувати його для siggen.0.update і stepgen.update_freq. Другий потік — «fast», який працює кожні 50 мікросекунд (µs) і не підтримує плаваючу кому. Ми будемо використовувати його для stepgen.make_pulses. Щоб підключити функції до відповідного потоку, ми використовуємо команду addf. Спочатку ми вказуємо функцію, а потім потік.

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

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

5.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, взагалі не знають (і не дбають) про масштабування. Якщо ми змінимо ходовий гвинт або двигун, ми змінимо тільки параметр масштабування генератора імпульсів кроку.

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

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

halcmd: start

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

6. Галскоп

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

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

Якщо LinuxCNC запущено в терміналі, ви можете запустити halscope за допомогою наступної команди.

Запуск Halscope
halcmd loadusr halscope

Якщо LinuxCNC не працює або файл autosave.halscope не відповідає контактам, доступним у поточній версії LinuxCNC, відкриється вікно графічного інтерфейсу, а відразу після цього з’явиться діалогове вікно «Функція реального часу не пов’язана», яке виглядає так, як показано на малюнку нижче. Щоб змінити частоту дискретизації, клацніть лівою кнопкою миші на полі «Зразки».

Діалогове вікно не пов'язане з функцією реального часу
Figure 3. Діалогове вікно не пов’язане з функцією реального часу

У цьому діалоговому вікні ви можете встановити частоту дискретизації для осцилографа. Наразі ми хочемо дискретизувати один раз на мілісекунду, тому натисніть на нитку 1,00 мс «slow» і залиште множник на рівні 1. Ми також залишимо довжину запису на рівні 4000 дискретизацій, щоб ми могли використовувати до чотирьох каналів одночасно. Коли ви виберете рядок і натиснете «OK», діалогове вікно зникне, а вікно осцилографа буде виглядати приблизно так, як на малюнку нижче.

Початкове вікно області застосування
Figure 4. Початкове вікно області застосування

6.1. Підключення зондів осцилографа

На цьому етапі Halscope готовий до використання. Ми вже вибрали частоту дискретизації та довжину запису, тому наступним кроком є визначення того, що саме потрібно спостерігати. Це еквівалентно підключенню «віртуальних зондів осцилографа» до HAL. Halscope має 16 каналів, але кількість каналів, які можна використовувати одночасно, залежить від довжини запису — більше каналів означає коротші записи, оскільки обсяг пам’яті, доступний для запису, фіксований і становить приблизно 16 000 зразків.

Кнопки каналів розташовані внизу екрана halscope. Натисніть кнопку «1», і ви побачите діалогове вікно «Вибір джерела каналу», як показано на малюнку нижче. Це діалогове вікно дуже схоже на те, що використовується в Halmeter. Ми хочемо переглянути сигнали, які ми визначили раніше, тому натискаємо вкладку «Сигнали», і діалогове вікно відображає всі сигнали в HAL (у цьому прикладі їх тільки два).

Виберіть джерело каналу
Figure 5. Виберіть джерело каналу

Щоб вибрати сигнал, просто клацніть на ньому. У цьому випадку ми хочемо, щоб канал 1 відображав сигнал «X-vel». Клацніть на вкладці «Сигнали», потім натисніть «X-vel», діалогове вікно закриється, і канал тепер вибрано.

Виберіть сигнал
Figure 6. Виберіть сигнал

Натискається кнопка каналу 1, і під рядом кнопок з’являються номер каналу 1 та назва «X-vel». Цей дисплей завжди показує вибраний канал — на екрані може бути багато каналів, але вибраний канал виділяється, і різні елементи керування, такі як вертикальне положення та масштаб, завжди працюють саме для вибраного каналу.

Галскоп
Figure 7. Галскоп

Щоб додати сигнал до каналу 2, натисніть кнопку «2». Коли з’явиться діалогове вікно, натисніть вкладку «Сигнали», а потім натисніть «Y-vel». Ми також хочемо подивитися на вихідні сигнали прямокутної та трикутної форми. До цих контактів не підключено жодних сигналів, тому ми використовуємо вкладку «Контакти». Для каналу 3 виберіть «siggen.0.triangle», а для каналу 4 — «siggen.0.square».

6.2. Захоплення наших перших хвильових форм

Тепер, коли ми підключили кілька датчиків до HAL, настав час записати деякі хвильові форми. Щоб запустити осцилограф, натисніть кнопку «Normal» у розділі «Run Mode» екрана (у правому верхньому куті). Оскільки ми маємо довжину запису 4000 зразків і отримуємо 1000 зразків на секунду, halscope знадобиться приблизно 2 секунди, щоб заповнити половину свого буфера. Протягом цього часу індикатор прогресу над головним екраном показуватиме заповнення буфера. Коли буфер заповниться наполовину, осцилограф чекатиме на тригер. Оскільки ми ще не налаштували тригер, він чекатиме вічно. Щоб запустити його вручну, натисніть кнопку «Force» у розділі «Trigger» у верхньому правому куті. Ви побачите, як заповнюється решта буфера, а потім на екрані з’являться записані хвильові форми. Результат буде схожий на зображення на малюнку нижче.

Захоплені форми хвиль
Figure 8. Захоплені форми хвиль

Поле «Вибраний канал» внизу показує, що фіолетовий трек є вибраним на даний момент, канал 4, який відображає значення виводу siggen.0.square. Спробуйте натиснути кнопки каналів від 1 до 3, щоб виділити інші три треки.

6.3. Вертикальні коригування

Сліди досить важко розрізнити, оскільки всі чотири знаходяться один над одним. Щоб виправити це, ми використовуємо елементи керування «Vertical» (Вертикальний) у вікні праворуч екрана. Ці елементи керування діють на поточний вибраний канал. Під час регулювання підсилення зверніть увагу, що воно охоплює великий діапазон — на відміну від реального осцилографа, цей може відображати сигнали від дуже малих (піко-одиниць) до дуже великих (тера-одиниць). Елемент керування положенням переміщує відображуваний слід вгору і вниз тільки по висоті екрана. Для більших регулювань слід використовувати кнопку зміщення.

Вертикальне регулювання
Figure 9. Вертикальне регулювання

Велика кнопка «Вибраний канал» внизу вказує, що канал 1 є вибраним каналом і відповідає сигналу «X-vel». Спробуйте натиснути на інші канали, щоб відобразити їхні криві та мати можливість переміщати їх за допомогою курсору «Pos».

6.4. Запуск

Використання кнопки «Force» є досить незадовільним способом запуску осцилографа. Щоб налаштувати справжній запуск, натисніть кнопку «Source» внизу праворуч. З’явиться діалогове вікно «Trigger Source», яке є просто списком усіх датчиків, що наразі підключені. Виберіть датчик, який буде використовуватися для запуску, натиснувши на нього. У цьому прикладі ми будемо використовувати канал 3, трикутну хвилю, як показано на наступному малюнку.

Діалогове вікно джерела тригера
Figure 10. Діалогове вікно джерела тригера

Після встановлення джерела тригера ви можете налаштувати рівень тригера та його положення за допомогою повзунків у полі «Тригер» праворуч. Рівень можна налаштувати від верхньої до нижньої частини екрана, він відображається під повзунками. Положення — це місце розташування точки тригера в загальному записі. Коли повзунок знаходиться внизу, точка тригера знаходиться в кінці запису, і halscope відображає те, що відбувалося до точки тригера. Коли повзунок знаходиться вгорі, точка тригера знаходиться на початку запису, відображаючи те, що відбулося після його спрацьовування. Точка тригера відображається у вигляді вертикальної лінії у вікні прогресу над екраном. Полярність тригера можна змінити, натиснувши кнопку трохи нижче індикатора рівня тригера. Тоді вона стане descendant. Зверніть увагу, що зміна положення тригера зупиняє осцилограф після налаштування положення. Ви можете перезапустити осцилограф, натиснувши кнопку Normal у групі Run mode.

Тепер, коли ми налаштували вертикальні елементи керування та спусковий механізм, дисплей прицілу виглядає приблизно так, як показано на наступному малюнку.

Форми хвиль із запуском
Figure 11. Форми хвиль із запуском

6.5. Горизонтальні коригування

Щоб детально розглянути частину хвильової форми, можна скористатися повзунком масштабування у верхній частині екрана, щоб розширити хвильові форми по горизонталі, а також повзунком положення, щоб визначити, яка частина збільшеної хвильової форми буде видима. Однак іноді простого розширення хвильових форм недостатньо, і потрібно збільшити частоту дискретизації. Наприклад, ми хотіли б розглянути фактичні імпульси, що генеруються в нашому прикладі. Оскільки імпульси можуть мати тривалість лише 50 мкс, дискретизація з частотою 1 кГц є недостатньо швидкою. Щоб змінити частоту дискретизації, натисніть кнопку, яка відображає кількість зразків і частоту дискретизації, щоб відкрити діалогове вікно «Вибір частоти дискретизації». У цьому прикладі ми натиснемо на рядок 50 мкс, «швидкий», що дає нам частоту дискретизації приблизно 20 кГц. Тепер замість відображення даних за приблизно 4 секунди, один запис становить 4000 зразків при 20 кГц, або приблизно 0,20 секунди.

Діалогове вікно частоти дискретизації
Figure 12. Діалогове вікно частоти дискретизації

6.6. Більше каналів

Тепер давайте розглянемо імпульси кроку. Halscope має 16 каналів, але в цьому прикладі ми використовуємо тільки 4 одночасно. Перш ніж вибрати інші канали, нам потрібно вимкнути декілька. Натискання на кнопку вибраного каналу (чорна рамка) вимкне канал. Тому натисніть на кнопку каналу 2, а потім натисніть на цю кнопку ще раз, і канал вимкнеться. Потім двічі натисніть на канал 3 і зробіть те саме для каналу 4. Незважаючи на те, що канали вимкнені, вони все одно пам’ятають, до чого вони підключені, і насправді ми продовжимо використовувати канал 3 як джерело тригера. Щоб додати нові канали, виберіть канал 5 і виберіть контакт stepgen.0.dir, потім канал 6 і виберіть stepgen.0.step. Потім натисніть режим роботи «Normal», щоб запустити осцилограф, і налаштуйте горизонтальне масштабування на 5 мс на поділку. Ви повинні побачити, як імпульси кроку сповільнюються, коли команда швидкості (канал 1) наближається до нуля, потім контакт напрямку змінює стан і імпульси кроку знову прискорюються. Можливо, ви захочете збільшити коефіцієнт підсилення на каналі 1 до приблизно 20 мілі на поділку, щоб краще бачити зміну команди швидкості. Результат повинен виглядати як на наступному малюнку.

Крокові імпульси
Figure 13. Крокові імпульси

6.7. Більше зразків

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

halcmd loadusr halscope 80000

Якщо компонент «scope_rt» ще не завантажено, halscope завантажить його і запросить загалом 80000 зразків, так що при вибірці 4 каналів одночасно буде 20000 зразків на канал. (Якщо «scope_rt» вже завантажено, числовий аргумент для halscope не матиме впливу).