SoftCraft
разноликое программирование

Top.Mail.Ru

Автоматное объектно-ориентированное проектирование


© 2002 г. Б. П. Кузнецов

Можно скачать текст статьи в формате html (38 кб)

Для управления техническими объектами в настоящее время создаются распределенные многоуровневые управляющие вычислительные системы. В простейшем случае верхний уровень представлен операторской станцией (СО), а нижний – станциями локальными технологическими (СЛТ). При этом все станции связаны либо общей магистралью, либо радиальными связями.

Программное обеспечение (ПО) СО обеспечивает управление техническим объектом типовыми средствами: клавиатурой и трекболом, а также отображение информации о состоянии объекта управления и не штатных ситуациях. При этом формируются команды на включение-отключение механизмов управляемого объекта в результате соответствующих действий оператора, а также ряд служебных команд типа деблокирования и других. Далее ПО СО не рассматривается. Собственно логическое управление осуществляется в СЛТ как на основе анализа входной локальной информации, так и по командам, формируемым в СО. Локальная информация из СЛТ передается в СО для представления оператору. Нас больше будут интересовать алгоритмы СЛТ.

ПО СЛТ обеспечивает контроль состояния и собственно управление техническим объектом. ПО СЛТ для управления сложным объектом, в котором реализуются параллельно протекающие процессы, строится по классической схеме: ввод - обработка - вывод с последовательным циклическим опросом входов [1]. Алгоритмы и программы должны быть построены по иерархическому принципу с использованием программных классов согласно принципам структурного [2] и объектно - ориентированного [3] проектирования. Кроме того автор предлагает использовать конечные автоматы [3, 4] при разработке методов классов. Поэтому предлагаемый подход будем называть автоматным объектно-ориентированным проектированием.

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

Структура типового класса логического управления

Опыт автора по синтезу ПО СЛТ системы управления корабельными техническими средствами показал ряд положительных моментов, а именно:

  • Алгоритмы управления и контроля отдельными агрегатами оформлены в виде автономных классов,
  • Классы изолированы друг от друга в силу инкапсуляции и могут быть независимо спроектированы и отлажены,
  • Объекты классов реализуются строго последовательно, что существенно упрощает алгоритмизацию и программирование,
  • Объектно-ориентированные алгоритмы отвечают требованию независимости фрагментов [5],
  • В целом ПО CЛТ слабо связано с используемой операционной системой, и может быть сравнительно легко перенесено даже в простейшую среду MS DOS.

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

Определим типовой класс как десятку

T = {A, S, D, X, Y, U, V, K, M, Z}, где:

  • А – множество настроек объекта класса Т,
  • S – множество состояний автоматных алгоритмов, входящих в класс Т как методы,
  • D – множество закрытых данных - членов класса Т,
  • X – множество входных сигналов нижнего уровня, или множество контролируемых параметров агрегата,
  • Y – множество выходных сигналов нижнего уровня (управляющие агрегатом сигналы),
  • U – открытые входные данные – члены класса Т,
  • V – открытые выходные данные – члены класса Т,
  • К – множество команд с верхнего уровня, на которые должен реагировать объект класса Т,
  • М – множество сигналов, посылаемых объектом класса Т на верхний уровень
  • Z – множество открытых и закрытых методов класса Т.

Графическая структура класса изображена на рис. 1.

Множество Z = {z0, z1, … , zN} представляет собой набор открытых и закрытых методов (функций-членов класса Т). Методы могут быть переопределяемыми (виртуальными). Обязательными методами являются:

  • run – основной открытый метод (z0), в теле которого последовательно вызываются остальные N методов класса Т. Если Т – базовый класс, то метод run может быть либо виртуальным, либо избыточным (вызывающим пустые функции-члены).
  • get – закрытый метод (z1), который осуществляет вызов и запоминание входной информации (X) нижнего уровня, а также осуществляющий необходимые преобразования этой информации к виду, удобному для последующей обработки. Метод может быть виртуальным.
  • put – закрытый метод, осуществляющий вывод результатов обработки как на нижний уровень (Y), так и на верхний уровень (M). Метод может быть виртуальным.

