Научно-исследовательская лаборатория систем ЧПУ
Научно-исследовательская лаборатория систем ЧПУ

Поиск по сайту:
 

Расписание курсов "Программирование SINUMERIK 810D/840D/840Di"



Использование SVG в приложениях SCADA

Автор: Антон Попов
Лаборатория систем ЧПУ
Опубликовано: 16.04.2006
Версия текста: 1.0

1. Введение в HMI для приложений SCADA

Термин SCADA описывает компьютерную систему, используемую для сбора и анализа информации поступающей в реальном времени от производственных процессов. Системы SCADA используются для мониторинга и контроля производства или оборудования в различных индустриях, таких как машиностроение, энергетика, нефтегазовая промышленность и т. д. В то время, как большинство задач систем SCADA не требуют взаимодействия с пользователем, некоторые из них требуют надсмотра или вмешательства оператора. Таким образом, интерфейс оператора играет очень важную роль в системах SCADA. Необходимо, чтобы вся необходимая информация выводилась оператору в ясном и однозначном виде, в соответствии с текущими стандартами графической сигнализации. Эта часть SCADA систем известна как HMI (Human Machine Interface).

Важную роль в контексте интерфейса оператора играют различные обозначения, как это определено в стандарте ANSI/ISA-S5.5. В качестве примера, рассмотрим обозначение двигателя (табл. 1). Его обозначение состоит из круга с бордюром, содержащее букву М. Также, обозначение может быть обведено прямоугольником. Цвет круга, его бордюра и буквы, так же как цвет прямоугольника и его бордюра определяются состоянием (выключен, включен, авария) устройства, которое определяется обозначением двигателя. Двигатель в состоянии <включен>, например, обозначается зеленым кругом с черным бордюром. Состояние <выключен> обозначается простой сменой фона круга на серый, а состояние <неисправность> обозначается символом выключенного двигателя обведенного красным прямоугольником с черной рамкой. Как видно, символ двигателя состоит из различных составляющих, которые имеют различные форму и цвета. В то же время, обозначение всегда воспринимается как единое целое, на которое оператор может кликнуть, вывести в интерфейсе или удалить. В дополнение к этому, каждая компания может использовать свою предпочтительную ей цветовую гамму. Такое использование графики предполагает объединение графических элементов в библиотеку образов и использование различных стандартизированных цветовых гамм. Такие параметры, как размер обозначений должно, в свою очередь, быть применено ко всем элементам библиотеки образов, для того, чтобы гарантировать однотипность вывода в интерфейсе пользователя.

Обозначение Описание
Двигатель в выключенном состоянии
Двигатель в рабочем состоянии
Двигатель в состоянии <неисправность>

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

Модульность

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

Настраиваемость

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

Расширяемость

Как и в настраиваемости, проще увеличить количество возможных графических состояний в векторной графике, нежели чем в растровых изображениях.

Большое количество современных интерфейсов оператора создаются с помощью компонентов ActiveX. Эта технология базируется на компонентной объектной модели COM (Component Object Model) и на языках программирования позволяющих создавать COM компоненты, таких как C++ и Visual Basic.

Компоненты ActiveX могут включать в себя формы Windows, растровые изображения и векторную графику для визуального отображения компонента. Многие компании работающие в сфере автоматизации промышленного производства разработали собственные наборы библиотек образов для HMI базирующихся на компонентах ActiveX. Качество графики этих компонентов может сильно отличаться и зависит от качества используемых графических библиотек. Как правило, интерфейсы использующие векторную графику создаются процедурно на основе функций примитивов GDI (Graphics Device Interface) - графического Windows API, а не на основе декларативного SVG. Однако GDI также позволяет сохранять векторную графику в метафайлах, которые могут быть позже обработаны вызовом соответствующих функций библиотеки. Эти механизмы, позволяющие разрабатывать инструментальные средства рисования позволяют сохранять, манипулировать и сохранять метафайлы, освобождая пользователя от программирования графических библиотек. Также компоненты ActiveX, как и SVG могут быть интегрированы на web-страницы, но только на системах Microsoft Windows и только браузер Internet Explorer в состоянии отобразить их. Это одно из самых важных недостатков технологии ActiveX - она запатентованная. В дополнение к этому, компоненты ActiveX выполняют <родной> код Windows, создавая, таким образом, серьезные проблемы в безопасности пользователей. В любом случае, ActiveX является успешной технологией в построении HMI благодаря повсеместности операционной системы Windows, совершенности технологии COM и относительной простоте написания ActiveX компонентов на Visual Basic.

2. Архитектура компонентов SVG

