От полигона участка до токов КЗ: как я написал генератор подстанций

от автора

Это моя первая статья на хабре, потому что хотелось поделиться своим опытом объединения знаний из разных сфер, ну и в целом, рассказать, что вот и такое бывает.
Для начала вводная, я почти всю послеуниверситетскую жизнь работал в энергетике, а конкретно в службе релейной защиты в Ленэнерго. Но ближе к началу 22 года стал задумываться о вечном, ситуация стала ухудшаться и я, как тогда было «модно», тряхнул стариной (благо в школе и универе увлекался программированием) и начал вспоминать как кодить. Довольно быстро попал в коммерческую разработку, специализирующуюся на урбанистике и застройке, где успешно и работаю по сей день.

В определенный момент мне стало жалко, что столько лет накопленного опыта в энергетике улетают в трубу и я решил, что хорошо было бы объединить опыт, полученный в РЗА с опытом, полученным в разработке. Т.к. основной проект на работе был связан с генерацией застройки, работой с картами и алгоритмами генерации, я решил особо не мудрить и сделать что-то похожее, но связанное с подстанциями. В нашем проекте электрические сети были условными и шли из внешней границы территории, из тумана войны. И я подумал, в реальности ведь у нас нет волшебных питающих сетей – городские районы часто питаются через расположенные неподалёку понижающие подстанции. Поэтому хорошо было бы, чтобы пользователь, который задумал какое-то строительство, и который понимает какая мощность ему требуется, чтобы запитать новый район, мог с ходу за пару секунд сгенерировать несколько вариантов расстановки условной и усредненной типовой понижающей подстанции с основным оборудованием, с кабель-каналами, охранными зонами и необходимыми расчетами и прочими штуками, чтобы понимать реально ли это на данной территории и что ему для этого потребуется. Потребуется ли это в действительности меня не очень волновало, хотя я знал, что есть подобные программы для проектантов, но идея уже запустилась в мозге и просто так уже оставить было нельзя. К тому же получив схему подстанции, можно было реализовать другие функции для других сфер. Т.е. первое, что специалист по территориальному планированию мог бы быстро проверить, помещается ли подстанция на разных участках и заранее заметить проблемы. Второе, для сетевой компании или заказчика генератор мог бы быть полезен на стадии обсуждения технического присоединения. Например, чтобы сравнить несколько заранее заданных вариантов класса напряжения и типовой схемы, оценить требуемую площадь, ожидаемые токи КЗ и возможные ограничения по оборудованию. Ещё одно возможное применение (и наверное чуть-ли не главное) — это обучение. На готовой схеме можно показывать и объяснять, как расположение оборудования связано с электрической моделью, что меняется при включении секционного выключателя, откуда берутся токи короткого замыкания, почему для проверки защиты выбирается определённый режим и как первичная схема затем представляется в файле IEC 61850 SCL для каких-нибудь цифровых подстанций.

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

Процесс генерации и окно результата

Процесс генерации и окно результата

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

            С чего начинается генерация

Чтобы реализовать первоначальный вариант от пользователя прежде всего требуется задать территорию, где бы ему хотелось видеть подстанцию, задать нужные параметры, а именно необходимую ему мощность, класс напряжения высокой стороны и некоторые опциональные параметры (класс напряжения низкой стороны, процент резервной мощности, параметры Sk/Ik для сети, тип выключателя). Для фронта (визуальной части) я использовал MapLibre GL, т.к. использовал его в других проектах и для режима редактирования, где пользователь рисует полигон территории и для режима результата, где результат отображается ближе и в 3D. Единственное, что в режиме редактирования используется maplibre-gl-draw для того, чтобы пользователь мог нарисовать территорию подстанции, а в режиме результата — MapLibre fill-extrusion для рисования оборудования и deck.gl для рисования проводов с провисами. Вообще я хотел вместо оборудования использовать 3д модели из Three.js, и даже нашел несколько бесплатных моделей трансформаторов, но сразу уперся в технический момент, что не смог добиться нормального отображения этих моделей на карте из-за рендеринга и отсутствия хорошего опыта фронтенд-скилла, и, наверное, можно было решить этот момент через ИИ, но мне сильно не хотелось поддаваться сладким обещаниям вайбкодинга, т.ч. я от glTF моделей отказался и стал рисовать оборудование через простые геометрические фигуры в MapLibre. Отдельная хохма как я рисовал трансформатор через куб с гребенкой ребер. Зато быстро грузится и вообще симпатично выглядит! 😊 Но фронтенд – это не то, ради чего я начинал писать, основная идея – как правильно сгенерировать.

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

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

