Пользователь
0,0
рейтинг
5 марта 2013 в 21:47

Разработка → Знакомство с libuniset — библиотекой для создания АСУ из песочницы

В данной статье речь пойдёт об открытой библиотеке для построения распределённых систем управления — libuniset, написанной на языке C++ под ОС Linux. Будет дан общий обзор основных понятий, элементов и концепций, используемых в библиотеке.

Основной целью библиотеки libuniset является предоставление готовых «кубиков» для построения распределённых автоматизированных систем управления (АСУ). В любой АСУ можно выделить такие основные направления как:
  • ввод/вывод;
  • сетевой обмен;
  • процессы управления (алгоритмы);
  • хранение данных;
  • работа с БД.

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

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

Небольшая историческая справка


Библиотека libuniset развивалась (и развивается сейчас) как и положено — постепенно. В ходе работы над различными проектами систем управления из них выделялись какие-то общие для всех систем свойства, механизмы или компоненты, и эти общие части вносились в библиотеку для дальнейшего повторного использования. На данный момент текущей версией является версия 1.6, которая представляет из себя уже достаточно зрелую библиотеку с установившимся API, которая позволяет легко (и быстро) создавать и разворачивать системы управления.

На данный момент библиотека и все её вспомогательные утилиты собираются под дистрибутив ALT Linux,
а так же дополнительно, при помощи системы Korinf, библиотека собирается под:


Что такое libuniset


libuniset

На рисунке сделана попытка графически представить, что из себя представляет libuniset.

В основу положена технология CORBA, на ней построено всё взаимодействие «компонентов» системы между собой. При этом следует заметить, что API библиотеки «маскирует» взаимодействие, основанное на CORBA и при необходимости взаимодействие может быть переписано с использованием других механизмов, не затрагивая интерфейсы, предназначенные для использования в проектах. Можно видеть, что libuniset по возможности задействует сторонние библиотеки (стараясь избегать изобретения велосипедов). Методы использования библиотеки могут быть различны: начиная от написания необходимой функциональности путём наследования от классов библиотеки и заканчивая использованием уже готовых компонентов без какой-либо модификации, а лишь настраивая их под свои задачи.

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


Основной информационной единицей в библиотеке является датчик. По сути, датчик — это некая переменная, хранящая состояние. Практически любая информация (о событиях, о состоянии того или иного процесса, объекта, сообщение оператору и т.п.) передаётся через состояние «датчика». В библиотеке предусмотрено четыре типа датчиков:
  • DI — дискретный вход (DigitalInput)
  • DO — дискретный выход (DigitalOutput)
  • AI — аналоговый вход (AnalogInput)
  • AO — аналоговый выход (AnalogOutput)

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

Взаимодействие процессов на узле


В ходе развития проекта опытным путём сформировалась следующая схема взаимодействие процессов на узле:
libuniset-node
Центральным элементом системы является SharedMemory (SM) — это процесс, осуществляющий хранение состояния всех датчиков. Всё взаимодействие между процессами осуществляется через него. При этом не следует путать это название с понятием «разделяемая память», относящимся к механизмам взаимодействия в UNIX-системах. В данном случае процесс SharedMemory просто выполняет функцию разделяемого хранилища и поэтому получил такое название. Помимо этого SharedMemory осуществляет рассылку уведомлений другим процессам об изменении состояния того или иного датчика.
Все процессы условно можно разделить на два типа: «активные» и «пассивные».
Пассивные процессы — это процессы, которые большую часть времени «спят», ожидая сообщений об изменении того или иного датчика. В основном к таким процессам относятся процессы управления.
Активные процессы — это процессы, которые постоянно выполняют какую-то работу. К таким процессам относятся:
  • процессы обмена по сети (в данном случае CAN);
  • процессы работы с картами ввода/вывода (IOControl);
  • процессы обмена с какими-то внешними устройствами (RS485 или ModbusTCP).

Так как активные процессы тесно взаимодействуют с SharedMemory, то для оптимизации работы (исключения удалённых вызовов процедур через CORBA) все активные процессы запускаются в одном адресном пространстве с SharedMemory (каждый процесс в отдельном потоке), и работают с SM напрямую, через указатели. Этот «объединённый» процесс по историческим причинам называется SharedMemory2.
Отдельно можно выделить группу «вспомогательных» процессов. На данном рисунке к таким относится DBServer, обычно запускаемый на операторских станциях, где ведётся БД. Его задача — получать уведомления от SM по изменении любого датчика и сохранять эти события в БД. По умолчанию в libuniset реализована поддержка MySQL и SQLite, но при необходимости можно реализовать взаимодействие с любой СУБД, разработав соответствующий DBServer.

