annotate core/VirtualClock.cpp @ 141:44d07fa9bd03 ClockSync

Ultra-basic feedback for clock sync works^CIssues: response time of the IIR filter is too slow, requires PID and better filtering algorithm.
author Giulio Moro <giuliomoro@yahoo.it>
date Mon, 14 Sep 2015 15:42:11 +0100
parents 4e2dd3eb1d28
children 134bff10e561
rev   line source
giuliomoro@135 1 #include "VirtualClock.h"
giuliomoro@135 2 void VirtualClock::init(){
giuliomoro@135 3 firstRun=true;
giuliomoro@141 4 movingAverage.setLength(101); //TODO: a better filtering algorithm ( Did you say Kalman?)
giuliomoro@135 5 period=-1;
giuliomoro@141 6 elapsedPeriods=0;
giuliomoro@141 7 startTime=0;
giuliomoro@141 8 startTimeOffset=0;
giuliomoro@141 9 elapsedPeriodsOffset=0;
giuliomoro@135 10 }
giuliomoro@135 11
giuliomoro@135 12 VirtualClock::VirtualClock(){
giuliomoro@135 13 init();
giuliomoro@135 14 }
giuliomoro@135 15 void VirtualClock::sync(){
giuliomoro@135 16 sync(1);
giuliomoro@135 17 }
giuliomoro@141 18 void VirtualClock::sync(double numPeriods){
giuliomoro@135 19 myClock_t currentTime=Clock::getTimeUs();
giuliomoro@141 20 static int calls=0;
giuliomoro@141 21 elapsedPeriods+=numPeriods;
giuliomoro@141 22 if(calls==50){ //TODO: this is dangerous as the clock might jump suddenly if currentTime is not precise
giuliomoro@141 23 calls=0;
giuliomoro@141 24 startTimeOffset=startTime;
giuliomoro@141 25 startTime=currentTime;
giuliomoro@141 26 elapsedPeriodsOffset=elapsedPeriods;
giuliomoro@141 27 }
giuliomoro@141 28 calls++;
giuliomoro@135 29 if(firstRun==true){
giuliomoro@135 30 firstRun=false;
giuliomoro@135 31 startTime=currentTime;
giuliomoro@135 32 } else {
giuliomoro@141 33 double newPeriod=(currentTime-lastSync)/numPeriods;
giuliomoro@141 34 double expectedPeriod=22.67;
giuliomoro@141 35 double maxPeriodDeviation=10;
giuliomoro@141 36 if(fabs(newPeriod-expectedPeriod)<maxPeriodDeviation){ // filtering outliers
giuliomoro@141 37 period=movingAverage.add(newPeriod); //TODO: replace with Kalman filter
giuliomoro@141 38 } else {
giuliomoro@141 39 printf("period out of range: %f\n", newPeriod);
giuliomoro@141 40 }
giuliomoro@135 41 }
giuliomoro@135 42 lastSync=currentTime;
giuliomoro@139 43 // printf("lastSync: %lld\n",lastSync-startTime);
giuliomoro@135 44 }
giuliomoro@135 45
giuliomoro@135 46 double VirtualClock::getNow(){
giuliomoro@139 47 myClock_t currentSystemTime=Clock::getTimeUs();
giuliomoro@135 48 if(period<=0){
giuliomoro@141 49 return currentSystemTime; // TODO: this is not very meaningful.
giuliomoro@135 50 }
giuliomoro@135 51 // double beginningOfPeriod=lastSync; // TODO: if sync() does not get called every time (but e.g. only every so often),
giuliomoro@135 52 // then this line (and the class) needs editing
giuliomoro@139 53 myClock_t elapsed=(currentSystemTime-startTime);
giuliomoro@141 54 double now=elapsedPeriodsOffset + elapsed/(double)period;
giuliomoro@139 55 // printf("elapsed=%lld; sincelastSync=%lld; period=%f; now=%f\n", elapsed, currentSystemTime-lastSync, period, now);
giuliomoro@139 56 return now;
giuliomoro@135 57 }
giuliomoro@135 58
giuliomoro@141 59 void VirtualClock::addOffset(double periodOffset){
giuliomoro@141 60 elapsedPeriods-=periodOffset;
giuliomoro@141 61 if(elapsedPeriods<0){
giuliomoro@141 62 printf("ERROR: periodOffset adjustment of %f resulted in elapsedPeriods=%f\n", periodOffset, elapsedPeriods);
giuliomoro@141 63 exit(1);
giuliomoro@141 64 }
giuliomoro@141 65 movingAverage.reset();
giuliomoro@141 66 }
giuliomoro@135 67 double VirtualClock::getPeriod(){
giuliomoro@135 68 return period;
giuliomoro@135 69 }