2)  Все оборудование, зоны, проезды должны соответствовать минимально допустимому расстоянию по ПУЭ, правилам пожарной безопасности и др.

3)  Минимальный состав оборудования должен влезть на территорию (т.е. нам нет смысла если все оборудование высокой стороны влезет, а для КРУН не останется места)

4)  Оборудование не должно пересекаться и должно располагаться внутри территории

5)  компоновка должна соответствовать электрической схеме (т.е. выключатели и разъединители должны располагаться в логическом порядке присоединения)

6)  Ориентация оборудования должна соответствовать его связям (т.е. оборудование нельзя свободно поворачивать без учёта его конструкции)

Как рождается раскладка

Бэкенд я писал на Kotlin плюс Spring Boot, а вся геометрия — на JTS/GeoTools. Опять же это то, что мне привычно с рабочих моментов. Полигон участка приходит в WGS84, первым делом проецируется в локальную метрическую систему координат (в градусах считать отступы для ПУЭ — такое себе развлечение), и дальше вся математика идёт в метрах.

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

Внешний вид

Внешний вид

Первыми на участке генерируются силовые трансформаторы. Это основа компоновки, т.к. они самые большие, вокруг них маслоприёмники, между ними противопожарные разрывы и если трансформаторы встали неудачно, всё остальное уже не имеет смысла продолжать генерировать. Расставлять их я решил генетическим алгоритмом: хромосома кодирует позиции и углы двух трансформаторов, популяция примерно в 60 особей эволюционирует около 120 поколений, четверть лучших проходит дальше, остальные скрещиваются и мутируют за счет сдвига и поворота. Заведомо негодные варианты отбрасываются сразу: вылез за участок, трансформаторы встали не в линию или не параллельно опорной стене, разрыв между маслоприёмниками меньше нормы. По остальным копится штраф: за прижатость к границе, за отклонение от целевого расстояния между маслоприёмниками, за проблемы с противопожарным барьером

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

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

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

Процесс поиска

Процесс поиска

Кабельные каналы, или как я прикручивал незначительную часть столько же, сколько делал все остальное (ну почти)

Отдельная история – это кабель-каналы вторичных цепей, по которым от оборудования к ОПУ и КРУН идут цепи защит и измерений. Намучился я с ними примерно столько же, сколько возился с ними, работая в релейке. Общая идея следующая: я выделил два этапа:

— зона рядом с высоковольтным оборудованием

— оставшаяся зона вне первой зоны

Если уже сгенерированное оборудование в целом имеет структурированную форму, то там можно, сохраняя необходимое расстояние, вести каналы вдоль оборудования, делая ответвления под кабели, подходящие к оборудованию. Для каждой из двух секций отдельный кабель-канал. А вот для внешней зоны, с одной стороны, надо не удлинять кабель-каналы, но и просто по кратчайшей провести не пойдет. В принятой модели для двух секций формируются раздельные маршруты, идущих к КРУН, кабельных каналов. Это не универсальное требование для любой подстанции, а выбранное проектное ограничение, позволяющее получить структурированную и резервированную трассировку. При этом территория подстанции – не всегда прямоугольник и при кривых территориях возникают проблемы. Здесь я использовал A* на ортогональной сетке с метровым шагом и штрафом за повороты, чтобы трассы получались прямоугольными, что в целом решило проблему, хотя я также осознаю некую условность трассировки.

От геометрии к электричеству

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