Не обязательными, но наиболее часто используемыми являются закрытые, в том числе виртуальные, методы Zon и Zoff обработки команд (К) или условий автоматического включения - отключения (U) управляемого агрегата.

Кроме перечисленных, класс может содержать и другие закрытые методы (подмножество Zcl) и открытые методы (подмножество Zop).

Множество настроек А – перечень данных и функций, которые должны идентифицировать и инициализировать конкретные объекты класса Т. Данный перечень включается в качестве набора параметров в открытом методе, называемом конструктором класса и имеющем то же имя что и класс Т. В теле конструктора выполняется присваивание закрытым данным – членам класса значений параметров из множества А.

Множество состояний S = {s0, s1, … , sN} объекта класса Т состоит из перечня наименований состояний алгоритмов методов z0, … , zN. Таким образом, объект класса Т характеризуется вектором значений переменных состояния всех алгоритмов - методов класса. Переменные состояний должны иметь имена, начинающиеся с буквы s и далее имени метода. Например, sget, sput, szon и так далее. Переменные состояний принадлежат к закрытым данным – членам класса Т. Эти переменные недоступны другим алгоритмам вне объекта класса Т, но являются доступны всем методам данного класса. При необходимости иметь информацию о состоянии алгоритма того или иного метода класса необходимо предусмотреть специальный открытый метод, возвращающий при его вызове значение переменной состояния.

Множество D представляет собой набор закрытых данных – членов класса, используемых в функциях – членах класса. Эти данные запоминаются, модифицируются и сохраняются от цикла к циклу.

Множество U – это открытые данные – члены класса Т, доступные для модификации из других объектов других классов.

Множество V – это открытые данные – члены класса Т, доступные для чтения другими объектами других классов.

