diff 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
line wrap: on
line diff
--- a/core/VirtualClock.cpp	Mon Sep 14 14:57:54 2015 +0100
+++ b/core/VirtualClock.cpp	Mon Sep 14 15:42:11 2015 +0100
@@ -1,8 +1,12 @@
 #include "VirtualClock.h"
 void VirtualClock::init(){
 	firstRun=true;
-	movingAverage.setLength(31); //TODO: a better filtering algorithm ( Did you say Kalman?)
+	movingAverage.setLength(101); //TODO: a better filtering algorithm ( Did you say Kalman?)
 	period=-1;
+	elapsedPeriods=0;
+	startTime=0;
+	startTimeOffset=0;
+	elapsedPeriodsOffset=0;
 }
 	
 VirtualClock::VirtualClock(){
@@ -11,13 +15,29 @@
 void VirtualClock::sync(){
 	sync(1);
 }
-void VirtualClock::sync(double count){
+void VirtualClock::sync(double numPeriods){
 	myClock_t currentTime=Clock::getTimeUs();
+	static int calls=0;
+	elapsedPeriods+=numPeriods;
+	if(calls==50){ //TODO: this is dangerous as the clock might jump suddenly if currentTime is not precise
+		calls=0;
+		startTimeOffset=startTime;
+		startTime=currentTime;
+		elapsedPeriodsOffset=elapsedPeriods;
+	}
+	calls++;
 	if(firstRun==true){
 		firstRun=false;
 		startTime=currentTime;
 	} else {
-		period=movingAverage.add((currentTime-lastSync)/count); //TODO: replace with Kalman filter
+		double newPeriod=(currentTime-lastSync)/numPeriods;
+		double expectedPeriod=22.67;
+		double maxPeriodDeviation=10;
+		if(fabs(newPeriod-expectedPeriod)<maxPeriodDeviation){ // filtering outliers
+			period=movingAverage.add(newPeriod); //TODO: replace with Kalman filter
+		} else {
+			printf("period out of range: %f\n", newPeriod);
+		}
 	}
 	lastSync=currentTime;
 //	printf("lastSync: %lld\n",lastSync-startTime);
@@ -26,16 +46,24 @@
 double VirtualClock::getNow(){
 	myClock_t currentSystemTime=Clock::getTimeUs();
 	if(period<=0){
-		return currentSystemTime;
+		return currentSystemTime; // TODO: this is not very meaningful.
 	}
 	//  double beginningOfPeriod=lastSync; // TODO: if sync() does not get called every time (but e.g. only every so often),
 													 // then this line (and the class) needs editing
 	myClock_t elapsed=(currentSystemTime-startTime);
-	double now=elapsed/(double)period;
+	double now=elapsedPeriodsOffset + elapsed/(double)period;
 //	printf("elapsed=%lld;  sincelastSync=%lld; period=%f; now=%f\n", elapsed, currentSystemTime-lastSync, period, now);
 	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);
+	}
+	movingAverage.reset();
+}
 double VirtualClock::getPeriod(){
 	return period;
 }