This section explains principles behind the implementation of HAL components with the Python programming language.
1. Базовый пример использования
Компонент, не работающий в режиме реального времени, начинает с создания своих контактов и параметров, затем входит в цикл, который периодически управляет всеми выходами со входов. Следующий компонент копирует значение, отображаемое на его входном контакте (passthrough.in), на выходной контакт (passthrough.out) примерно раз в секунду.
#!/usr/bin/env python3
import hal
import time
h = hal.component("passthrough")
h.newpin("in", hal.HAL_FLOAT, hal.HAL_IN)
h.newpin("out", hal.HAL_FLOAT, hal.HAL_OUT)
h.ready()
try:
while True:
h['out'] = h['in']
time.sleep(1)
except KeyboardInterrupt:
raise SystemExit
Copy the above listing into a file named "passthrough", make it executable (chmod +x). Then try it out (assuming the cpmponent "passthrough" is located in the current directory):
$ halrun
halcmd: loadusr ./passthrough
halcmd: show pin
Component Pins:
Owner Type Dir Value Name
4 float IN 0 passthrough.in
4 float OUT 0 passthrough.out
halcmd: setp passthrough.in 3.14
halcmd: show pin
Component Pins:
Owner Type Dir Value Name
4 float IN 3.14 passthrough.in
4 float OUT 3.14 passthrough.out
2. Компоненты и задержки, не относящиеся к реальному времени
Если вы быстро набрали "show pin", вы можете увидеть, что passthrough.out по-прежнему имеет старое значение 0. Это связано с вызовом time.sleep(1), который делает присвоение выходному контакту не чаще одного раза в секунду. Поскольку это компонент, не работающий в режиме реального времени, фактическая задержка между назначениями может быть намного дольше, если память, используемая транзитным компонентом, выгружается на диск, поскольку назначение может быть отложено до тех пор, пока эта память не будет выгружена обратно.
Таким образом, компоненты, не работающие в режиме реального времени, подходят для интерактивных с пользователем элементов, таких как панели управления (задержки в диапазоне миллисекунд не заметны и более длинные задержки допустимы), но не для отправки шаговых импульсов на плату шагового драйвера (задержки всегда должны быть в диапазоне микросекунд, несмотря ни на что).
3. Создание контактов и параметров
mycomp = hal.component("passthrough")
Сам компонент создается вызовом конструктора hal.component. Аргументами являются имя компонента HAL и (опционально) префикс, используемый для имен выводов и параметров. Если префикс не указан, используется имя компонента.
mycomp.newpin("in", hal.HAL_FLOAT, hal.HAL_IN)
mycomp.newparam("has-feature-rotate", hal.HAL_BIT, hal.HAL_RO)
Затем выводы создаются путем вызова методов объекта компонента. Аргументами являются: суффикс имени контакта, тип контакта и направление контакта. Для параметров аргументами являются: суффикс имени параметра, тип параметра и направление параметра.
Типы контактов и параметров: |
|
|
|
|
|
|
|
Направления контактов: |
|
|
|
||||
Направления параметров: |
|
|
|
Note
|
Only pins and signals can use the |
Полное имя контакта или параметра формируется путем объединения префикса и суффикса с помощью ".", поэтому в примере созданный вывод называется passthrough.in.
mycomp.ready()
После создания всех выводов и параметров вызовите метод .ready().
3.1. Изменение префикса
Префикс можно изменить, вызвав метод .setprefix(). Текущий префикс можно получить, вызвав метод .getprefix().
4. Чтение и запись контактов и параметров
Для контактов и параметров, которые также являются правильными идентификаторами Python, значение можно получить или установить с помощью синтаксиса атрибута:
mycomp.out = mycomp.in
Для всех контактов, независимо от того, являются ли они правильными идентификаторами Python, значение можно получить или установить с помощью синтаксиса индексов:
mycomp['out'] = mycomp['in']
Чтобы увидеть все контакты с их значениями, getpins возвращает все значения в словаре этого компонента.
mycomp.getpins()
>>>{'in': 0.0, 'out': 0.0}
4.1. Управляющие выходные контакты (HAL_OUT)
Periodically, usually in response to a timer, all HAL_OUT pins should be "driven" by assigning them a new value. This should be done whether or not the value is different than the last one assigned. When a pin is connected to a signal, its old output value is not copied into the signal. The proper value will only appear on the signal once the component assigns a new value.
4.2. Управление двунаправленными (HAL_IO) контактами
The above rule does not apply to bidirectional pins. Instead, a bidirectional pin should only be driven by the component when the component wishes to change the value. For instance, in the canonical encoder interface, the encoder component only sets the index-enable pin to False (when an index pulse is seen and the old value is True), but never sets it to True. Repeatedly driving the pin False might cause the other connected component to act as though another index pulse had been seen.
5. Выход
A halcmd unload request for the component is delivered as a KeyboardInterrupt exception. When an unload request arrives, the process should either exit in a short time, or call the .exit() method on the component if substantial work (such as reading or writing files) must be done to complete the shutdown process.
6. HAL Python module reference
See Python HAL Interface for an overview and description of available classes and methods.
7. Constants
Используйте их для указания деталей, а не значения, которое они содержат.
-
Pin, parameter and signal types:
-
HAL_BIT -
HAL_FLOAT -
HAL_S32 -
HAL_U32 -
HAL_S64 -
HAL_U64
-
-
Pin direction:
-
HAL_IN -
HAL_OUT
-
-
Parameter access:
-
HAL_RO -
HAL_RW
-
-
Message severity:
-
MSG_NONE -
MSG_ALL -
MSG_DBG -
MSG_ERR -
MSG_INFO -
MSG_WARN
-
8. Системная информация
Прочтите их, чтобы получить информацию о системе реального времени.
-
lcnc_realtime: See Python module for managing the realtime backend. -
is_kernelspace -
is_userspace -
get_realtime_type()