Одной из идей, стоящей за распространением SVG является идея создания библиотек графических образов каждым сообществом. Тег <use> позволяет повторное использование графических символов описанных в этом же или других файлах SVG. Эти SVG-фрагменты могут комбинироваться в структурные схемы управляющей логики, электронные узлы, диаграммы классов UML или в любой другой вид графики. Промышленная автоматизация является одной из отраслей, где применение SVG крайне удобно, что демонстрируется успехом компонентов ActiveX. Но насколько графика SVG соответствует потребностям промышленных интерфейсов?

В качестве образца архитектуры для промышленных SVG компонентов возьмем следующие 4 идеи:

  1. Каждый компонент SVG описывается в отдельном файле.
  2. Каждый компонент SVG привязан к отдельному файлу каскадных таблиц стилей CSS (Cascading Style Sheet), который описывает набор возможных состояний компонента.
  3. Каждый компонент SVG сопровождается кодом Java выполняющий конфигурирование и определяющий его поведение во время работы.
  4. Интерфейс оператора HMI строится из этих компонентов используя тег <use>. Код Java применяет различные стили для каждого компонента базируясь на данных реального времени, полученных от оборудования и от взаимодействия с оператором.

2.1. Применимость CSS для SVG

Технология CSS была изначально разработана для модернизации страниц HTML. На обычной web-странице каждый тег служит для описания логической части документа. Например, тег <h1> означает, что текст внутри него является главным заголовком. В таком случае таблица стилей CSS может использовать селектор h1 для определения стиля текста обрамленного тегом <h1>. Теги HTML описывают логическую структуру документа, тогда как CSS определяет стиль каждой структуры документа.

В SVG обычно не имеет смысла использовать селекторы для определенного тега, как в HTML, потому что графический документ не является логически структурным документом. Это становится бесполезным, например, для определения стиля всех прямоугольников в рисунке (это применимо скорее к единообразным элементам и не применимо к определенным стандартным описаниям символов). Таким образом, самое простое и распространенное применение CSS селекторов на HTML страницах становится бесполезным в SVG.

С другой стороны, в HTML есть тег <div>, который не описывает логическую структуру содержимого и используется только для группировки других элементов. Как и в SVG документах довольно бессмысленно применять к этому тегу один стиль, так как это отразится на всех тегах <div> присутствующих на странице. В то же время, часто случается, что нам необходимо применить определенный стиль к разным элементам на HTML странице в независимости от тега. Атрибут class позволяет это сделать, связывая элемент HTML с соответствующим стилем. Добавляя в таблицу стилей CSS селектор .classname, который относится ко всем элементам класса classname. Эту же практику, в свою очередь, удобно использовать и для SVG документов. Нам может быть неудобно применять определенный стиль для всех прямоугольников, но только для некоторых, которые принадлежат определенному классу. В частности, в SVG существует тег <g>, который очень напоминает тег <div> HTML и который служит для группировки других графических элементов. Так же и как тег <div>, тег <g> особенно полезен с точки зрения возможности привязки к определенному классу, так как обычно бессмысленно привязывать один стиль ко всем группам, определенным в SVG файле.

В дополнение к этому, каждый элемент в SVG документе или на странице HTML может быть идентифицирован атрибутом id. CSS позволяет выбирать уникальный элемент используя нотацию #identifier и применять стиль только к такому элементу. Селекторы CSS могут также комбинироваться для того, чтобы достичь определенных элементов дерева SVG или HTML. Последнее особенно удобно для нашей архитектуры компонентов SVG.

2.2 CSS и элемент <use>

Тег <use> позволяет ссылаться на компоненты SVG описанные в этом же или другом файле. Этот тег является базой для нашей компонентной архитектуры. Однако, совместное использование тега <use> и таблиц стилей CSS имеет два препятствия:

  1. Тег <use> скрывает структуру дерева компонента SVG.
  2. Компонент, описанный в другом SVG файле может использовать таблицу стилей, ассоциированную только с этим документом.

В первом случае получается, что селекторы CSS не могут обращаться к внутренней структуре компонента, что снижает удобство применения стилей для элементов <use> до самых простейших. Например, мы можем назначить стиль элемента <use> используя атрибут class. Но этот стиль будет назначен для всех подкомпонентов внутри компонента, на который ссылается тег <use>. Таким образом, получается невозможным выбрать подкомпонент и назначить ему один цвет, в тоже время как другому подкомпоненту назначить другой цвет. Во втором случае, проблемы вытекают из того факта, что внешняя таблица стилей неизвеста текущему документу - он импортирует SVG документ, а не таблицу стилей. На рис. 1 видно, как цвет обозначения двигателя может быть изменен применением определенного атрибута class для элемента <use>.