Множество К – это набор кодов команд, на которые должны реагировать конкретные объекты данного класса. Эти коды задаются и запоминаются конструктором класса. Код команды, получаемой из станции операторской обозначим "komanda". Закрытые переменные - конкретные коды команд начинаются с буквы К, например: Kon, Koff (включить и отключить, соответственно.

Множество М – сигналы, передаваемые в станцию операторскую. Эти сигналы могут быть двух типов. Первый тип сигналов предполагает передачу в станцию операторскую пары: номер сообщения и обобщенного кода состояния контролируемого агрегата. Номер сообщения задается одним из параметров настройки А. Обобщенный код формируется всеми методами класса и кодируется методом put. При этом сигналы первого типа передаются в станцию операторскую в произвольном порядке от различных объектов различных классов.

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

Множество Х представляет собой подмножество разрядов вектора всех входных двоичных сигналов, получаемых методом опроса в каждом программном цикле. Номера разрядов перечисляются в множестве А параметров настройки. (Для класса измерений или вычисления уставки множество Х есть либо дискретное значение аналогового параметра, либо множество последовательных отсчетов, например, синусоидального сигнала.)

Множество Y – это значения подмножества разрядов вектора всех выходных дискретных сигналов контроллера. Номера разрядов этого подмножества задаются в множестве А параметров настройки. Множество Y формируется методом put на основе результатов вычислений в остальных методах класса.

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

Классы контроля и управления агрегатами с триггерным выходом

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

Автором предложена линейка типовых классов для контроля и управления такими агрегатами, которую и рассмотрим ниже.

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

А = { im, numinon, numinoff, mig, kod, kodfault, kodnofault, tdreb } – множество настроек, где im – имя (номер) объекта, numinon – номер разряда "агрегат включен" вектора входов контроллера, numinoff – номер разряда "агрегат отключен" вектора входов контроллера, mig – признак мигания мнемознака агрегата на экране дисплея станции операторской при включении (отключении) агрегата без команды оператора, kod – код (номер) сообщения о состоянии агрегата (сигнал первого типа – см. выше поснения к множеству М), kodfault – код сообщения об отказе агрегата (или возможной потери кабельной связи контроллера с агрегатом), kodnofault – сообщение о восстановлении агрегата после отказа, tdreb – допустимая длительность дребезга выходных контактов агрегата.

Z = { run, get, Zst, Zout, put, Zfl } – множество методов класса, где run – головной открытый виртуальный метод, get – ввод и запоминание выходов агрегата, Zst – определение текущего состояния агрегата, Zout – формирование обобщенного состояния агрегата для передачи в станцию операторскую, put – вывод в буфер магистрального обмена обобщенного состояния агрегата, Zfl – вывод в буфер магистрального обмена сообщения об отказе агрегата. Все перечисленные методы будут детально рассмотрены ниже после представления всех множеств, образующих данный класс.

S = { Sst, Ssto } – множество переменных состояния алгоритмов методов, в данном случае представленным только переменной состояния (Sst) алгоритма метода Zst и его предыдущего значения (Ssto) , в силу того, что остальные методы этого класса представляются комбинационной логикой.

D = { dism, dkom, dtdreb, dmo } – множество закрытых членов – данных, где dism – признак изменения входных сигналов, dkom – признак поступления команды от оператора на включение – отключение агрегата, dtdreb – время начала переходного процесса для подавления дребезга контактов выходов агрегата, dmo – упакованное обобщенное состояние агрегата, отправленное в последний раз в магистраль.

Х = { xoff, xon } – множество переменных, обозначающих выходы отключен (xoff) и включен (xon) агрегата.

V = { voff, von, vfault } – множество открытых членов – данных, используемых в алгоритмах других классов, где voff – агрегат отключен, von – агрегат включен, vfault – агрегат неисправен.

К = { Kdebl, KALL } – множество команд, на которые должен реагировать объект класса TTrig, в частности – это единственная команда деблокирования (отмены) мигания значка агрегата в станции операторской, а также команда пересылки всех сообщений в станцию операторскую.

М = { kod, m, } – множество сигналов, передаваемых в станцию операторскую: вслед за кодом сообщения kod из множества А настроек передается упакованное обобщенное текущее состояние m агрегата: разряд 0 – отключен, разряд 1 – включен, разряд 2 – мигать на отключение, разряд 3 – мигать на включение.

Множества U и Y – пустые, то есть не используются в базовом классе.

Далее по тексту будут использованы интуитивно понятные конструкции языка С.

Перейдем к рассмотрению методов класса TTrig.

Конструктор рассматривать не будем, так как в нем осуществляется лишь запоминание настроечных параметров множества А и обнуление всех данных – членов множества D.

Метод run имеет следующую структуру, представляемую на алгоритмическом языке С:


run()      // единственный открытый (основной) метод
{  
   get();  // формирование множества Х (ввод данных агрегата)
   Zst(),  // вычисление текущего состояния Sst агрегата
   Zout(); // формирование сигнала m для передачи в магистраль
   put();  // вывод данных в буфер магистрали
   if(Sst != 7)   // проверяется: не наблюдается  ли переходный
                  // процесс в поведении агрегата
      Ssto = Sst; // запоминание текущего состояния алгоритма Zst
}

Как следует из этого текста, метод run осуществляет последовательный вызов на исполнение остальных методов класса в указанном порядке, в конце программы запоминается текущее состояние Sst алгоритма Zst, если не наблюдается переходный процесс в поведении агрегата (Sst не равно 7 – см. ниже).

Метод get имеет следующую структуру:


get() // ввод данных с выхода агрегата
{ 
  int p0, p1; // объявление временных переменных
  p0 = inkont(numinoff); // ввод сигнала «отключен»
  p1 = inkont(numinon);  // ввод сигнала «включен»
  dism = (p0 != xoff || p1 != xon); // признак изменения 
                                    // выхода агрегата
  xoff = p0; // запоминание сигнала "отключен" агрегата
  xon = p1;  // запоминание сигнала "включен" агрегата
} 

Здесь inkont – внешняя по отношению к классу функция выделения значения заданного параметром разряда во входном векторе. Признак dism принимает значение единица при несовпадении одного из запомненных сигналов отключено xoff или включено xon со вновь введенным значением p0 или p1 соответственно, и ноль – в случае совпадения указанных соответствующих сигналов. Знаком "||" обозначена операция ИЛИ, знаком "!=" – неравенство.

Рассмотрим метод Zst определения обобщенного состояния агрегата. Автоматный алгоритм данного метода представлен на рис. 2.

Состояния Sst данного автомата имеют следующую физическую трактовку:

0 – исходное состояние, устанавливаемое конструктором объекта класса TTrig при включении контроллера.

1 – агрегат находится в отключенном состоянии, мигания мнемознака на экране станции операторской нет.

2 – агрегат находится во включенном состоянии, мигания мнемознака на экране нет.

3 – отказ блок-контактов агрегата вида 00 (оба выхода агрегата показывают ноль, что свидетельствует о неопределенности в определении истинного состояния агрегата)

4 – отказ блок-контактов агрегата вида 11 (оба выхода агрегата показывают единицу, что свидетельствует о неопределенности в определении истинного состояния агрегата)

5 – отключенное состояние агрегата с миганием мнемознака на экране.

6 – включенное состояние агрегата с миганием мнемознака на экране.

7 – переходное состояние алгоритма при переключении из одного состояния агрегата в другое.

Пунктиром обозначено обобщенное состояние алгоритма, включающее любое из состояний 1 – 6.

Перечислим переходы, условия выполнения которых (события) обозначены на рис. 2. идентификаторами, начинающимися с буквы b:

Переходы из начального состояния:

b1 = xoff && !xon – агрегат отключен
b2 = !xoff && xon – агрегат включен
b3 = !xoff && !xon – агрегат неисправен
b4 = xoff && xon – агрегат неисправенъ

Переход из любого из состояний 1 – 6 в состояние 7 осуществляется при единичном значении признака dism. При этом выполняется подпрограмма t1

dtdreb = clock() ,

то есть, запоминается текущее время в переменной dtdreb.

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

b0 = ( clock() >= dtdreb + tdreb ).
b11 = b0 && b1 && (dkom || !mig).
(была команда на отключение или запрещено мигание)
b21 = b0 && b2 && (dkom || !mig).
(была команда на включение или запрещено мигание)
b31 = b0 && b3.
b41 = b0 && b4.
b5 = b0 && b1 && !dkom && mig.
(агрегат отключился без команды и разрешено мигание)
b6 = b0 && b2 && !dkom && mig.
(агрегат включился без команды и разрешено мигание)

На этих переходах возможны два действия:

c1: if (vfault) Zfl(kodnofault) – отсылка сообщения о восстановлении рабочего состояния агрегата после отказа.

c2: Zfl(kodfault) – отсылка сообщения об отказе агрегата.

Переходы из состояний, в которых на экране осуществляется мигание:

b51 = b62 = (komanda == Kdebl) – поступила команда деблокировки (сброса мигания).

Дополним алгоритм (рис.2.) следующим пояснением. Состояния 1 – 6 являются основными состояниями агрегата, отображаемые на экране станции операторской. В состояние 7 алгоритм переходит при всяком изменении выходных сигналов агрегата и пребывает в нем до истечении временного интервала tdreb, необходимого для пропуска случайных сочетаний сигналов, вызванных возможным появлением "дребезжания" контактов реле (блок-контактов агрегата).

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

TTrig::Zout()
{ 
  if(Sst != 7 || Ssto < 0)
   { // общедоступные выходные члены класса для других 
      // программ, работающих в этом же контроллере
      voff = xoff && !xon; // voff - отключен
      von = !xoff && xon; // von  - включен
          vfault = !voff && !von;  // vfault - неисправен
      // кодированное обобщенное состояние m агрегата 
      // для передачи в магистраль
      m = 0;
          if(xoff) 
          m |= 1;      // off – 0-й разряд
           if(xon) 
          m |= 2;      // on – 1-й разряд
           if(mig)            // разрешено мигание
           { if(Sst == 5) 
             m |= 4; // off – мигание 2-й разряд
              else if(Sst == 6) 
              m |= 8; // on – мигание 3-й разряд
        }  
    }
} // TTrig::Zout .-------------------------------------------------

В заключение описания данного базового класса представим системно независимый метод put вывода данных в магистраль, где outbuf – системно зависимая функция записи данных в буферный массив, передаваемый непосредственно в магистраль:

TTrig::put()
{ if(Sst != 7 && Sst != Ssto || komanda == KALL)
    outbuf(kod,m);
} 

Класс TTrig0

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

T = {A, S, D, X, Y, U, V, K, M, Z}

Множество А настроек дополняем следующими элементами: Koff - код команды на отключение, numoutoff - номер разряда выхода отключения в выходном векторе контроллера, toff – максимальная длительность выходного импульса отключения, count_off - максимальное число несрабатывания отключения. Множество Z методов класса дополняется методом Zoff – управления отключением. Множество S обозначения состояний алгоритмов методов класса дополняется обозначением состояния Soff алгоритма добавленного метода класса. Множество закрытых членов – данных дополняется двумя элементами: dtoff – момент времени формирования переднего фронта импульса отключения агрегата, dcount_off – счетчик попыток отключения агрегата. Множество Y образуется из единственного элемента yoff – значение сигнала управления отключением. Множество U также включает единственный элемент uoff – значение сигнала автоматического (без команды от оператора) программного отключения агрегата, формируемого другими алгоритмами того же контроллера. Множество К дополняется командой Koff (см. дополнение множества А). Множество М дополняется кодом сообщения о невыполнения коммутационной операции (отключения или включения) с заданным числом попыток – nocount.

Представим автоматный алгоритм, реализующий метод Zoff (рис. 3).

Граф переходов такого автомата включает 5 состояний:

0 – исходное состояние (агрегат не находится в процессе отключения),

1 – формирование переднего фронта импульса отключеия агрегата,

2 – проверка результата отключения и формирование заднего фронта импульса отключения агрегата,

3 – завершение процесса отключения агрегата

10 – режим ожидания процесса включения агрегата (данное состояние присуще следующему дочернему классу TTrig1, но мы его рассматриваем, чтобы в дальнейшем не повторяться).

Перечислим переходы автомата, в том числе события (условия переходов), обозначаемые b и действия на переходе, обозначаемые с:

b0 = !voff && komanda == Koff && Son – поступила команда на отключеие агрегата, для которого не завершился процесс включения и выполняется переход в состояние 10.

b1 = !voff && komanda == Koff && !Son – поступила команда на отключение агрегата и выполняется с1 группа следующих действий:

с1:  1) dkom = 1 -  установить признак поступившей команды 
     2) dcount_off = 0 - подготовить счетчик попыток отключения
     3) if(mig) 
           m |= 4; // off – признак мигания отключения

