Pull to refresh

Как мы новую производственную линию запускали

Reading time19 min
Views3.6K

Привет, Хабр! Мы инженеры‑программисты SCADA‑системы фармацевтической компании BIOCAD. В этой статье хотели бы рассказать о том, как мы запускали новую производственную линию на биотехнологическом заводе, с чем при этом столкнулись и как решали возникающие проблемы с точки зрения управления со стороны SCADA‑системы. Нюансов было достаточно много, и, возможно, способы решения возникавших у нас задач понадобятся и вам.

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

Как у нас все устроено

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

Гибким, достаточно удобным и модульным инструментом для автоматизации наших процессов было решено выбрать SCADA-систему OpenSCADA. Мы разбили нашу систему на функциональные блоки для сбора данных, визуализации и рецептурного управления. В терминологии OpenSCADA эти блоки называются станциями. Таким образом, у нас сформировалась структура (связка станций), как на Рисунке 1.

Рисунок 1 - Структура проекта
Рисунок 1 - Структура проекта

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

Вы можете заметить, что в блоке сбора данных находится не одна станция сбора. Это требует пояснения. Любой технологический процесс строится на поэтапном преобразовании/трансформации сырья и его приближении к виду конечного продукта. Более подробно о внутренних процессах и этапах в производстве можно почитать здесь. Мы с нашим производством препаратов тут не исключение. Прежде чем лекарство можно будет считать таковым, оно проходит кучу стадий, которые  могут сильно различаться. Как раз за какую-то одну или несколько стадий у нас отвечает одна установка (одна единица оборудования). Данные с этого оборудования требуется собирать, поэтому на схеме и в общей структуре нашего проекта это трансформировалось в отдельную станцию сбора данных, которая отвечает за сбор данных именно с этой установки. Совокупность требуемых установок формируется в линию производства препарата. На нашем производстве в среднем на одну линию приходится около 30–40 установок, а это значит, что ежесекундно генерируется огромное количество данных, которое необходимо хранить, обрабатывать и отображать пользователю в удобном для него виде.

Станции сами по себе являются отдельными программными единицами, которые могут взаимодействовать друг с другом по сети при помощи собственного протокола OpenSCADA и могут быть развернуты на разных виртуальных машинах. Разбиение системы на отдельные станции позволяет использовать модульность SCADA, что хорошо сказывается на надежности системы в целом.

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

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

С точки зрения блока сбора данных и визуализации все достаточно тривиально. Эти два блока, можно сказать, реализуют функционал классической SCADA-системы в полном объеме. «Ну а как же блок рецептурного управления?» — спросите вы. О нем и поговорим далее.

Рецепты

Само по себе понятие рецептурного управления не ново. Достаточно подробно оно описано в стандарте ГОСТ P МЭК 61512-2016.  И даже в самой SCADA-системе реализована возможность рецептурного управления. Для того чтобы не изобретать велосипед, мы взяли ее за основу и переписали под нужды производства.

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

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

Возникает резонный вопрос: а как же сделать так, чтобы рецепты можно было писать и корректировать быстрее, не привлекая дополнительный персонал? Решение данной проблемы на первый взгляд неочевидно, но со временем в голову приходит достаточно простой ответ: дать возможность технологам самим конструировать рецепт.

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

Рисунок 2 - Структура инструмента
Рисунок 2 - Структура инструмента

 

Каждый шаг в рецепте создан для каких-то действий, необходимых в технологичеcком процессе. Каждое такое действие требует каких-то данных для работы. Например, в рецепте требуется выждать некоторое время. Должен быть шаг, который сможет обеспечить это действие, а также нужно понимать, какое время необходимо выждать. Как раз для этого и используются входные данные для шага.

Из Рисунка 2 можно понять, что входными данными для шагов является совокупность аргументов. Каждому шагу, в зависимости от того, для чего он предназначен, будет соответствовать ровно столько аргументов, сколько он потребует для своей работы. В приведенном примере аргументом может служить необходимое количество секунд для выжидания (один аргумент).

Для большей наглядности на Рисунке 3 отображена часть пользовательского интерфейса, работающего с шагом для управления насосом установки.

Рисунок 3 - Шаг для управления насосом
Рисунок 3 - Шаг для управления насосом

