Потоковый анализ во временной области с блоками EngeeDSP
Потоковый анализ во временной области с блоками EngeeDSP
Продолжаем знакомиться с функционалом EngeeDSP на примере решения задачи, которая ранее рассматривалась в проекте Анализ и обработка во временной области с EngeeDSP.
Основные цели:
- визуализировать сигнал
- удалить постоянную составляющую
- проанализировать статистику
- сгладить форму
Но задача усложняется тем, что теперь мы работаем с потоковым сигналом, а значит импорт отсчётов сигнала, анализ и обработка должны осуществляться "на лету". Алгоритму обработки будут доступны лишь те отсчёты или кадры сигнала, которые пришли на его вход в определённый момент времени симуляции.
Мы рассмотрим модель time_analysis_blocks.engee, состоящую из специализированных блоков библиотеки Обработки сигналов, и узнаем особенности потоковой обработки в динамике:

Импорт и визуализация сигнала
Данные с сенсора так же хранятся в текстовом файле data.txt. Мы считываем их в Рабочую область в матрицу datamat при помощи следующих команд:
# using DelimitedFiles
# datamat = readdlm("data.txt")
Те же команды прописаны в Обратных вызовах модели для того, чтобы данные автоматически подгружались в Рабочую область при открытии модели.
Для чтения отсчётов матрицы из Рабочей области в модель мы используем блок Signal From Workspace, а для того, чтобы выделить из матрицы данных второй столбец, в котором находятся отсчёты исследуемого сигнала - блок Выбора.
Запустим модель на динамическую симуляцию и рассмотрим форму исходного сигнала original.
mdlname = "time_analysis_blocks.engee";
engee.open(mdlname);
engee.run();
Мы можем наблюдать исходный сигнал во времени в окне "Визуализации":
Сигнал содержит постоянную составляющую, от которой нам было бы полезно избавиться для дальнейшего анализа и обработки.
Удаление постоянной составляющей
При работе в скрипте нам был доступен весь сигнал от первого до последнего отсчёта, и удаление постоянной составляющей производилось метдом приближения его формы полиномом 12-го порядка, но в случае потоковой обработки нам нужно использовать другой подход.
В модели сравниваются два способа удаления "тренда" на небольших кадрах сигнала.
Во первых, при помощи блока Удаления тренда, который приближает последовательные отрезки сигнала полиномом первого порядка (то есть линией). Перед данной операцией скалярный сигнал буферизуется в вектора по 32 отсчёта без перекрытия.
Помимо этого, сигнал проходит через подсистему, внутри которой "тренд" вычисляется как среднее значение в окне из 64 отсчётов, и производится вычитание его из сигнала с задержкой:
Сравнивая сигналы на выходе этих двух операций в окне "Визуализации", можно убедиться, что подходы работаю примерно одинаково - необходимо только правильно настроить размеры окна (или кадра). Далее по цепи обработки пойдёт сигнал detrend с выхода блока Unbuffer:

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

Выгрузка результатов симуляции
Для записи сигнала в область переменных используем блок В рабочую область. А также запишем сигнал в виде *.wav файла, чтобы можно было прослушать его в любом медиа-плеере.
DF = collect(workspace_out);
time = DF.time;
value = DF.value;
plot(time,value,leg=false,xguide = "Время, с")
Заключение
Мы познакомились с функционалом блоков EngeeDSP (библиотека Обработка сигналов) для задач потоковой визуализации, анализа и обработки во времени, а также сравнили подходы к решению подобной задачи в скрипте Engee из данного примера.