|
Усреднение периодической величины |
|
|
|
Nov 24 2011, 18:47
|
Группа: Участник
Сообщений: 8
Регистрация: 16-09-09
Пользователь №: 52 413

|
Доброго дня, форумчане!
У меня есть периодическая величина, значение которой нужно усреднить средним арифметическим (X1+X2+..+Хn)/n - в простейшем случае (Х1+Х2)/2. Величина - это угол сдвига фаз, меняющийся от 0 до 359 градусов. Измерение ведется путем захвата таймером интервала времени между фронтами прямоугольных импульсов. При условии синфазности сигналов (должно измеряться значение 0 градусов), появляется неразрешимая пока мною проблема: из-за джиттера, являющегося следствием шума на входе, начинается гонка фронтов сигналов, при этом я получаю захваченные таймером интервалы, соответствующие углу в градусах, к примеру в такой последовательности: 1, 359, 1, 359.... Если попытаться усреднить эту последовательность, то получится значение 180 градусов, вместо ожидаемого нуля. Вариант перехода к формату -180->0->+180 уже рассматривался, и он имеет такую же проблему при усреднении, возникающую в окрестностях 180 градусов (-179,+179 после усреднения дает 0 вместо 180). Алгоритм нужен для целочисленного МК, желательно простой арифметическо-логический. Какие есть варианты решения этой проблемы?
|
|
|
|
|
Nov 24 2011, 20:10
|
Группа: Участник
Сообщений: 8
Регистрация: 16-09-09
Пользователь №: 52 413

|
Цитата Перед прибавлением очередного значения к сумме, новое значение корректируется на -360 или 0 и выбирается ближайшее. GetSmart, извините, не уловил смысл того что нужно сделать. Можете пояснить на примере: что нужно сделать с цифрами, если сначала приходит значение 1, затем 359, чтобы получить результат 0?
|
|
|
|
|
Nov 24 2011, 20:38
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Brains @ Nov 25 2011, 01:10)  GetSmart, извините, не уловил смысл того что нужно сделать. Можете пояснить на примере: что нужно сделать с цифрами, если сначала приходит значение 1, затем 359, чтобы получить результат 0? 359 можно представить как -1, если прибавить к исходному значению -360. Вообще, можно прибавлять к углу хоть -360, хоть +360 и это будет тот же угол. Так что, если первое число было 1, а второе 359, то смотрим разницу между ними = 358. А если к 359 прибавить -360, то разница между числами будет 2 (1 - (359-360)). А 2 меньше чем 358. Значит его и используем в среднем арифметическом. Соответственно, 1+(-1) = 0. 0 это и есть среднее значение. Разницу только нужно сравнивать по модулю (без знака).
Сообщение отредактировал GetSmart - Nov 24 2011, 20:45
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Nov 24 2011, 21:09
|
Группа: Участник
Сообщений: 8
Регистрация: 16-09-09
Пользователь №: 52 413

|
Цитата Можно от угла перейти к декартовым координатам (x,y) и усреднять их а потом обратно к углу вернуться (это реализуемо в целочисленой арифметике). Но, насколько я понимаю, это преобразование задействует тригонометрические функции, а они выполняются долго. GetSmart, спасибо, я попробую этот метод. Если переложить в псевдокод получится: Код if(|Xn - Xn-1| < |Xn - 360 - Xn-1|) Acc += Xn - 360; else Acc += Xn; Xn-1 = Xn; Понятно стало, что кроме аккумулятора и счетчика накопления потребуется еще переменная предыдущего отчета Xn-1, необходимая для предложенного вами кастинга. Но еще не понял как тогда ее инициализировать.
Сообщение отредактировал Brains - Nov 24 2011, 21:16
|
|
|
|
|
Nov 24 2011, 21:16
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Brains @ Nov 25 2011, 02:09)  Понятно стало, что кроме аккумулятора и счетчика накопления потребуется еще переменная предыдущего отчета Xn-1, необходимая для предложенного вами кастинга. Но еще не понял как тогда ее инициализировать. Во-первых, "кастинг" должен быть именно с аккумулятором. Во-вторых, сравнивать нужно модуль, то есть abs(acc/n - X), либо abs(acc-X*n). Обычно проще и быстрее умножать, чем делить. В-третьих, нужно контролировать диапазон аккумулятора, чтобы он был диапазоне 0..360*n. Иначе корректировать на -360*n, либо на +360*n. Ну и арифметика со знаком ессно. А если после каждого добавление аккума алгоритм считает среднее значение от акка, то так будет даже проще. Защита от переполнения не понадобится.
Сообщение отредактировал GetSmart - Nov 24 2011, 21:19
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Nov 24 2011, 21:28
|
Группа: Участник
Сообщений: 8
Регистрация: 16-09-09
Пользователь №: 52 413

