Mercurial > hg > beaglert
view core/VirtualClock.cpp @ 149:134bff10e561 ClockSync
Added simple one-variable one-measurement Kalman filter, Pid controller(which output is not used). Virtual clock is now much more precise and reactive for period. Still it is lagging behind a bit on the overall offset.
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Mon, 21 Sep 2015 03:12:21 +0100 |
parents | 44d07fa9bd03 |
children | ebbfb154351a |
line wrap: on
line source
#include "VirtualClock.h" void VirtualClock::init(float initialValueUs){ firstRun=true; movingAverage.setLength(101); //TODO: a better filtering algorithm ( Did you say Kalman?) blockPeriod=-1; elapsedPeriods=0; startTime=0; elapsedPeriodsOffset = 0; lastSyncEstimatedTime = 0; double coefficients[IIR_FILTER_STAGE_COEFFICIENTS] = { 0.000241359049041961, 0.000482718098083923, 0.000241359049041961, -1.95557824031504, 0.956543676511203 }; iir.setNumberOfStages(4); iir.setCoefficients(coefficients); printf("kalmanInit=%f\n",initialValueUs); kalman.init(0.01, 158575.715009816 /*measured var() */, initialValueUs //#ifdef USE_JUCE // 5804.98866213152 /*blockSize/Fs*1e6*/ //#else // 5804.98866213152 /*blockSize/Fs*1e6*/ //#endif ); } VirtualClock::VirtualClock(){} void VirtualClock::sync(){ sync(1); } void VirtualClock::sync(double numPeriods){ myClock_t currentTime = Clock::getTimeUs(); elapsedPeriods += numPeriods; static int calls = 0; if(calls == 0){ startTime = currentTime; //AA lastSyncEstimatedTime = startTime; lastSyncEstimatedTime = 0; } else { double newBlockPeriod = (currentTime - lastSyncTime); // period = iir.process(movingAverage.add(newPeriod)); //TODO: replace with Kalman filter blockPeriod = iir.process(kalman.process(newBlockPeriod)); // period = 22.6760958210091; period = blockPeriod / numPeriods; lastSyncEstimatedTime += (period * numPeriods); // if(calls == 800) // lastSyncEstimatedTime = lastSyncTime; // printf("%lld, %lld\n", lastSyncTime, lastSyncEstimatedTime); } lastSyncTime = currentTime; // printf("%lld\n", lastSyncTime); calls++; } double VirtualClock::getNow(){ myClock_t currentSystemTime=Clock::getTimeUs(); if(blockPeriod<=0){ return currentSystemTime; // TODO: this is not very meaningful. } double elapsed = (currentSystemTime - startTime) - lastSyncEstimatedTime; double now = elapsedPeriods + elapsed / (double)period; // if(now>currentSystemTime+10*1e6) // now=0; // static long long int pastSy=0; // printf("%lld\n", currentSystemTime-pastSy); // pastSy=currentSystemTime; static int count=0; count++; // if(count&1) #ifdef USE_JUCE #else // printf("%f %f %f\n", (currentSystemTime - startTime)/1e6*44100.0, blockPeriod, now); #endif return now; } void VirtualClock::addOffset(double periodOffset){ elapsedPeriods-=periodOffset; if(elapsedPeriods<0){ printf("ERROR: periodOffset adjustment of %f resulted in elapsedPeriods=%f\n", periodOffset, elapsedPeriods); exit(1); } printf("this is not called\n"); movingAverage.reset(); } double VirtualClock::getPeriod(){ return blockPeriod; }