1. Введение

Конфигурация переходит от теории к устройству — то есть к устройству HAL. Для тех, кто хоть немного разбирался в компьютерном программировании, этот раздел называется Hello World HAL.

halrun можно использовать для создания работающей системы. Это инструмент командной строки или текстового файла для настройки и настройки. Следующие примеры иллюстрируют его настройку и работу.

2. Halcmd

«halcmd» — это инструмент командной строки для управления HAL. Для halcmd существует более полная справочная страница, которая устанавливается вместе с LinuxCNC из исходного кода или из пакета. Если LinuxCNC был скомпилирован как run-in-place, страница руководства не устанавливается, но доступна в главном каталоге LinuxCNC с помощью следующей команды:

$ man -M docs/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. Просто запустите следующую команду из окна терминала:

Загрузка HAL
cd linuxcnc
halrun
halcmd:

Загрузив ОС реального времени и RTAPI, мы можем перейти к первому примеру. Обратите внимание, что приглашение теперь отображается как halcmd:. Это связано с тем, что последующие команды будут интерпретироваться как команды HAL, а не команды оболочки.

В первом примере мы будем использовать компонент HAL под названием siggen, который представляет собой простой генератор сигналов. Полное описание компонента siggen можно найти в разделе SigGen данного руководства. Это компонент реального времени. Чтобы загрузить компонент "siggen", используйте команду HAL loadrt.

Загрузка siggen
halcmd: loadrt siggen

3.2. Изучение HAL

Теперь, когда модуль загружен, пришло время представить halcmd — инструмент командной строки, используемый для настройки HAL. В этом руководстве будут представлены только некоторые функции halcmd. Для более полного описания попробуйте man halcmd или посмотрите ссылку в разделе HAL Commands этого документа. Первая функция halcmd — это команда show. Эта команда отображает информацию о текущем состоянии HAL. Чтобы отобразить все установленные компоненты:

Показать компоненты с помощью halrun/halcmd
halcmd: 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

Компонент siggen экспортировал одну функцию. Ей требуется плавающая запятая. В настоящее время она не связана ни с какими потоками, поэтому users равны нулю, footnote: [Поля CodeAddr и Arg использовались во время разработки и, вероятно, должны исчезнуть.].

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 )

Получилось. Этот период не равен точно 1,000,000 нс из-за аппаратных ограничений, но у нас есть поток, который работает примерно с правильной скоростью и может обрабатывать функции с плавающей запятой. Следующий шаг — подключить функцию к потоку:

Добавить функцию
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 имеет память слона и сохранит эту конфигурацию, пока мы его не выключим. Но что насчет следующего раза? Мы не хотим вручную вводить кучу команд каждый раз, когда хотим использовать систему.

Сохранение конфигурации всего 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 . Чтобы сохранить эти команды для дальнейшего использования, мы просто перенаправляем вывод в файл:

Сохраните конфигурацию в файл с помощью halcmd
halcmd: save all saved.hal

3.6. Выход из halrun

Когда вы закончите сеанс HAL, введите exit в командной строке halcmd:. Это вернет вас к системному приглашению и закроет сеанс HAL. Не закрывайте просто окно терминала, не завершив сеанс 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 перед началом следующего сеанса. Для этого введите следующую команду в окне терминала.

Удаление HAL
halrun -U

4. Halmeter

Вы можете создавать очень сложные системы HAL, даже не используя графический интерфейс. Однако есть что-то приятное в том, чтобы видеть результат своей работы. Первый и самый простой инструмент с ГИП для HAL — это halmeter. Это очень простая программа, которая является HAL-эквивалентом удобного мультиметра (или аналогового измерителя для олдов).

Это позволяет наблюдать за контактами, сигналами или параметрами, отображая текущие значения этих объектов. Это очень простое в использовании приложение для графических сред. В консоли введите:

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.

Запуск Halmeter
halcmd: loadusr halmeter

Первое окно, которое вы увидите, — это окно "Select Item to Probe".

Halmeter Окно выбора
Figure 1. Halmeter Окно выбора