Распределённое взаимодействие (сетевое)


На рисунке представлена типичная схема сетевого взаимодействия на основе libuniset.
libuniset-network

Для обеспечения «прозрачности сети» на каждом узле запускается своя копия SharedMemory(SM). «Прозрачность» при этом обеспечивают процессы обмена между узлами по соответствующему протоколу (на рисунке это CAN и UNET). Узлы постоянно обмениваются между собой датчиками обеспечивая «одинаковость» хранимой в SM информации. Каждый процесс обмена получает от других узлов информацию о находящихся у них датчиков, и в свою очередь посылает другим узлам информацию о датчиках находящихся у него на узле.
Так же через SM функционирует и процесс ввода/вывода (IOControl). Всё, что считывается с каналов ввода, сохраняется в SM, а состояние «выходов» читается из SM и выводится в каналы вывода.
Из рисунка можно видеть, что взаимодействие может быть построено практически на основе любого интерфейса (Ethernet, CAN, RS, MIL-STD и т. п.). Для этого достаточно написать процесс обмена, реализующий соответствующий интерфейс и взаимодействующий с SM. При этом вся остальная система не потребует модификации.

Краткое описание готовых компонентов, входящих в libuniset


Готовые компоненты представляют из себя уже законченные программы (процессы), которые «умеют» взаимодействовать с SharedMemory и позволяют легко «развёртывать» распределённые системы. В библиотеке libuniset имеются следующие готовые компоненты:
  • SharedMemory — хранение «переменных»;
  • IOControl — работа с картами ввода/вывода;
  • ModbusMaster — реализация Modbus TCP/RTU master режима;
  • ModbusSlave — реализация Modbus TCP/RTU slave режима;
  • UNetExchange — взаимодействие по протоколу UDP;
  • LogicProcessor — компонент, позволяющий описывать алгоритмы на основе логических схем (записываемых в xml-файле);
  • DBServer_MySQL — сервер для взаимодействия с БД MySQL;
  • DBServer_SQLite — сервер для работы с SQLite.


Утилиты, входящие в состав libuniset


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

  • uniset-admin — многофункциональная консольная утилита, позволяющая писать/читать состояние датчиков, а таки же имеющая различные вспомогательные функции;
  • uniset-simitator — имитатор линейного изменения аналоговых датчиков;
  • uniset-smviewer — просмотр состояния всех датчиков;
  • uniset-smonit — мониторинг изменения состояния датчика (или группы датчиков).

Утилиты работы с сетевыми протоколами:

  • uniset-mbtcpserver-echo — имитатор Modbus TCP Slave устройства;
  • uniset-mbtcptest — Консольная утилита, позволяющая опрашивать (проверять) устройства по протоколу Modbus TCP (режим Master);
  • uniset-mbrtuslave-echo — имитатор Modbu RTU Slave устройства;
  • uniset-mbrtutest — Консольная утилита, позволяющая опрашивать (проверять) устройства по протоколу Modbus RTU (режим Master);
  • uniset-unet-udp-tester — работа с протоколом UnetUDP.

Различные дополнительные утилиты:

  • uniset-iotest — тестирование работы с картами ввода-вывода;
  • uniset-iocalibr — калибровка аналоговых датчиков;
  • uniset-codegen — генератор скелета процесса управления.


Дополнительные проекты