Как видно из рисунка, шаг для работы требует ввода информации о конкретном насосе (pump1), режиме его работы (Manual), действии в выбранном режиме (Start), установки насоса (20 мл/мин), направления вращения (Forward), сброса накопленного расхода (False). Итого для работы шагу необходимо задать 6 аргументов. После выполнения данного шага выбранный насос начнет вращаться в заданном направлении, обеспечивая заданный расход.

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

Шаги в рецепте выполняются один за другим, и для реализации этого функционала необходимо было написать движок. Он уже реализован в OpenSCADA, и нам оставалось только разобраться, как он работает, и «перепилить» для своих нужд.

На Рисунке 4 более подробно отображена структура (в ключе модулей OpenSCADA), позволяющая реализовать рецептурное управление. Некоторые блоки соединены пунктирной линией. Это значит, что имеется класс, а на его основе создаются объекты. Также на рисунке отображено создание объектов шагов и объектов движков.

Рисунок 4 - Структура движка в модулях OpenSCADA
Рисунок 4 - Структура движка в модулях OpenSCADA

Для реализации шагов в OpenSCADA используется модуль LogicLev. Для этого описывается класс с необходимыми атрибутами объекта шага (аргументы) и методы для этого объекта (run, pause, abort). Методы позволяют запускать объект шага (run), приостанавливать выполнение с сохранением контекста (pause) и экстренно прерывать работу шага (abort). Каждый объект имеет свое имя, соответствующее имени шага из рецепта, для того чтобы потом можно было идентифицировать его при выполнении шага рецепта. Примерно так же реализовывается и движок, но он работает в модуле JavaLikeCalc.

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

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

Хорошо, теперь программисты нужны только для написания новых классов для шагов в рецепте, и технологи занимаются конструированием рецептов сами. На первых этапах использования рецептурного управления рецепты были небольшими, однако со временем персонал освоился, а количество шагов в рецепте начало кратно расти. Где-то на отметке 200–300 шагов для человека становится тяжело идентифицировать и перепроверять каждый из шагов, что стало проблемой, так как участились случаи ошибок при вводе аргументов. Очередной вопрос, который нам пришлось себе задать, звучит так: а как же сделать так, чтобы технологи делали меньше ошибок при написании рецептов?

Валидатор

Человеческий фактор полностью не исключить, но можно минимизировать элементарные ошибки. Так нам в голову пришла идея дополнить функционал написания рецептов анализатором, который позволил бы нам выявить наличие каких-то грубых ошибок, либо ошибок невнимательности, либо проблем «замыленности» глаза при написании рецептов. Этот функционал мы реализовали и назвали валидатором рецептов.

Около 60% всех ошибок составляют опечатки, неверно выбранные элементы из выпадающего списка и всякого рода логические ошибки. Если первые два типа ошибок достаточно тривиальны и проверяются обычным перебором всех аргументов шага (проверка наличия аргумента и валидности его значения), то третий тип ошибок не совсем очевиден.

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

Также логической ошибкой может служить наличие дополнительной зависимости шага от значения аргумента. Например, требуется получить какое-либо значение из базы данных. База данных может быть недоступна, или в базе может не быть требуемых значений для шага. Это всего лишь два примера логических ошибок. В работе с реальными рецептами их гораздо больше.

Количество логических ошибок полностью зависит от сложности логики, которую вы закладываете в функционал написания рецептов. Для избежания логических ошибок достаточно придерживаться одного очень простого правила «чем проще шаг, тем лучше». Человечество ничего умнее еще пока не придумало.

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

Кроме обычных механических и логических ошибок, существуют также и ошибки связи. Если во время выполнения рецепта произойдет обрыв связи, то ничего страшного случиться не должно. А почему? Да потому что в каждом шаге был заложен механизм проверки на валидность получаемых данных с ПЛК. Это важно!

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

Хорошо, мы можем писать правильные с точки зрения корректности аргументов и достаточно сложные с точки зрения логики рецепты для установок. Рецепты cредней сложности имеют около 500–600 шагов, что и для опытного технолога тяжело воспринять, даже если этот рецепт он сам и написал. Тут у нас возникает вопрос: как же нам упростить восприятие рецепта?

Плеер

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

Этот функционал помогает нашим работникам не только понимать, что делает тот или иной рецепт, но и, если рецепт написан им, быть уверенным, что результат будет именно таким, каким его закладывал творец рецепта.

