UniSet 2.32.1
Основные понятия

В библиотеке uniset имеется ряд основополагающих кубиков (терминов), из которых складывается библиотека, и которые используются во многих местах данной документации. Здесь приводятся определения этих терминов.

Объект

В разных местах описаний, в зависимости от контекста, под "объектом" подразумевается либо объект класса так или иначе наследующегося от базового класса библиотеки UniSetObject, либо некий концептуальный программный объект способный получать и обрабатывать сообщения.

Основные типы объектов

В библиотеке произведено условное деление на следующие типы объектов:

  • (простые) объекты - наследуются от класса UniSetObject
  • контроллеры - являются наследниками класса IOController
  • сервисы - являются наследниками специальных классов
  • узлы - в строгом смысле, не являются объектами, но обладают уникальным идентификатором.

Сообщения

Вся система взаимодействия между объектами в основном построена на использовании сообщений (передаваемых путём удаленного вызова специальных функций, посредством CORBA). При этом основные типы сообщений объявлены в файле MessageType.h. Каждое сообщение имеет свой уникальный идентификатор (enum). См. UniSetTypes::Message::TypeOfMessage.

Для разработчиков систем на основе libuniset, заложена возможность определять свои типы сообщений, при этом их идентификаторы должны начинаться от значения UniSetTypes::Message::TheLastFieldOfTypeOfMessage.

enum MyMessageTypes
{
myBegin = UniSetTypes::Message::TheLastFieldOfTypeOfMessage,
myMessageType1,
myMessageType2,
myMessageType3,
...
};

Идентификатор объекта

Каждый объект, которому необходимо взаимодействовать с другими объектами (в том числе датчиками см. Датчик) должен обладать уникальным идентификатором. В качестве идентификатора выступает любое число типа UniSetTypes::ObjectId. Зарезервированным числом является UniSetTypes::DefaultObjectId. Минимальное требование - это уникальность в рамках одного узла. Так как полный идентификатор объекта формируется парой <id,node> Где node - такое же число, являющееся идентификатором узла. При этом приветствуется использование идентификатора уникального в рамках всей создаваемой системы. Т.к. в последствии возможен уход от использования параметра node.

На текущий момент существует два основных способа задать идентификатор объекта.

Автоматическое присвоение при загрузке.
Для этого в конфигурационном файле в секциях <nodes>, <sensors>, <objects>, <controllers>, <services> достаточно задать только имя объекта (поле name). А в секции <ObjectsMap> вписать параметр idfromfile="0".
<Configurations>
...
<ObjectsMap idfromfile="0">
<nodes port="2809">
<item name="LocalhostNode" alias="" textname="Локальный узел" ip="127.0.0.1" dbserver=""/>
<item name="Node2" alias="" textname="Локальный узел" ip="127.0.0.1" dbserver=""/>
</nodes>
<sensors>
<item name="Input1_S" textname="Команда 1" node="" iotype="DI" priority="Medium" default="1" />
<item name="Input2_S" textname="Команда 2" node="" iotype="DI" priority="Medium" mbtype="rtu" mbaddr="0x01" mbfunc="0x04" mbreg="0x02" rs="2" />
</sensors>
<controllers name="Controllers">
<item name="SharedMemory"/>
<item name="UniExchange"/>
<item name="UniExchange2"/>
</controllers>
<!-- ******************* Идентификаторы сервисов ***************** -->
<services name="Services">
<item name="DBServer"/>
<item name="PrintServer"/>
</services>
<!-- ******************* Идентификаторы объектов ***************** -->
<objects name="UniObjects">
<item name="TestProc1"/>
<item name="TestProc2"/>
</objects>
</ObjectsMap>
...
</Configurations>
При этом, автоматически при загрузке конфигурационного файла, каждому объекту будет присвоен идентификатор (просто по порядку). См. UniSetTypes::ObjectIndex_XML
Заметки
Следует иметь ввиду, что автоматическое присвоение идентификаторов, зависит от положения описания объекта в конфигурационном файле. Поэтому если вставить новый объект в любой секции, то все идентификаторы после него, станут недействительными (сместятся на единицу). Т.е. необходимо отслеживать, что конфигурационные файлы на всех узлах совпадают между собой.
Из-за не надёжности это способ не рекомендуется к использованию.
Ручное задание идентификаторов
Этот способ подразумевает ручное (самостоятельное) указание идентификатора для каждого объекта. На практике, это оказывается не сложно, потому-что объекты вносятся в файл по мере необходимости небольшими порциями или же эта часть файла может быть сгенерирована автоматически. К плюсам данного способа можно отнести, то, что идентификаторы могут быть "осмысленными" (например являться кодами сигналов или группироваться диапазонами по определённой логике). Для ручного задания идентификаторов, необходимо в секциях <nodes>, <sensors>, <objects>, <controllers>, <services> задать поле id. А в секции <ObjectsMap> вписать параметр idfromfile="1".
<Configurations>
...
<ObjectsMap idfromfile="1">
<nodes port="2809">
<item id="1000" name="LocalhostNode" alias="" textname="Локальный узел" ip="127.0.0.1" dbserver=""/>
<item id="1001" name="Node2" alias="" textname="Локальный узел" ip="127.0.0.1" dbserver=""/>
</nodes>
<sensors>
<item id="1" name="Input1_S" textname="Команда 1" node="" iotype="DI" priority="Medium" default="1" />
<item id="10" name="Input2_S" textname="Команда 2" node="" iotype="DI" priority="Medium" mbtype="rtu" mbaddr="0x01" mbfunc="0x04" mbreg="0x02" rs="2" />
</sensors>
<controllers name="Controllers">
<item id="100" name="SharedMemory"/>
<item id="101" name="UniExchange"/>
<item id="102" name="UniExchange2"/>
</controllers>
<!-- ******************* Идентификаторы сервисов ***************** -->
<services name="Services">
<item id="501" name="DBServer"/>
<item id="502" name="PrintServer"/>
</services>
<!-- ******************* Идентификаторы объектов ***************** -->
<objects name="UniObjects">
<item id="200" name="TestProc1"/>
<item id="201" name="TestProc2"/>
</objects>
</ObjectsMap>
...
</Configurations>
Заметки
При этом за уникальностью(отсутствием дублей) идентификаторов должен следить сам разработчик (хотя эта проверка может быть автоматизирована не сложными скриптами).