Вкратце, из готовой раскладки собирается электрическая модель сети, схема замещения: узлы (шины ВН, шины НН посекционно) и ветви (питающая система, трансформаторы) в относительных единицах. Дальше классический вариант расчёта токов КЗ через матрицу узловых сопротивлений Zшин, которую я считаю обращением матрицы проводимостей Yшин, написав для этого небольшую, но свою комплексную матричную систему расчета. Для каждого коммутационного состояния строится приведённая матрица узловых проводимостей Ybus​, после обращения которой получается матрица узловых сопротивлений Zbus​. Диагональный элемент Zkk ​ используется как эквивалентное сопротивление Тевенина относительно узла КЗ, а соответствующий столбец позволяет определить напряжения остальных узлов и вклады ветвей. В целом для такой небольшой схемы подстанции это излишне, но мы можем рассматривать разные режимы, когда какой-либо из секционных выключателей включен или отключен. Кроме того, возможно генератор расширится и вместе с ней схема подстанции, что усложнит расчет токов КЗ, поэтому подход через Ybus/Zbus и эквивалент Тевенина оказался удобной основой для дальнейшего расширения модели.

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

Панель расчёта токов КЗ

Панель расчёта токов КЗ

Методик расчёта при этом две — ГОСТ Р 52735-2007 «Короткие замыкания в электроустановках. Методы расчёта в электроустановках переменного тока напряжением свыше 1 кВ» и IEC 60909.

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

Доверяй, но проверяй: пересчитываю за своим же генератором

Красивая панель с числами — это хорошо, но давайте все же пересчитаем все на бумажке. Возьму режим D со скриншота — СВ-110 отключен, СВ-10 включен. По высокой стороне секции разделены и каждая питается от своей линии, по низкой — связаны через секционник. КЗ ставлю на шине 1с-10 кВ. Панель утверждает:

I⁽³⁾ = 38.1 кА, iуд = 100.6 кА, RΣ = 0.006 о.е., XΣ = 0.144 о.е.

Исходные данные: два трансформатора по 40 МВА (uк = 10.5%, ΔPк = 172 кВт согласно паспортным данным трансформатора), мощность КЗ системы Sк = 3800 МВА, X/R системы = 12 (выбраны как дефолтные значения системы). Считаю по ГОСТ: базисная мощность Sб = 100 МВА, напряжения средненоминальные 115/10.5 кВ, c = 1.0.

Сначала сопротивления. Sк, и uк задают модуль полного сопротивления, а не реактивную часть поэтому раскладывать на R и X нужно самому.

Система:

|Zс| = Sб/Sк = 100/3800 = 0.026316 о.е.

Rс = |Zс|/√(1 + 12²) ≈ 0.002185 о.е.

Xс = 12·Rс ≈ 0.026225 о.е. => Zc = 0.002185+ j0.026225

Трансформатор:

|Zт| = (uк/100)·(Sб/Sн) = 0.105·100/40 = 0.2625 о.е.

Rт = ΔPк·Sб/(1000·Sн²) = 172·100/(1000·40²) = 0.010750 о.е.

Xт = √(|Zт|² − Rт²) ≈ 0.262280 о.е. => Zt= 0.01075 + j0.26228

Сопротивление одной ветви — Zветви = Zс + Zт, поэтому

Zветви = (0.002185 + j0.026225) + (0.010750 + j0.262280) = 0.012935 + j0.288505 о.е.

Собираю схему замещения режима D. СВ-110 отключен — ветви не связаны по высокой стороне, каждая несёт своё сопротивление системы. СВ-10 включен — на шине 10 кВ обе ветви встают в параллель. Т.к. параметры ветвей одинаковы из-за одинаковых трансформаторов и параметров сети (ЭДС источников), то можно сказать, что Zветвь1 = Zветвь2 и соответственно Zобщ = Zветвь/2

RΣ = 0.012935/2 = 0.006468 о.е.   → панель: 0.006

XΣ = 0.288505/2 = 0.144252 о.е.   → панель: 0.144

