- BrainTools - https://www.braintools.ru -
Дисклеймер: Это продолжение первой статьи [1] про PLC AI Studio — инструмент, который заставляет ИИ сначала разобраться в задании, а потом писать код ПЛК, и проверяет результат фактами. В первой части был разобран базовый режим: одна установка, один IOLIST + одно ТЗ → один проверенный ST-файл. Здесь рассказываю то, что в прошлый раз было только тизером «что дальше»: многопроектный (многосистемный) режим и маршрутные окна — пошаговую навигацию по программе. Инструмент по-прежнему проходит тестирование, и я по-прежнему публикую до релиза, чтобы услышать инженеров-практиков.
В первой части я показал, как ИИ из «уверенного галлюцинатора» превращается в управляемого исполнителя: разбор задания перед генерацией, три специализированных агента (R2-PLCGen, Agents4PLC, truST Platform), проверка кода в программном симуляторе (Tier S) и в настоящем компиляторе matiec (Tier H), детерминированный ремонт типовых ошибок и финальное слово всегда за инженером.
Всё это работало для одной установки. Но я закончил статью честным признанием: реальный крупный объект — это не одна установка. И обещал многосистемный режим. Он теперь есть. Расскажу, как он устроен — и почему по дороге пришлось переделать саму навигацию по программе.
Возьмём типичный объект — производственный корпус. Внутри:
приточно-вытяжная вентиляция (несколько систем П1, П2, …),
индивидуальный тепловой пункт (ИТП),
пожарная сигнализация,
дымоудаление и подпор воздуха,
конвейерная линия,
водоподготовка.
Каждая система живёт в своём техническом задании и, нередко, в своём ПЛК. Но работают они в единой цепочке:
при пожаре пожарная сигнализация останавливает приточки и запускает дымоудаление и подпор;
приточка с водяным калорифером зависит от готовности теплоносителя от ИТП;
конвейер не пускается, пока вентиляция зоны не вышла на режим.
Эти связи — самое важное и самое хрупкое в проекте. И при этом они почти нигде не формализованы: инженер держит их в голове или, в лучшем случае, в Excel. Когда систему программируют по отдельности, межсистемная блокировка — первое, что ломается.
Многопроектный режим — это попытка вытащить эти связи на свет, дать инженеру их явно подтвердить и только потом генерировать код, единый для всего объекта.
В первой части я уже объяснял ST, IOLIST, POU, RAG и matiec. Для второй части добавлю ещё несколько.
GVL (Global Variable List) — список глобальных переменных. В CODESYS и других средах это переменные, видимые всем программам проекта. Именно через них одна система передаёт сигнал другой: например, переменная gFIRE_ALARM (глобальный сигнал «Пожар»), которую пишет пожарная сигнализация, а читают приточки и дымоудаление.
Межсистемная блокировка — логическая связь, при которой состояние одной системы влияет на работу другой. Классика: «при пожаре закрыть противопожарный клапан и остановить вентилятор».
Топологический порядок — порядок, в котором системы нужно обрабатывать, чтобы «производитель» сигнала шёл раньше «потребителя». Пожарная сигнализация и ИТП производят сигналы, которые потребляют приточки, — значит, их логично [2] рассматривать первыми.
Ко-симуляция — совместный прогон нескольких программ в одном расчётном цикле через общую таблицу сигналов. В отличие от проверки одной POU, ко-симуляция показывает, как системы реагируют друг на друга.
Контракт интерфейсов — формализованное описание, какие межсистемные сигналы существуют, какого они типа, кто их производит и кто потребляет. По сути — техническое соглашение между системами, которое раньше жило только в голове инженера.
Когда базовый режим оброс возможностями — разбор задания, три агента, две ступени проверки, аудит, редакторы, отчёт, — возникла банальная проблема: в программе стало легко потеряться. Что нажимать первым? Что обязательно, а что нет? На каком я шаге?
Поэтому появилось маршрутное окно — вертикальная панель-чеклист, которая ведёт инженера по шагам и подсвечивает следующее действие. Это не модальное окно, которое мешает работать: панель живёт сбоку, её можно скрыть, менять размер (тянуть за угол — сужать, расширять) и она не перекрывает рабочую область.
Маршрутных окна теперь два, по числу режимов работы — и в заголовке проводника две отдельные кнопки:
🧭 Объект — для одиночного проекта (одна установка);
🏢 Комплекс (много систем) — для комплексного объекта.
Какой режим вы выбрали кнопкой, так и работает ИИ. Панели взаимно исключаются: открыли одну — вторая прячется, чтобы не путаться.
Раньше одиночный маршрут был коротким: загрузить ТЗ → загрузить теги → выбрать сценарий → сгенерировать. Но в процессе работы над многосистемным режимом стало очевидно, что и одиночному проекту не хватает того же дисциплинирующего разбора. Поэтому перед генерацией добавились три шага:
Взаимосвязи — здесь инженер описывает зависимости и блокировки внутри самой установки (что от чего зависит, какие режимы, какие защиты).
Критические запреты — что обязательно и что запрещено (например: «запрещено пускать вентилятор при сработавшем термостате защиты от замерзания»).
Понимание системы — сводка перед генерацией: загружено ли ТЗ, есть ли теги, какой сценарий, заданы ли взаимосвязи и запреты. Инженер подтверждает — и только потом идёт генерация.
Эти взаимосвязи и запреты не остаются «для галочки»: они подмешиваются в задание для ИИ в обоих потоках генерации — и в одиночном провайдере, и в мультиагентном. ИИ получает их явным блоком, а не вынужден угадывать.
Кнопка 🏢 Комплекс открывает расширенный маршрут. Принцип всего режима один: ИИ предлагает — инженер принимает или переписывает по-своему. Никаких «доверьтесь ИИ». Везде, где ИИ что-то решает, последнее слово — за человеком.
На вход подаётся ZIP-архив, где папка = система. Внутри каждой папки — её ТЗ (txt/pdf) и IOLIST (csv/xlsx). Программа разбирает архив, распознаёт системы, считывает теги и определяет тип каждого канала по реальному формату IOLIST: DI/DO/AI/AO → дискретный/аналоговый вход/выход, и сразу сопоставляет с типом МЭК (BOOL/REAL) и направлением.
Откуда берётся такой аккуратный архив? Это результат предварительного этапа: моё приложение анализирует ТЗ заказчика (даже если оно написано «от руки», без внятных тегов), само разбивает объект на оборудование и формирует теги. На вход многопроектного маршрута уже приходит структурированная картина.
В одном объекте системы относятся к разным инженерным мирам: приточка — это bms_hvac, конвейер — conveyor, водоподготовка — water_treatment, пожарная — fire_alarm. От категории зависит, какой доменный промпт получит система при генерации (в первой части я показывал, почему ПВУ и конвейер нельзя писать одним промптом).
ИИ предлагает категорию каждой системы по её имени, ТЗ и сигналам. Инженер проверяет и при необходимости меняет. Кстати, именно здесь вылез поучительный баг: приточка, в IOLIST которой есть «пожарная заслонка», поначалу классифицировалась как пожарная система. Пришлось научить классификатор не путать наличие противопожарного клапана в составе ОВ с системой пожарной сигнализации — взвешивать имя и ТЗ выше, чем пару сигналов в списке.
Это сердце режима. Инженер загружает общее ТЗ взаимодействий (как всё работает в единой цепочке), и ИИ анализирует весь архив целиком — имена систем, их ТЗ и сигналы — и предлагает карту межсистемных связей: кто кому какой сигнал передаёт. Например: «Пожарная сигнализация → Центральный кондиционер П1.1: FIRE_ALARM (останов вентиляции)».
Дальше — ключевой принцип. ИИ предлагает, а инженер:
принимает предложенную связь как есть,
удаляет лишнее,
или дописывает свою (выбирает систему-источник, систему-потребитель и имя сигнала).
Источник предложения честно подписан: «предложено ИИ (анализ архива)» или «эвристика». Если у вас связи уже формализованы — можно ничего не принимать от ИИ и задать их руками.
Правила уровня всего объекта: что обязательно и что запрещено. Они подмешиваются в промпт каждой системы, чтобы ни один агент про них не «забыл». Это то место, где инженер закладывает безопасность всего объекта одним списком.
Какие системы в какой ПЛК и какой марки (ОВЕН, WAGO, CODESYS-совместимый и т.д.). Это определяет, какие POU объединяются в один проект и под какую платформу пойдёт экспорт. ИИ и здесь предлагает черновик: инженерные системы — в общий контроллер, пожарную автоматику, дымоудаление и подпор — на отдельные (безопасность принято изолировать). Инженер принимает или переопределяет — состав и марку.
Финальный экран перед генерацией. Программа собирает всю картину: системы и их категории, карту связей, распределение по контроллерам, список запретов — и показывает раздел «что уточнить». Здесь же работает автоматическая проверка интерфейсов: если какой-то межсистемный сигнал кто-то читает, но никто не производит (висячая ссылка), или один сигнал производят сразу несколько систем — это подсвечивается, и подтвердить понимание нельзя, пока не исправлено.
Это не «пусть ИИ угадает связи». Это «инженер явно верифицирует понимание объекта, прежде чем нажать кнопку».
Когда понимание подтверждено, из карты связей автоматически формируется контракт интерфейсов:
Общий GVL межсистемных сигналов — единый список глобальных переменных с префиксом g и автоматически выведенным типом (сигнал «Пожар» — BOOL, «температура подающей воды» — REAL). Здесь, к слову, тоже была ловушка: имя HEAT_READY поначалу ошибочно становилось REAL из-за подстроки. Пришлось типизировать по токенам, а не по случайному совпадению букв.
Матрица блокировок — наглядная таблица «источник → потребитель → сигнал».
Контракт на каждую систему — что она читает (входы от других) и что пишет (выходы для других), под едиными именами.
Этот контракт — то самое техническое соглашение, которое раньше жило только в голове. Теперь оно явное, проверяемое и попадает в задание каждому агенту: «используй именно эти глобальные имена, не выдумывай свои».
Здесь важный момент, на котором я в процессе сам споткнулся и переделал. Был соблазн «нагенерировать всё одним ИИ по кругу». Это неправильно: в одиночном режиме код пишут три агента с аудитом и сравнением вариантов, а инженер выбирает лучший. Многопроектный режим не должен быть слабее.
Поэтому генерация идёт посистемно через тот же штатный поток, что и в одиночном проекте:
Маршрут загружает входы текущей системы в рабочую область — её теги, ТЗ, блок межсистемного контракта (что читать/писать) и критические запреты, и выставляет нужную категорию.
Инженер запускает штатную генерацию: работают R2-PLCGen, Agents4PLC, truST Platform, идёт аудит, инженер выбирает лучший вариант — код оказывается в редакторе.
Инженер проверяет, при необходимости правит логику, и нажимает «Подтвердить и сохранить систему». Код этой установки сохраняется (на диск, по системе), и маршрут переходит к следующей.
Системы идут в топологическом порядке — производители сигналов раньше потребителей. Подтверждённые системы помечаются, и к их коду всегда можно вернуться — открыть в редакторе. По каждой системе подключаются и ваши загруженные библиотеки функциональных блоков, если они активны, — ровно так же, как в одиночном режиме (это серверная логика, она не зависит от режима).
То есть многопроектный режим — это не «другая программа внутри программы». Это оркестратор поверх той же проверенной одиночной генерации: он готовит контекст для каждой системы и собирает результат.
В первой части главным принципом была «проверка фактами, а не доверие ИИ». Для одной установки это симулятор Tier S и компилятор matiec. Для объекта появляется новый уровень проверки — ко-симуляция взаимных блокировок.
Все подтверждённые системы запускаются в одном расчётном цикле, разделяя общую таблицу g-сигналов. В топологическом порядке каждой системе подаются сигналы, которые она читает, она исполняется, и сигналы, которые она пишет, собираются обратно — так производитель и потребитель связаны уже внутри одного цикла.
Дальше подаётся сценарий — например, «Пожар» — и программа показывает трассу по тактам. На реальном прогоне это выглядит так:
такты до пожара: приточка работает (насос включён), дымоудаление стоит;
такт, в котором подан пожар: gFIRE_ALARM = TRUE → в том же цикле приточка встаёт (насос выключен), дымоудаление запускается;
дальше блокировка держится.
Это и есть интеграционный тест взаимосвязей. Не «ИИ так написал» и не «вроде должно работать» — а реально просчитанное поведение [3] всего объекта на подаче аварийного сценария.
Когда все системы подтверждены, нажимается «Собрать ZIP проект». В архиве:
папка на каждую установку — её сгенерированный код плюс исходные ТЗ и IOLIST;
общая папка _PROJECT/ — склеенный код всего объекта (общий GVL + все POU по порядку) и готовая пояснительная записка по ГОСТ в Word.
Записка — это не «таблицы ради таблиц», а тот же ГОСТ-документ, что формируется в одиночном режиме: с описанием состава, технических характеристик и алгоритмов, плюс раздел межсистемных связей и матрица блокировок. Системы пожарной автоматики в записке отдельно помечены как черновик, требующий проверки и сертификации — об этом ниже.
Боевая генерация требует живого ИИ. Вся логика маршрута, контракта, ко-симуляции и сборки проверяется автотестами, но сам код пишет внешняя языковая модель — её итоговое качество вы проверяете на своём ключе и своём проекте.
Пожарные системы — это черновик. Код пожарной сигнализации, дымоудаления и подпора формируется как заготовка и обязан пройти проверку и сертификацию профильным специалистом по действующим нормам пожарной безопасности. Программа явно об этом предупреждает и в интерфейсе, и в отчёте.
Ко-симуляция честна ровно настолько, насколько честен код. Она доказывает блокировки при условии, что системы используют согласованные имена межсистемных сигналов, — поэтому контракт и прокидывается в задание каждому агенту.
Фактический импорт проекта в конкретную среду (CODESYS, e!COCKPIT и т.д.) — следующий рубеж; межсистемный обмен через GVL формируется, но финальную привязку проекта проверяет инженер.
И отдельно — про мелочь, которая на практике бесит больше всего: маршрут проекта теперь сохраняет состояние между перезагрузками страницы. Раньше случайный F5 обнулял весь прогресс; теперь системы, категории, связи, запреты, распределение и подтверждённый код подтягиваются обратно. Маленькая вещь, но именно из таких складывается доверие к инструменту.
Как и в первой части, публикую до релиза ради обратной связи практиков.
Как вы сейчас фиксируете межсистемные блокировки на крупном объекте — есть ли у вас рабочий стандарт, или это всегда «по месту»? Подошёл бы вам формат «контракт интерфейсов» (общий GVL + матрица блокировок) как часть проектной документации?
Ко-симуляция взаимных блокировок на программном симуляторе — это для вас аргумент при приёмке, или заказчику нужна только проверка на железе?
Распределение систем по ПЛК — чаще решение проектировщика или диктуется комплектацией от вендора?
Маршрутные окна-чеклисты: помогает ли такая пошаговая навигация, или опытному инженеру это мешает? Где грань между «ведёт за руку» и «не путается под ногами»?
Какой формат вы бы хотели видеть на выходе для комплексного объекта — ZIP с папками по системам, единый проект среды, или что-то ещё?
Жду комментариев, особенно критических. Отвечу на всё.
Автор: ura-ch
Источник [4]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/31519
URLs in this post:
[1] первой статьи: https://habr.com/ru/articles/1044392/
[2] логично: http://www.braintools.ru/article/7640
[3] поведение: http://www.braintools.ru/article/9372
[4] Источник: https://habr.com/ru/articles/1045772/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1045772
Нажмите здесь для печати.