b2 = !voff && uoff && !Son – поступил сигнал автоматического отключения агрегата из других алгоритмов, реализуемых данным контроллером, например, отключение автоматического выключателя ЭЭУ при появлении сигнала короткого замыкания, и реализация группы с2 следующих действий:

с2:  1) dkom = 0 -  сбросить признак поступившей команды 
     2) dcount_off = 0 - подготовить счетчик попыток отключения
     3) if(mig) 
           m |= 4; // off – признак мигания отключения

b5 = (komanda == Kdebl) – поступила команда отмены отключения.

b6 = !b5 – нет команды отмены отключения, при этом реализуются действия с4.

с4: 1) dtoff = clock();  // запомнить текущее время 
                         //(переднего фронта импульса отключения)
    2) yoff = 1; // выходной сигнал отключения установить в единицу
    3) outkont(numoutoff,yoff); // Вывод единицы на выход отключения 
               // посредством подпрограммы общего назначения outkont.
    4) dcount_off++;   // приращение счетчика попыток отключения.

b8 = voff || (komanda == Kdebl) – агрегат отключился либо поступила команда отмены отключения, при этом реализуется группа действий с6.

с6:  1) yoff = 0;
     2) outkont(numoutoff,yoff); // сброс единицы на выходе отключения

b7 = (clock() >= (dtoff + toff)) && (dcount_off < count_off) - импульс закончился и выполнено меньше заданного числа попыток отключения агрегата, при этом реализуются действия с6.

