Mercurial > hg > beaglert
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 } |