2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки


Правила форума


Посмотреть правила форума



Начать новую тему Ответить на тему
 
 Фильтрация сигнала (численные методы, C++)
Сообщение15.05.2016, 09:18 


09/01/13
33
Здравствуйте.
Выполняю фильтрацию сигнала мгновенной мощности (т.е. имеются датчики тока и напряжения, с них синхронно поступают данные с определенной частотой). Эта фильтрация позволяет выделить постоянную поставляющую мощности, а именно активную составляющую мощности.
На рисунке представлена схема в matlab, реализующая данную фильтрацию ( ссылка на яндекс диск https://yadi.sk/i/IntrXGamriNhG , не получилось залить картинку сюда).

Задача состоит в том, чтобы реализовать данную фильтрацию на С++. Для интегрирования выбран метод Эйлера (одношаговый).
Попробовал реализовать, но что-то не так сделал. Подскажите, что не так или вообще может другой способ реализации посоветуете.

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
// double Current[] - массив значений мгновенных токов
// double Voltage[] - массив значений мгновенных напряжений
// double Step - шаг опроса
// int N - количество значений в массиве токов (напряжения)

double Filter (double Current[], double Voltage[], double Step, int N) {
        double y1Past=0; // предыдущее значение y1
        double yPast=0;  // предыдущее значение y
        double xPast=0;  // предыдущее значение х
        double y1=0;     // текущее значение y1
        double y=0;      // текущее значение y
        double x=0;      // текущее значение х
        double ksi=0.707;
        double T=1/(5*M_PI);
        for (int i = 0; i < N; i++) {
                x= (Current[i] * Voltage[i] - y1Past - 2*ksi*T*yPast)/(T*T);
                y= yPast + (x-xPast)*Step;
                xPast = x;
                y1 = y1Past + (y-yPast) * Step;
                yPast = y1 ;
        }
                return y1;
}
}

 Профиль  
                  
 
 Re: Фильтрация сигнала (численные методы, C++)
Сообщение15.05.2016, 12:04 
Заслуженный участник
Аватара пользователя


23/07/08
10910
Crna Gora
(Неверная схема удалена.)

Распилите Ваш вопрос пополам: запишите в $\TeX$ математическую формулу для текущего значения $y_1$, и получатся два отдельных более простых вопроса:
$\bullet$ Правильная ли формула?
$\bullet$ При условии, что формула верна, правильно ли Вы реализовали её в программе?

-- Вс май 15, 2016 12:33:22 --

Судя по схеме, использовать надо предыдущее значение $y$, а Вы оператором yPast=y1; запоминаете значение $y_1$.

 Профиль  
                  
 
 Re: Фильтрация сигнала (численные методы, C++)
Сообщение15.05.2016, 13:48 


09/01/13
33
Извините, скинул не тот скрин.
Вот нужный скрин
Изображение

svv в сообщении #1123667 писал(а):
Судя по схеме, использовать надо предыдущее значение $y$, а Вы оператором yPast=y1; запоминаете значение $y_1$.

Это тоже я заметил.

