По чем синтаксический сахар в графических языках программирования?

Графические языки программирования

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

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

Что говорят стандарты?

Обратимся к МЭК 61131–3. Там описано два чисто графических языка программирования:

 FBD (Function Block Diagram) — графический язык программирования стандарта МЭК 61131–3. Предназначен для программирования программируемых логических контроллеров (ПЛК). 

LD (Ladder diagram) — язык релейно-контактной логики.

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

Если релейную электрическую схему можно назвать программой, то почему не назвать программой на специальном языке программирования электрическую принципиальную схему, собранную в среде 1Dмоделирования. Например, как на рисунке 1:

Рисунок 1. Электрическая схема с набором мощности турбины и генератора и выходом его на номинальную нагрузку, питаемую через трансформатор 500/24 кВ. 

Рисунок 1. Электрическая схема с набором мощности турбины и генератора и выходом его на номинальную нагрузку, питаемую через трансформатор 500/24 кВ. 

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

И чем тогда хуже принципиальная гидравлическая схема, где вместо проводов трубопроводы, а вместо электрического тока течет вода? С моей точки зрения, принципиально ничем. Вот, например, на следующем рисунке реальная задача, выполненная для одного из заводов, создающего турбины для атомных подводных лодок, ледоколов и плавучих атомных электростанций. (занимательный факт — это задача, на которой сломался Matlab Simulink, и мы тогда исполнили акт импортозамещения в далеком 2009 году. Я делал импортозамещение еще до того, как это стало мейнстримом). 

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

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