Этот диалог имеет три вкладки. На первой вкладке отображаются все контакты HAL в системе. На втором отображаются все сигналы, а на третьем — все параметры. Мы хотели бы сначала посмотреть на контакт siggen.0.cosine, поэтому щелкните его, а затем нажмите кнопку "Close". Диалоговое окно выбора объекта для измерения закроется, и окно измерения будет выглядеть примерно так, как показано на следующем рисунке.

Halmeter Окно
Figure 2. Halmeter Окно

Чтобы изменить то, что отображает измеритель, нажмите кнопку "Select", которая возвращает окно "Select Item to Probe".

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

Чтобы выключить Halmeter, просто нажмите кнопку выхода.

Если вы хотите просмотреть более одного контакта, сигнала или параметра одновременно, вы можете просто запустить больше halmeter’ов. Окно halmeter было намеренно сделано очень маленьким, чтобы на экране могло быть одновременно много изображений.

5. Stepgen Example

До сих пор мы загрузили только один компонент HAL. Но вся идея HAL заключается в том, чтобы позволить вам загружать и соединять ряд простых компонентов для создания сложной системы. В следующем примере будут использоваться два компонента.

Прежде чем мы сможем приступить к созданию этого нового примера, мы хотим начать с чистого листа. Если вы только что закончили один из предыдущих примеров, нам нужно удалить все компоненты и перезагрузить библиотеки RTAPI и HAL.

halcmd: exit

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

Первая команда загружает два генератора шагов, оба настроены на генерацию шаговых импульсов типа 0. Вторая команда загружает нашего старого друга siggen, а третья создает два потока: быстрый с периодом 50 микросекунд (мкс) и медленный с периодом 1 миллисекунда (мс). Быстрый поток не поддерживает функции с плавающей запятой.

Как и прежде, мы можем использовать 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

5.2. Соединение контактов с сигналами

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

net command
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.

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

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

Последняя функция, stepgen.update-freq, отвечает за масштабирование и некоторые другие вычисления, которые необходимо выполнять только при изменении команды частоты.

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

Мы запускаем функции, добавляя их в потоки. Каждый поток работает с определенной скоростью. Давайте посмотрим, какие потоки у нас есть.

halcmd: show thread

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

Два потока были созданы, когда мы загрузили потоки. Первый, медленный, выполняется каждую миллисекунду и способен выполнять функции с плавающей запятой. Мы будем использовать его для siggen.0.update и stepgen.update_freq. Второй поток является быстрым, он выполняется каждые 50 микросекунд (мкс) и не поддерживает операции с плавающей запятой. Мы будем использовать его для stepgen.make_pulses. Чтобы подключить функции к нужному потоку, мы используем команду addf. Сначала мы указываем функцию, а затем поток.

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

После того, как мы дадим эти команды, мы можем снова запустить команду show thread, чтобы увидеть, что произошло.

halcmd: show thread

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

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

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

5.5. Запустить его!

Теперь у нас все настроено и мы готовы к запуску. Как и в первом примере, мы используем команду start.

halcmd: start

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

6. Halscope

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

Halscope состоит из двух частей: части реального времени, которая считывает сигналы HAL, и части не реального времени, которая обеспечивает ГИП и отображение. Однако вам не нужно об этом беспокоиться, поскольку часть, не работающая в реальном времени, автоматически загрузит часть реального времени, когда это необходимо.

Когда LinuxCNC работает в терминале, вы можете запустить halscope с помощью следующей команды.

Запуск Halscope
halcmd loadusr halscope

Если LinuxCNC не запущен или файл autosave.halscope не соответствует контактам, доступным в текущем работающем LinuxCNC, откроется окно ГИП осциллографа, за которым сразу последует диалоговое окно Realtime function not linked, которое выглядит как показано на следующем рисунке. Чтобы изменить частоту дискретизации, щелкните левой кнопкой мыши на поле семплов.

Диалоговое окно не связанное с функцией реального времени
Figure 3. Диалоговое окно не связанное с функцией реального времени

