40 std::getline(str, line);
42 std::stringstream lineStream(line);
46 while (std::getline(lineStream, cell,
';'))
51 if (!lineStream && cell.empty())
72 for (
int i = 0; i < fifoSize - 1; i++)
74 tickFifo[i] = tickFifo[i + 1];
75 clockFifo[i] = clockFifo[i + 1];
77 tickFifo[fifoSize - 1] = curtick;
78 clockFifo[fifoSize - 1] = curTimeStamp;
80 if (numberValInFifo < fifoSize)
84 FirstTick(tickFifo[0]);
85 FirstTimeStamp(clockFifo[0]);
93 tempTick = tick - (uint32_t) (0xFFFFFFFF & FirstTick());
94 double timeDiff = tempTick * this->InterpolationSlope();
102 double minAllowedDiff = (1.0 - tol) * diff;
103 double maxAllowedDiff = (1.0 + tol) * diff;
105 for (
int i = 0; i < numberValInFifo - 1; i++)
107 double diffTime = this->clockFifo[i + 1] - clockFifo[i];
108 if ((diffTime >= minAllowedDiff) && (diffTime <= maxAllowedDiff))
127 if (curtick != this->lastcurtick)
129 this->lastcurtick = curtick;
130 double start = sec + nanoSec * 1E-9;
133 if (
false == IsInitialized())
135 pushIntoFifo(start, curtick);
136 bool bCheck = this->updateInterpolationSlope();
143 if (IsInitialized() ==
false)
148 double relTimeStamp = extraPolateRelativeTimeStamp(curtick);
149 double cmpTimeStamp = start - this->FirstTimeStamp();
151 bool timeStampVerified =
false;
152 if (nearSameTimeStamp(relTimeStamp, cmpTimeStamp) ==
true)
154 timeStampVerified =
true;
155 pushIntoFifo(start, curtick);
156 updateInterpolationSlope();
157 ExtrapolationDivergenceCounter(0);
160 if (timeStampVerified ==
false)
163 uint32_t tmp = ExtrapolationDivergenceCounter();
165 ExtrapolationDivergenceCounter(tmp);
168 IsInitialized(
false);
185 if (IsInitialized() ==
false)
190 double relTimeStamp = extraPolateRelativeTimeStamp(curtick);
191 double corrTime = relTimeStamp + this->FirstTimeStamp();
192 sec = (uint32_t) corrTime;
193 double frac = corrTime - sec;
194 nanoSec = (uint32_t) (1E9 * frac);
200 double dTAbs = fabs(relTimeStamp1 - relTimeStamp2);
201 if (dTAbs < AllowedTimeDeviation())
214 if (numberValInFifo < fifoSize)
218 std::vector<uint64_t> tickFifoUnwrap;
219 std::vector<double> clockFifoUnwrap;
220 clockFifoUnwrap.resize(fifoSize);
221 tickFifoUnwrap.resize(fifoSize);
222 uint64_t tickOffset = 0;
223 clockFifoUnwrap[0] = 0.00;
224 tickFifoUnwrap[0] = 0;
225 FirstTimeStamp(this->clockFifo[0]);
226 FirstTick(this->tickFifo[0]);
228 uint64_t tickDivisor = 0x100000000;
234 if (tickFifo[i] < tickFifo[i - 1])
236 tickOffset += tickDivisor;
238 tickFifoUnwrap[i] = tickOffset + tickFifo[i] - FirstTick();
239 clockFifoUnwrap[i] = (this->clockFifo[i] - FirstTimeStamp());
246 for (
int i = 0; i < fifoSize; i++)
248 sum_xy += tickFifoUnwrap[i] * clockFifoUnwrap[i];
249 sum_x += tickFifoUnwrap[i];
250 sum_y += clockFifoUnwrap[i];
251 sum_xx += tickFifoUnwrap[i] * tickFifoUnwrap[i];
255 double m = (fifoSize * sum_xy - sum_x * sum_y) / (fifoSize * sum_xx - sum_x * sum_x);
258 for (
int i = 0; i < fifoSize; i++)
260 double yesti = m * tickFifoUnwrap[i];
261 if (this->nearSameTimeStamp(yesti, clockFifoUnwrap[i]))
268 if (matchCnt == fifoSize)
270 InterpolationSlope(m);
278 bool SoftwarePLL::getDemoFileData(std::string fileName, std::vector<uint32_t>& tickVec,std::vector<uint32_t>& secVec, std::vector<uint32_t>& nanoSecVec )
280 std::ifstream file(fileName);
287 while (file >> row) {
290 uint32_t tickVal = (uint32_t)std::stoi(row[0]);
291 uint32_t secVal = (uint32_t)std::stoi(row[1]);
292 uint32_t nanoSecVal = (uint32_t)std::stoi(row[2]);
293 tickVec.push_back(tickVal);
294 secVec.push_back(secVal);
295 nanoSecVec.push_back(nanoSecVal);
309 std::cout <<
"Running testbed for SofwarePLL" << std::endl;
310 uint32_t curtick = 0;
315 uint32_t nanoSec = 0;
316 double tickPerSec = 1E6;
317 uint32_t tickInc = 1000;
320 std::vector<uint32_t> tickVec;
321 std::vector<uint32_t> secVec;
322 std::vector<uint32_t> nanoSecVec;
325 bool testWithDataFile =
true;
326 if (testWithDataFile)
329 maxLoop = tickVec.size();
332 for (
int i = 0; i < maxLoop; i++)
334 if (testWithDataFile)
336 curtick = tickVec[i];
338 nanoSec = nanoSecVec[i];
344 double deltaT = tickInc / tickPerSec;
345 nanoSec += (int) (deltaT * 1E9);
356 printf(
"Before correction: %3d.%09d\n", sec, nanoSec);
357 uint32_t org_sec = sec;
358 uint32_t org_nanoSec = nanoSec;
362 bool corrected =
false;
363 if ((nanoSec != org_nanoSec) || (sec != org_sec))
367 printf(
"After correction : %3d.%09d %s %s\n", sec, nanoSec, bRet ?
"OK " :
"DISMISS",
368 corrected ?
"MODI." :
"OK ");
375 #ifdef softwarePLL_MAINTEST 376 int main(
int argc,
char **argv)
378 printf(
"Test for softwarePLL-Class\n");
bool getDemoFileData(std::string fileName, std::vector< uint32_t > &tickVec, std::vector< uint32_t > &secVec, std::vector< uint32_t > &nanoSecVec)
class SoftwarePLL implements synchronisation between ticks and timestamp. See https://github.com/michael1309/SoftwarePLL/blob/master/README.md for details.
void readNextRow(std::istream &str)
double extraPolateRelativeTimeStamp(uint32_t tick)
std::string const & operator[](std::size_t index) const
bool getCorrectedTimeStamp(uint32_t &sec, uint32_t &nanoSec, uint32_t tick)
bool pushIntoFifo(double curTimeStamp, uint32_t curtick)
int main(int argc, char **argv)
Startup routine - if called with no argmuments we assume debug session. Set scanner name variable by ...
std::istream & operator>>(std::istream &str, CSVRow &data)
static const uint32_t MaxExtrapolationCounter
static const double MaxAllowedTimeDeviation
bool nearSameTimeStamp(double relTimeStamp1, double relTimeStamp2)
int findDiffInFifo(double diff, double tol)
bool updateInterpolationSlope()
std::vector< std::string > m_data
bool updatePLL(uint32_t sec, uint32_t nanoSec, uint32_t curtick)
Updates PLL internale State should be called only with network send timestamps.