Перекрестная корреляция Arduino?
Как я могу написать легкий код кросс-корреляции для arduino? Я не мог найти никакого решения. Измерительная система содержит ультразвуковой датчик и сервопривод, который поворачивается от 45 до 135 градусов и измеряет расстояние от 4-300 см. Чем я собираю данные в массив, который содержит расстояния по отношению к углу. Система делает несколько подобных измерений, и программа находит перекрестную корреляцию между новыми и старыми массивами.
http://www.instructables.com/id/How-To-Make-an-Obstacle-Avoiding-Arduino-Robot/
@acs, 👍2
Обсуждение2 ответа
Лучший ответ:
Учитывая временной масштаб измерений, производительность не является проблемой. А поскольку вы не вычисляете в режиме реального времени, когда измеряются выборки, вы можете применить определение перекрестной корреляции как есть и вычислить ее в двойном цикле. Единственная трудность заключается в том, чтобы выяснить, что кросс-корреляция не может быть подходящим инструментом для этой работы... и найти правильный! Я предполагаю, что вы хотите оценить угол поворота между двумя измерениями.
Математическое определение перекрестной корреляции предполагает бесконечные массивы. На практике кросс-корреляция часто используется для нахождения короткого паттерна внутри длинного сигнала. В этом случае вычисление выполняется только для сдвигов, когда паттерн полностью перекрывает сигнал. Тогда длина результата равна
length(result) = length(signal) − length(pattern) + 1
В вашем случае, поскольку ваш паттерн является ранее измеренным сигналом, это даст результат с одной выборкой, который бесполезен.
Вместо этого вы можете вычислить интеграл для всех сдвигов, где есть любое перекрытие между паттерном и сигналом. Это эквивалентно заполнению сигнала нулем. У этого есть недостаток смещения результата: если ваш сигнал и паттерн оба безликие (положительные константы), вы найдете очень хороший пик при нулевом сдвиге!
Вы можете устранить это смещение, вычитая среднее значение как из сигнала , так и из паттерна и коррелируя(signal − avg (сигнал)) с (pattern − avg (паттерн)). Это все еще несет в себе предубеждение к “большим” функциям. Представьте себе, например, что после удаления средних значений у вас есть
pattern = [ 0, 0, −20, +20, 0, 0];
signal = [−50, +50, 0, 0, −20, +20];
Вы ожидаете, что ваш коррелятор найдет хорошее совпадение между [-20, +20] паттерна и [-20, +20] сигнала. Однако корреляция гораздо лучше с [-50, +50] сигнала. Вы можете попытаться облегчить эту проблему, вычислив вместо этого нормализованную кросс-корреляцию, но в лучшем случае вы сделаете оба совпадения одинаково хорошими.
Я предлагаю вам полностью забыть о корреляциях и вместо этого думать в терминах “хорошего соответствия”. Корреляции хороши для поиска масштабированных и сдвинутых копий паттерна внутри сигнала. Вы ищете только сдвинутые копии без масштабирования. Ваш вопрос должен звучать так: если вы сдвинете паттерн на некоторую величину, насколько хорошо он соответствует сигналу? Какая величина сдвига дает лучшую посадку? Канонический ответ на все вопросы “goodness of fit” состоит в том, чтобы минимизировать среднеквадратичную разницу между ними: вы вычисляете сумму
S = Σ(signal − shifted(pattern))²
Тогда среднеквадратичная разница равна
RMS(difference) = √(S/N)
где N-количество выборок, участвующих в сумме. Наиболее вероятный сдвиг-тот, который минимизирует эту ошибку. На практике вам не нужен квадратный корень, вы просто минимизируете
RMS(difference)² = Σ(signal − shifted(pattern))² / N
Вы можете реализовать эту формулу как есть, она совершенно проста. Просто имейте в виду, что N зависит от сдвига, так как это длина перекрытия. И избегайте очень маленьких перекрытий (то есть больших сдвигов).
Теперь, если вы развернете квадрат внутри суммы, вы можете обнаружить, что, в конце концов, это не так уж далеко от перекрестной корреляции... И кстати, все это не имеет никакого отношения к Arduino.
Мне нужна как задержка, так и корреляция информации. информация о задержке будет использоваться для оценки смещения, а отношение будет использоваться для определения важности предполагаемого смещения (действительно ли оно имеет значение или нет). Система будет работать как ультразвуковой радар на основе мертвого счета. Также я пытаюсь реализовать это [ссылка](http://paulbourke.net/miscellaneous/correlate/), @acs
У вас есть обе информации: 1) величина сдвига, которая дает лучшую подгонку, 2) среднеквадратичная разница при данном конкретном сдвиге., @Edgar Bonet
Это сработает. Никаких массивов или сложных вещей о cross blabla. Код находится в пределах 4-5 микрон
int mic1 = 2;// использование леонардо для внешних прерываний на этих выводах.
int mic2 = 3;
int mic3 = 7;
volatile unsigned long tid1 = 0; //Var для хранения метки времени в micros in.
volatile unsigned long tid2 = 0;
volatile unsigned long tid3 = 0;
volatile int stop1 = 0;//Флаги в прерываниях не запускаются снова.
volatile int stop2 = 0;
volatile int stop3 = 0;
void setup() {
pinMode(mic1, INPUT);
pinMode(mic2, INPUT);
pinMode(mic3, INPUT);
pinMode(11, OUTPUT);//Например, зуммер подает звуковой сигнал, когда все триггеры в порядке!
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(mic1), trig1, RISING);
attachInterrupt(digitalPinToInterrupt(mic2), trig2, RISING);
attachInterrupt(digitalPinToInterrupt(mic3), trig3, RISING);
}
void loop() {
if (stop1 == 1 && stop2 == 1 && stop3 == 1) {
stop1 = 20;
stop2 = 20;
stop3 = 20;
delay(250); //ЭХО-задержка.
tid1 = 0;
tid2 = 0;
tid3 = 0;
stop1 = 0;
stop2 = 0;
stop3 = 0;
}
}
void trig1() {
if (stop1 == 0);
tid1=micros();// Как написать это хардкорным способом, адресуя timer1, чтобы получить значение на основе clockcycles, я не знаю. Jus
tid1=tid1;
stop1 = 1;
}
void trig2() {
if ( stop2 == 0);
tid2=micros();
tid2=tid2;
stop2 = 1;
}
void trig3() {
if ( stop3 == 0);
tid3=micros();
tid3=tid3;
stop3 = 1;
}
У вас что-то странное происходит с if (stop1 == 0);
и подобными строками. Обратите внимание на точку с запятой., @timemage
Я не вижу, как это даже отдаленно связано с вопросом, даже игнорируя необычный код., @Dave Newton
- создание анализатора гармоник мощности, который будет измерять амплитуды основной и кратных ей частот (например, 50 Гц, 100 Гц, 150 Гц, 200 Гц,...)
- Существуют ли библиотеки сглаживания сигналов для Arduino?
- Отправка значения с одного Arduino на другой
- Использование аналогового входа для чтения кнопки
- Как работать с аналоговыми контактами в цикле?
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Распиновка аналога Arduino Pro Micro
- analogRead всегда 1023 на Arduino Due
Вы хотите соотнести два сигнала реального времени или сигнал реального времени с предопределенным шаблоном? Насколько велико (по количеству выборок) окно, в которое вы хотите интегрироваться?, @Edgar Bonet
сигнал собран и чем кросс корр будет работать. длина сигнала-90., @acs
Не мог понять вашего предложения. Не могли бы вы обновить вопрос информацией о двух сигналах, которые вы хотите соотнести? Известны ли они во время компиляции? Должны ли они обрабатываться образец за образцом во время приобретения?, @Edgar Bonet
Я написал разреженный кросс-коррелятор, который работает с цифровым сигналом, дискретизированным по значениям таймера. Он работал на очень маленьком микроконтроллере. Если вы дадите нам больше информации о том, какой сигнал вы коррелируете, я буду рад опубликовать его здесь, @benathon
Есть ультразвуковой датчик.и сервопривод, который поворачивается от 45 до 135 градусов и измеряет расстояние от 4-300 см. теперь я собираю данные в массив, который содержит расстояния по отношению к углу. система делает несколько таких измерений, а затем программа находит корреляцию между новым и старым массивами., @acs