В этом диалоговом окне вы устанавливаете частоту дискретизации осциллографа. На данный момент мы хотим производить выборку один раз в миллисекунду, поэтому нажмите на медленный поток 989 мкс и оставьте множитель равным 1. Мы также оставим длину записи равной 4000 выборок, чтобы мы могли использовать до четырех каналов одновременно. Когда вы выбираете поток и нажимаете ОК, диалоговое окно исчезает, а окно области действия выглядит примерно так, как показано на следующем рисунке.

Начальное окно осциллографа
Figure 4. Начальное окно осциллографа

6.1. Подключение щупов

На этом этапе Halscope готов к использованию. Мы уже выбрали частоту дискретизации и длину записи, поэтому следующий шаг — решить, на что обратить внимание. Это эквивалентно подключению виртуальных щупов осциллографа к HAL. Halscope имеет 16 каналов, но количество, которое вы можете использовать одновременно, зависит от длины записи: больше каналов означает более короткие записи, поскольку доступная для записи память фиксирована и составляет примерно 16 000 выборок.

Кнопки каналов расположены в нижней части экрана галоскопа. Нажмите кнопку 1, и вы увидите диалоговое окно Select Channel Source, как показано на следующем рисунке. Этот диалог очень похож на тот, который использует Halmeter. Нам хотелось бы просмотреть сигналы, которые мы определили ранее, поэтому мы нажимаем вкладку Signals, и в диалоговом окне отображаются все сигналы в HAL (только два для этого примера).

Выбор канала источника
Figure 5. Выбор канала источника

Чтобы выбрать сигнал, просто нажмите на него. В данном случае мы хотим, чтобы канал 1 отображал сигнал X-vel. Нажмите вкладку «Сигналы», затем нажмите X-vel, диалоговое окно закроется, и канал будет выбран.

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

Кнопка канала 1 нажата, и под рядом кнопок появляются номер канала 1 и название X-vel. На этом дисплее всегда отображается выбранный канал — на экране может быть много каналов, но выбранный будет выделен, а различные элементы управления, такие как вертикальное положение и масштаб, всегда будут работать с выбранным каналом.

Halscope
Figure 7. Halscope

Чтобы добавить сигнал на канал 2, нажмите кнопку 2. Когда появится диалоговое окно, перейдите на вкладку Signals, затем нажмите Y-vel. Мы также хотим посмотреть на выходные сигналы прямоугольных и треугольных волн. К этим контактам не подключены никакие сигналы, поэтому вместо этого мы используем вкладку Pins. Для канала 3 выберите siggen.0.triangle, а для канала 4 — siggen.0.square.

6.2. Захват наших первых сигналов

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

Захваченные сигналы
Figure 8. Захваченные сигналы

В поле Selected Channel внизу указано, что фиолетовая кривая — это выбранный в данный момент канал 4, который отображает значение вывода siggen.0.square. Попробуйте нажать кнопки каналов с 1 по 3, чтобы выделить три другие кривые.

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

Сигналы довольно сложно различить, поскольку все четыре находятся друг на друге. Чтобы это исправить, мы используем элементы управления Vertical в поле справа от экрана. Эти элементы управления действуют на текущий выбранный канал. При настройке усиления обратите внимание, что он охватывает огромный диапазон — в отличие от настоящего осциллографа, он может отображать сигналы в диапазоне от очень маленьких (пико-единицы) до очень больших (тера-единицы). Элемент управления положением перемещает отображаемый сигнал вверх и вниз только по высоте экрана. Для более крупных регулировок следует использовать кнопку смещения.

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

Большая кнопка Selected Channel внизу указывает, что канал 1 в данный момент выбран и соответствует сигналу X-vel. Попробуйте нажать на другие каналы, чтобы увидеть их сигналы и иметь возможность перемещать их с помощью курсора Pos.

6.4. Запуск развертки

Использование кнопки Force — довольно неудовлетворительный способ активировать осциллограф. Чтобы настроить реальный триггер, нажмите кнопку Source справа внизу. Появится диалоговое окно Trigger Source, которое представляет собой просто список всех щупов, которые в данный момент подключены. Выберите щуп, который будет использоваться для запуска, щелкнув по нему. В этом примере мы будем использовать канал 3, треугольную волну, как показано на следующем рисунке.