Все тоже, самое, исполняется в среде 1D моделирования. Нельзя только сгенерировать на СИ, но можно реализовать в железе и будет конденсатор турбины ледокола. (Но, к слову, реальные компьютеры, где программы текут в виде потока воды по каналам существуют:  https://habr.com/ru/articles/374309/ — струйный компьютер!)

Даешь больше разнообразных языков программирования!  

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

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

Но оказывается, очень даже можно сравнивать. Обратимся к официальным документам, а именно к MЭК 60880 2011 «Атомные станции. Системы контроля и управления, важные для безопасности. Программное обеспечение компьютерных систем, выполняющих функции категории А». (полный перевод западного варианта) Читаем определение:

Проблемно-ориентированный язык (application oriented language): компьютерный язык, специально разработанный для определенного типа применений и используемый лицами, являющимися специалистами в данном типе применений. [МЭК 62138]

Это значит, что и принципиальная гидравлическая схема конденсатора турбины, и электрическая схема разгона генератора и есть application oriented language. Все сходится: его специально разработали для специалистов «по говну и пару» мирного и не очень атома, и они его таки используют, и несомненно являются специалистами в данном типе применений. Все соответствует западным стандартам, как в лучших домах Парижа и Лондона.

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

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

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

Пока мы проектируем, тестируем, налаживаем 1D модель в графической среде, у нас в графическом виде присутствует и софт и хард реального объекта, потом софт из графического языка автоматически генерируется в программу на обычном языке, заливается в контроллеры и едет управлять атомной станцией. Ну, а атомная станция строится в бетоне и железе. Все то же самое можно применить к любой технической системе от космических высот (моделирование спутников) до океанских глубин (моделирование подводной лодки). (см. рисунок 3) 

Рисунок 3.  Применение проблемно-ориентированного языка программирования

Рисунок 3.  Применение проблемно-ориентированного языка программирования

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

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

Там я использовал реальные примеры больших и сложных проектов систем управления АЭС и системами добычи газа. Здесь же хотелось бы поговорить о синтаксическом сахаре на простых учебных задачах.

Сначала определение из википедии, причем в английской версии как мне кажется определение более правильно:

In computer science,  syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language «sweeter» for human use: things can be expressed more clearly, more concisely, or in an alternative style that some may prefer.

Сахар, чтобы человеку было хорошо. 

Синтаксический сахар (англ. syntactic sugar) в языке программирования — это синтаксические возможности, применение которых не влияет на поведение программы, но делает использование языка более удобным для человека.

У нас зачем-то добавили условия невлияния на поведения программы (с чего бы?). У русских всегда свой путь.

Может возникнуть вопрос: если графический язык и так более понятный, чем текстовый, зачем его еще упрощать? Отвечу: совершенству нет предела, и всегда хочется сделать вещи еще более легкими (make thingseasier).  Человек ленивое создание и не хочет напрягать мозг, поэтому легче много не бывает! Кто-то для этого использует вещества, но это не наш метод. Как говорил Ленин: «Мы пойдем другим путем» и будем упариваться по-другому. 

Далее будет приведён ряд примеров, которые помогут сделать ваши программы на графических языках программирования, а также схемы для 1D расчетов более простыми для чтения и написания (to make things easierto read or to express).

Синтаксический сахар на простых примерах в графических языках

Лучше меньше да лучше

Рассмотрим два варианта одной и той же программы управления температурой. На рисунке 1 приведен вариант, который выполнен, что называется в лоб, без синтаксического сахара.

Рисунок 4. Программа регулятора температурой без «сахара»

Рисунок 4. Программа регулятора температурой без «сахара»

Все по классике: справа входы, слева выходы, между ними математические вычисления в виде функциональных блоков. Заданная температура 40 град. переводится в проценты, затем сравнивается с показанием датчика в процентах и отправляется в ПИД регулятор. Поскольку программа предназначена для технологов и проектантов, входы и выходы в таблицах даны с пояснениями. Что очень удобно и полезно даже разработчику. Через пару лет ему будет легко вспомнить, что он напрограммировал на реакторе.

Поскольку задача учебная все просто. Казалось бы, что здесь можно улучшить? Но посмотрите на рисунок 5. Все тоже сомое, но с сахаром.

Рисунок 5. Подпрограмма управления температурой с «сахаром»

Рисунок 5. Подпрограмма управления температурой с «сахаром»

Второй вариант явно более читаемый. Как это получилось? Разберем в чем соль, вернее сахар. 

Начнем с самого очевидного. Вместо того, чтобы линию связи из блока сравнения разворачивать на схеме, чтобы подключить к блоку регулятора как на рисунке 1, мы ее разорвали на две части. Первую часть продолжили до таблицы выходов и создали «новую переменную» (желтый блок »в память»), — Esp. А вторую часть линии, используя зеленый блок »из памяти», подключили к входу блока ПИД регулятора Рассогласование. При этом мы поместили эти новые блоки (желтый и зеленый) на схему таким образом, чтобы они казались частью таблиц входов и выходов. И сразу читаемость схемы упростилась даже для такой простой схемы.

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

Простейшая расчетная схема перевода любой величины в проценты от заданного диапазона см. рисунок 6

Рисунок 6. Расчетная схема регулятора PID

Рисунок 6. Расчетная схема регулятора PID

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

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

Например, у нас есть простая учебная система, типа котла с подогревом, и три параметра, которые надо поддерживать в заданном состояния, а значит нам нужно три разных датчика: давления 100 000 Па, температуры 40 градусов и расхода 0.1 кг/с. Для изменения этих параметров в системе мы используем исполнительные механизмы клапана, положение которых мы можем определять и менять от 0 до 100 в процентах. В этом случае мы можем использовать для регулирования всех параметров одинаковый блок регулятора, например, как на рисунке 7, это внутренняя структура блока ПИД на рисунках 6 и 7

Рисунок 7. Расчетная схема регулятора PID

Рисунок 7. Расчетная схема регулятора PID

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

А раз схема одинаковая, то можно применить векторную обработку данных, как это описано в статье про ООП. Например, для всех датчиков, которые у нас есть, мы создаем структуру данных, которая содержит все параметры датчика. Пусть у нас три датчика D1, D2, D3. Тогда в базе данных сигналов у нас три структуры с такими же именами. (см. рис. 8)

Рисунок 8. Структура базы данных сигналов для датчиков в модели

Рисунок 8. Структура базы данных сигналов для датчиков в модели

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

На следующем рисунке отображаются значения на линиях связи. На входе у нас Давление в Паскалях (порядок 105), расхода в кг/с (порядок 10–2),   и температуры порядок 102, которые мы считаем в гидравлической схеме, а выходе у нас все то же самое, но уже в процентах от заданного диапазона. Такии образом абсолютные единицы измерения параметров, которые отличаются на 7 порядков, мы приводим в относительные единицы одного порядка, что упрощает проектирование регуляторов.

Рисунок 9. Результаты пересчёта показаний датчиков в проценты.

Рисунок 9. Результаты пересчёта показаний датчиков в проценты.

После этого результаты расчета можно использовать в соответствующих регуляторах. Рассмотрим простой регулятор температуры, с которого мы начали (см. рис. 4). Например, если нам нужно поддерживать температуру 40 град, мы должны пересчитать температуру в проценты от диапазона, сравнить ее с показаниями датчика в процентах, рассчитанные схемой на рисунке 7. (третий элемент вектора). И рассогласование отправить в регулятор, который и выдает команду Открыть или Закрыть для задвижки Z4.  

Рисунок 10. Схема регулятора температуры

Рисунок 10. Схема регулятора температуры

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

В этом варианте пересчёт заданной температуры перемещается в схему обработки датчика (на рисунке 9). Добавился виртуальный датчик D03 (четвертый элемент вектора), в котором 40 град, превращаются в 25% процентов, которые уже можно использовать в схеме регулятора.

Рисунок 11. Пересчет показаний в проценты

Рисунок 11. Пересчет показаний в проценты

А сама расчетная схема регулятора упрощается. Остается только в таблице добавить пояснения, что D03-xq01 это уставка в градусах, а D03-xq03 — значение уставки в процентах.  См. рисунок 12.

Рисунок 12. Регулятор температуры

Рисунок 12. Регулятор температуры

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

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

Невидимый суслик наоборот

— Видишь суслика?

— Вижу!

— А его там нет!

Обратите внимание, что мы используем пересчет температуры в проценты, мы отправили 40 град в базу данных сигналов, и получили показание датчика в процентах в базе данных сигналов. Мы убрали с расчетной схемы блоки, потому что расчеты этих блоков отправились в векторный блок см. рисунок 11. 

Но давайте войдем в блок PID2, что мы там видим? А ничего мы там не видим, рассогласование и положение попали внутрь блока и сразу исчезли. (см. рис. 13)

Рисунок 13. Внутренняя структура ПИД

Рисунок 13. Внутренняя структура ПИД

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

Рисунок 14. Группа сигналов для ПИД

Рисунок 14. Группа сигналов для ПИД

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

Рисунок 15. Векторный ПИД регулятор

Рисунок 15. Векторный ПИД регулятор

В принципе, все очевидно и понятно. Единственный возможной вопрос: как результат работы регулятора (981.32278) на схеме превратился в команду Меньше. Это просто преобразование вещественного числа в булевскую переменную. Если вещественное число больше или равно 0,5, то это Да, если меньше, то Нет. 

Получается, в одном случае для облегчения чтения мы убираем блоки со схемы, во втором случае добавляем. Ведь на самом деле имя векторный блок рассчитывает все ПИД регуляторы в модели, его можно убрать и тогда наша схема будет выглядеть вообще просто, как на рисунке 16:

Рисунок 16. Схема ПИД регулятора температуры без блока ПИД

Рисунок 16. Схема ПИД регулятора температуры без блока ПИД

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

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

Рисунок 17. Редактирование свойств блока, которого нет

Рисунок 17. Редактирование свойств блока, которого нет

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

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

Синтаксический сахар в 1D моделировании

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

Рисунок 18. Принципиальная тепло-гидравлическая схема без сахара

Рисунок 18. Принципиальная тепло-гидравлическая схема без сахара

Обратите внимание, что для гидравлической 1D модели клапан представляет собой просто коэффициент сопротивления. Для расчета переходного процесса системы нам нужно знать степень открытия и характеристику — зависимость коэффициента сопротивления от степени открытия, после этого гидравлический код рассчитает полученное давление и расход в системе. 

В свойствах мы видим, что степень открытия % берет из базы сигналов имя переменной для управления — K1A_State. Расчет этой переменной осуществляется в другой части модели, которая представлена на рисунке 19. Данная схема представляет собой ПИД регулятор, где происходит сравнение расхода с заданным значением 35. Величина рассогласования после блока усилителя передается в ПИД регулятор. Результат работы регулятора передается на релейное звено с зоной нечувствительности. Данное звено может иметь на выходе следующие значения -1,0,1, которые соответствуют командам для управления клапаном: закрыть, стоять, открыть. Эти команды отправляются на интегратор, который и увеличивает K1A_State (открывает клапан), если на входе 1, или уменьшает K1A_State (закрывает клапан), если на входе -1, или не делает ничего, если 0. 

Рисунок 19. Расчет положения клапана

Рисунок 19. Расчет положения клапана

Поскольку задача учебная, все достаточно просто и понятно, кроме одного. Раз процесс динамический, то для правильного моделирования системы в целом (гидравлика + привода + система управления) нам нужно знать скорость открытия и закрытия клапана, иначе правильно рассчитать переходный процесс невозможно. А где у нас определяется скорость движения клапана? Открываем свойства интегратора и для параметра коэффициент усиления в столбце Формула видим время открытия, спрятанное в знаменатель расчета коэффициента усиления (см. рисунок 20). Общий диапазон перемещения 0 — 100%, время открытия 25 сек, коэффициент усиления интегратора 100/25 = 4. 

В данном случае идентифицировать место задания времени открытия задвижки можно, только хорошо понимая математическую модель, хотя она здесь очень простая. 

Рисунок 20. Свойства интегратора

Рисунок 20. Свойства интегратора

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

Рисунок 21. Схема регулятора с виртуальным датчиком

Рисунок 21. Схема регулятора с виртуальным датчиком

Все то же самое, только теперь в свойствах клапана появилось новое свойство Totk Время открытия [сек]. И хотя это значение реально не используется в расчетах тепло-гидравлической схемы, наличие такого свойства значительно упрощает создание и понимание схемы. В базе данных сигналов комплексной модели для категории задвижки появляется новая переменная Totk — время открытия 25. (см. рис. 22)

Рисунок 22. Время открытия в базе данных сигналов.

Рисунок 22. Время открытия в базе данных сигналов.

А на схеме автоматического регулирования мы используем эту переменную для расчета коэффициента усиления для интегратора. (см. рис. 23)

Рисунок 23. Настройка интегратора в модели управления клапаном

Рисунок 23. Настройка интегратора в модели управления клапаном

Простое добавление «ненужного» свойства на гидравлическую схему, облегчающее понимание модели, попадает под критерии синтаксического сахара.  In computer science,  syntactic sugar … is designed to make things easier to read or to express.

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

И пока весь мир объединяет данные и алгоритмы в ООП, на этом примере мы идем в другую сторону. Параметры задаем на одной схеме, а алгоритм, который их использует, работает в другой расчетной схеме. Но для технолога или проектанта тепло-гидравлики естественным является привязка всех параметров оборудования к его элементу на тепло-гидравлической схеме. А как нас учат стандарты, тепло-гидравлическая схема — это «компьютерный язык, специально разработанный для определенного типа применений и используемый лицами, являющимися специалистами в данном типе применений» (тепло-гидравлики). И вот для этих специалистов мыmake things easier to read or to express. Переносим свойства объекта туда, где ими удобно пользоваться. (см. рисунок 19)

Рисунок 19. Перенос свойств объекта

Рисунок 19. Перенос свойств объекта

Выводы

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

Красота спасет мир!

© Habrahabr.ru