UniSet/ОбъектыСистемы
Об интерфейсах объектов системы управления UniSet
Далее изложение предполагает наличие у читателя представления о том, как была организована работа с сообщениями, датчиками и выходными сигналами в последней версии UniSet (применённой в Имитаторе), где был опробован отказ от вкомпилированных числовых идентификаторов.
Просьба сторонним читателям не особо беспокоиться по поводу данного текста.
Основные положения
Детали реализации
!! Этот раздел надо распилить!!
Каждый объект в системе должен иметь уникальное имя, с которым он регистрируется в репозитории. По этому имени к объекту можно обратиться (получив по его имени специальную ссылку). Идеология примерно как в интернете, где по web-адресу обращаешься к нужной странице.
В системе существуют разные объекты:
- процессы управления
- процессы ввода/вывода
- процессы обмена с каким-либо оборудованием
- датчики (каждый датчик имеет уникальное имя и является объектом)
В общем случае репозиторий представляет из себя древовидную структуру наподобие каталогов и файлов. Никто конечно не запрещает всем объектам регистрироваться сразу в "корневом каталоге". Тогда они будут иметь самые короткие имена "Корень/ИмяОбъекта".
Но мы у себя используем следующую структуру (пока негласную):
- Корень(Имя проекта)
- Объекты
- О1
- О2
- ...
- Процессы ввод/вывода
- IO1
- IO2
- ...
- Датчики
- S1
- S2
- ...
- Сервисы
- DBServer1
- ...
Т.е. для того, чтобы получить ссылку на объект О1 необходимо использовать полное имя "Корень/Объекты/О1".
Чем удобна такая структура (если её зафиксировать):
- На этом построены средства отладки. Например просмотрщик состояния датчиков обращается к разделу "Корень/Датчики" и получает полный список всех датчиков доступных сейчас в системе. В другом случае ему пришлось бы пройтись по всему репозиторию и обращаться к каждому объекту, чтобы выяснить "датчик" он или "не датчик"...
- Наличие "Корня" позволяет работать(отладка) одновременно двум проектам. Т.к. каждый имеет свой корень и они не пересекаются.
- Ну в принципе информация становится структурированной, с ней легче работать. Потом планировалось написать универсальный (графический) просмотрщик репозитория. С возможностью узнавать информацию о любом объекте и посылать любые сообщения выбранному объекту, естественно он выглядел бы в виде древовидной структуры.
Конечно все эти вещи можно решить и без обязательной древовидной структуры, но пока проблемм особых она не вызывала, да и "внутренне" мне как-то больше нравится именно такое разбиение, чем "валить всё в кучу".
Раньше мы использовали статический массив и автоматическое генерирование enum-а. Конечно использование выглядело лучше conf->oind->getNameById(Sensor1).
Но статическая компиляция не позволяет:
- без перекомпиляции добавлять новые датчик или объекты
- генерировать имена на ходу
Глобальный вопрос использования числовых идентификаторов.
Т.е. в CORBA все ссылки являются строками (по крайней мере имеют функции преобразования в строку и обратно). И в "числе" ей для работы нет необходимости. ЧИСЛО (ID) придумали мы.
Числовые идентификаторы объектов имеют следующие плюсы:
- экономия места в сообщения (указание адресата, от кого и т.п.)
- в сетях типа CAN, вообще не предусмотрена передача тестовых сообщений (ну по крайней мере штатным быстрым способом).
- с числами легче устраивать всякие там циклы(for), применять какие-то формулы вычисления идентификатора и т.п.
- с числами работа более оптимальна по быстродействию
К минусам приходится отнести только усложнение механизма работы и возможно некоторое неудобство при программировании (по крайней мере визуально). Т.е. получается - что надо каким-то образом каждому объекту присваивать уникальный идентификатор
- внутри (при вызовах) частенько происходит преобразование ID -> текстовое имя -> ID.
- сложности в синхронизации ID на разных узлах (необходимо следить, чтобы на двух разных узлах идентификаторы одного и того же объекта совпадали. Это достигается либо статической компиляцией, либо (как сейчас) требуется следить, чтобы на узлах был одинаковый исходный xml-файл настроек проекта).
Объекты и интерфейсы
Объект регистрируется в репозитории с уникальным именем и только после этого может взаимодействовать с другими объектами.
Активный объект представлен классом (в С++) и имеет свойства, которые хранятся в конф. файле проекта и определяют тип интерфейса объекта.
Существует ряд базовых типов интерфейса:(UniSetObject, ObjectsManager, IONotifyController, для каждого из которых определён набор допустимых над ним операций.
- UniSetObject позволяет ему посылать сообщения
- ObjectsManager свойства UniSetObject + позволяет через него посылать сообщения подчинённым ему объектам, гарантируя доставку
- IONotifyController позволяет узнавать значения входов и управлять выходами
Названия типов, хранящиеся в конф. файле, соответствуют названию классов в С++.
Для каждого активного объекта на основе конф. файла генерируется базовый класс, который наследован от одного из базовых классов, в зависимости от типа его интерфейса. Класс записывается в отдельный файл и содержит в секции protected переменные состояния датчиков и идентификаторы датчиков. Для этого класса формируется функция, отвечающая за обновление переменных с состояниями датчиков. Также указывается название объекта (уникальное для данного узла). В конструкторе класса происходит получение необходимых идентификаторов.
В конфигурационном файле для каждого объекта перечислены объекты, с которыми он взаимодействует. Для датчиков - перечислены заказчики, для выходов - перечислены управляющие им объекты, для активных объектов - объекты, имеющие право отправлять сообщения. Программа проверки должна проверять корректность этих ссылок. Этот механизм позволяет генерировать локальные переменные, содержащие идентификаторы используемых объектов (получаемые на основании имени) и контролировать допустимость взаимодействия, то есть право использования.
Текстовое название объекта
Полный путь объекта имеет вид
\\узел\Корень\Вид объекта\Устройство\Название объекта на устройстве
(допустимы любые символы в названии, кроме \0, \\ и '.'
Этот путь является полностью уникальных в пределах системы.
Локальный путь к объекту имеет вид
\Корень\Вид объекта\Название объекта
Для разных узлов сети адрес может повторяться.
Название объекта может повторяться для различных видов объектов.
Числовой код объекта
Для пересылки и обработки использоваться числовой код (идентификатор) объекта, имеющий однозначное взаимное соответствие с путём к объекту.
Должен предлагаться дешёвый механизм по преобразованию код->путь->код.
Конкретных реализаций может быть несколько: от непосредственного задания кода в XML-файле до создания хэш-функции.
Принятым рабочим вариантом является хранение всей информации об объектах в XML-файлах, копируемых на все узлы сети
В использовании констант, обозначающих код объекта, необходимости не найдено.
Способы обмена информацией между объектами
- Получение сообщения о состоянии (датчика)
- Передача извещения (сообщения с командой)
- Установка выходного значения