Таким образом, был реализован удобный интерфейс, который помогает пользователю выбрать требуемый рецепт и, переходя в нем от шага к шагу, видеть результат выполнения каждого из них в SCADA без запуска оборудования, на котором этот рецепт должен будет запуститься. Иначе говоря, данный инструментарий отвечает на вопрос «А каким будет состояние оборудования, используемого в рецепте, если я запущу выбранный рецепт прямо сейчас и он выполнится до шага, который я указал?». С первого взгляда задачка кажется весьма сложной, но, используя возможности OpenSCADA, получилось решить ее достаточно просто.

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

Каждый реальный ИМ, установленный на оборудовании, имеет отображение в SCADA, притом данные, на основании которых идет отображение, запрашиваются из ПЛК по протоколу Modbus. В идеальных условиях, когда каждый из ИМ работает как нужно, их поведение предсказуемо. На основании этого и строится вся «психология» плеера рецептов. Иначе говоря, при определенном воздействии на ИМ он будет реагировать строго определенным образом, а это значит, что мы можем программно эмулировать работу каждого из ИМ в «идеальном» случае. Именно здесь и зарождаются данные для отображения в плеере рецептов. То есть фактически эмулируется работа станции сбора данных (из Рисунка 1).

Для того чтобы понять, как у нас работает плеер, давайте рассмотрим основные этапы выполнения алгоритма на Рисунке 5.

Рисунок 5 - Этапы выполнения алгоритма плеера
Рисунок 5 - Этапы выполнения алгоритма плеера

На первом этапе пользователь выбирает рецепт и шаг, до которого он хочет «проиграть» работу рецепта. Далее происходит анализ рецепта до выбранного шага и генерируется объект действий. Что это такое? Это объект, в котором хранится информация об ИМ и их состоянии, которое должно быть в результате выполнения рецепта до выбранного шага. По сути, на этапе анализа рецепта происходит трансформация информации из шага в конечное состояние ИМ, тем самым дает понимание, как тот или иной шаг воздействует на оборудование. Получив конечные состояния всех ИМ, мы можем применить их на эмуляционном сборе и корректно отобразить на мнемосхеме SCADA. Этим и занимается алгоритм на третьем и четвертом этапах.

У внимательного читателя может возникнуть резонный вопрос: а зачем нам нужна эмуляция оборудования, если мы уже на втором этапе знаем конечные состояния всех ИМ? Да, вопрос достаточно хороший, и он требует разъяснений. Дело в том, что на первых версиях плеера так и было. Вся информация о конечных состояниях ИМ хранилась и отображалась непосредственно в коде, что сильно усложняло его восприятие и утяжеляло работу визуальной части. Переложив информацию об ИМ на другой модуль (эмуляции сбора), удалось повысить быстродействие отображения и сделать код плеера более простым и читабельным.  В конкретном случае «модульность» сильно помогла с упрощением внутренних принципов работы инструмента.

Хорошо, мы можем писать корректный, логичный и, что самое главное, рабочий рецепт, который при запуске на реальном оборудовании будет работать так, как задумывалось (при отсутствии физических поломок ИМ и при наличии корректных показаний измерительных устройств). Фактически мы можем проверить правильность и корректность написания, но как же быть с повышением удобства написания, если со временем количество ИМ на единицу оборудования становится все больше и больше?

До сих пор мы рассматривали усложнение рецептов с точки зрения увеличения количества используемых шагов, однако эту проблему можно решить и на другом уровне. Далее рассмотрим способы облегчения работы на оборудовании, которое имеет достаточно большое количество ИМ, как с этим работать и как облегчить себе жизнь.

Формирование путей потока

Перед нами, программистами SCADA и технологами-рецептописцами, эта проблема встала тогда, когда на оборудовании новой производственной линии начало использоваться порядка 100–150 клапанов на установку (это много!). Прописывать в рецепте шаг под каждый клапан — дело неблагодарное. Особенно если тот или иной клапан в рецепте используется несколько раз. Мы, конечно же, можем проверить правильность работы рецепта даже с таким большим количеством клапанов при помощи плеера, но вывод, который сразу приходит на ум, — неудобно.

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

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

Рисунок 6 - Инструмент формирования путей потока
Рисунок 6 - Инструмент формирования путей потока