b9 = (clock() >= (dtoff + toff)) && (dcount_off >= count_off) импульс закончился и выполнено заданное число попыток отключения агрегата, при этом реализуются действия с7.

с7: 1) выполняются действия с6.
    2) Zfl(nocount) – сообщение о неотключении с заданного числа попыток.

b3 = (komanda == Kdebl) – отмена отключения

b4 = !Son – процесс включения не активен (см. ниже), при этом реализуются действия с1.

Перечисленные состояния и переходы полностью описывают поведение объекта класса TTrig0 при отключении агрегата. Изменяется и метод run, в теле которого между вызовом методов Zout и put вставляется вызов рассмотренного метода Zoff.

Класс TTrig1

Следующим наследуемым классом разработаем класс TTrig1, наследуемый из класса TTrig0. Задачей нового класса является не только регистрация состояния агрегата и управление его отключением, но и автоматическое и по команде оператора включение. Рассмотрим дополнение множеств десятки (8.1) для этого класса.

T = {A, S, D, X, Y, U, V, K, M, Z}

Множество А настроек дополняем следующими элементами: Kon - код команды на отключение, numouton - номер разряда выхода включения в выходном векторе контроллера, ton – максимальная длительность выходного импульса включения, Tpermit – максимальное время ожидания работы внешней функции Z8 разрешения включения агрегата в зависимости от состояния других агрегатов, count_on - максимальное число несрабатывания включения. Множество Z методов класса дополняется методом Zon – управления включением. Множество S обозначения состояний алгоритмов методов класса дополняется обозначением состояния Son алгоритма добавленного метода класса. Множество закрытых членов – данных дополняется двумя элементами: dton – момент времени формирования переднего фронта импульса включения агрегата, dcount_on – счетчик попыток включения агрегата. Множество Y дополняется элементом yon – значение сигнала управления включением. Множество U также дополняется элементом uon – значение сигнала автоматического (без команды от оператора) программного включения агрегата, формируемого другими алгоритмами того же контроллера. Множество К дополняется командой Kon (см. дополнение множества А). Множество М дополняется сообщениями Exclusion – сообщение о запрете включения, NTPermit – сообщение об окончании времени на ожидание разрешения включения.

