1. Введение
Конфигурация переходит от теории к устройству — то есть к устройству HAL. Для тех, кто хоть немного разбирался в компьютерном программировании, этот раздел называется Hello World HAL.
halrun можно использовать для создания работающей системы. Это инструмент командной строки или текстового файла для настройки и настройки. Следующие примеры иллюстрируют его настройку и работу.
2. Halcmd
halcmd is a command line tool for manipulating HAL. A more complete man page exists for halcmd and installed together with LinuxCNC, from source or from a package. If LinuxCNC has been compiled as run-in-place, the man page is not installed but is accessible in the LinuxCNC main directory with the following command:
$ man -M docs/build/man halcmd
2.1. Обозначения
В этом руководстве команды для операционной системы обычно отображаются без приглашения оболочки UNIX, т. е. обычно со знаком доллара ($) или решеткой/двойным крестом (#). При прямом общении с HAL через halcmd or halrun подсказки показаны в примерах. Окно терминала находится в разделе Applications/Accessories в главной строке меню Ubuntu.
me@computer:~linuxcnc$ halrun (will be shown like the following line) halrun (the halcmd: prompt will be shown when running HAL) halcmd: loadrt counter halcmd: show pin
2.2. Табуляция-завершение
Ваша версия halcmd может включать в себя завершение табуляции. Вместо завершения имен файлов, как это делает оболочка, она дополняет команды идентификаторами HAL. Вам нужно будет ввести достаточно букв, чтобы получить уникальное совпадение. Попробуйте нажать Tab после запуска команды HAL:
halcmd: loa<TAB> halcmd: load halcmd: loadrt halcmd: loadrt cou<TAB> halcmd: loadrt counter
2.3. Среда RTAPI
RTAPI означает Real Time Application Programming Interface. Многие компоненты 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 footnote: [Run In Place, когда исходные файлы загружены в пользовательский каталог, компилируются и выполняются непосредственно оттуда.], вызовите сценарий rip-environment, чтобы подготовить shell. В этом случае все, что вам нужно сделать, это загрузить в память необходимые модули 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
Loaded HAL Components:
ID Type Name PID State
3 RT siggen ready
2 User halcmd2177 2177 ready
Поскольку halcmd сам по себе также является компонентом HAL, он всегда будет отображаться в списке. Число после "halcmd" в списке компонентов — это ID UNIX процесса. Можно запустить более одной копии halcmd одновременно (например, в разных окнах терминала), поэтому PID добавляется в конец имени, чтобы сделать его уникальным. В списке также показан компонент siggen, который мы установили на предыдущем шаге. RT в разделе Type указывает, что siggen — это компонент реального времени. User в разделе Type указывает, что это компонент, не работающий в реальном времени.
Далее, давайте посмотрим, какие контакты делает доступными siggen:
halcmd: show pin
Component Pins:
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
Parameters:
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 Exported Functions: 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 [1].
3.3. Запуск кода в реальном времени
Чтобы фактически запустить код, содержащийся в функции siggen.0.update, нам нужен поток реального времени. Компонент под названием threads, который используется для создания нового потока. Давайте создадим поток под названием "test-thread" с периодом 1 мс (1,000 мкс или 1,000,000 нс):
halcmd: loadrt threads name1=test-thread period1=1000000
Посмотрим, сработало ли это:
halcmd: show thread
Realtime Threads:
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
Realtime Threads:
Period FP Name ( Time, Max-Time )
999855 YES test-thread ( 0, 0 )
1 siggen.0.update
Прежде чем компонент siggen начнет генерировать сигналы, необходим еще один шаг. При первом запуске HAL поток(и) фактически не выполняются. Это позволит вам полностью настроить систему до запуска кода реального времени. Как только вы будете довольны конфигурацией, вы можете запустить код реального времени следующим образом:
halcmd: start
Теперь генератор сигналов работает. Давайте посмотрим на его выходные контакты:
halcmd: show pin
Component Pins:
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
Component Pins:
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
Parameters:
Owner Type Dir Value Name
3 s32 RO 1754 siggen.0.update.time
3 s32 RW 16997 siggen.0.update.tmax
halcmd: show pin
Component Pins:
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 # components loadrt threads name1=test-thread period1=1000000 loadrt siggen # pin aliases # signals # nets # parameter values setp siggen.0.update.tmax 14687 # realtime thread/function links addf siggen.0.update test-thread
Вывод команды save представляет собой последовательность команд HAL. Если вы начнете с empty HAL и запустите все эти команды, вы получите конфигурацию, которая существовала на момент выполнения команды save . Чтобы сохранить эти команды для дальнейшего использования, мы просто перенаправляем вывод в файл:
halcmdhalcmd: save all saved.hal
3.6. Выход из halrun
Когда вы закончите сеанс HAL, введите exit в командной строке halcmd:. Это вернет вас к системному приглашению и закроет сеанс HAL. Не закрывайте просто окно терминала, не завершив сеанс HAL.
halcmd: exit
3.7. Восстановление конфигурации HAL
Чтобы восстановить конфигурацию HAL, хранящуюся в файле "saved.hal", нам нужно выполнить все эти команды HAL. Для этого мы используем ключи "-f _<file name>_", который считывает команды из файла, и «-I» (заглавная буква i), который показывает приглашение halcmd после выполнения команд:
halrun -I -f saved.hal
Обратите внимание, что в файле saved.hal нет команды "start". Необходимо ввести ее снова (или отредактировать файл saved.hal, чтобы добавить ее туда).
3.8. Удаление HAL из памяти
Если произойдет неожиданное завершение сеанса HAL, возможно, вам придется выгрузить HAL перед началом следующего сеанса. Для этого введите следующую команду в окне терминала.
halrun -U
4. Stepgen Пример
Up till now we have only loaded one HAL component. But the whole idea behind the HAL is to allow you to load and connect a number of simple components to make up a complex system. The next example will use two components.
Прежде чем мы сможем приступить к созданию этого нового примера, мы хотим начать с чистого листа. Если вы только что закончили один из предыдущих примеров, нам нужно удалить все компоненты и перезагрузить библиотеки RTAPI и HAL.
halcmd: exit
4.1. Установка компонентов
Теперь мы собираемся загрузить компонент генератора шаговых импульсов. Подробное описание этого компонента см. в разделе «Stepgen» Руководства интегратора. В этом примере мы будем использовать тип управления 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
Component Pins:
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
Parameters:
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 Signals: 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
Signals:
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 Exported Functions: 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
Realtime Threads:
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 оборотов. Это означает, что общее масштабирование составляет 10 000 шагов на дюйм. Нам нужно умножить входную скорость, подаваемую на генератор шаговых импульсов, на 10000, чтобы получить правильный выходной сигнал. Именно для этого нужен параметр stepgen.n.position-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. Halmeter
You can build very complex HAL systems without ever using a graphical interface. However there is something satisfying about seeing the result of your work. The first and simplest GUI tool for the HAL is halmeter. It is a very simple program that is the HAL equivalent of the handy multimeter (or analog meter for the old timers).
Это позволяет наблюдать за контактами, сигналами или параметрами, отображая текущие значения этих объектов. Это очень простое в использовании приложение для графических сред. В консоли введите:
halmeter
Появятся два окна. Окно выбора самое большое и включает в себя три вкладки:
-
В одном перечислены все контакты, определенные в настоящее время в HAL,
-
в другом перечислены все сигналы,
-
в третьем перечислены все параметры.
Нажмите на вкладку, затем нажмите на один из элементов, чтобы выбрать его. В небольшом окне будет показано имя и значение выбранного элемента. Дисплей обновляется примерно 10 раз в секунду. Чтобы освободить место на экране, окно выбора можно закрыть кнопкой Close. В маленьком окне, скрытом под окном выбора при запуске программы, кнопка Select повторно открывает окно выбора, а кнопка Exit останавливает программу и закрывает оба окна.
Возможен запуск нескольких 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
Первое окно, которое вы увидите, — это окно "Select Item to Probe".
Этот диалог имеет три вкладки. На первой вкладке отображаются все контакты HAL в системе. На втором отображаются все сигналы, а на третьем — все параметры. Мы хотели бы сначала посмотреть на контакт siggen.0.cosine, поэтому щелкните его, а затем нажмите кнопку "Close". Диалоговое окно выбора объекта для измерения закроется, и окно измерения будет выглядеть примерно так, как показано на следующем рисунке.
Чтобы изменить то, что отображает измеритель, нажмите кнопку "Select", которая возвращает окно "Select Item to Probe".
Вы должны увидеть, как значение меняется по мере того, как siggen генерирует косинусоидальную волну. Halmeter обновляет дисплей примерно 5 раз в секунду.
Чтобы выключить Halmeter, просто нажмите кнопку выхода.
Если вы хотите просмотреть более одного контакта, сигнала или параметра одновременно, вы можете просто запустить больше halmeter’ов. Окно halmeter было намеренно сделано очень маленьким, чтобы на экране могло быть одновременно много изображений.
6. Halshow
The script halshow can help you find your way around a running HAL. It displays chosen HAL values and updates them continuously.
Это очень специализированная система, и она должна подключаться к работающему HAL. Он не может работать автономно, поскольку полагается на способность HAL "introspect" и сообщать то, что он знает о себе, через библиотеку интерфейса halcmd. Когда конфигурация LinuxCNC изменится, вывод halshow тоже будет другим.
Как мы вскоре увидим, способность HAL документировать себя является одним из ключей к созданию эффективной системы ЧПУ.
6.1. Starting Halshow
Halshow is available
-
in the AXIS menu under Machine/Show HAL Configuration,
-
in the TkLinuxCNC menu under Scripts/HAL Show,
-
in GMOCCAPY on the settings page.
halshow can also be started from a terminal command line and specify formats for integer and float items (pins or signals) and identify a saved watchlist file to use:
$ halshow --help
Usage:
halshow [Options] [watchfile]
Options:
--help (this help)
--fformat format_string_for_float
--iformat format_string_for_int
--noprefs don't use preference file to save settings
Notes:
Create watchfile in halshow using: 'File/Save Watch List'.
LinuxCNC must be running for standalone usage.
Example to limit number of decimal points for floats and use a file named my.halshow in the current directory:
$ halshow --fformat "%.5f" ./my.halshow
For more information regarding the format, please refer to the Tcl format man page.
At the left of its display as shown in above figure is a tree view, resembling what you may have seen as file browsers. At the right is a tabbed notebook with tabs for show, watch and settings.
6.2. HAL Tree Area
Per default this entry filters the tree by pin names or tree-nodes by a regular expression. For example, entering "lim-sw" would filter the tree to the following:
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
If you would like to display all joint.0-related, you have to click the settings icon and select "Full path". Pay attention to escape the regex special characters, so you have to enter "joint\.1\." to explicitly request the dot and not also find joint 10.
The tree shows all of the major parts of a HAL. In front of each is a small plus (+) or minus (-) sign in a box to expand or collapse the corresponding section of the tree.
You can also expand or collapse the tree display using the Tree View menu at the upper left edge of the display.
Under Tree View you will find: Expand All, Collapse All; Expand Pins, Expand Parameters, Expand Signals; and Reload tree view. Reload tree view is useful when new components are loaded during runtime and should be displayed.
Because the pins and parameters of a component cannot share the same name, they are listed together in a single Pins & Parameters branch, with parameters shown in brown. To list pins and parameters in separate branches, enable Separate parameters from pins in tree in the Settings tab.
6.3. HAL Show Area
Clicking on the node name, "Components" in the tree for example, will show you (under the "Show" tab) all that HAL knows about the contents of that node. Figure Halshow Show Tab shows a list exactly like you will see if you click the "Components" name. The information display is exactly like those shown in traditional text based HAL analysis tools. The advantage here is that we have mouse click access, access that can be as broad or as focused as you need.
If we take a closer look at the tree display we can see that the six major parts of a HAL can all be expanded at least one level. As these levels are expanded you can get more focused with the reply when you click on the rightmost tree node. You will find that there are some HAL pins and parameters that show more than one reply. This is due to the nature of the search routines in halcmd itself. If you search one pin you may get two, like this:
Component Pins: Owner Type Dir Value Name 06 bit -W TRUE parport.0.pin-10-in 06 bit -W FALSE parport.0.pin-10-in-not
The second pin’s name contains the complete name of the first.
Selected text inside the Show tab can be copied by right-click or CTRL-C.
The Show area allows to add pins from selected text by using the right-click menu. All valid pins that are enclosed in the selection are added to the Watch tab.
6.4. Watch Tab Area
Clicking the watch tab produces a blank canvas. You can add signals and pins to this canvas and watch their values. You can add signals or pins when the watch tab is displayed by clicking on the name of it in the tree view.
You can also add all sub-items of this node by selecting that in the right click menu (see figure Halshow Watch Tab).
The following figure shows this canvas with several pins.
Watch displays bit type (binary) values using colored circles representing LEDs. They show as dark red when a bit signal or pin is false, and as light yellow whenever that signal is true. If you select a pin or signal that is not a bit type (binary) signal, watch will show it as a numerical value. Pins are displayed in black, signals in blue and parameters in brown.
Watch will quickly allow you to test switches or see the effect of changes that you make to LinuxCNC while using the graphical interface. Watch’s refresh rate is a bit slow to see stepper pulses, but you can use it for these if you move an axis very slowly or in very small increments of distance.
The pins and signals that are writable have buttons for manipulation on the right side. Pins that are linked to a signal have disabled buttons. To set these values, the corresponding pin has to be unlinked from the signal. That can be done by right-click on the signal name and select "Unlink pin", see Watch Tach Context Menu.
The watch list will be saved automatically on exit. If you don’t want Halshow to save your watchlist, it can be disabled in the Settings.
Context Menu
The context menu allows further:
-
Copy the pin name to clipboard
-
Set a value
-
Unlink a pin (if linked to a signal)
-
Show apin in the Tree view (highlights the pin, doesn’t scroll to the position)
-
Remove a pin from the list
6.5. Command Entry
In the lower part is an entry box to test HAL commands. The commands you enter here and the effect that they have on the running HAL are not saved. They will persist as long as LinuxCNC remains up but are gone as soon as LinuxCNC is.
The command entry has a BASH-like history (during the session), so you can restore inserted commands with the arrow up key.
The entry box labeled "HAL Command:" will accept any of the commands listed for halcmd. These include:
-
loadrt,unloadrt(load/unload real-time module) -
loadusr,unloadusr(load/unload non-realtime component) -
addf,delf(add/delete a function to/from a real-time thread) -
net(create a connection between two or more items) -
setp(set parameter (or pin) to a value)
This little editor will enter a command any time you press enter or push the execute button. An error message from halcmd will be shown when these commands are not properly formed. If you are not certain how to set up a proper command, you’ll need to read again the documentation on halcmd and the specific modules that you are working with.
6.6. Settings
The geometry of the window and the settings are saved in a file in the configuration directory on exit. If that path cannot be determined, they are stored in the home directory. The path will be displayed in the settings page. You can omit using the preferences file by calling halshow with the command line argument --no-prefs.
- Override format string
-
Sets the format of the displayed values, for more information refer to the Tcl format man page.
- Always on top
-
Keeps the halshow window on top.
- Remember watchlist
-
Keeps the saved items in the watchlist on exit.
- Separate parameters from pins in tree
-
Lists pins and parameters in separate Pins and Parameters branches of the tree, instead of the combined Pins & Parameters branch. The setting takes effect when you press Apply and is remembered between sessions.
The further settings should be self-explaining.
6.7. Example/Tutorial
Let’s use this editor to add a differential module to a HAL and connect it to axis position so that we could see the rate of change in position, i.e., acceleration. We first need to load a HAL component named ddt, add it to the servo thread, then connect it to the position pin of a joint. Once that is done we can find the output of the differentiator in halscope. So let’s go.
loadrt ddt
Now look at the components node and you should see ddt in there someplace.
Loaded HAL Components:
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
Sure enough, there it is. Notice that its ID is 08. Next we need to find out what functions are available with it so we look at functions:
Exported Functions: 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
Here we look for owner #08 and see a function named ddt.0. We should be able to add ddt.0 to the servo thread and it will do its math each time the servo thread is updated. Once again we look up the addf command and find that it uses three arguments like this:
addf <functname> <threadname> [<position>]
We already know the functname=ddt.0 so let’s get the thread name right by expanding the thread node in the tree. Here we see two threads, servo-thread and base-thread. The position of ddt.0 in the thread is not critical. So we add the function ddt.0 to the servo-thread:
addf ddt.0 servo-thread
This is just for viewing, so we leave position blank and get the last position in the thread. The following figure shows the state of halshow after this command has been issued.
Next we need to connect ddt to something. But how do we know what pins are available? The answer is to look under pins. There we find ddt and see this:
Component Pins: Owner Type Dir Value Name 08 float R- 0.00000e+00 ddt.0.in 08 float -W 0.00000e+00 ddt.0.out
That looks easy enough to understand, but what signal or pin do we want to to connect to it? It could be an axis pin, a stepgen pin, or a signal. We see this when we look at joint.0:
Component Pins: Owner Type Dir Value Name 03 float -W 0.00000e+00 joint.0.motor-pos-cmd ==> Xpos-cmd
So it looks like Xpos-cmd should be a good signal to use. Back to the editor where we enter the following command:
linksp Xpos-cmd ddt.0.in
Now if we look at the Xpos-cmd signal using the tree node we’ll see what we’ve done:
Signals: Type Value Name float 0.00000e+00 Xpos-cmd <== joint.0.motor-pos-cmd ==> ddt.0.in ==> stepgen.0.position-cmd
We see that this signal comes from joint.o.motor-pos-cmd and goes to both ddt.0.in and stepgen.0.position-cmd. By connecting our block to the signal we have avoided any complications with the normal flow of this motion command.
The HAL Show Area uses halcmd to discover what is happening in a running HAL. It gives you complete information about what it has discovered. It also updates as you issue commands from the little editor panel to modify that HAL. There are times when you want a different set of things displayed without all of the information available in this area. That is where the HAL Watch Area is of value.
7. Halscope
The previous example generates some very interesting signals. But much of what happens is far too fast to see with halmeter. To take a closer look at what is going on inside the HAL, we want an oscilloscope. Fortunately HAL has one, called halscope.
Halscope состоит из двух частей: части реального времени, которая считывает сигналы HAL, и части не реального времени, которая обеспечивает ГИП и отображение. Однако вам не нужно об этом беспокоиться, поскольку часть, не работающая в реальном времени, автоматически загрузит часть реального времени, когда это необходимо.
Когда LinuxCNC работает в терминале, вы можете запустить halscope с помощью следующей команды.
halcmd loadusr halscope
Если LinuxCNC не запущен или файл autosave.halscope не соответствует контактам, доступным в текущем работающем LinuxCNC, откроется окно ГИП осциллографа, за которым сразу последует диалоговое окно Realtime function not linked, которое выглядит как показано на следующем рисунке. Чтобы изменить частоту дискретизации, щелкните левой кнопкой мыши на поле семплов.
В этом диалоговом окне вы устанавливаете частоту дискретизации осциллографа. На данный момент мы хотим производить выборку один раз в миллисекунду, поэтому нажмите на медленный поток 989 мкс и оставьте множитель равным 1. Мы также оставим длину записи равной 4000 выборок, чтобы мы могли использовать до четырех каналов одновременно. Когда вы выбираете поток и нажимаете ОК, диалоговое окно исчезает, а окно области действия выглядит примерно так, как показано на следующем рисунке.
7.1. Подключение щупов
На этом этапе Halscope готов к использованию. Мы уже выбрали частоту дискретизации и длину записи, поэтому следующий шаг — решить, на что обратить внимание. Это эквивалентно подключению виртуальных щупов осциллографа к HAL. Halscope имеет 16 каналов, но количество, которое вы можете использовать одновременно, зависит от длины записи: больше каналов означает более короткие записи, поскольку доступная для записи память фиксирована и составляет примерно 16 000 выборок.
Кнопки каналов расположены в нижней части экрана галоскопа. Нажмите кнопку 1, и вы увидите диалоговое окно Select Channel Source, как показано на следующем рисунке. Этот диалог очень похож на тот, который использует Halmeter. Нам хотелось бы просмотреть сигналы, которые мы определили ранее, поэтому мы нажимаем вкладку Signals, и в диалоговом окне отображаются все сигналы в HAL (только два для этого примера).
Чтобы выбрать сигнал, просто нажмите на него. В данном случае мы хотим, чтобы канал 1 отображал сигнал X-vel. Нажмите вкладку «Сигналы», затем нажмите X-vel, диалоговое окно закроется, и канал будет выбран.
Кнопка канала 1 нажата, и под рядом кнопок появляются номер канала 1 и название X-vel. На этом дисплее всегда отображается выбранный канал — на экране может быть много каналов, но выбранный будет выделен, а различные элементы управления, такие как вертикальное положение и масштаб, всегда будут работать с выбранным каналом.
Чтобы добавить сигнал на канал 2, нажмите кнопку 2. Когда появится диалоговое окно, перейдите на вкладку Signals, затем нажмите Y-vel. Мы также хотим посмотреть на выходные сигналы прямоугольных и треугольных волн. К этим контактам не подключены никакие сигналы, поэтому вместо этого мы используем вкладку Pins. Для канала 3 выберите siggen.0.triangle, а для канала 4 — siggen.0.square.
7.2. Захват наших первых сигналов
Теперь, когда к HAL подключено несколько щупов, пришло время посмотреть несколько сигналов. Чтобы запустить halscope, нажмите кнопку Normal в разделе экрана Run Mode (вверху справа). Поскольку у нас есть длина записи 4000 выборок и мы получаем 1000 выборок в секунду, halscope потребуется около 2 секунд, чтобы заполнить половину буфера. В это время индикатор выполнения над главным экраном будет показывать заполнение буфера. Как только буфер заполнится наполовину, halscope ожидает триггера. Поскольку мы его еще не настроили, он будет ждать вечно. Чтобы запустить его вручную, нажмите кнопку Force в разделе Trigger в правом верхнем углу. Вы должны увидеть заполнение оставшейся части буфера, после чего на экране отобразятся захваченные сигналы. Результат будет выглядеть примерно так, как показано на следующем рисунке.
В поле Selected Channel внизу указано, что фиолетовая кривая — это выбранный в данный момент канал 4, который отображает значение вывода siggen.0.square. Попробуйте нажать кнопки каналов с 1 по 3, чтобы выделить три другие кривые.
7.3. Вертикальная регулировки
Сигналы довольно сложно различить, поскольку все четыре находятся друг на друге. Чтобы это исправить, мы используем элементы управления Vertical в поле справа от экрана. Эти элементы управления действуют на текущий выбранный канал. При настройке усиления обратите внимание, что он охватывает огромный диапазон — в отличие от настоящего осциллографа, он может отображать сигналы в диапазоне от очень маленьких (пико-единицы) до очень больших (тера-единицы). Элемент управления положением перемещает отображаемый сигнал вверх и вниз только по высоте экрана. Для более крупных регулировок следует использовать кнопку смещения.
Большая кнопка Selected Channel внизу указывает, что канал 1 в данный момент выбран и соответствует сигналу X-vel. Попробуйте нажать на другие каналы, чтобы увидеть их сигналы и иметь возможность перемещать их с помощью курсора Pos.
7.4. Запуск развертки
Использование кнопки Force — довольно неудовлетворительный способ активировать осциллограф. Чтобы настроить реальный триггер, нажмите кнопку Source справа внизу. Появится диалоговое окно Trigger Source, которое представляет собой просто список всех щупов, которые в данный момент подключены. Выберите щуп, который будет использоваться для запуска, щелкнув по нему. В этом примере мы будем использовать канал 3, треугольную волну, как показано на следующем рисунке.
После установки источника триггера вы можете настроить уровень и положение триггера с помощью ползунков в поле Trigger вдоль правого края. Уровень можно регулировать сверху вниз по экрану, он отображается под ползунками. Позиция — это расположение триггерной точки в общей записи. Если ползунок полностью опущен, точка запуска находится в конце записи, а halscope отображает то, что произошло до точки запуска. Когда ползунок полностью поднят, точка запуска находится в начале записи, отображая то, что произошло после ее запуска. Точка запуска отображается в виде вертикальной линии в окне выполнения над экраном. Полярность триггера можно изменить, нажав кнопку чуть ниже дисплея уровня триггера. Тогда он станет descendant. Обратите внимание, что изменение положения триггера останавливает осциллограф, как только положение было отрегулировано. Вы перезапускаете осциллограф, нажав кнопку Normal в группе Run mode .
Теперь, когда мы настроили вертикальные элементы управления и триггер, отображение осциллографа выглядит примерно так, как показано на следующем рисунке.
7.5. Горизонтальные регулировки
Чтобы внимательно рассмотреть часть сигнала, вы можете использовать ползунок масштабирования в верхней части экрана, чтобы развернуть сигналы по горизонтали, а также ползунок положения, чтобы определить, какая часть увеличенного сигнала видна. Однако, иногда простого расширения формы сигнала недостаточно, и необходимо увеличить частоту дискретизации. Например, мы хотели бы взглянуть на фактические шаговые импульсы, которые генерируются в нашем примере. Поскольку длительность шаговых импульсов может составлять всего 50 мкс, выборка на частоте 1 кГц недостаточна. Для изменения частоты дискретизации, нажмите кнопку, которая отображает количество выборок и частоту дискретизации, чтобы открыть диалоговое окно Select Sample Rate. В этом примере мы выберем поток 50 мкс, быстрый, что даст нам частоту дискретизации около 20 кГц. Теперь вместо отображения данных за 4 секунды одна запись содержит 4000 выборок с частотой 20 кГц, или около 0,20 секунды.
7.6. Больше каналов
Теперь давайте посмотрим на импульсы шага. У Halscope 16 каналов, но в этом примере мы используем только 4 за раз. Прежде чем выбирать другие каналы, нам нужно отключить несколько из них. Нажатие на кнопку выбранного канала (черная рамка) выключит канал. Поэтому нажмите кнопку канала 2, затем снова нажмите на эту кнопку, и канал выключится. Затем дважды щелкните на канале 3 и сделайте то же самое для канала 4. Несмотря на то, что каналы выключены, они все еще помнят, к чему они подключены, и фактически мы продолжим использовать канал 3 в качестве источника запуска. Чтобы добавить новые каналы, выберите канал 5 и выберите вывод stepgen.0.dir, затем канал 6 и выберите stepgen.0.step. Затем выберите режим работы Normal, чтобы запустить осциллограф, и настройте горизонтальное масштабирование до 5 мс на деление. Вы должны увидеть, как импульсы шага замедляются по мере того, как команда скорости (канал 1) приближается к нулю, затем вывод направления меняет состояние, и импульсы шага снова ускоряются. Возможно, вам стоит увеличить усиление на канале 1 примерно до 20 миллисекунд на деление, чтобы лучше увидеть изменение команды скорости. Результат должен выглядеть, как показано на следующем рисунке.
7.7. Больше выборок
Если вы хотите записать больше выборок одновременно, перезапустите режим реального времени и загрузите halscope с числовым аргументом, который указывает количество выборок, которые вы хотите захватить.
halcmd loadusr halscope 80000
Если компонент scope_rt еще не был загружен, halscope загрузит его и запросит 80 000 общих выборок, так что при выборке 4 каналов одновременно будет 20 000 выборок на канал. (Если scope_rt уже загружен, числовой аргумент halscope не будет иметь никакого эффекта).