Обозначим задачу более конкретно. На рисунке 6 в правой части отображена конфигурация трубопровода из 5 клапанов. Нужно сформировать путь потока жидкости из точки 1 в точку 2. Очевидно, что необходимо закрыть 4-й и 5-й клапаны, а 1, 2 и 3-й открыть.

Задачей пользователя является группировка этих клапанов в какую-то сущность (путь потока), которая описывала бы конечное состояние каждого из клапанов. Для этого был реализован удобный пользовательский интерфейс, который позволяет выбрать конкретный клапан (id), его конечное состояние (открыто/закрыто) и временную задержку на выполнение действия (в секундах). Тут стоит отметить, что временная задержка на выполнение действия клапаном введена в силу физических ограничений любой пневмосистемы (после переключения нужно время на восстановление необходимого давления в системе). Таким образом, конечное состояние каждого клапана описывается объектом, а атрибутами объекта являются параметры, задаваемые пользователем (на рисунке 6 слева). Каждая совокупность таких объектов с требуемыми параметрами и требуемой последовательностью составляет путь потока, который будет иметь имя (псевдоним). На рисунке 6 это «Путь потока 1».

Формирования пути потока недостаточно. Нужно, чтобы функционал имел возможность физически переключать клапаны в требуемое состояние. Это реализовано нами на станции сбора посредством JavaScript-подобного языка. То есть после формирования пути потока он имеет возможность выполниться и переключить выбранные пользователем клапаны в требуемое состояние с заданными временными интервалами. В этой части осуществляется физическое воздействие непосредственно на саму установку с реальными клапанами.

Теперь, всего лишь раз сформировав такой путь, можно обращаться к нему по псевдониму, что сильно облегчает работу. В приведенном примере используется всего 5 клапанов. На деле же среднее количество клапанов доходит до 40–50, а это значит, что рецепт становится меньше на 40–50 шагов.

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

Теперь мы можем достаточно эффективно и с малым количеством ошибок управлять оборудованием, но как же быть с его отображением? Об этом поговорим далее.

Отображение путей потока

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

Сплетение трубопроводов и запорной арматуры в ней представилось нам как некоторый граф или дерево. Именно так мы и начали рассматривать возможность отображения путей потока. Каждый ИМ — это узел графа, а ребрами являются трубопроводы. На Рисунке 7 схематично отображен данный подход.

Рисунок 7 - Трансформация трубопроводов в граф
Рисунок 7 - Трансформация трубопроводов в граф

На Рисунке 7 слева схематично отображен участок трубопровода с шестью клапанами и одним насосом. Вместе, соединенные трубами, они могут организовать доставку жидкости из точки 1 в точку 2, 3, 4. Тот же самый участок трубопровода на рисунке 7 справа отображен как дерево, в котором каждый из ИМ — узел, а трубопроводы являются гранями. Стоит отметить, что пересечение нескольких труб тоже отображено в виде узла дерева, так как логика течения жидкости в нем иная. Так, в зависимости от того, какой клапан открыт и как работает насос (включен /выключен), можно смоделировать течение жидкости в трубах.

Кратко опишем работу каждого типа узлов. На Рисунке 7 (справа) имеется 3 типа узлов: К — клапан, Н — насос, П — пересечение труб. Узел типа К будет пропускать жидкость, если клапан открыт. Узел типа Н будет пропускать жидкость, если насос работает с ненулевой скоростью (имеется расход). Узел типа П будет пропускать жидкость тогда, когда хотя бы на одном из его выходов имеется возможность течения жидкости. Таким образом, обойдя данное дерево/граф любым алгоритмом обхода (DFS или BFS), можно вычислить путь потока жидкости. Мы рассмотрели первый способ.

Второй подход к решению немного отличается, так как для этого мы использовали возможности работы с сущностями самой OpenSCADA. На мнемосхеме для отображения ИМ используется сущность «виджет». Виджет может иметь некоторые атрибуты, которые мы можем задать. Так, для каждого из виджетов был задан свой набор атрибутов, характеризующих вход и выход элемента. Логика работы каждого виджета была прописана внутри нее посредством JavaScript-подобного языка и задавала зависимости входов от выходов, и наоборот. Кроме этого, в OpenSCADA есть возможность задания типа атрибутов (link), что позволяет связывать виджеты друг с другом непосредственно в среде разработки (на этом этапе формируются связи между виджетами). На Рисунке 8 отображен описываемый механизм.

