annotate 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
rev   line source
giuliomoro@135 1 #include "VirtualClock.h"
giuliomoro@149 2 void VirtualClock::init(float initialValueUs){
giuliomoro@135 3 firstRun=true;
giuliomoro@141 4 movingAverage.setLength(101); //TODO: a better filtering algorithm ( Did you say Kalman?)
giuliomoro@149 5 blockPeriod=-1;
giuliomoro@141 6 elapsedPeriods=0;
giuliomoro@141 7 startTime=0;
giuliomoro@149 8 elapsedPeriodsOffset = 0;
giuliomoro@149 9 lastSyncEstimatedTime = 0;
giuliomoro@149 10 double coefficients[IIR_FILTER_STAGE_COEFFICIENTS] = {
giuliomoro@149 11 0.000241359049041961, 0.000482718098083923, 0.000241359049041961, -1.95557824031504, 0.956543676511203
giuliomoro@149 12 };
giuliomoro@149 13 iir.setNumberOfStages(4);
giuliomoro@149 14 iir.setCoefficients(coefficients);
giuliomoro@149 15 printf("kalmanInit=%f\n",initialValueUs);
giuliomoro@149 16 kalman.init(0.01, 158575.715009816 /*measured var() */,
giuliomoro@149 17 initialValueUs
giuliomoro@149 18 //#ifdef USE_JUCE
giuliomoro@149 19 // 5804.98866213152 /*blockSize/Fs*1e6*/
giuliomoro@149 20 //#else
giuliomoro@149 21 // 5804.98866213152 /*blockSize/Fs*1e6*/
giuliomoro@149 22 //#endif
giuliomoro@149 23 );
giuliomoro@135 24 }
giuliomoro@135 25
giuliomoro@149 26 VirtualClock::VirtualClock(){}
giuliomoro@135 27 void VirtualClock::sync(){
giuliomoro@135 28 sync(1);
giuliomoro@135 29 }
giuliomoro@141 30 void VirtualClock::sync(double numPeriods){
giuliomoro@149 31 myClock_t currentTime = Clock::getTimeUs();
giuliomoro@149 32 elapsedPeriods += numPeriods;
giuliomoro@149 33 static int calls = 0;
giuliomoro@149 34 if(calls == 0){
giuliomoro@149 35 startTime = currentTime;
giuliomoro@149 36 //AA lastSyncEstimatedTime = startTime;
giuliomoro@149 37 lastSyncEstimatedTime = 0;
giuliomoro@149 38 } else {
giuliomoro@149 39 double newBlockPeriod = (currentTime - lastSyncTime);
giuliomoro@149 40 // period = iir.process(movingAverage.add(newPeriod)); //TODO: replace with Kalman filter
giuliomoro@149 41 blockPeriod = iir.process(kalman.process(newBlockPeriod));
giuliomoro@149 42 // period = 22.6760958210091;
giuliomoro@149 43 period = blockPeriod / numPeriods;
giuliomoro@149 44 lastSyncEstimatedTime += (period * numPeriods);
giuliomoro@149 45 // if(calls == 800)
giuliomoro@149 46 // lastSyncEstimatedTime = lastSyncTime;
giuliomoro@149 47 // printf("%lld, %lld\n", lastSyncTime, lastSyncEstimatedTime);
giuliomoro@141 48 }
giuliomoro@149 49 lastSyncTime = currentTime;
giuliomoro@149 50 // printf("%lld\n", lastSyncTime);
giuliomoro@141 51 calls++;
giuliomoro@135 52 }
giuliomoro@135 53
giuliomoro@135 54 double VirtualClock::getNow(){
giuliomoro@139 55 myClock_t currentSystemTime=Clock::getTimeUs();
giuliomoro@149 56 if(blockPeriod<=0){
giuliomoro@141 57 return currentSystemTime; // TODO: this is not very meaningful.
giuliomoro@135 58 }
giuliomoro@149 59 double elapsed = (currentSystemTime - startTime) - lastSyncEstimatedTime;
giuliomoro@149 60 double now = elapsedPeriods + elapsed / (double)period;
giuliomoro@149 61 // if(now>currentSystemTime+10*1e6)
giuliomoro@149 62 // now=0;
giuliomoro@149 63 // static long long int pastSy=0;
giuliomoro@149 64 // printf("%lld\n", currentSystemTime-pastSy);
giuliomoro@149 65 // pastSy=currentSystemTime;
giuliomoro@149 66 static int count=0;
giuliomoro@149 67 count++;
giuliomoro@149 68 // if(count&1)
giuliomoro@149 69 #ifdef USE_JUCE
giuliomoro@149 70 #else
giuliomoro@149 71 // printf("%f %f %f\n", (currentSystemTime - startTime)/1e6*44100.0, blockPeriod, now);
giuliomoro@149 72 #endif
giuliomoro@139 73 return now;
giuliomoro@135 74 }
giuliomoro@135 75
giuliomoro@141 76 void VirtualClock::addOffset(double periodOffset){
giuliomoro@141 77 elapsedPeriods-=periodOffset;
giuliomoro@141 78 if(elapsedPeriods<0){
giuliomoro@141 79 printf("ERROR: periodOffset adjustment of %f resulted in elapsedPeriods=%f\n", periodOffset, elapsedPeriods);
giuliomoro@141 80 exit(1);
giuliomoro@141 81 }
giuliomoro@149 82 printf("this is not called\n");
giuliomoro@141 83 movingAverage.reset();
giuliomoro@141 84 }
giuliomoro@135 85 double VirtualClock::getPeriod(){
giuliomoro@149 86 return blockPeriod;
giuliomoro@135 87 }