Сервис имён (Names service)

Сервис имён предназначен для получения ссылок на объекты (для возможности удалённого вызова) по имени объекта. Все объекты и датчики регистрируются в этом сервисе и становятся доступны для удалённого вызова. В данном проекте используется реализация службы имён входящая в состав библиотеки omniORB. Сервис поставляется отдельной утилитой под названием omniNames.

см. Сервис имён

Датчик

Датчик - это одно из базовых понятий при построении систем на основе libuniset. Датчик - это информационная единица. Практически любая информация (о событиях, о состоянии того или иного процесса, объекта, сообщение оператору и т.п.) передаётся через состояние "датчика". В библиотеке предусмотрено четыре типа датчиков.

  • DI - UniversalIO::DigitalInput - дискретный вход
  • DO - UniversalIO::DigitalOutput - дискретный выход
  • AI - UniversalIO::AnalogInput - аналоговый вход
  • AO - UniversalIO::AnalogOutput - аналоговый выход

Исходно данные типы используются непосредственно процессами ввода/вывода. "Выходы"(DO,AO) - это, команды "от системы управления" "Входы"(DI,AI) - это информация от объекта "в систему управления". Помимо этого, датчики не обязательно должны быть "живыми" входами или выходами. При помощи этих четырёх типов, можно кодировать любую информацию, Например можно передавать сообщения оператору, заранее создавая для каждого сообщения свой "датчик" и в случае необходимости послать сообщение выставлять его в "1". Удобство и универсальность датчиков (цифр) позволяет использовать для передачи данных большое число различных протоколов, рассчитанных на передачу цифровой информации (не текстовой). Например CAN, ModbusRTU, ModbusTCP и т.п.

Процесс

Под процессом в документации чаще всего подразумевается системный процесс (запущенная программа) выполняющий те или иные функции управления и обменивающийся для этого с другими процессами сообщениями или удалённо вызывающий функции других объектов. Чаще всего понятия процесс и объект совпадают. В некоторых случаях процесс может содержать несколько взаимодействующих объектов. Все процессы в системе - многопоточные. Так как для взаимодействия с другими объектами (процессами) в обязательном порядке создаются потоки для CORBA, а также у каждого объекта создаётся свой поток обработки сообщений (если его специально не отключить).

Если в документации речь идёт о "процессе", как последовательности действий во времени, это должно быть очевидно из контекста.