Сходится (генератор округляет вывод до третьего знака). Ток КЗ считается по полному модулю комплексного сопротивления:

|ZΣ| = √(0.006468² + 0.144252²) ≈ 0.144397 о.е.

Iб = 100/(√3·10.5) ≈ 5.4986 кА

I⁽³⁾ = c·Iб/|ZΣ| = 5.4986/0.144397 ≈ 38.079 кА

Панель показывает 38.07 в подробной таблице и 38.1.

Дальше перекрёстные проверки:

  • Вклады. Схема симметричная, поэтому неокруглённые вклады Т1 и Т2 одинаковы и в сумме дают полный ток КЗ: по 19.04 кА. Интерфейс показывает каждый как 19.03, а итог как 38.07. Сходится.

  • Напряжение на ВН во время КЗ. Ток ветви в о.е. — 3.463;

Iветви = 1 / Zветви = 1 / (0.012935 + j0.288505) ≈ 0.1551 − j3.4592 о.е.

|Iветви| ≈ 3.4627 о.е.

приближённо ΔUс ≈ |Iветви| · |Zс| ≈ 3.463 · 0.026316 ≈ 0.0911 о.е.

U = 1 - ΔUс ≈ 1 − 3.463·0.0263 ≈ 0. 90895 о.е., а панель: 0.909. При металлическом КЗ на шине 10 кВ шины 110 кВ просаживаются всего на 9%.

  • Сквозной ток по ВН. Ток НН, приведённый через отношение напряжений: 19.04·10.5/115 ≈ 1.74 кА. Панель: 1.74.

  • Ударный ток. XΣ/RΣ = 0.144252/0.006468 ≈ 22.30, постоянная времени

  • Tа = 22.30/314 ≈ 0.0710 с,

  • kуд = 1 + e^(−0.01/Tа) ≈ 1.8686, иiуд =  √2·1.8686·38.079 ≈ 100.63 кА против 100.6 на панели.

Итого: все шесть контрольных точек — ток, суммарные R и X, вклады, остаточное напряжение, сквозной ток, ударный ток воспроизводятся ручным расчётом с учетом округления.

Уставки — сердце релейщика

Дальше по накатанной: раз есть токи КЗ в основных режимах, можно считать уставки защит. МТЗ (ANSI 51), токовая отсечка (50), предварительная оценка базисных токов и начальных параметров для 87T, а также упрощённая оценка функции перегрузки 49, плюс проверка селективности по ступеням времени. Эти результаты не являются готовыми эксплуатационными уставками: они показывают логику предварительного выбора и требуют реальных данных ТТ и конкретного терминала защиты. Очередная условность – мы ничего не знаем про отходящие линии, какие кабели от них отходят и куда, поэтому не считаем ток КЗ у абонента и не считаем уставки на фидерах. Очередной задел на будущее.

Панель с выбором уставок

Панель с выбором уставок

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

IEC 61850, куда же без цифровой подстанции

Содержимое сгенерированного файла SCD

Содержимое сгенерированного файла SCD

Раз уж есть первичная схема и уставки, грех было не довести дело до модных нынче цифровых подстанций. Среди подстанций, где я работал, у меня только одна была цифровой, и то наполовину. Не самая моя изученная тема, т.ч. приходилось параллельно разбираться в семействе стандартов IEC 61850, его информационной модели и языке SCL. Генератор экспортирует результат в SCL-файлы стандарта IEC 61850-6: SSD как системная спецификация с моделью подстанции и требуемыми функциями, а также прототип SCD, в котором к модели подстанции добавляются IED, коммуникационная конфигурация и шаблоны типов данных. В разделе Substation выключатели и разъединители представлены элементами ConductingEquipment с типами CBR и DIS, силовые трансформаторы — элементами PowerTransformer, а функции защит связываются с логическими узлами PTOC, PIOC и PDIF. В SCD на каждую ячейку заводится контроллер присоединения и объединяющее устройство (merging unit), поднимаются GOOSE для блокировок и обменом сигналами между IED и Sampled Values для измерений, станционная и процессная шины. Модель SCL я написал руками (JAXB-классы под нужное подмножество схемы, т.к. полный сгенерированный вариант из XSD был бы переизбытком), при этом каждый выгруженный файл валидируется против официальной XSD стандарта. Каждый файл проходит XSD-валидацию для выбранной редакции схемы. Это подтверждает структурную корректность XML, но не гарантирует полную семантическую совместимость со всеми вендорскими инструментами и реальными IED: она зависит от редакции стандарта, профиля устройства и требований конкретного конфигуратора.

