Привет всем!

Ко мне часто обращаются молодые инженеры с вопросом: «А зачем вообще идти в аспирантуру?» Я обычно рассказываю, какие плюсы и минусы есть у такого шага — как учёба прокачивает навыки, помогает упорядочить знания и научиться грамотно ставить эксперименты. Но выбор каждому нужно делать самому, стоит ли прокачивать такие навыки или нет.

И вот во время одного такого разговора, погрузившись в воспоминания о собственных научных делах, я случайно наткнулся в интернете на хакатон. И угадайте, по какой теме? По диагностике асинхронных электродвигателей — прямо в точку! Своего рода - мой незакрытый гештальт во время собственного обучения.

Решили с товарищем поучаствовать. Правда, мы были вдвоём, а в команде могло быть до 9 человек. Спойлер: мы не взяли первое место и даже не попали в шорт‑лист из 9 команд — заняли 16‑е место из 35.

Да, это не история про успех, а про опыт — тот самый, который, как известно, «сын ошибок трудных». Главный урок прост: да, быть экспертом и действовать в одиночку — это неплохо. Но настоящая суперсила — в команде!

А теперь — обо всём по порядку…

Как ИИ видит ремонт электродвигателя, любопытно
Как ИИ видит ремонт электродвигателя, любопытно

Постановка задачи и разработка приложений

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

Работа велась совместно с коллегой(уговорил его в последний день подачи заявок): я сосредоточился на разработке десктопного приложения на JavaFX — автоматизированного рабочего места (АРМ) диагноста. С десктопным приложением мне было (и есть) гораздо проще разобраться. Собрать прототип для анализа данных и диагностировать «пациентов» по потребляемому току – на все ушло пара вечеров. Затем, используя эту основу, мы совместно создали веб‑приложение(про него мы поговорим в следующий раз), которое позволяет проводить диагностику и автоматически рассчитывать индекс технического состояния за счёт встроенной нейронной сети.

Функционал приложения, обработка сигналов, датасеты и его величество – преобразование Фурье

Основное окно приложен��я
Основное окно приложения

Представьте себе «умный микроскоп» для электродвигателей — такая ассоциация приходит мне на ум про разработанное приложение. Напоминает АРМ диагноста или врача, сидишь и исследуешь результаты анализов. Разберём, как оно работает — шаг за шагом.

Шаг 1. Подготовка сигнала: убираем лишнее

Прежде чем анализировать сигнал, его нужно «причесать» — очистить от всего ненужного. Для этого мы:

  • Фильтруем. Применяем цифровой фильтр нижних частот (ФНЧ) с частотой среза 1 кГц — а если нужно, можем снизить ещё. Почему именно так? Дело в том, что большинство проблем двигателя (эксцентриситет ротора, межвитковые замыкания, износ подшипников) «проявляются» на низких частотах. Фильтр убирает высокочастотные помехи и шумы — они только мешают диагностике. Плюс снижается риск алиасинга при дальнейшей обработке.

    Собственно, в этом диапазоне и кроются самые частые проблемы с механической частью – эксцентриситеты ротора, дефект подшипников и даже обрывы стержней беличьей клетки.
    Собственно, в этом диапазоне и кроются самые частые проблемы с механической частью – эксцентриситеты ротора, дефект подшипников и даже обрывы стержней беличьей клетки.
  •   Взвешиваем. К очищенному сигналу применяем «окно Хемминга» — это такой математический приём, чтобы сделать спектр более плавным. Он помогает:

    • избежать «размазывания» спектра при анализе (так называемой спектральной утечки);

    • точнее определить амплитуды разных частот;

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

В коде это выглядит следующим образом.

       public double[] applyHammingWindow(double[] signal) {
            int N = signal.length;
            int Fs = 25600; // Частота дискретизации исходных датасетов
            int order = 4; // Порядок фильтра
            int cutOff = 1000; // Частота среза
            
            Butterworth flt = new Butterworth(Fs);
            double[] result = flt.lowPassFilter(signal, order, cutOff);
            
            double[] windowedSignal = new double[N];
            Hamming w1 = new Hamming(N);
            double[] out = w1.getWindow();

           
           for (int i = 0; i < N; i++) {
                windowedSignal[i] = result[i] * out[i];
            }
            return windowedSignal;
        }

Шаг 2. Смотрим, как меняется ток во времени

Система рисует осциллограммы тока, при этом пользовать может:

  • приближать и отдалять картинку, чтобы рассмотреть любой участок подробнее;

  • анализировать длительные записи — даже если они идут часами.

Шаг 3. Вектор Парка: превращаем 3 фазы в наглядную картинку

Я добавил реализацию преобразования Кларка‑Парка (αβdq). Давно читал вот эту статью http://news.elteh.ru/arh/2008/49/10.php?ysclid=mn0jmaeyyv442788543 и подумал, что помимо самого спектра тока, неплохо бы добавить какой то альтернативный метод анализа. Что же делает преобразование?

  • берёт трёхфазные токи (Ia​, Ib​, Ic​) и превращает их в двухфазную вращающуюся систему координат (Id​, Iq​);

  • рисует траекторию вектора тока на плоскости d-q — получается красивая и понятная картинка;

Шаг 4. Спектральный анализ: раскладываем сигнал на частоты