Представим автоматный алгоритм, реализующий метод Zon (рис. 4).

Граф переходов такого автомата включает 5 состояний:

0 – исходное состояние (агрегат не находится в процессе включения),

1 – формирование переднего фронта импульса включеия агрегата,

2 – проверка результата включения и формирование заднего фронта импульса включения агрегата,

3 – завершение процесса включения агрегата

4 – ожидание разрешения на включение агрегата

40 – режим ожидания процесса отключения агрегата.

Перечислим переходы автомата, в том числе события (условия переходов), обозначаемые b и действия на переходе, обозначаемые с.

Переходы из состояния 0:


  b0: (!von && s6 != 0 && komanda == Kon) 
     – агрегат не включен, не завершен процесс отключения 
       и поступила команда на включение.
  b1/c1: (!von && !s6 && komanda == Kon) 
     - команда включить при завершенном процессе отключения. 
       При этом реализуется действие с1.
  с1: 1) dkom = 1; установить признак поступившей команды.
      2) dcount_on = 0;  подготовить счетчик числа попыток включений.
      3) if(mig) m |= 8; признак мигания включенного положения агрегата
      4) dton = clock(); запомнить текущее время.
  b2: (uon && !s6) - есть условие автоматического включения. 
                     Выполняются действия с2.
  с2: 1) dkom = 0; сброс признака поступления команды.
      2) dcount_on = 0; подготовить счетчик числа попыток включения.
      3) if(mig) m |= 8; признак мигания включенного положения агрегата
      4) dton = clock(); запомнить текущее время.

Переходы из состояния 40:


  b3: (komanda == Kdebl || komanda == Koff || s6 == 10) 
      - отмена команды включения или взаимная 
        блокировка включения и отключения.
  b4/c1:(!s6) 
      - процесс отключения не активен. 
        Реализуются действия с1 (см. выше).

В состоянии 4 реализуется действие с8:


permit = Z8(); запоминание в промежуточной переменной 
   значения функции Z8 разрешения включения: 
   0 – разрешение включения еще не сформировано, 
   1 – разрешено включение, 
   2 – запрет включения. 

Переходы из состояния 4:


группой B12/C5 обозначены сразу три перехода: b12_1, b12_2 и b12_3, 
а также соответствующие им действия: с9_1б с9_2 и c9_3.
b12_1: (von || komanda == Kdebl) 
   – агрегат включился или отмена команды включения. 
     Выполняется действие с9_1:
с9_1: 1) yon = 0; Сброс единицы на выходе включения
      2) outkont(numouton,yon); вывод выходного сигнала.