Программный интерфейс (API) библиотеки libuniset стабилизировался уже давно, и постепенно в дополнение к ней возникли различные вспомогательные программы. Поскольку целью данной статьи является общее знакомство именно с libuniset, ограничимся только перечислением таких дополнений:
  • uniset-configurator— графическая утилита, позволяющая производить настройку различных параметров системы (карт ввода/вывода, каналов ввода/вывода, сетевое взаимодействие и т. п.
  • uniset-testsuite — набор утилит (отдельный проект) для создания специальных тестовых сценариев позволяющих проводить автоматические (регрессионные и не только) тесты работы системы построенной на основе libuniset.
  • uniwidgets — библиотека для построения графических интерфейсов на основе gtkmm, взаимодействующая с использованием libuniset.


Заключение


Библиотека libuniset позволяет довольно быстро создавать «сложные» системы. В чём-то она похожа по идеологии на SCADA-системы, но следует иметь ввиду, что это только поверхностное сходство: пользователю в данном случае представлен полный контроль над работой системы, возможность программировать любые алгоритмы (на языке C++). Хотя следует заметить, что система, построенная на libuniset, может быть легко интегрирована в какую-либо существующую систему (на основе SCADA) — просто выступая, например, в качестве Modbus Slave узла. Или же наоборот, может взаимодействовать с любой сторонней SCADA-системой, просто используя процесс обмена Modbus Master (готовый компонент).
Имеется положительный опыт применения её в ответственных проектах, где она проявила себя как надёжно работающая система (24x7x365).

Ссылки по теме


@PavelVainerman
карма
11,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (25)

  • +1
    Спасибо, очень интересная штука, работаю непосредственно в этой теме(промышленная автоматизация) и как раз сейчас стою перед очередным этапом разработки, в которой придется плотно использовать Linux/C++ для промышленной автоматизации.
    • –1
      Поделитесь, зачем? Никогда не видел решения на базе Linux. Как-то на Windows-е :(
      • +1
        Решения разные бывают, тут должно быть устройстов без морды, исключительно бекграунд сервис, который занимается конверсией протоколов, и архивирование указанного списка параметров их контроллеров, для этого была выбрана железка на ARM, потому что А — дешевая, Б — мало-потребляющая, в ней будет стоять какой нить дебиан, на котором должно что-то крутиться, такая штука как описана в этой статье может быть удачной стартовой платформой.
      • 0
        «Как-то на Windows'е» решения стабильно вывешивают синий экран? Или могут год проработать без перезагрузки?
        • –1
          >>Или могут год проработать без перезагрузки?
          Когда работал в АСУТП на одной из ТЭЦ нашей необъятной родины, то мне не приходилось видеть ситуации когда нужно было перезагружать комп. Как правило, что-то случалось связанное с производством, а не ИТ-спецификой. Минус тогдашнего процесса, то что на бесперебойники экономили (((
        • +1
          Это домыслы. Вывешивает синий экран не виндовс, а кривые драйвера, даже кривое пользовательское приложение давно не может вывесить синий экран. Если у вас стабильная платформа, конфигурация которой не меняется три раа в месяц, то виндовс решения могут работать без перезагрузки месяцами. Сам недавно реализовывал такое приложение, которое в поле, без какого либо обслуживания крутится по многу месяцев. Писал на .NET+WPF. Были проблемы при разработке, и стабильностью, и как ни странно с очень именитым опен сорс компонентом.
          • 0
            Что значит домыслы? Это реальность вокруг: зависшие табло с рекламой и информацией в офис. центрах и вокзалах, зависшие банкоматы, перезагрузка компьютера в почтовом отделении. И как-то всё равно, что ядро в Windows идеальное, а вот драйвера к железу не отлажены. Суть, наверное, в другом. Windows снижает порог вхождения. Как PHP. Это значит, что специалист меньшей квалификации может написать программу и она заработает. Но это не означает, что он может написать хорошую программу.
            Не очень понятно из фразы, что за проблемы при разработке и стабильностью.
            И что же вы не назвали этот именитый опенсорс компонент? Страна должна знать своих героев.
            • 0
              SqLite, проблемы конечно были объективно не в нем в самом, а в том, в каком окружении он применялся, но как мне кажется, компонент, основное применение которого встраиваемые решения, должен был бы заострять внимание на той проблеме которая у меня возникла. Если коротко, то проблема была в непрерывном создание/удалении файла журнала, что при использовании в сочетании копакт-флеш диском, приводило к порче оного(диска) через 2 месяца работы, со всеми вытекающими. Просто если вы просто часто пишете на CF данные, то они пишутся циклически, и одни и те-же ячейки флеша не используются часто, что не приводит к отказу, если же вы будете раз в секунду создавать/удалять файл с одним и тем же названием — это приводит к непрерывной модификации одной и тойже ячейки, что для флеша смертельно.
            • 0
              А что касательно порога вхождения, возможно вы где-то и правы, но не все замыкается на порог вхождения. Есть еще интеграция с существующей инфраструктурой, дальнейшее обслуживание(люди которые будут пользоваться продуктом) итд…
              • 0
                Да, вы правы, таких факторов много. И в общем-то в совокупности они вполне оправдывают создание решений на Windows. Интеграция с существующей инфраструктурой сильна похожа на пресловутую совместимость, которая была основной картой Microsoft при изгнании других игроков с рынка. Это очень удобно, когда твои программные продукты совместимы… только с твоими же продуктами :)
                Дальнейшее обслуживание — весомый аргумент. В случае АСУ ТП часто требуется вмешательство местных инженеров при изменении процедуры производства. Но есть случаи, когда система поставляется в закрытой коробке и вмешательства не требуется.

                В общем, в каждом случае, конечно, требуется выбор, исходя из обстоятельств. Но Windows никогда не являлась и не является универсальной платформой на все случаи жизни. Тем более, лучшей по техническим характеристикам. Иначе бы не существовало, например, QNX или Solaris.

                • 0
                  Никто не говорил слово лучшая, любое решение принимается по совокупности многих факторов, таких как цена решения/стоимость разработки/обслуживание и еще много других. В нашем случае решение на Windows было оправдан тогда, сейчас оправдано решение на Linux :)
    • 0
      может стоит тогда попробовать эту? ;)
  • 0
    — ввод/вывод;
    — сетевой обмен;
    — процессы управления (алгоритмы);
    — хранение данных;
    — работа с БД.

    — транзакции;
    • 0
      с точки зрения «АСУ», что вы имеете ввиду?
      • 0
        В основные направления также стоит включить «транзакции», в не «сетевого обмена», в АСУ должна присутствовать единица отката/подтверждения операции, допустим транзакция АСУ какого либо диспетчерского пункта.
        Я это имел введу.
        • 0
          я конечно не совсем понял, всё-таки что имелось ввиду… но в любом случае… если речь об управлении — это часть темы «Алгоритмы»,
          если это речь об общепринятом понимании транзакций, как части относящейся к БД — то собственно это тема «работа с БД».
          Под направлениями, я именно это имел ввиду.
  • 0
    Я правильно понял, это можно использовать как альтернативу OPC-серверу?
    • 0
      Думаю что не совсем, это можно использовать как каркас для создания OPC сервера, при этом реализацию части отвечающей за OPC вам придется делать самому.
    • 0
      Да, если под альтернативой понимать «назначение». В данном случае аналогом OPC-сервера является компонент названный SharedMemory(SM). Т.е. хранилище значений всех переменных, уведомляющее всех «заказчиков» об изменениях. Но в строгом смысле это всё-таки не OPC-сервер, т.к. не соответствует спецификации для OPC-серверов. OPC-сервера — заточены на windows-технологии.
      При этом, как я писал в конце, систему построенную с использованием libuniset легко можно интегрировать в другую систему в том числе, она может взаимодействовать с любым OPC-сервером по протоколу Modbus (RTU или TCP) выступая в качестве slave-устройства. Т.е. вы можете на контроллере всё построить на libuniset с Linux и дополнительно запустить ModbusSlave (готовый компонент), который будет брать значения из SM и отдавать в ответ на запросы внешнего OPC-сервера.

      • 0
        Павел, а пробовали это все собирать и работать на linux arm процессорах? Так как у меня сейчас стоит задача именно сделать modbus tcp2rtu slave контроллер(gateway) на ARM-linux на борту.
        • 0
          К сожалению нет, пока не было такой необходимости. НО! т.к. разработка базируется на ALTLinux, у них вроде есть отдельный репозиторий пересобранных под ARM пакетов. То предполагаю, если в этом репозитории есть всё необходимое для сборки libuniset (а вроде есть),
          то и libuniset сам по себе соберётся, т.к. какого-то специального архитектурно-зависимого кода в себе не содержит.
        • 0
          заодно: у вас задача сделать просто шлюз modbus TCP<-->RTU или там что-то интеллектуальное с какой-то своей логикой?
          А то готовые шлюзы именно для этой задачи существуют и относительно не дорого.
          • 0
            Да, я находил такие шлюзы. Но хочется уложиться в меньшие деньги, да и на контроллер задумал завести больше задач, чем шлюз. Если у меня получется — обязательно отпишу вам.
            • 0
              Хорошо. Пишите и если будут вопросы по использованию…

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