Рисунок 8 - Реализация отображения путей потока силами OpenSCADA
Рисунок 8 - Реализация отображения путей потока силами OpenSCADA

Так, в каждом из виджетов прописывается логика его работы, а возможность передачи информации при помощи механизма связей атрибутов (links) позволяет передать состояние присутствия/отсутствия течения жидкости через каждый из виджетов (ИМ).

Если сравнивать данный подход с предыдущим, то узлом дерева является виджет, а гранью — взаимосвязи между виджетами (links). Обход такого дерева происходит естественным образом во время обсчета и отображения виджетов силами OpenSCADA.

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

Контроль переиспользования исполнительных механизмов

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

В разделе о валидаторе мы немного коснулись темы самого коварного типа ошибок — ошибок, связанных с тем, что разные рецепты могут конкурировать друг с другом за какой-то ИМ, который используется каждым из них. Действительно, пока выполняемых рецептов не так много, в общем и целом, можно понять, какой рецепт что делает и какими ИМ управляет. Но если таких рецептов становится больше и каждый из них может использовать ИМ каждой установки (механизм рецептов написан гибко, и такие случаи возможны), то возникает опасность переиспользования ИМ и приведения установки в неожидаемое состояние. На Рисунке 9 отображена суть проблемы.

Рисунок 9 - Проблема переиспользования ИМР
Рисунок 9 - Проблема переиспользования ИМР

Рассмотрим случай на рисунке. На установках 1 и 3 были запущены рецепты, которые так или иначе используют один и тот же клапан 2 установки 2. Пусть рецепт установки 1 требует закрытия клапана 2, а рецепт установки 3 — его открытия. В стандартном случае, если пользователь не заметил этого конфликта, то при одновременном запуске обоих рецептов для какого-то из них ИМ будет в неожидаемом состоянии, что может привести к тому, что технологический процесс не будет выдержан или в крайнем случае может привести к поломке оборудования. Этого мы допустить не можем. Поэтому мы задались очередным вопросом: как же сделать так, чтобы выполняемые рецепты не пересекались в использовании одних и тех же ИМ?

Ответ на этот вопрос мы нашли достаточно быстро. Было решено следить за используемыми ИМ всех рецептов из одной сущности. Идея тут в том, чтобы создать один централизованный список всех используемых на данный момент ИМ.

Теперь при запуске рецепта происходит последовательность следующих действий. Идет обращение к этому списку, по которому можно понять, возникнет ли переиспользование при запуске. Если переиспользования не возникает, то все ИМ, которые будут работать с данным рецептом, должны быть добавлены в список. Если же переиспользование угрожает, то не давать возможности запускать рецепт. После окончания рецепта все ИМ, использованные в рецепте, должны быть удалены из списка для возможности использования другими рецептами. «Как же должен выглядеть этот список?»  — спросите вы. Этот список мы реализовали в виде объекта.

На Рисунке 10 показана структура такого объекта.

 

Рисунок 10 - Объект всех используемых ИМ
Рисунок 10 - Объект всех используемых ИМ

Он представляет из себя XML-объект. Просто потому, что в OpenSCADA удобно с ним работать. Структура объекта очень простая. Корневой объект включает в себя дочерние объекты, теги которых соответствуют названиям установок, а те, в свою очередь, состоят из дочерних объектов с именами ИМ. Как только рецепт завершает свою работу, требуемые ИМ удаляются из объекта родителя.

Такой подход к контролю переиспользования ИМ является весьма ограничивающим, так как во время работы одного рецепта будут зарезервированы все ИМ, которые используются им, без возможности как-то изменить их состояние. Однако таким образом обеспечивается «бронирование» и фиксация состояния каждого ИМ, что позволит избежать неопределенного состояния системы из-за конфликта переиспользования. В некоторых случаях мы получали от пользователей обратную связь о том, что этот механизм сильно ограничивает их действия, поэтому мы дали возможность в случае необходимости отключать данный функционал. В таком случае контроль за корректной работой оборудования ложится на плечи пользователя.

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

Статью для вас готовил Азат Хайруллин, Старший инженер-программист АСУТП BIOCAD.

 

Больше о проектах BIOCAD в нашем блоге на Хабре:

Tags:
Hubs:
Total votes 2: ↑2 and ↓0+2
Comments0

Articles