Дальше в дело вступает быстрое преобразование Фурье (БПФ / FFT). На выходе мы получаем следующее:

  • амплитудный и фазовый спектр исходного сигнала;

  • гармонические и субгармонические составляющие;

  • автоматически выделенные самые сильные гармоники и их амплитуды;

Шаг 5. Пакетная обработка: анализируем не один файл, а сразу много

Испытаний может быть очень много. Даже в тестовом датасете их было 40 штук. Не нужно загружать и анализировать файлы по одному! Поэтому система должна уметь:

  • принимать сразу пачку файлов (в том числе в формате CSV) за одну операцию;

  • применять одинаковые настройки ко всем наборам данных — например, один и тот же фильтр или тип окна;

  • сравнивать результаты между разными файлами прямо в одной сессии — удобно для отслеживания изменений во времени.

Шаг 6. Всё на одном экране: сравниваем и делаем выводы

Все результаты — осциллограммы, векторные диаграммы, спектры — выводятся на едином интерфейсе. Мне показалось это удобным, а главное позволяет:

  • видеть, как меняется состояние двигателя с течением времени(в зависимости от датасетов);

  • вовремя замечать появление новых гармоник — они могут указывать на развитие дефектов;   

  • сопоставлять изменения в спектре с динамикой вектора Парка и получать полную картину происходящего.

А насколько это быстро?

Сразу скажу что некоторые решения пришлось пересматривать и оптимизировать под реальную работу:

  • Обработка CSV‑файлов. Файл размером 70 МБ анализируется за ≤2 с на обычной рабочей станции (процессор не ниже Intel Core i5, 16 ГБ ОЗУ). Вот здесь пришлось поэкспериментировать. Но эффективнее всего получилось использовать BufferedReader. 

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

А знаете, что самое приятное? Разрабатывать такое было не так уж сложно — спасибо экосистеме Java! Библиотека JDSP (Java Digital Signal Processing,  — https://jdsp.dev/) взяла на себя всю тяжёлую работу по обработке сигналов. В Java вообще полно крутых библиотек — с ними прототипы собираются как конструктор, и можно быстрее переходить от идеи к работающему решению.

Более подробно про интерфейсы

Мы коснулись алгоритмической и математической части, но стоит поговорить и о внешнем виде приложения. Для чего нужны все эти графики, настройки и куда именно нужно смотреть.

Итак, основные графики:

а) Временная область (верхний левый угол)

  • Отображает форму тока в зависимости от времени (ток, А по вертикали; время, с — по горизонтали).

  • Используется для анализа периодичности, искажений, выбросов в сигнале.

  • Загружен датасет current_1.csv.

б) Амплитуда вектора Парка тока (верхний правый угол)

  • Показывает модулированный сигнал (вероятно, после преобразования Парка).

  • Помогает анализировать векторные характеристики тока.

в) Частотная область (FFT, нижний левый угол)

  • Спектрограмма, полученная с помощью быстрого преобразования Фурье (FFT).

  • Ось X — частота (Гц), ось Y — амплитуда.

  • Видны пиковые значения, указывающие на доминирующие частоты в сигнале.

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

public static void setupTooltip(XYChart.Data<Number, Number> data, String seriesName) {

    Circle circle = new Circle(2);

    circle.setOpacity(0.5);

 

    circle.setOnMouseEntered(event -> {

        Tooltip tooltip = new Tooltip(

            "Y: " + data.getYValue() + "\n" +

            "X: " + data.getXValue() + "\n" + seriesName

        );

        tooltip.setShowDelay(Duration.ONE);

        Tooltip.install(circle, tooltip);

    });

 

    data.setNode(circle);

}

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

  • Одновременно отображаются спектры нескольких датасетов (current_1.csvcurrent_3.csv и т. д.).

  • Каждый датасет окрашен в свой цвет для дифференциации.

  • Позволяет сравнивать спектры разных сигналов на одном графике.

    Окно для пакетной обработки датасетов
    Окно для пакетной обработки датасетов

Набор настроек получился минималистичным, но функциональным. Что можно поменять:

  • Отн. ед./дБ — выбор единицы измерения амплитуды (относительные единицы или децибелы).

  • Частота — установка диапазона частот для анализа (здесь — 100 Гц).

  • Спектр сигнала — выбор типа анализируемого сигнала («Ток фазы» или «модуль вектора Парка тока»).

Ну и немного украшательств в виде я тоже добавил:

  • Подсказки на графиках — при наведении курсора отображаются значения точек (время, амплитуда, частота и т. д.).

  • Легенда — в всплывающем окне указана связь цветов с конкретными CSV-файлами.

  • Ползунки и шкалы — для детального масштабирования графиков.

  • Кнопки управления (файл, редактировать, помощь) — для работы с данными и справки.

И, конечно, интерфейс доступен в двух темах оформления – темной и светлой. Это, пожалуй, самое легкое во всей разработке.

 

И что получилось в итоге
И что получилось в итоге

Вывод и очередной урок

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

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

Так что, если кто-то сейчас бьётся головой о какой-нибудь сложный софт — не отчаивайтесь. Это часть пути. Каждый такой опыт — это кирпичик в фундаменте вашего будущего профессионализма. И я уверен, именно эти трудности помогут вам создать что-то действительно крутое!