Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
timestampManager.hpp
00001 
00002 #include <iostream>
00003 #include <iomanip>
00004 
00005 #define AVGSIZE 3
00006 
00007 #define PHI 1.618033989 // golden ratio
00008 /*
00009 struct Timestamp
00010 {
00011   double sensorDate;
00012   double rawhostDate;
00013   double fixedhostDate;
00014   double arrivalDate;
00015 };
00016 */
00017 
00018 class TimestampSensor
00019 {
00020  private:
00021   double clockScale;
00022   double clockShiftS;
00023   double clockShiftH;
00024   double latency;
00025   double averagingLength;
00026 
00027   bool first;
00028   unsigned sector;
00029   double next_sector_date;
00030   double delay_min;
00031   double currentAvgLength;
00032   unsigned nAvgLength;
00033 
00034   double sectorBestS[AVGSIZE];
00035   double sectorBestH[AVGSIZE];
00036 
00037  public:
00047   TimestampSensor(double clockScale, double latency, double averagingLength = 30):
00048     clockScale(clockScale), latency(latency), averagingLength(averagingLength), first(true), sector(0), currentAvgLength(0.1), nAvgLength(0)
00049   {}
00050 
00058   double filter(double sensorDate, double hostDate)
00059   {
00060     // first
00061     if (first)
00062     {
00063       clockShiftS = sensorDate;
00064       clockShiftH = hostDate - latency;
00065       delay_min = 1e9;
00066       first = false;
00067       next_sector_date = hostDate + currentAvgLength;
00068       return hostDate;
00069     }
00070 
00071     // new sector
00072     if (hostDate > next_sector_date)
00073     {
00074       if (sector >= AVGSIZE-1) // if we have at least AVGSIZE sectors
00075       {
00076         unsigned best1, best2;
00077         double max_scale = 0.;
00078         for(int i = 0; i < AVGSIZE-1; ++i)
00079           for(int j = i+1; j < AVGSIZE; ++j)
00080           {
00081             // compute scale hypothesis
00082             unsigned s1 = (sector+1+i) % AVGSIZE;
00083             unsigned s2 = (sector+1+j) % AVGSIZE;
00084             double scale = (sectorBestH[s2]-sectorBestH[s1])/(sectorBestS[s2]-sectorBestS[s1]);
00085 
00086             // check it is comptatible with all the other sectors
00087             bool compatible = true;
00088             for(int k = 0; k < AVGSIZE; ++k) if (k != s1 && k != s2)
00089               if (sectorBestH[k] - (sectorBestH[s2] + (sectorBestS[k]-sectorBestS[s2])*scale) < 0)
00090                 { compatible = false; break; }
00091 
00092             // if so check if it is the best so far
00093             if (compatible && scale > max_scale) { max_scale = scale; best1 = s1; best2 = s2; }
00094           }
00095 
00096         // compute final scale
00097         clockScale = (sectorBestH[best2]-sectorBestH[best1])/(sectorBestS[best2]-sectorBestS[best1]);
00098         clockShiftS = sectorBestS[best2];
00099         clockShiftH = sectorBestH[best2]-latency;
00100       }
00101 
00102       if (nAvgLength == 0)
00103       {
00104         currentAvgLength *= PHI; // using this ratio so that when we merge two sectors, the new size is the same than the next one
00105         if (currentAvgLength > averagingLength) { currentAvgLength = averagingLength; nAvgLength++; }
00106       } else
00107       if (nAvgLength <= AVGSIZE) nAvgLength++;
00108 
00109       // merge two first sectors
00110       if (nAvgLength <= AVGSIZE)
00111       {
00112         unsigned s1 = (sector+1) % AVGSIZE;
00113         unsigned s2 = (sector+2) % AVGSIZE;
00114 
00115         if ((sectorBestH[s1] - (clockShiftH + (sectorBestS[s1]-clockShiftS)*clockScale + latency))
00116           < (sectorBestH[s2] - (clockShiftH + (sectorBestS[s2]-clockShiftS)*clockScale + latency)))
00117         {
00118           sectorBestS[s2] = sectorBestS[s1];
00119           sectorBestH[s2] = sectorBestH[s1];
00120         }
00121       }
00122 
00123       ++sector;
00124       next_sector_date += currentAvgLength;
00125       delay_min = 1e9;
00126     }
00127 
00128     // update
00129     double fixedDate = clockShiftH + (sensorDate-clockShiftS)*clockScale;
00130     double delay = hostDate - (fixedDate + latency);
00131 
00132     // check shift
00133     if (delay < 0)
00134     {
00135       clockShiftH += delay;
00136       fixedDate += delay;
00137       sectorBestS[sector % AVGSIZE] = sensorDate;
00138       sectorBestH[sector % AVGSIZE] = hostDate;
00139       delay_min = 0;
00140     }
00141 
00142     if (delay < delay_min)
00143     {
00144       sectorBestS[sector % AVGSIZE] = sensorDate;
00145       sectorBestH[sector % AVGSIZE] = hostDate;
00146       delay_min = delay;
00147     }
00148 
00149     return fixedDate;
00150   }
00151 
00152 
00157   //bool isExpectingDataBefore(double date); // NOT IMPLEMENTED YET
00158 
00159   #if 0 // SYNC
00160   private:
00161     TimestampSensor *syncSensor;
00162     double syncShift;
00163 
00164   public:
00165     void syncTo(TimestampSensor *sensor, double shift);
00166   #endif
00167 };
00168 
00169 
00170 
00171 class TimestampManager
00172 {
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:27 for Jafar by doxygen 1.7.6.1
LAAS-CNRS