ИИ-ассистент

Под конец я всё-таки добавил тоже модный нынче LLM поиграться. Сначала я сделал довольно простой вариант, когда вопрос пользователя почти не модифицировался и шел модели как есть. Но почти сразу вылез момент, что пошло жуткое вранье, выдумывание формул, несуществующих констант и все это, разумеется, с серьезным видом. Ну, вы знаете, как это обычно бывает. Да, дело еще и в модели, т.к. для теста я взял бесплатный Гигачат. Посмотрел я на это безобразие и реализовал систему с карточками и контекстом. В итоге, модель перестала считать и все числа даёт движок, а ассистент только объясняет, т.е. показывает формулу, подставляет уже посчитанные значения, ссылается на пункт ПУЭ или методику. В дополнение к гигачату, добавил дипсик, который выбрал за дешевизну. С ним дело пошло бодрее.

Объяснения ассистента

Объяснения ассистента

Что в итоге

Итого получилось: Kotlin + Spring Boot + JTS на бэке и Vue + MapLibre + deck.gl на фронте, генетика для компоновки, A* для трасс, Zшин для токов КЗ, уставки из книжек РЗА, экспорт в DXF и IEC 61850 и ассистент, который объясняет, но не считает.

Но главный вывод для меня не технический. Этот генератор занял у меня полгода в свободное от работы время. Хотелось совместить свой специфический опыт из энергетики с программированием. Хотелось написать что-то, что хваленая нейронка не сможет написать. Она, конечно, может, и гораздо быстрее, но какой получится результат? Модель могла бы помочь с шаблонными классами, рефакторингом или поиском ошибки, но она не смогла бы решить, какая компоновка выглядит правдоподобно, какой коммутационный режим является расчётным, где заканчивается допустимое упрощение и почему результат противоречит реальной эксплуатации подстанции. Так что, для тех людей, кто пришел в программирование из других сфер, доменный опыт — это не балласт, который улетает в трубу при смене профессии, а преимущество, которым надо пользоваться. Почти все содержательные решения в этом проекте пришли не из программирования, а из прошлых лет на подстанциях. Код был лишь способом это оформить. Так что, если вы когда-то сменили сферу и вам жалко прошлый опыт — не жалейте, а объединяйте.

 

Краткий словарь

  • РЗА — релейная защита и автоматика.

  • ПС — электрическая подстанция.

  • ВН / НН — высокая и низкая стороны напряжения подстанции.

  • КЗ — короткое замыкание.

  • СВ — секционный выключатель, соединяющий две секции шин.

  • КРУН — комплектное распределительное устройство наружной установки.

  • ОПУ — общеподстанционный пункт управления.

  • ОПН — ограничитель перенапряжений.

  • ТТ — трансформатор тока.

  • ПУЭ — Правила устройства электроустановок.

  • Ybus / Zbus — матрицы узловых проводимостей и сопротивлений электрической сети.

  • SCL — язык описания конфигурации подстанции в IEC 61850; SSD описывает системные требования, SCD — сконфигурированную систему.

  • IED / MU — интеллектуальное электронное устройство и устройство слияния данных (merging unit).

  • GOOSE / SV — быстрый обмен дискретными сигналами и передача оцифрованных измерений в IEC 61850.

  • ANSI 50 / 51 / 87T / 49 — токовая отсечка, максимальная токовая защита, дифференциальная защита трансформатора и защита от тепловой перегрузки.

ссылка на оригинал статьи https://habr.com/ru/articles/1060366/