Рис. 1. Обозначение двигателя в различных состояниях

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet href="simplestyle.css" type="text/css"?>

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">

  <defs>
    <symbol id="motor" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet" stroke-width="2">
      <circle cx="50" cy="50" r="30"/>
      <path d="M 40 60 L 40 40 L 50 50 L 60 40 L 60 60"/>
    </symbol>
  </defs>
  <g>
    <use xlink:href="#motor" class="on" x="10" y="10" height="80" width="80"/>
    <use xlink:href="#motor" class="off" x="110" y="10" height="80" width="80"/>
    <use xlink:href="#motor" class="alarm" x="10" y="110" height="80" width="80"/>
    <use xlink:href="#motor" class="repair" x="110" y="110" height="80" width="80"/>
  </g>
</svg>

.on
{
  stroke: black;
  fill: lime;
}

.off
{
  stroke: black;
  fill: lightgrey;
}

.alarm
{
  stroke: black;
  fill: red;
}

.repair
{
  stroke: black;
  fill: deepskyblue;
}

Выше, при обозначении двигателя в различных состояниях мы обозначили состояние неисправности красным кругом, однако в табл. 1 было показано, что обычная схема обозначения двигателя в состоянии неисправности - красный прямоугольник с серым кругом. Чтобы продемонстрировать это мы расширим код представляющий обозначение двигателя и разделим его на 2 подкомпонента - задний и передний фон с помощью атрибута class.

На этом примере можно показать как тег <use> скрывает дерево SVG документа предотвращая возможность использования CSS селекторов для подкомпонентов. Чтобы доказать это, сделаем копию обозначения двигателя используя тег <g> в отображаемой секции документа SVG. В противоположность изображению, полученному с использованием элемента <use>, дерево этой копии доступно для применения стилей CSS.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet href="motorstyle.css" type="text/css"?>

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="240" height="120">

  <defs>
    <symbol id="motor" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet" stroke-width="2">
      <g class="background">
        <rect x="0" y="0" width="100" height="100"/>
      </g>
      <g class="foreground">
        <circle cx="50" cy="50" r="30"/>
        <path d="M 40 60 L 40 40 L 50 50 L 60 40 L 60 60"/>
      </g>
    </symbol>
  </defs>
  <g>
    <!-- Копия обозначения двигателя -->
    <g id="motor1" transform="translate(10,10)" stroke-width="2" class="alarm">
      <g class="background">
        <rect x="0" y="0" width="100" height="100"/>
      </g>
      <g class="foreground">
        <circle cx="50" cy="50" r="30"/>
        <path d="M 40 60 L 40 40 L 50 50 L 60 40 L 60 60"/>
      </g>
    </g>
    <!-- Использование тега <use> скрывает подкомпоненты -->
    <use xlink:href="#motor" class="alarm" x="130" y="10" height="100" width="100"/>
  </g>
</svg>

Ниже приведен код CSS, который применяется для отображения этого SVG документа. Эта таблица стилей заполняет красным цветом все элементы класса alarm, в тоже время, заполняя серым цветом те элементы, которые одновременно принадлежат и классу alarm и классу foreground.

.alarm
{
  stroke: black;
  fill: red;
}

.alarm .foreground
{
  stroke: black;
  fill: lightgrey;
}

Результат представлен на рис. 2. Слева представлено изображение копии обозначения двигателя. В данном случае селекторы CSS определили группу элементов класса foreground, которые также наследуют класс alarm от родительского элемента и, следуя правилам описанным в motorstyle.css, окрасили круг в серый цвет, а прямоугольник в красный цвет. С правой стороны результат отображения элемента <use>. Как видно, все окрашено в красный цвет в соответствии с классом alarm, так как подкомпонент foreground скрыт от таблицы стилей. Отсюда можно сделать вывод, что подкомпоненты SVG документов невидны для тиблиц стилей CSS.


Рис. 2. Результат сокрытия подкомпонентов от таблицы стилей.

3. Выводы

Тот факт, что таблицы стилей применяются для всего документа, а не для отдельных компонентов и то, что полное дерево SVG компонента скрыто во время его использования внутри другого SVG файла ограничивает возможности совместного применения SVG и CSS. Однако, разрабатываемая в данный момент версия SVG 1.2 позволит избежать подобного рода проблем со стилями благодаря тому, что всю работу по внешнему виду документов SVG возьмут на себя XSLT (XSL Transformations) преобразования. Таблицы стилей XSL (Extensible Stylesheet Language) будут определять, каким образом трансформировать оригинальный SVG документ в изображение.

4. Литература

  1. Cтандарт SVG 1.1
  2. Стандарт SVG 1.2
  3. Adobe SVG Viewer

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