Диалог источника запуска
Figure 10. Диалог источника запуска

После установки источника триггера вы можете настроить уровень и положение триггера с помощью ползунков в поле Trigger вдоль правого края. Уровень можно регулировать сверху вниз по экрану, он отображается под ползунками. Позиция — это расположение триггерной точки в общей записи. Если ползунок полностью опущен, точка запуска находится в конце записи, а halscope отображает то, что произошло до точки запуска. Когда ползунок полностью поднят, точка запуска находится в начале записи, отображая то, что произошло после ее запуска. Точка запуска отображается в виде вертикальной линии в окне выполнения над экраном. Полярность триггера можно изменить, нажав кнопку чуть ниже дисплея уровня триггера. Тогда он станет descendant. Обратите внимание, что изменение положения триггера останавливает осциллограф, как только положение было отрегулировано. Вы перезапускаете осциллограф, нажав кнопку Normal в группе Run mode .

Теперь, когда мы настроили вертикальные элементы управления и триггер, отображение осциллографа выглядит примерно так, как показано на следующем рисунке.

Сигналы с запуском
Figure 11. Сигналы с запуском

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

Чтобы внимательно рассмотреть часть сигнала, вы можете использовать ползунок масштабирования в верхней части экрана, чтобы развернуть сигналы по горизонтали, а также ползунок положения, чтобы определить, какая часть увеличенного сигнала видна. Однако, иногда простого расширения формы сигнала недостаточно, и необходимо увеличить частоту дискретизации. Например, мы хотели бы взглянуть на фактические шаговые импульсы, которые генерируются в нашем примере. Поскольку длительность шаговых импульсов может составлять всего 50 мкс, выборка на частоте 1 кГц недостаточна. Для изменения частоты дискретизации, нажмите кнопку, которая отображает количество выборок и частоту дискретизации, чтобы открыть диалоговое окно Select Sample Rate. В этом примере мы выберем поток 50 мкс, быстрый, что даст нам частоту дискретизации около 20 кГц. Теперь вместо отображения данных за 4 секунды одна запись содержит 4000 выборок с частотой 20 кГц, или около 0,20 секунды.

Диалог частоты выборки
Figure 12. Диалог частоты выборки

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

Теперь посмотрим на шаговые импульсы. Halscope имеет 16 каналов, но в этом примере мы одновременно используем только 4. Прежде чем выбрать еще какие-либо каналы, нам нужно пару отключить . Нажмите кнопку канала 2, затем нажмите кнопку Chan Off в нижней части поля Vertical. Затем нажмите на канал 3, выключите его и сделайте то же самое для канала 4. Несмотря на то что каналы выключены, они все равно запоминают к чему они подключены, и фактически мы продолжим использовать канал 3 в качестве источника запуска. Чтобы добавить новые каналы, выберите канал 5 и выберите контакт stepgen.0.dir, затем канал 6 и выберите stepgen.0.step. Затем выберите режим запуска Normal, чтобы запустить осциллограф, и отрегулируйте горизонтальное масштабирование до 5 мс на деление. Вы должны увидеть, что шаговые импульсы замедляются когда команда скорости (канал 1) приближается к нулю, затем контакт направления меняет состояние, и шаговые импульсы снова ускоряются. Возможно, вам захочется увеличить усиление на канале 1 примерно до 20 милли на деление, чтобы лучше видеть изменение команды скорости. Результат должен выглядеть как на следующем рисунке.

Шаговые импульсы
Figure 13. Шаговые импульсы

6.7. Больше выборок

Если вы хотите записать больше выборок одновременно, перезапустите режим реального времени и загрузите halscope с числовым аргументом, который указывает количество выборок, которые вы хотите захватить.

halcmd loadusr halscope 80000

Если компонент scope_rt еще не был загружен, halscope загрузит его и запросит 80 000 общих выборок, так что при выборке 4 каналов одновременно будет 20 000 выборок на канал. (Если scope_rt уже загружен, числовой аргумент halscope не будет иметь никакого эффекта).