|
Цитата Во-первых, "кастинг" должен быть именно с аккумулятором. Во-вторых, сравнивать нужно модуль, то есть abs(acc/n - X), либо abs(acc-X*n). Обычно проще и быстрее умножать, чем делить. Про это понял. Цитата В-третьих, нужно контролировать диапазон аккумулятора, чтобы он был диапазоне 0..360*n. Иначе корректировать на -360*n, либо на +360*n. А эту фразу нет. Вы имеете ввиду, что после каждого прибавления (и увеличения n на единицу) в аккумуляторе должно быть число не больше чем 360*n ? Цитата А если после каждого добавление аккума алгоритм считает среднее значение от акка, то так будет даже проще. Защита от переполнения не понадобится. Этого, к сожалению, достичь нельзя, нет ресурсов для деления на любое число, а потому рассчитываю n как степень двойки, подбираю разрядность аккума для худшего случая, и после накопления 2^n отсчетов делю аккум сдвигами.
|
|
|
|
|
Nov 25 2011, 07:54
|

Эксперт
    
Группа: Свой
Сообщений: 1 467
Регистрация: 25-06-04
Пользователь №: 183

|
QUOTE (Brains @ Nov 24 2011, 21:47)  Вариант перехода к формату -180->0->+180 уже рассматривался, и он имеет такую же проблему при усреднении, возникающую в окрестностях 180 градусов (-179,+179 после усреднения дает 0 вместо 180). Алгоритм нужен для целочисленного МК, желательно простой арифметическо-логический. Какие есть варианты решения этой проблемы? Можно разрыв арктангенса сделать на противоположной стороне круга по отношению к текущим данным, т.е. например к первому отсчету fi0 + 180 % 360 а все другие значения приводить уже к этому новому интервалу (который определяется точкой разрыва) и просто суммировать. Если есть такие сильные помехи, что выбивают угол больше чем на 180 градусов, то от них всё равно нельзя избавиться любым способом
|
|
|
|
|
Nov 25 2011, 08:17
|

Частый гость
 
Группа: Участник
Сообщений: 159
Регистрация: 3-01-11
Пользователь №: 62 000

|
Есть способ лучше: построить гистограмму углов, сгладить её круговой свёрткой и найти максимум. Он даст "основной угол". А затем все значения углов из несглаженной гистограммы суммируются относительно "основного угла".
А с аккумулятором будет нестабильно: последовательность типа {0, 0, 90, 180, 270, 0, 0, 90, 180, 270, ...} будет ваш аккумулятор водить кругами... Впрочем, это, наверное, редкий на практике случай.
Сообщение отредактировал Alexey Lukin - Nov 25 2011, 08:18
|
|
|
|
|
Nov 25 2011, 13:16
|

Эксперт
    
Группа: Свой
Сообщений: 1 467
Регистрация: 25-06-04
Пользователь №: 183

|
QUOTE (GetSmart @ Nov 25 2011, 12:53)  Воруют © Перельман и китайцы  PS. Это там деление, или мне показалось?  Это там остаток по модулю 360. Сначада интервал был 0-360. Вычисляем то что там написано Х. В этой точке делаем на круге разрыв. Т.е. все последующие значения фазы приводятся к интервалу [X-360, Х] и тупо суммируются. Здесь, есть конечно неустойчивость к забитости первой точки помехой - вдруг она ляжет криво по отношению к среднему. Собственно разрыв на круге нужно сделать бы в точке среднего, но оно нам как раз неизвестно заранее Поэтому действительно как-то так QUOTE (Alexey Lukin @ Nov 25 2011, 11:17)  Есть способ лучше: построить гистограмму углов, сгладить её круговой свёрткой и найти максимум. Он даст "основной угол". А затем все значения углов из несглаженной гистограммы суммируются относительно "основного угла".
|
|
|
|
|
Nov 25 2011, 13:49
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(fontp @ Nov 25 2011, 18:16)  Это там остаток по модулю 360. То есть остаток по модулю имеем без деления? Как-то с полуслова Вы меня не понимаете. ТС-у делить в напряг. Он же написал. Цитата(fontp @ Nov 25 2011, 18:16)  Сначада интервал был 0-360. Вычисляем то что там написано Х. В этой точке делаем на круге разрыв. Т.е. все последующие значения фазы приводятся к интервалу [X-360, Х] и тупо суммируются. Здесь, есть конечно неустойчивость к забитости первой точки помехой - вдруг она ляжет криво по отношению к среднему. Собственно разрыв на круге нужно сделать бы в точке среднего, но оно нам как раз неизвестно заранее Я так и не понял, чем это отличается от предложенного мной? Цитата Поэтому действительно как-то так А свёртка это вообще жесть. Причём свёртка будет каждого элемента в гистограмме. Хотя результат вобщем достоверный. Но сложение векторов в декартовых координатах будет явно проще.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Nov 25 2011, 14:26
|

Эксперт
    
Группа: Свой
Сообщений: 1 467
Регистрация: 25-06-04
Пользователь №: 183

|
QUOTE (GetSmart @ Nov 25 2011, 16:49)  Я так и не понял, чем это отличается от предложенного мной? Где вы предлагали смещать интервал? Не вижу. Вы же рассматривали стандартный интервал [0, 360] или аналогичный стандартный [-180, 180],а я предложил убрать разрыв от данных подальше. Проблема же в точке разрыва. QUOTE (GetSmart @ Nov 25 2011, 16:49)  То есть остаток по модулю имеем без деления? Как-то с полуслова Вы меня не понимаете. ТС-у делить в напряг. Он же написал. Да нет там деления, это просто запись, там 2 if
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|