1. после преобразования передаточная функция примет вид W(p)=1/(T^2\cdot p^2+2\cdot\xi\cdot T\cdot p+1)
$W(p)=y1/u$
получаем $T^2 \cdot y1''+2\cdot\xi\cdot T\cdot y1'+y1=u$
относительно старшей производной $y1''=(u-2\cdot\xi\cdot T\cdot y1'-y1)/T^2$

Код выглядит так
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
// double Current[] - массив значений мгновенных токов
// double Voltage[] - массив значений мгновенных напряжений
// double Step - шаг опроса
// int N - количество значений в массиве токов (напряжения)

double Filter (double Current[], double Voltage[], double Step, int N) {
        double y1Past=0; // предыдущее значение y1
        double yPast=0;  // предыдущее значение y
        double xPast=0;  // предыдущее значение х
        double y1=0;     // текущее значение y1
        double y=0;      // текущее значение y
        double x=0;      // текущее значение х
        double ksi=0.707;
        double T=1/(5*M_PI);
        for (int i = 0; i < N; i++) {
                x= (Current[i] * Voltage[i] - y1Past - 2*ksi*T*yPast)/(T*T);
                y= yPast + (x-xPast)*Step;
                xPast = x;
                y1 = y1Past + (y-yPast) * Step;
                yPast=y;
                y1Past = y1 ;
        }
                return y1;
}

Реализация все равно не корректна :(

 Профиль  
                  
 
 Re: Фильтрация сигнала (численные методы, C++)
Сообщение16.05.2016, 00:04 
Заслуженный участник


09/09/10
3729
Ну тогда ручками считаете шага три или даже четыре, потом вставляете внутрь цикла отладочную печать, запускаете, читаете вывод, сравниваете с посчитанным вручную, находите, где начинаются расхождения и исправляете.

 Профиль  
                  
 
 Re: Фильтрация сигнала (численные методы, C++)
Сообщение16.05.2016, 02:44 
Заслуженный участник
Аватара пользователя


23/07/08
10910
Crna Gora
У Вас неправильно организовано интегрирование. Не нужно вычитать xPast и yPast.
Думаю, это не единственная ошибка.

 Профиль  
                  
 
 Re: Фильтрация сигнала (численные методы, C++)
Сообщение16.05.2016, 03:39 


09/01/13
33
svv, Joker_vD спасибо за помощь. Результат программы на С++ и моделирования в матлаб на разных участках (от 0 до 1 секунды) очень близки. Сказывается маленький шаг дискретизации.
Еще раз спасибо, без Вас ничего бы не получилось.

 Профиль  
                  
 
 Re: Фильтрация сигнала (численные методы, C++)
Сообщение16.05.2016, 14:19 
Заслуженный участник
Аватара пользователя


23/07/08
10910
Crna Gora
colding
Спасибо за благодарность :-) , но всё-таки имейте в виду, что вот такое:
$s_i=s_{i-1}+(y_i-y_{i-1})h$
— это не интегрирование $y$ ни в каком приближении. (обозначения мои)

 Профиль  
                  
 
 Re: Фильтрация сигнала (численные методы, C++)
Сообщение16.05.2016, 18:35 


09/01/13
33
svv в сообщении #1123916 писал(а):
colding
Спасибо за благодарность :-) , но всё-таки имейте в виду, что вот такое:
$s_i=s_{i-1}+(y_i-y_{i-1})h$
— это не интегрирование $y$ ни в каком приближении. (обозначения мои)

Правда Ваша :facepalm:

Может кому-нибудь пригодится (но думаю, что этот материал мало ценен):
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
// double Current[] - массив значений мгновенных токов
// double Voltage[] - массив значений мгновенных напряжений
// double Step - шаг опроса
// int N - количество значений в массиве токов (напряжения)

double Filter (double Current[], double Voltage[], double Step, int N) {
        double y1Past=0; // предыдущее значение y1
        double yPast=0;  // предыдущее значение y
        double xPast=0;  // предыдущее значение x
        double y1;       // текущее значение y1
        double y;        // текущее значение y
        double x;        // текущее значение x
        double ksi=0.707;
        double T=1/(5*M_PI);
        for (int i = 0; i < N; i++) {
                x = (Current[i] * Voltage[i] - y1Past - 2*ksi*T*yPast)/(T*T);
                y = yPast + (x)*Step;
                y1 = y1Past + (y) * Step;
                yPast= y;
                y1Past = y1 ;

        }
                return y1;
}


Результат отрисовки:
Изображение

Для сравнения, приложу результаты матлаба
Изображение

 Профиль  
                  
 
 Re: Фильтрация сигнала (численные методы, C++)
Сообщение16.05.2016, 19:37 
Заслуженный участник
Аватара пользователя


23/07/08
10910
Crna Gora
Отлично! :D

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 9 ] 

Модераторы: Модераторы Математики, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group