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