b12_2: (permit == 2) - запрет включения автомата. 
                       Выполняется действие с9_2
с9_2: Zfl(Exclusion); сообщение о запрете включения в магистраль.
b12_3: (!permit && (clock() > (dton + Tpermit)) ) 
   -  истекло время ожидания разрешения включения агрегата. 
      Выполняется следующее действие:
      с9_3: Zfl(NTPermit);  сообщение: истекло время 
      ожидания разрешения включения.
b10: (permit == 1) -  разрешено включение.

Переходы из состояния 1:


b5: (komanda == Kdebl) // отмена команды включения
В случае невыполнения этого условия (~b5) 
выполняется переход в состояние 2 
и реализуется действие c4
с4: 1) dton = clock();    // запомнить текущее время
    2) yon = 1; - установить выход включения агрегата.             
    3) outkont(numouton,yon); Вывод единицы на выход включения
    4) dcount_on++; приращение счетчика попыток включения.

Переходы из состояния 2:


 b8: (von || komanda == Kdebl) 
    - агрегат включился или отмена команды включения. 
    Выполняется действие с6.
    c6: 1) yon = 0; сброс выхода включения.
        2) outkont(numouton,yon); Вывод выходного сигнала.
 b7: (clock() >= (dton + ton)) && (dcount_on < count_on) 
     – завершился импульс включения и есть еще попытки 
       включения агрегата. Выполняется действие с5: 
    dton = clock();   запомнить текущее время
 b9 = (clock() >= (dton + ton)) && (dcount_on >= count_on) 
    – завершились попытки включения. Выполняется действие c7.    
    c7: 1) Zfl(nocount);  
               сообщение: агрегат не включился с 10 попыток.
        2) yon = 0; сброс выхода включения.
        3) outkont(numouton,yon); Вывод выходного сигнала.
 Безусловный переход из состояния 3 
 сопровождается выполнением действия с10.
    c10: 1) dkom = 0; сброс признака поступившей команды
         2) uon = 0;  сброс признака автоматического включения. 

Данный закрытый метод класса вызывается после Zoff.

Таким образом, предложенный класс TTrig1 обеспечивает как традиционные функции контроля состояния агрегата и управления им, так и новые функции:

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

Рассмотрим использование этого класса для объектов типа автоматического выключателя. Назовем один из таких объектов QG1 – генераторный автоматический выключатель первого дизель-генератора электростанции. В программе контроллера нижнего уровня объект инициализируется конструктором, в котором перечислены настроечные параметры из множества А. Управление включением-отключением выполняется как по команде оператора командами KQG1on, KQG1off, так и автоматически путем присваивания открытым данным членам: QG1.uon = 1 (QG1.uoff = 1). Состояние автоматического выключателя в программе контроллера проверяется путем опроса открытых членов данных: QG1.von, QG1.voff, QG1.vfault. При этом в каждом программном глобальном цикле реализуется вызов открытого метода QG1.run(). Программа разрешения включения Permit вызывается из закрытого метода Z8 и является общей для всех объектов типа автоматический выключатель.

Подобным же образом автором разработан типовой набор классов в обеспечение решения задач логического управления и контроля параметров. В частности это такие классы как: формирование импульса на включение (отключения) агрегата, вычисление значения аналогового параметра (с исключением возможных помех), контроль уставок. Представленные классы пригодны для использования в ПО логического управления самыми разнообразными техническими средствами.

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

ЛИТЕРАТУРА

  1. Шакиров С., Биюсов Р., Якубович Б. и др. ULTRALOGIC – система подготовки программ для промышленных контроллеров // Современные технологии автоматизации. – 1997. № 3. С. 96 – 102.

  2. Йодан Э. Структурное проектирование и конструирование программ. - М.:Мир. 1979. - 416 с.

  3. Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на С++. – М.: «Бином», СПб.: «Невский диалект». 1998. – 560 с.

  4. Шалыто А.А. SWITCH-технология. Алгоритмизация и программирование задач логического управления. СПб.:Наука. 1998. - 628 с.

  5. Кузнецов Б.П. Структура и сложность модулей циклических программ // Автоматика и телемеханика, 1999, № 2, с.151-165.