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:
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 в пам’ять. Просто виконайте наступну команду з терміналу:
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/halcmdhalcmd: 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:
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 має пам’ять слона і збереже цю конфігурацію, поки ми її не вимкнемо. Але що буде наступного разу? Ми не хочемо вручну вводити купу команд щоразу, коли хочемо використовувати систему.
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». Щоб зберегти ці команди для подальшого використання, ми просто перенаправимо вихідні дані у файл:
halcmdhalcmd: save all saved.hal
3.6. Вихід з Халруна
Коли ви закінчите сеанс HAL, введіть exit у командному рядку "halcmd:". Це поверне вас до системного командного рядка і закриє сеанс 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, перш ніж зможе розпочатися інший сеанс. Для цього введіть таку команду у вікні терміналу.
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
Перше вікно, яке ви побачите, це вікно «Вибір елемента для дослідження».
Це діалогове вікно має три вкладки. Перша вкладка відображає всі контакти HAL в системі. Друга вкладка відображає всі сигнали, а третя — всі параметри. Спочатку ми хочемо розглянути контакт siggen.0.cosine, тому клацніть на ньому, а потім натисніть кнопку «Закрити». Діалогове вікно вибору зонда закриється, а вимірювач буде виглядати приблизно так, як показано на малюнку нижче.
Щоб змінити відображення на лічильнику, натисніть кнопку «Вибрати», яка поверне вікно «Вибір елемента для вимірювання».
Ви повинні побачити зміну значення, коли 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].
Ліворуч від його дисплея, як показано на рисунку вище, розташоване деревоподібне подання, що нагадує те, що ви могли бачити у файлових браузерах. Праворуч знаходиться блокнот із вкладками для показу, перегляду та налаштувань.
6.2. Площа дерева HAL
За замовчуванням цей запис фільтрує дерево за назвами контактів або вузлами дерева за допомогою регулярного виразу. Наприклад, введення "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
Натиснувши на ім’я вузла, наприклад «Компоненти» в дереві, ви побачите (на вкладці «Показати») всю інформацію, яку 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
Назва другого піна містить повну назву першого.
6.4. Область вкладок годинника
При натисканні на вкладку «Спостереження» з’являється порожнє полотно. Ви можете додавати сигнали та контакти на це полотно і спостерігати за їхніми значеннями. Ви можете додавати сигнали або контакти, коли вкладка «Спостереження» відображається, натиснувши на її назву в дереві.
На наступному малюнку показано це полотно з кількома шпильками.
Watch відображає значення бітового типу (бінарні) за допомогою кольорових кіл, що представляють світлодіоди. Вони відображаються темно-червоним кольором, коли бітовий сигнал або контакт є хибним, і світло-жовтим кольором, коли цей сигнал є істинним. Якщо ви виберете контакт або сигнал, який не є сигналом бітового типу (бінарним), watch відобразить його як числове значення. Контакти відображаються чорним кольором, сигнали — синім, а параметри — коричневим.
Watch дозволить вам швидко протестувати перемикачі або побачити ефект змін, які ви вносите в LinuxCNC під час використання графічного інтерфейсу. Частота оновлення Watch є дещо повільною для перегляду імпульсів крокового двигуна, але ви можете використовувати її для цього, якщо рухаєте вісь дуже повільно або з дуже невеликими кроками відстані.
Контекстне меню
6.5. Введення команди
У нижній частині знаходиться поле введення для тестування команд HAL. Команди, які ви вводите тут, та їхній вплив на працюючий HAL не зберігаються. Вони залишатимуться активними, доки працює LinuxCNC, але зникнуть, щойно LinuxCNC буде вимкнено.
Поле введення з назвою «Команда HAL:» прийматиме будь-які команди, перелічені для halcmd. До них належать:
-
loadrt,unloadrt(завантаження/вивантаження модуля реального часу) -
loadusr,unloadusr(завантаження/вивантаження компонента, що не працює в реальному часі) -
addf,delf(додавання/видалення функції до/з потоку реального часу) -
net(створити зв’язок між двома або більше елементами) -
setp(встановити параметр (або pin) у значення)
Цей невеликий редактор вводитиме команду щоразу, коли ви натискатимете клавішу enter або кнопку виконання. Якщо ці команди сформовані неправильно, halcmd відображатиме повідомлення про помилку. Якщо ви не впевнені, як правильно налаштувати команду, вам потрібно буде ще раз прочитати документацію про halcmd та конкретні модулі, з якими ви працюєте.
6.6. Налаштування
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 після виконання цієї команди.
Далі нам потрібно підключити 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.