Правительство Российской Федерации Федеральное государственное автономное образовательное учреждение высшего профессионального образования «Национальный исследовательский университет «Высшая школа экономики» Отделение программной инженерии Кафедра Управления разработкой программного обеспечения УТВЕРЖДАЮ Зав. кафедрой УРПО ______________/Авдошин С.М. / «____»__________ 2014 г. ВЫПУСКНАЯ КВАЛИФИКАЦИОННАЯ РАБОТА по направлению 231000.62 Программная инженерия подготовки бакалавра На тему: «Программа моделирования дискретно-событийных систем временными сетями Петри» Студента группы 472ПИ Куприянова Максима Сергеевича ____________ Научный руководитель К.т.н, профессор кафедры УРПО «____»__________ 2014 г. Авдошин Сергей Михайлович ____________ Москва, 2014 «____»__________ 2014 г. 2 АННОТАЦИЯ Математическое моделирование дискретно-событийных динамических систем является относительно молодым направлением науки теории управления. Однако, существует несколько математических аппаратов и подходов, которые не только хорошо зарекомендовали себя среди математиков-специалистов в данной области, но и имеют программную реализацию в виде расширений к популярным вычислительным средам и в виде отдельных программных систем. Такие методы пригодны для решения прикладных задач и их сфера применения весьма широка. Цель данной работы заключается в разработке независимого программного решения, ориентированного на применение методов идемпотентной алгебры (диоидной алгебры) и аппарата временных сетей Петри (временных графов синхронизации) к задаче моделирования дискретно-событийных систем. Ключевой особенностью разрабатываемого решения является наличие продвинутого графического интерфейса, призванного максимально упростить процесс создания модели для целевой системы. В нём же заключается и ключевое отличие от существующих решений. Кроме того, благодаря выбранному стеку технологий (строго типизированный язык Go-lang и инструментарий Qt Framework), данная программа является полностью кроссплатформенной, и, что немаловажно, её код был написан с использованием современных методов разработки прикладных программ, что позволит существенно упростить процесс последующих модификаций с целью расширения функционала программы сторонними разработчиками. Ранняя версия данного редактора сетей Петри была отмечена автором библиотеки интеграции go-qml и продемонстрирована в рамках конференции GopherCon (CO, Denver, 24-26 April 2014), как пример проекта, успешно использующего Go и QML для создания приложения с графическим пользовательским интерфейсом. Поскольку суть этой работы заключалась в создании полезной обёртки для сторонней библиотеки выполнения символьных вычислений в диоидной алгебре, область применения продукта совпадает с областью применения целевой библиотеки, то есть моделирование и анализ динамических асинхронных систем, изменение состояния которых происходит под воздействием событий, возникающих в дискретные промежутки времени. В современном мире примерами таких систем могут служить гибкие производственные системы, системы контроля многопоточные вычислительные среды и тому подобные. трафика, различные 3 Дальнейшее развитие работы возможно в двух направлениях — упрощение и улучшение кода, с целью повысить производительность графического вывода, а также в направлении добавления нового функционала, расширения набора поддерживаемых моделей и методов. 4 СОДЕРЖАНИЕ АННОТАЦИЯ ............................................................................................................. 2 ВВЕДЕНИЕ .................................................................................................................. 5 МЕТОДЫ И ИНСТРУМЕНТЫ МОДЕЛИРОВАНИЯ ................................ 7 1.1. ОБОСНОВАНИЕ ВЫБРАННОГО МЕТОДА ............................................................. 7 1.2. СЕТИ ПЕТРИ И КЛАССИФИКАЦИЯ...................................................................... 8 Временные сети Петри ........................................................................... 8 Временные графы синхронизации. .......................................................... 9 1.3. АЛГЕБРА ДИОИДОВ ............................................................................................ 9 1.4. ИНФОРМАЦИЯ О СОБЫТИЯХ ............................................................................ 10 1.5. СРАВНЕНИЕ АНАЛОГОВ ................................................................................... 13 1.6. ЗАКЛЮЧЕНИЕ .................................................................................................. 16 ТЕХНОЛОГИИ, АРХИТЕКТУРА, АЛГОРИТМЫ ПРОГРАММЫ ....... 17 2.1. СТЕК ТЕХНОЛОГИЙ .......................................................................................... 17 Qt Framework и QtQuick ......................................................................... 17 Go lang ..................................................................................................... 18 Go-qml ...................................................................................................... 18 2.2. АРХИТЕКТУРА И КОМПОНЕНТЫ ...................................................................... 19 Компоненты на стороне Go.................................................................. 20 Компоненты на стороне QtQuick/QML ............................................... 21 2.3. ГЕОМЕТРИЧЕСКИЕ АЛГОРИТМЫ ...................................................................... 22 ОСОБЕННОСТИ РЕАЛИЗАЦИИ ................................................................. 24 3.1. ПРИМЕР С TEGVIEW ......................................................................................... 24 3.2. ГРАФИЧЕСКИЙ ИНТЕРФЕЙС ПРОГРАММЫ ........................................................ 26 ЗАКЛЮЧЕНИЕ ................................................................................................. 27 СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ .................................... 28 ПРИЛОЖЕНИЕ А. Техническое задание ........................................................... 30 ПРИЛОЖЕНИЕ Б. Руководство оператора ........................................................ 47 ПРИЛОЖЕНИЕ В. Программа и методика испытаний ................................... 54 ПРИЛОЖЕНИЕ Г. Текст программы ................................................................. 63 5 ВВЕДЕНИЕ Математическое моделирование дискретно-событийных динамических систем является относительно молодым направлением науки теории управления. Разработка математического аппарата активно шла в 80-х годах, и хотя проблемой занимались как советские учёные[1, 2], так и французские [7–9], именно теория французов продолжила развитие и на данный момент является одним из базовых инструментов моделирования дискретно-событийных динамических систем (Discrete-Event Dynamic Systems, DES). Под дискретно-событийными системами подразумеваются динамические асинхронные системы, изменение состояния которых происходит под воздействием событий, возникающих в дискретные промежутки времени. В современном мире примерами таких систем могут служить гибкие производственные системы (Flexible Manufacturing Systems, FMS), системы контроля трафика, различные вычислительные среды и т.п. Событием называется начало или конец какой-либо активности, например, для FMS это начало или завершение работы над деталью, для многопоточной вычислительной среды это начало или завершение потока вычислительного процесса. Данная работа ориентирована, в первую очередь, на аналитический подход к моделированию дискретно-событийных систем, так как при таком подходе предоставляется возможность производить анализ статически, выполняя, например, символьные вычисления в линейной алгебре, без симуляции построенной модели и траты циклов процессора. Такой метод анализа является перспективным, согласно обзору[4] наиболее востребованных аналитических методик моделирования DES. Примеры вопросов, ответы на которые можно получить мгновенно при таком подходе: В данном временном промежутке, сколько раз произойдёт событие заданного типа? В какой момент времени событие заданного типа произойдёт в N-ный раз? При наличии информации о графике подачи ресурсов на вход заданной системы, вычислить информацию о графике получения готовой продукции на выходе заданной системы; Обратная задача: если установлено самое позднее допустимое время получения готовой продукции на выходе, рассчитать самое позднее возможное время подачи ресурсов на вход; 6 А также: если ресурсы на входе всегда доступны, рассчитать длительность производственного цикла и темп. Заодно вычисляется информация о критических путях (critical paths) и узких местах (bottlenecks) системы. Программное средство, разрабатываемое в данной работе, призвано объединить два метода моделирования DEDS — первый, классический, это сети Петри, а точнее их подкласс — временные сети Петри. Второй метод — специальной аппарат идемпотентной алгебры (алгебра диоидов)[14], с использованием которого нелинейная в обычной алгебре модель может быть представлена в линейном виде, к которому применимы классические методы линейной алгебры. Их дуализм будет рассмотрен нами позже, после описания каждого метода по-отдельности это станет очевидным. Основной акцент в программе и в данном документе сделан на двух главных составляющих инструмента — редакторе временных сетей Петри, позволяющем задать модель системы, а также редакторе входных данных, позволяющем задать информацию о событиях, возникающих на входах системы. Сами символьные вычисления в специальной алгебре выполняются при помощи сторонней библиотеки[10, 16], разработанной французами — авторами теории. Допускается рассматривать данное программное средство как оболочку, специалистов с данной библиотекой. призванную упростить взаимодействие 7 МЕТОДЫ И ИНСТРУМЕНТЫ МОДЕЛИРОВАНИЯ 1.1. Обоснование выбранного метода При дизайне системы согласно требованиям или при оптимизации существующей необходимо ввести модель, позволяющую не только представлять знания о свойствах и поведении системы, но и имеющую инструменты для предсказания производительности разрабатываемой системы. На данный момент существует множество техник моделирования и анализа дискретно-событийных динамических систем (DEDS), хорошую подборку известных методов можно найти в источниках работы-обзора [4]. Методы делятся на две категории — аналитические и имитационные, при выборе подходящего метода важно учитывать то, что чем точнее модель соответствует процессам, тем меньше свойств можно вычислить аналитически. На данный момент самой распространённой техникой является компьютерное моделирование (computer simulation), что относится к имитационному подходу и имеет существенные недостатки: во-первых, из требования повышенной точности модели вытекает трудоёмкость вычислений, во-вторых, мы не всегда можем понимать, как изменение параметров системы влияет на показатели вроде стабильности и производительности — производительности или например, достигли абсолютного? ли Поэтому мы локального активно максимума разрабатываются аналитические подходы, позволяющие использовать математические модели и алгебраические инструменты при решении задач моделирования, поскольку к таким моделям могут быть применены эффективные оценочные алгоритмы и могут быть установлены точные причины влияния параметров системы на её свойства. В самом же обзоре [4] рассмотрены самые эффективные методы из набора аналитических, в частности это аппарат сетей Петри, позволяющий, с одной стороны, графически смоделировать модель, более-менее адекватную процессу, а с другой, такой аппарат хорошо подходит для обработки алгоритмами в программах. Другой метод, использующий специальную идемпотентную алгебру max-plus, подразумевающую замену обычного сложения на операцию max(𝑎, 𝑏), а операцию произведения на обычный +, используется для особого класса дискретно-событийных систем, которые представляются нелинейно в обычной алгебре, но могут быть смоделированы линейно в алгебре max-plus. Последователем алгебры max-plus является другая диоидная алгебра, min-max, с историей которой можно ознакомиться по ссылке [9]. Далее в работе речь идти будет именно об этом варианте. 8 Учитывая степень проработанности теоретической базы, возможность применения подкласса сетей Петри для графического моделирования системы вместе с ней, а также существование программной реализации основных вычислительных алгоритмов, ориентирование программного продукта на использование в первую очередь именно с этими методами является целесообразным. 1.2. Сети Петри и классификация Сеть Петри это двудольный направленный граф с маркировкой, ребра которого задают причинно-следственные отношения «события-условия» и именуются дугами. Первый тип вершин — позиции — представляют условия, а второй тип вершин — переходы — представляют события. Динамика сетей задаётся при помощи маркировки позиций фишками. На рис. 1 и 2 представлен пример сети Петри, до и после срабатывания перехода. В классических сетях Петри при срабатывании перехода по всем входящим дугам из позиций снимается по одной фишке, а во все позиции по исходящим дугам помещается по одной фишке. Переход срабатывает только тогда, когда во всех входящих позициях есть минимум одна фишка. Рисунок 1. Сеть Петри, Рисунок 2. Сеть Петри, до срабатывания перехода после срабатывания перехода Временные сети Петри Временные сети Петри — это такой подкласс сетей Петри, в которых допустимо помимо фишек маркировать вершины параметром временной задержки (holding time). В данной работе рассматривается временная задержка только для позиций. Когда фишка попадает в позицию с задержкой 𝑁, должно пройти 𝑁 тактов, прежде чем фишка сможет участвовать в активации перехода и покинуть позицию. Пример простой очереди представлен на рис. 3: событие 𝑥2 означает начало работы с клиентом, срабатывает только при выполнении двух условий — кто-то ждёт в очереди (фишка в соответствующей позиции) и активность кассы, что обусловлено дугой активации 9 𝑥2 |𝑥1 . 𝑥2 сработает, когда фишка клиента пребудет достаточное время в кассе, то есть два тика. После завершения работы с клиентом, по дуге активации фишка готова будет активировать 𝑥1 . Вход системы 𝑢 и выход 𝑦 для наглядности показаны другим цветом. Рисунок 3. Модель окошка кассы, построенная временной сетью Петри Временные графы синхронизации. В англоязычной литературе используется термин Timed Event Graphs (TEG) и наиболее точный перевод может быть именно таким. Итак, временные графы синхронизации это подкласс временных сетей Петри, предназначенный, как следует из названия, для моделирования лишь явлений синхронизации в системе. Отличает этот класс от вышеописанного дополнительное условие, гарантирующее, что каждая позиция имеет ровно одну исходящую дугу и ровно одну входящую (SISO). Это делает модель непригодной для описания явлений одновременности, исключает возможность возникновения конфликтов и тупиков (deadlocks). Но зато данный вариант может быть описан специальной диоидной алгеброй, при чём состояние системы в любой момент времени может быть вычислено при помощи линейных методов. Подробнее этом в разделе 1.4. 1.3. Алгебра диоидов С наиболее полным формальным введением, посвящённым данному алгебраическому инструменту анализа и моделирования дискретно-событийных динамических систем можно ознакомиться в [8], авторы называют эту работу «самодостаточной теоретической базой для работы в данном направлении», позже была выпущена целая книга [3]. Здесь же упомянем наиболее важные определения и результаты, которые так или иначе используются в данной работе. Множество D с двумя заданными на нём операциями ⊕ (плюс) и ⊗ (умножение) называется диоидом, если выполнены следующие аксиомы: Ассоциативность 10 Коммутативность сложения Левая дистрибутивность (умножение не обязано быть коммутативным) Только левая, поскольку умножение не обязано быть коммутативным. Существование нулевого элемента и единицы (𝜀 и 𝑒 соответственно) Поглощающий нуль Идемпотентность сложения (𝑎 ⊕ 𝑎 = 𝑎) Поэтому иначе можно сказать, что диоид это идемпотентное полукольцо, но изза сходства с моноидами, где операция одна, авторы назвали эту структуру диоидом. Далее возьмём множество двоичных значений 𝔹 = {𝑒, 𝜀} и обозначим как ℬ⟦𝛾, 𝛿⟧ множество всех степенных рядов с неизвестными 𝛾 и 𝛿, двоичными коэффициентами и степенями из ℤ, с двумя заданными операциями ⊕ и ⊗. Таким образом, множество 𝑝=⨁ 𝑛, 𝑡 ∈ ℤ всех степенных рядов вида: 𝑠(𝑛, 𝑡) ⊗ 𝛾 𝑛 ⊗ 𝛿 𝑡 где 𝑠(𝑛, 𝑡) = 𝑒 или 𝜀, является диоидом. Существует отображение ℤ2 ↦ 𝑠(𝑛, 𝑡). Замыкание Клини (“звёздочка”) определяется как бесконечная сумма: 𝑎 ∗ = 𝑒 ⊕ 𝑎 ⊕ 𝑎2 ⊕ … где 𝑎𝑖 = 𝑎 ⊗ 𝑎 ⊗ … ⊗ 𝑎, 𝑖 ∈ ℤ и 𝑎0 = 𝑒. Согласно Теореме 9 из [8], для уравнения 𝑥 = 𝑎𝑥 ⊕ 𝑏 верно, что 1.4. Частным решением является 𝑥 = 𝑎 ⋆ 𝑏; Если 𝑥 является решением, то 𝑥 = 𝑎⋆ 𝑥; Информация о событиях Когда мы говорим о типе события, для временных графов синхронизации подразумеваются события срабатывания переходов и тип ассоциируется с именем сработавшего перехода. Для перехода 𝑥 мы рассматриваем “фрагменты информации” о событиях как целочисленные пары (𝑛, 𝑡)𝑥 . Во временном графе синхронизации фрагменты информации переносятся от входящих переходов к исходящим, на каждом переходе происходит объединение фрагментов информации. Принцип объединения продемонстрирован на рис. 4 и 6, до срабатывания перехода 𝑥 и после, соответсвтенно. 11 Рисунок 4. Рисунок 5. Объединение информации. Очевидно, что после срабатывания перехода, в соответствии с правилами работы сети, информация со входящих дуг объединяется по принципу min(𝑛1 , 𝑛2 ) и max(𝑡1 , 𝑡2 ), где 𝑛𝑖 и 𝑡𝑖 это информация, представленная фишками и задержкой соответствующих позиций в определённый момент времени. Возвращаясь к алгебре диоидов, определим операции ⊕ и ⊗: 𝛾 𝑛 𝛿 𝑡 ⊕ 𝛾 𝑛 𝛿 𝑙 = 𝛾 n 𝛿 max(𝑡,𝑙) {𝛾 𝑛 𝛿 𝑡 ⊕ 𝛾 𝑘 𝛿 𝑡 = 𝛾 min(𝑛,𝑘) 𝛿 𝑡 𝛾 𝑛 𝛿 𝑡 ⊗ 𝛾 𝑘 𝛿 𝑙 = 𝛾 n+k 𝛿 t+l Таким образом, объединение (1) информации теперь можно выполнять при помощи методов линейной алгебры на множестве диоидов. При использовании умножения, 𝛾 и 𝛿 задают сдвиг, например сдвиг по времени: 𝑥2 = 𝛿 6 ⊗ 𝑥1 сдвинет информацию, доступную при срабатывании перехода 𝑥1 , на 6 временных тиков. Знак умножения, как и в обычной алгебре, можно опустить. Пары чисел (𝑛, 𝑡), при условии, что все события пронумерованы целыми числами, интерпретируются как «событие с номером 𝑛 случилось не раньше времени 𝑡» или «на момент времени 𝑡, номер последнего случившегося события не больше 𝑛». Напомним, что за строгими определениями и сопутствующими теоремами читателю следует заглянуть по ссылке [8]. При объединении информации некоторые фрагменты могут быть полностью доминировать над другими. Для наглядности представим юго-восточные конусы на декартовой плоскости ℤ2 на рис. 6. представьте точку 𝛾 1 𝛿 2, тогда по формуле (1): γ2 δ2 ⊕ γ1 δ8 = (γ1 δ2 ⊕ γ2 δ2 ) ⊕ (γ1 δ8 ⊕ γ1 δ2 ) = γ1 δ2 ⊕ γ1 δ8 = γ1 δ8 (рис.7). Возвращаясь к определению множества ℬ⟦𝛾, 𝛿⟧, которое представляет все возможные ряды, в том числе с избыточной информацией. Поэтому авторы теории фильтруют при помощи отношения эквивалентности так, чтобы в итоговом фактормножестве остались лишь неубывающие ряды без избыточной информации (рис. 8). Обозначается как 𝑖𝑛 ⟦𝛾, ℳ𝑎𝑥 𝛿⟧ = ℬ⟦𝛾, 𝛿⟧/(𝛾 ⊕ 𝛿 −1 ) — читается min max gd. 12 Рисунок 6. Конусы 𝛾 2 𝛿 2 и 𝛾1 𝛿 8 на плоскости раздельно Рисунок 7. Доминирование 𝛾 2 𝛿 2 ⊕ 𝛾𝛿 8 = 𝛾𝛿 8 после объединения Рисунок 8. Объединение без доминирования 𝑒 ⊕ 𝛾 4 𝛿 2 ⊕ 𝛾 5 𝛿 5 ⊕ 𝛾 8 𝛿 6 ⊕ 𝛾14 𝛿 7 13 1.5. Сравнение аналогов Поскольку конечной целью работы был редактор сетей Петри, интегрированный с внешней библиотекой алгебраических вычислений, было рациональным рассмотреть существующие редакторы сетей Петри, пригодные для модификаций и дополнения недостающим функционалом. Некоторые варианты отклонялись сразу же, по причине недоступности исходного кода или из-за использованного стека технологий — например, .NET, Java, в сочетании с неудобными интерфейсами. Если в случае .NET о кроссплатформенности не может идти и речи, то в случае с Java трудности могут возникнуть при интеграции библиотеки libminmaxgd[10, 16], реализованной на C++. Особенно, если учитывать качество исполнения этих существующих решений. Фактически, проблемы у всех одни и те же, но некоторые программы можно выделить как более-менее пригодные к использованию, хотя, к сожалению, миссии данной работы они посодействовать никак не смогут. Petri Net Toolbox Популярное расширение[17, 18] для MATLAB, обладает хорошим набором функционала, поддерживаются разные типы (т.е. наборы правил) сетей Петри, имеется интеграция с алгебраическим аппаратом max-plus, что приближает это решение к целям данной работы. Но плагин является платным, исходный код недоступен. Сам MATLAB также является платным и довольно большим комплексом программ, что отметает данный вариант. Во-вторых, использовать данный плагин невозможно, скриншот программы представлен на рис. 9. Рисунок 9. Petri Net Toolbox (скриншот из [Saudi]) без модификаций 14 PIPE v4.3 Пожалуй, самое проработанное решение[5, 6] из доступных, разрабатывалось с 2003 по 2011 год разными специалистами из разных университетов, некоторые интегрируют это решение с MATLAB. Данный редактор выполнен качественно, большинство опций интерфейса (рис. 10) работают, сама программа стабильна — установка и запуск прошли гладко, работе ничего не мешает. К недостаткам данного приложения можно отнести: Интерфейс и управление слишком перегружены, а редактирование сети осуществляется исключительно при помощи мыши. На 10 позиций, 10 дуг и 10 переходов пришлось 120 нажатий мыши. При этом скопировать уже созданную структуру невозможно. Слишком общий подход. Нельзя выбрать конкретный набор правил организации сети, то есть система автоматически предлагает подкрутить вес дуги, разрешает делать позициям несколько входящих дуг и так далее. В то же время, некоторые опции оказываются недоступными или проработаны недостаточно хорошо — каждый элемент автоматически снабжается видимой подписью, хотя в большинстве случаев важна именно маркировка, а не имя. Позициям нельзя назначать временную задержку. Навигация по полотну затруднена, полотно ограничено слева-сверху, значит сеть при росте может упереться в край и нужно будет сдвигать; У программы проседает производительность даже на относительно небольших сетях, что при наличии процессора Intel i5 (1.7GHz) ставит под сомнение оптимальность реализации; При желании, список можно было бы продолжить, но ключевая цель программы — облегчить пользователю работу с алгебраическими инструментами, выполнена по всем признакам недостаточно хорошо. Рисунок 10. PIPE в действии 15 Romeo Ещё одно популярное решение[12, 13] для построения и верификации сетей Петри. К программе написано несколько инструментов для интеграции с другими проектами, но сама программа обладает недостаточным качеством исполнения, устаревшим подходом к разработке графического интерфейса (используются Tcl/Tk). Более того, в отличие от предыдущего решения функционала здесь меньше, но стабильность программы страдает — при осуществлении бытовых операций иногда возникают неприятные внутренние ошибки (рис. 11 и 12). Кстати, код написан частично на французском, поэтому модифицировать его для своих нужд де-факто не удастся. Положительным моментом является наличие возможности копировать отдельные участки сети, идея хорошая. Рисунок 11. Romeo в действии Рисунок 12. Или нет 16 1.6. Заключение После рассмотрения как и отрицательных, так и положительных сторон у существующих решений, а также после согласования требований научным руководителем, был составлен список функциональных требований, которым должна удовлетворять создаваемая программа. Графическое задание временной сети Петри. Возможность добавлять элементы сети, соединять дугами, устанавливать начальную маркировку позиций с указанием задержки и фишек, снабжать элементы сети именами/комментариями. Полотно должно быть условно-бесконечным без ограничения перемещения в возможностью масштабировать произвольного центра. любую из отдельно Поддержка 4х сторон, взятые формирования должно участки и обладать относительно расформирования изолированных групп элементов, с целью скрыть детали реализации участков сети и для создания множества участков сети с единой конфигурацией. Поддержка копирования участков сети и групп с сохранением настроек дуг (контрольные точки для кривых) и настроек внешнего вида элементов (комментарии, ориентация, и т.д.). Должна иметься возможность снятия скриншота как минимум видимой области с последующим сохранением в файл. Возможность сохранять созданную сеть в файл и загружать из файла. Редактор информации о входящем потоке событий. Как в графическом режиме (расстановка конусов на плоскости), так и при помощи символьного описания элементов 𝑖𝑛 ⟦𝛾, ℳ𝑎𝑥 𝛿⟧. Добавление точек, выделение точек, перемещение точек, применения замыкания Клини к выделенной коллекции точек, отображение информации для каждого перехода (входы системы) в отдельном слое. Этот же редактор в режиме read-only должен обеспечивать просмотр информации о событиях на выходе системы. Интеграция с библиотекой символьных вычислений в диоидной алгебре 𝑖𝑛 ⟦𝛾, ℳ𝑎𝑥 𝛿⟧ и разработка с учётом необходимости подключения дополнительных модулей в дальнейшем. 17 ТЕХНОЛОГИИ, АРХИТЕКТУРА, АЛГОРИТМЫ ПРОГРАММЫ 2.1. Стек технологий При выборе стека технологий основное внимание уделялось следующим факторам, в порядке убывания значимости: Кроссплатформенность; Поддержка взаимодействия с нативными библиотеками (C/C++); Современные средства для создания графических интерфейсов пользователя с поддержкой аппаратного ускорения отрисовки; Хорошая известность в сообществе разработчиков, то есть наличие хорошей документации и решений к часто встречающимся проблемам (не всегда тривиальным). Qt Framework и QtQuick Единственным решением, которое проходит по всем поставленным критериям, является Qt Framework[22], на текущий момент самое полноценный инструмент для кроссплатформенной разработки. Последняя мажорная (5ая) версия предоставляет большое количество полезных возможностей. Во-первых, есть QtQuick[23], позволяющий описывать интерактивные пользовательские интерфейсы с нетривиальной логикой при помощи декларативного языка разметки QML[24]. QML использует подмножество JavaScript для логики интерфейса, вроде привязки действий к событиям, выполнения различных функций, обращения к модели данных и так далее. Во-вторых, в последних минорных версиях значительно улучшилась поддержка интеграции с нативными компонентами родительской OS, таким образом, не смотря на полностью самостоятельный интерфейс (с самостоятельно нарисованными кнопками), у разработчика есть возможность вызвать нативный диалог сохранения файла или разместить на форме нативно выглядящие кнопки и флажки. В-третьих, не смотря на возможность интеграции системных компонент, разрабатываемое с применением технологии QtQuick приложения является полностью независимым от платформы и может быть запущено под Windows, OSX, Linux, iOS, Android и так далее. К сожалению, QtQuick и JS не подходят для написания сложных вычислительных процессов, которые должны работать максимально быстро и эффективно расходовать память. Поэтому в части QtQuick реализовано лишь “лицо” программы. 18 Go lang Основная же часть кода написана на статически типизированном, компилируемом, высокопроизводительном языке программирования Go[25, 26] от компании Google, который стал доступен общественности совсем недавно, в 2011 году. Причиной этому послужили несколько факторов, например разработка с использованием Qt Framework идёт на C++, когда дело доходит до внутренних механизмов прикладного приложения. C++, несомненно, имеет множество преимуществ с технической точки зрения, но на практике всё перекрывается чрезмерной низкоуровневостью языка, медленной скоростью компилятора, запутанным стандартом и взамен C++ не даёт ничего, что могло бы дать прикладному приложению с графическим интерфейсом какое-либо преимущество. С языком Go ситуация другая. Сам язык разрабатывался с учётом опыта других языков программирования, вбирая в себя только то, что прошло проверку временем и доказало свою эффективность. Отличительными чертами Go являются прагматичность, малый размер стандарта, заморозка API стандартной библиотеки, быстрая скорость компиляции, runtime-производительность на уровне Java или C++, возможность низкоуровневых вызовов и компоновки с объектными файлами, полученными в результате компиляции C/C++. В отличие от других языков программирования, легковесные потоки являются одним из базовых примитивов языка. Для синхронизации процесса выполнения различных частей программы между собой и для обмена данными в языке применяются каналы[15]. Эти возможности активно использовались при разработке приложения. Go-qml В компании Canonical с 2012 года планомерно идёт перевод нескольких крупных проектов с Python на Go[11], и одновременно c этим Qt Framework является базой для многих клиентских разработок Canonical, начиная от библиотек интеграции с обачными сервисами, заканчивая прикладными приложениями рабочего стола. Важность и возможность взаимодействия Go и Qt сыграли свою роль и усилиями сотрудника компании появился инструмент go-qml[19–21], позволяющий производитеь операции с Qt-объектами и реализующий необходимые «мосты» для запуска QtQuick с логикой на стороне Go. Таким образом, выбранный стек технологий позволяет создать пользовательское приложение, одинаково работающее на трёх основных OS, 19 использующее самый продвинутый инструментарий разработки GUI и один из современных и перспективных языков для внутренней логики. 2.2. Архитектура и компоненты Приложение разрабатывается в соответствии с паттерном проектирования Model-View-Presenter (MVP), который является производным от Model-View-Controller (MVC) и предназначается для использования при написании приложений с графическим интерфейсом. Особенности такого подхода заключаются в следующем: Модель полностью изолирована и является исключительно предметноориентированной. Фактически, модель можно использовать в отрыве от интерфейса, например при встраивании в другой инструмент; Presenter извлекает данные из модели и форматирует их для отображения в представлении. В данном случае из внутреннего представления модели сети Петри генерируются наборы графических примитивов, которые рисуются покоординатным способом на стороне отображения, без учёта предметной области. В то же время Presenter занимается обработкой пользовательских событий, поступающих из отображения — нажатие мышкой, нажатие клавиши и так далее. После обработки события Presenter изменяет модель; Отображение отвечает за пользовательский интерфейс — отрисовки окна, формы, кнопок и других элементов приложения в операционной среде. Здесь также обрабатываются события, поступающие от операционной среды и в зависимости от типа передаются Presenter’у. Отображение ничего не знает о предметной области, но тем не менее логика пользовательского интерфейса реализуется частично на его стороне (JavaScript, QtQuick). Иллюстрация находится на рисунке 13. 20 Рисунок 13. Model-View-Presenter Компоненты на стороне Go Исходя из поставленных задач и списка необходимого функционала, приложение поделено на следующие компоненты (пакеты): tegview — изолированный пакет редактора сети Петри, внутри построен при помощи паттерна MVP, на Go написаны Model и Presenter. Первое окно программы создаётся именно на основе этого модуля. Из окна tegview может вызываться открытие других окон tegview для групп и открываемых файлов. planeview — изолированный пакет редактора входных данных, реализует отображение конусов на плоскости и их редактирование, написан по подобию tegview, используется паттерн MVP, на Go написаны Model и Presenter. Из окна tegview вызывается открытие окон planeview. render — пакет с типами графических примитивов и методами для работы с ними. geometry — пакет с типами геометрических примитивов и методами для работы с ними. dioid — пакет для работы с диоидной алгеброй. Включает в себя парсер выражений вида «g^3d^2 + g^4d^7 + g^3d^4 x (g^1d^2)*», обёртку над библиотекой libminmaxgd, декларацию типов для внутреннего представления элементов алгебры. 21 workspace — пакет для управления набором открытых окон, реализован с целью контролировать максимальное количество открытых одновременно окон (существует намеренное ограничение в go-qml, при необходимости можно обойти), также обеспечить корректное завершение приложения после закрытия последнего окна. util — пакет вспомогательных утилит: реализация стека, генератор UUID, конвертер hex-представления цвета из формата RGB в ARGB. Компоненты на стороне QtQuick/QML TegView — реализация вида, компонент унаследован от QtQuickкомпонента ApplicationWindow. Содержит инструментальную панель, панель статуса, полотно с отображением модели (сеть Петри). PlaneView — аналогично TegView. Содержит инструментальную панель, панель статуса, текстовое поле для редактирования элементов степенного ряда, панель выбора активного слоя и изменения видимости других, область менеджера слоёв. Plane — менеджер слоёв на декартовой плоскости. Каждый слой отображает модель (коллекцию точек) в виде конусов на плоскости, по ТЗ эти слои должны накладываться друг на друга. Содержит корневой слой (отображающий координатную сетку, оси, подписи) и коллекцию слоёв, построенных по модели в Presenter’е. PlaneLayer — отображение слоя. Содержит полотно и методы, рисующие графические примитивы из кешированной коллекции. Коллекция кешируется на стороне QML/JavaScript из-за особенностей управления памятью при передачи объектов из Go в QML. В любом случае, без него новые данные будут заменять старые прямо в процессе отрисовки, что неправильно. XButton, XToggle — самостоятельная реализация кнопки (с поддержкой иконок) и кнопки-выключателя. 22 2.3. Геометрические алгоритмы Поворот точки относительно центра на заданный угол X = o.X + (p.X-o.X) * cos(angle) - (p.Y-o.Y) * sin(angle) Y = o.Y + (p.X-o.X) * sin(angle) + (p.Y-o.Y) * cos(angle) где o.X, o.Y — координаты центра поворота, p.X, p.Y — координаты исходной точки, angle — угол. Алгоритм применяется при повороте стрелки направления дуги вокруг центра позиции. Точка на окружности с заданным отступом angle := math.Atan2(x-c.X, y-c.Y) dX := (c.r + distance) * math.Sin(angle) dY := (c.r + distance) * math.Cos(angle) где c.X, c.Y, c.r — координаты центра и радиус окружности, distance — отступ от дуги окружности; x,y — координаты направляющей точки. В сочетании с предыдущим алгоритмом позволяют ориентировать указатель дуги как показано на рис. 14. Рисунок 14. Поворот стрелки в заданном точкой направлении, с заданным отступом от дуги окружности. Проверка пересечения двух прямоугольников RectA.X1 < RectB.X2 && RectA.X2 > RectB.X1 && RectA.Y1 < RectB.Y2 && RectA.Y2 > RectB.Y1 где RectA, RectB — заданные прямоугольники. Используется при выделении элементов (рис. 15). Рисунок 15. Пересечение прямоугольной части перехода инструментом выделения 23 Проверка пересечения двух отрезков на плоскости x0, y0, x1, y1 := p0.X, p0.Y, p1.X, p1.Y x2, y2, x3, y3 := p2.X, p2.Y, p3.X, p3.Y sx1 := x1 - x0 sy1 := y1 - y0 sx2 := x3 - x2 sy2 := y3 - y2 s := (-sy1*(x0-x2) + sx1*(y0-y2)) / (-sx2*sy1 + sx1*sy2) t := (sx2*(y0-y2) - sy2*(x0-x2)) / (-sx2*sy1 + sx1*sy2) if s >= 0 && s <= 1 && t >= 0 && t <= 1 { return true } где p0, p1 — концы первого отрезка; p2, p3 — концы второго. Используется при удалении дуг методом “отрезания” огибающих ломанных. На рис. 16 дуга будет удалена, на рис. 17 — нет. Рисунок 16. Удаление дуги. Рисунок 17. Отрезки не пересекаются 24 ОСОБЕННОСТИ РЕАЛИЗАЦИИ 3.1. Пример с tegview │ └── qml │ ├── tegrender.js │ └── tegview.qml ├── tegview │ ├── controller.go │ ├── model.go │ ├── renderer.go │ └── view.go Здесь, если брать модель MVP, роль Presenter распределена по файлам controller.go, view.go и renderer.go. Модель описана в файле model.go, а отображение выполнено на QML и JavaScript в файлах tegrender.qml и tegrender.js соответственно. Находится в соседней ветке (для возможности работать с QML в отдельном редакторе QtCreator) view.go — точка входа, отвечает за окно с редактором. Создаёт пустую модель, создаёт экземпляр контроллера, загружает QML файлы и отображает в окне QtQuick-сцену. Создаёт два отдельных потока — в одном следит за изменениями в модели, во втором — запускает процесс рендеринга при получении изменений в первом потоке. То есть, обработка изменений модели задействует дургое ядро, отличное от того, на котором запущен GUI-поток; model.go — представляет собой модель участка сети Петри (вся сеть целиком — тоже участок), хранит наборы позиций, переходов, групп (в каждой группе — своя дочерняя модель), набор выделенных элементов, набор информаци о событиях на входе (набор степенных рядов, ассоциированных с каждым из входов системы); render.go — генерирует набор буферов с графическими примитивами по модели. Внешний вид отображаемой сети Петри зависит от состояния модели, конечно, но в большей степени он задан в процедурах рендера. На данном этапе рендер генерирует примитивы совместимые с API Context2D[27, 28] у Canvas[29] в QtQuick. Нет технических преград дополнить рендер возможностью генерировать примитивы совместимые с OpenGL и SVG. controller.go — в отдельном потоке получает пользовательский ввод, в зависимости от нажатых клавиш, состояния модели, состояния контроллера 25 выполняет операции над моделью. Также здесь определён специальный объект, видимый из отображения. Через него контроллер считывает некоторые важные параметры отображения (например, коэффициент масштабирования сцены, который вычисляется средствами QtQuick и JavaScript). Также у отображения есть возможность напрямую вызывать публичные методы контроллера, например метод, отвечающий за открытие нового окна (используется в качестве обработчика события нажатия кнопки в интерфейсе приложения). tegview.qml — декларативное описание интерфейса приложения, немного логики на JavaScript, в основном это привязки обработчиков к событиям. При получении сигнала от контроллера о том, что новый буфер графических примитивов готов для отрисовке на полотне, создаёт кэш на стороне JavaScript. tegview.js — итерирует элементы кэша и непосредственно выполняет отрисовку графических примитивов в соответствии с параметрами. Редактор точек на плоскости фактически унаследован от редактора сети Петри, общий принцип взаимодействия компонент одинаков. Конкретные отличия стоит сравнивать в коде. Например, вместо одного слоя в редакторе используется несколько слоёв, поэтому код контроллера и QML части значительно увеличился в объёмах. 26 3.2. Графический интерфейс программы Рисунок 18. Графический интерфейс реализованного редактора временных графов синхронизации Рисунок 19. Графический интерфейс реализованного редактора информации о событиях на входах системы 27 ЗАКЛЮЧЕНИЕ Результатом выполнения задания является реализованный редактор временных графов синхронизации (класс временных сетей Петри), соответствующий задачам, поставленным в постановке задачи. Редактор информации о событиях с поддержкой вычислений в диоидной алгебре. Произведена интеграция обоих компонент в виде общей прикладной программы с возможностями строить модель любой сложности и смотреть зависимость значений на выходе от значений на входе. Как и упоминалось в начале этой работы, результат может быть использован как замена существующим решениям для редактирования сетей Петри, а интеграция с математическим аппаратом диоидной алгебры может служить хорошим примером такой интеграции. Здесь стоит сделать акцент на том, что это интерфейс для “боевой” вычислительной библиотеки и вполне “боевой” редактор временных сетей Петри, то есть после выявления и исправления существующих недочётов, программа способна лечь рядом со “взрослыми” изделиями для решения задач в данной области применения. Помимо улучшения документации и исправления недочётов, в данном направлении есть ещё задачи, над которыми следует продолжить работу. Так, на данный момент отрисовка сети происходит в программном режиме на растровой поверхности довольно медленного полотна. Здесь напрашивается аппаратное ускорение и использование OpenGL, но из-за нестабильности связки Go+QML+OpenGL на данном этапе этот вопрос был отложен. Помимо отображения сети в программе, следовало бы добавить возможность сохранять построенную сеть в виде дерева SVG, что позволит добавлять построенные графы напрямую в научно-технические работы, свёрстанные в LaTeX. Соответствующий код для этого уже подготовлен, но из-за разности API у Canvas2D и у SVG требуется дополнительное время на тестирование, чтобы внешний вид совпадал в обоих случаях. Помимо сохранения в виде картинок, дополнительной задачей является сохранения сети в распространённые форматы, пригодные для импорта в среды вроде MATLAB, Scilab и им подобным. Например, для некоторых существующих аналогов имеются скрипты для конвертации, которые пользуются спросом, но реализованная в данной работе программа сохраняет исключительно в свой формат и пока к интеграции не готова. 28 СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ 1. Авдошин С.М. Оптимизация гибких производственных систем // 1987. 2. Лескин А.А. Алгебраические модели гибких производственных систем // 1986. 3. Baccelli F.L. и др. Synchronization and linearity. Wiley New York, 1992. 4. Ben-Naoum L. и др. Methodologies for discrete event dynamic systems: A survey // Journal A. 1995. Т. 36. № 4. С. 3–14. 5. Bonet P. и др. Platform Independent Petri net Editor 2 [Электронный ресурс]. URL: http://pipe2.sourceforge.net/ (дата обращения: 30.05.2014). 6. Bonet P. и др. PIPE v2. 5: A Petri net tool for performance modelling // Proc. 23rd Latin American Conference on Informatics (CLEI 2007). , 2007. 7. Cohen G. и др. A linear-system-theoretic view of discrete-event processes and its use for performance evaluation in manufacturing // Automatic Control, IEEE Transactions on. 1985. Т. 30. № 3. С. 210–220. 8. Cohen G. и др. Algebraic tools for the performance evaluation of discrete event systems // Proceedings of the IEEE. 1989. Т. 77. № 1. С. 39–85. 9. Cohen G., Gaubert S., Quadrat J.-P. Max-plus algebra and system theory: where we are and where to go now // Annual Reviews in Control. 1999. Т. 23. С. 207–219. 10. Cottenceau B. и др. Data processing tool for calculation in dioid // Proceedings of WODES’2000, Workshop on Discrete Event Systems. , 2000. 11. Dave C. Juju at Canonical [Электронный ресурс]. URL: https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/jLnMsUbYwrQ (дата обращения: 29.05.2014). 12. Gardey G., Lime D., Magnin M. Roméo - A tool for Time Petri Nets analysis [Электронный ресурс]. URL: http://romeo.rts-software.org/?page_id=2 (дата обращения: 28.05.2014). 13. Gardey G., Lime D., Magnin M. Romeo: A tool for analyzing time Petri nets // Computer Aided Verification. Springer, 2005. С. 418–423. 14. Gaubert S., Klimann C. Rational computation in dioid algebra and its application to performance evaluation of discrete event systems // Algebraic computing in control. Springer, 1991. С. 241–252. 15. Gerrand A. Share Memory By Communicating [Электронный ресурс]. URL: http://blog.golang.org/sharememory-by-communicating (дата обращения: 30.05.2014). 16. Hardouin L. Software tools to handle periodic series in dioid [Электронный ресурс]. URL: http://persolaris.univ-angers.fr/~hardouin/outils.html (дата обращения: 28.05.2014). 17. Matcovschi M.-H., Mahulea C., Pastravanu O. Petri Net Toolbox for MATLAB [Электронный ресурс]. URL: http://www.pntool.ac.tuiasi.ro/ (дата обращения: 30.05.2014). 18. Matcovschi M.-H., Mahulea C., Pastravanu O. Petri net toolbox for MATLAB // 11th IEEE Mediterranean Conference on Control and Automation MED’03. Citeseer, 2003. 19. Niemeyer G. Arbitrary Qt extensions with Go QML [Электронный ресурс]. URL: http://blog.labix.org/2014/03/21/arbitrary-qt-extensions-with-go-qml (дата обращения: 30.05.2014). 29 20. Niemeyer G. QML components with Go and OpenGL [Электронный ресурс]. URL: http://blog.labix.org/2013/12/23/qml-components-with-go-and-opengl (дата обращения: 30.05.2014). 21. Niemeyer G. Go-QML Documentation [Электронный ресурс]. URL: http://godoc.org/gopkg.in/qml.v0 (дата обращения: 30.05.2014). 22. Qt Overviews | Qt Project [Электронный ресурс]. URL: http://qt-project.org/doc/qt-5/overviews-main.html (дата обращения: 30.05.2014). 23. Qt Quick | Qt Project [Электронный ресурс]. URL: http://qt-project.org/doc/qt-5/qtquick-index.html (дата обращения: 30.05.2014). 24. The QML Reference | Qt Project [Электронный ресурс]. URL: http://qt-project.org/doc/qt5/qmlreference.html (дата обращения: 30.05.2014). 25. The Go Programming Language Specification [Электронный ресурс]. URL: http://golang.org/ref/spec (дата обращения: 30.05.2014). 26. Effective Go [Электронный ресурс]. URL: http://golang.org/doc/effective_go.html (дата обращения: 30.05.2014). 27. Context2D | Qt Project [Электронный ресурс]. URL: http://qt-project.org/doc/qt-5/qml-qtquickcontext2d.html (дата обращения: 30.05.2014). 28. HTML Canvas 2D Context | W3C [Электронный ресурс]. URL: http://www.w3.org/TR/2dcontext/ (дата обращения: 30.05.2014). 29. Canvas | Qt Project [Электронный ресурс]. URL: http://qt-project.org/doc/qt-5/qml-qtquick-canvas.html (дата обращения: 30.05.2014).