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

Функція haltcl надає можливість використовувати скрипти Tcl та їхні функції для обчислень, циклів, розгалужень, процедур тощо в файлах INI. Щоб скористатися цією функцією, використовуйте мову Tcl та розширення .tcl для файлів HAL.

Розширення .tcl розуміється основним скриптом (linuxcnc), який обробляє INI-файли. Файли Haltcl ідентифікуються в розділі HAL INI-файлів (як і HAL-файли).

Приклад
[HAL]
HALFILE = conventional_file.hal
HALFILE = tcl_based_file.tcl

За належної обережності файли HAL та Tcl можна змішувати.

1. Сумісність

Мова halcmd, що використовується у файлах HAL, має простий синтаксис, який насправді є підмножиною потужнішої універсальної мови сценаріїв Tcl.

2. Команди Haltcl

Файли Haltcl використовують мову сценаріїв Tcl, доповнену специфічними командами рівня абстракції обладнання (HAL) LinuxCNC. Специфічні команди HAL:

addf, alias,
delf, delsig,
getp, gets
ptype,
stype,
help,
linkpp, linkps, linksp, list, loadrt, loadusr, lock,
net, newsig,
save, setp, sets, show, source, start, status, stop,
unalias, unlinkp, unload, unloadrt, unloadusr, unlock,
waitusr

Два особливі випадки виникають для команд «gets» та «list» через конфлікти з вбудованими командами Tcl. Для haltcl цим командам має передувати ключове слово «hal»:

halcmd   haltcl
------   ------
gets     hal gets
list     hal list

3. Змінні INI-файлу Haltcl

Змінні INI-файлу доступні як за допомогою halcmd, так і за допомогою haltcl, але з різним синтаксисом. INI-файли LinuxCNC використовують специфікатори SECTION та ITEM для ідентифікації елементів конфігурації:

[SECTION_A]
ITEM1 = value_1
ITEM2 = value_2
...
[SECTION_B]
...

Доступ до значень INI-файлу можна отримати шляхом підстановки тексту у HAL-файлах у такій формі:

[SECTION]ITEM

Ті самі значення INI-файлу доступні у Tcl-файлах за допомогою форми глобальної змінної масиву Tcl:

$::SECTION(ITEM)

Наприклад, елемент INI-файлу, такий як:

[JOINT_0]
MAX_VELOCITY = 4

виражається як [JOINT_0]MAX_VELOCITY у файлах HAL для halcmd
та як. $::JOINT_0(MAX_VELOCITY) у файлах Tcl для haltcl.

Оскільки INI-файли можуть повторювати один і той самий елемент ITEM в одному розділі SECTION кілька разів, $::SECTION(ITEM) насправді є списком Tcl для кожного окремого значення.

Коли є тільки одне значення і воно є простим (усі значення, що складаються тільки з літер і цифр без пробілів, належать до цієї групи), то можна розглядати $::SECTION(ITEM) так, ніби це не список.

Якщо значення може містити спеціальні символи (лапки, фігурні дужки, вбудовані пробіли та інші символи, що мають спеціальне значення в Tcl), то необхідно розрізняти список значень і початкове (і, можливо, єдине) значення в списку.

У Tcl це написано [lindex $::SECTION(ITEM) 0].

Наприклад: враховуючи наступні значення INI

[HOSTMOT2]
DRIVER=hm2_eth
IPADDR="10.10.10.10"
BOARD=7i92
CONFIG="num_encoders=0 num_pwmgens=0 num_stepgens=6"

А ця команда loadrt:

loadrt $::HOSTMOT2(DRIVER) board_ip=$::HOSTMOT2(IPADDR) config=$::HOSTMOT2(CONFIG)

Ось фактична команда, яка виконується:

loadrt hm2_eth board_ip={"10.10.10.10"} config={"num_encoders=0 num_pwmgens=0 num_stepgens=6"}

Це не вдається, оскільки loadrt не розпізнає дужки.

Отже, щоб отримати значення саме так, як вони були введені у файлі INI, перепишіть рядок loadrt ось так:

loadrt $::HOSTMOT2(DRIVER) board_ip=[lindex $::HOSTMOT2(IPADDR) 0] config=[lindex $::HOSTMOT2(CONFIG) 0]

4. Конвертування HAL-файлів у Tcl-файли

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

[SECTION]ITEM ---> $::SECTION(ITEM)
gets          ---> hal gets
list          ---> hal list

5. Примітки Haltcl

У haltcl аргумент-значення для команд sets та setp неявно обробляється як вираз у мові Tcl.

Приклад
# встановити коефіцієнт підсилення для перетворення град/с в одиниці/хв для радіуса JOINT_0
setp scale.0.gain 6.28/360.0*$::JOINT_0(radius)*60.0

Пробіли у виразі не допускаються, для цього використовуйте лапки:

setp scale.0.gain "6.28 / 360.0 * $::JOINT_0(radius) * 60.0"

В інших контекстах, таких як «loadrt», для обчислювальних виразів необхідно явно використовувати команду Tcl expr, ([expr {}]).

Приклад
loadrt motion base_period=[expr {500000000/$::TRAJ(MAX_PULSE_RATE)}]

6. Приклади Haltcl

Розглянемо тему «запас потужності stepgen». Програмне забезпечення stepgen найкраще працює з обмеженням прискорення, яке є «трохи вищим», ніж те, що використовується планувальником руху. Тому при використанні файлів halcmd ми змушуємо файли INI мати значення, обчислене вручну.

[JOINT_0]
MAXACCEL = 10.0
STEPGEN_MAXACCEL = 10.5

За допомогою haltcl ви можете використовувати команди Tcl для виконання обчислень та повного виключення елемента INI-файлу STEPGEN_MAXACCEL:

setp stepgen.0.maxaccel $::JOINT_0(MAXACCEL)*1.05

Ще однією функцією haltcl є циклічність і тестування. Наприклад, багато конфігурацій симуляторів використовують файли HAL «core_sim.hal» або «core_sim9.hal». Вони відрізняються між собою через необхідність підключення більшої або меншої кількості осей. Наступний код haltcl працюватиме для будь-якої комбінації осей у машині trivkins.

# Створити сигнали положення, швидкості та прискорення для кожної осі
set ddt 0
for {set jnum 0} {$jnum < $::KINS(JOINTS)} {incr jnum} {
  # «list pin» повертає порожній список, якщо pin не існує
  if {[hal list pin joint.${jnum}.motor-pos-cmd] == {}} {
    continue
  }
  net ${jnum}pos joint.${jnum}.motor-pos-cmd => joint.$axno.motor-pos-fb \
                                             => ddt.$ddt.in
  net ${axis}vel <= ddt.$ddt.out
  incr ddt
  net ${axis}vel => ddt.$ddt.in
  net ${axis}acc <= ddt.$ddt.out
  incr ddt
}
puts [show sig *vel]
puts [show sig *acc]

7. Haltcl Інтерактивний

Команда halrun розпізнає файли haltcl. З параметром -T haltcl можна запускати інтерактивно як інтерпретатор Tcl. Ця можливість корисна для тестування та для автономних HAL-застосунків.

Приклад
$ halrun -T haltclfile.tcl

8. Приклади розподілу Haltcl (simulator)

Каталог configs/sim/axis/simtcl містить INI-файл, який використовує файл .tcl для демонстрації конфігурації haltcl у поєднанні з використанням двопрохідної обробки. Приклад показує використання процедур Tcl, циклів, коментарів та виведення на термінал.