У меня есть события, которые происходят примерно каждые X мс (скажем, 50 для примера). Я хотел бы определить их периодичность, но есть небольшое дрожание. Так что я решил, что хорошей идеей было поместить событие в корзину, исходя из того, в какую секунду MS оно пришло (TIME_IN_MS% 1024, 1024, потому что математика FFT). Затем через несколько секунд FFT полученными лотками. Я не могу решить, читаю ли я этот метод онлайн, во сне или что-то еще.
Так что это вроде работает. Я могу моделировать события каждые 50 мс с дрожанием 5 мс. Это производит примерно квадратную волну в бункерах. БПФ выводит основную частоту с гармониками.
Проблема заключается в том, что самый сильный «сигнал» находится в ячейке 322. Я не могу найти математику, которая превращает это в частоту, которая имеет смысл. На 50 мс я ожидал 20 Гц. Моя математика неверна или метод или что-то еще?
Извините, не знаю, как привести минимальный пример в присутствии внешних библиотек.
#define US_MS 1000
#define MS_S 1000
#define US_S (US_MS*MS_S)
#define FFT_SIZE 1024
void FrameGroup::calcFrequency()
{
PFFFT_Setup *pSetup;
float *output = (float*) pffft_aligned_malloc(FFT_SIZE*sizeof(float));
pSetup = pffft_new_setup(FFT_SIZE, PFFFT_REAL);
if (pSetup == NULL)
{
qDebug("couldn't set up FFT\n");
return;
}
pffft_transform(pSetup, m_timingCounts, output, NULL, PFFFT_FORWARD);
qDebug("FFT Results:\n");
for (int i = 0; i < FFT_SIZE; i++)
{
qDebug("%f,", output[i]);
}
qDebug("\n");
pffft_aligned_free(output);
pffft_destroy_setup(pSetup);
}
void FrameGroup::recordTiming(QCanBusFrame &frame)
{
uint64_t bucket;
bucket = (frame.timeStamp().microSeconds()/US_MS)%FFT_SIZE;
m_timingCounts[bucket] += 1.0;
if (m_timingCounts[bucket] > 100)
{
for (int i = 0; i < MS_S; i++)
{
m_timingCounts[i] /= 2.0;
}
}
}