SoftwarePLL.cpp
Go to the documentation of this file.
1 /*
2 ====================================================================================================
3 File: SoftwarePLL.cpp
4 Note: SoftwarePLL intentionally copied from https://github.com/michael1309/SoftwarePLL
5 See https://github.com/michael1309/SoftwarePLL/blob/master/README.md for details.
6 ====================================================================================================
7 */
8 #ifdef _MSC_VER
10 #else
11 #include "sick_scan/SoftwarePLL.h"
12 #endif
13 
14 // #include "softwarePLL.h"
15 #include <iostream>
16 // #include <chrono>
17 // #include <thread>
18 #include <math.h>
19 #include <iterator>
20 #include <iostream>
21 #include <fstream>
22 #include <sstream>
23 #include <vector>
24 #include <string>
25 
26 
27 std::map<std::string,SoftwarePLL*> SoftwarePLL::_instances; // list of SoftwarePLL instances, mapped by id
28 
29 const double SoftwarePLL::MaxAllowedTimeDeviation_ = 0.1;
30 const uint32_t SoftwarePLL::MaxExtrapolationCounter_ = 20;
31 
32 SoftwarePLL& SoftwarePLL::Instance(const std::string & id, int fifo_length)
33 {
34  SoftwarePLL* pll = _instances[id];
35  if(!pll)
36  {
37  pll = new SoftwarePLL(fifo_length);
38  _instances[id] = pll;
39  }
40  return *pll;
41 }
42 
44 {
45  // Remove this from the list of SoftwarePLL instances
46  for(std::map<std::string,SoftwarePLL*>::iterator iter = _instances.begin(); iter != _instances.end(); )
47  {
48  if(iter->second == this)
49  iter = _instances.erase(iter);
50  else
51  iter++;
52  }
53 }
54 
55 bool SoftwarePLL::PushIntoFifo(double curTimeStamp, uint32_t curtick)
56 // update tick fifo and update clock (timestamp) fifo
57 {
58  for (int i = 0; i < FifoSize_ - 1; i++)
59  {
60  TickFifo_[i] = TickFifo_[i + 1];
61  ClockFifo_[i] = ClockFifo_[i + 1];
62  }
63  TickFifo_[FifoSize_ - 1] = curtick; // push most recent tick and timestamp into fifo
64  ClockFifo_[FifoSize_ - 1] = curTimeStamp;
65 
67  {
68  NumberValInFifo_++; // remember the number of valid number in fifo
69  }
70  FirstTick(TickFifo_[0]);
72 
73  return(true);
74 }
75 
77 {
78  int32_t tempTick =0;
79  tempTick = tick-(uint32_t)(0xFFFFFFFF & FirstTick());
80  double timeDiff = tempTick * this->InterpolationSlope();
81  return(timeDiff);
82 
83 }
84 
85 bool SoftwarePLL::UpdatePLL(uint32_t sec, uint32_t nanoSec, uint32_t curtick)
86 {
87  if(curtick!=this->Lastcurtick_)
88  {
89  this->Lastcurtick_ = curtick;
90  double start = sec + nanoSec * 1E-9;
91  // bool bRet = true;
92 
93  if (false == IsInitialized())
94  {
95  PushIntoFifo(start, curtick);
96  bool bCheck = this->UpdateInterpolationSlope();
97  if (bCheck)
98  {
99  IsInitialized(true);
100  }
101  }
102 
103  if (IsInitialized() == false)
104  {
105  return (false);
106  }
107 
108  double relTimeStamp = ExtraPolateRelativeTimeStamp(curtick);
109  double cmpTimeStamp = start - this->FirstTimeStamp();
110 
111  bool timeStampVerified = false;
112  if (NearSameTimeStamp(relTimeStamp, cmpTimeStamp) == true)// if timestamp matches prediction update FIFO
113  {
114  timeStampVerified = true;
115  PushIntoFifo(start, curtick);
118  }
119 
120  if (timeStampVerified == false)
121  {
122  // BEGIN HANDLING Extrapolation divergence
123  uint32_t tmp = ExtrapolationDivergenceCounter();
124  tmp++;
127  {
128  IsInitialized(false); // reset FIFO - maybe happened due to abrupt change of time base
129  }
130  // END HANDLING Extrapolation divergence
131  }
132  return(true);
133  }
134  else
135  {
136  return(false);
137  //this curtick has been updated allready
138  }
139 
140 }
141 
142 bool SoftwarePLL::GetCorrectedTimeStamp(uint32_t& sec, uint32_t& nanoSec, uint32_t curtick)
143 {
144  if (IsInitialized() == false)
145  {
146  return(false);
147  }
148 
149  double relTimeStamp = ExtraPolateRelativeTimeStamp(curtick); // evtl. hier wg. Ueberlauf noch einmal pruefen
150  double corrTime = relTimeStamp + this->FirstTimeStamp();
151  sec = (uint32_t)corrTime;
152  double frac = corrTime - sec;
153  nanoSec = (uint32_t)(1E9 * frac);
154  return(true);
155 }
156 
157 bool SoftwarePLL::NearSameTimeStamp(double relTimeStamp1, double relTimeStamp2)
158 {
159  double dTAbs = fabs(relTimeStamp1 - relTimeStamp2);
160  if (dTAbs < AllowedTimeDeviation())
161  {
162  return(true);
163  }
164  else
165  {
166  return(false);
167  }
168 }
169 
170 bool SoftwarePLL::UpdateInterpolationSlope() // fifo already updated
171 {
172 
174  {
175  return(false);
176  }
177  std::vector<uint64_t> tickFifoUnwrap;
178  std::vector<double> clockFifoUnwrap;
179  clockFifoUnwrap.resize(FifoSize_);
180  tickFifoUnwrap.resize(FifoSize_);
181  uint64_t tickOffset = 0;
182  clockFifoUnwrap[0] = 0.00;
183  tickFifoUnwrap[0] = 0;
184  FirstTimeStamp(this->ClockFifo_[0]);
185  FirstTick(this->TickFifo_[0]);
186 
187  uint64_t tickDivisor = 0x100000000;
188 
189 
190 
191  for (int i = 1; i < FifoSize_; i++) // typical 643 for 20ms -> round about 32150 --> near to 32768 standard clock in many watches
192  {
193  if (TickFifo_[i] < TickFifo_[i - 1]) // Overflow
194  {
195  tickOffset += tickDivisor;
196  }
197  tickFifoUnwrap[i] = tickOffset + TickFifo_[i] - FirstTick();
198  clockFifoUnwrap[i] = (this->ClockFifo_[i] - FirstTimeStamp());
199  }
200 
201  double sum_xy = 0.0;
202  double sum_x = 0.0;
203  double sum_y = 0.0;
204  double sum_xx = 0.0;
205  for (int i = 0; i < FifoSize_; i++)
206  {
207  sum_xy += tickFifoUnwrap[i] * clockFifoUnwrap[i];
208  sum_x += tickFifoUnwrap[i];
209  sum_y += clockFifoUnwrap[i];
210  sum_xx += tickFifoUnwrap[i] * tickFifoUnwrap[i];
211  }
212 
213  // calculate slope of regression line, interception is 0 by construction
214  double m = (FifoSize_ * sum_xy - sum_x * sum_y) / (FifoSize_ * sum_xx - sum_x*sum_x);
215 
216  int matchCnt = 0;
217  for (int i = 0; i < FifoSize_; i++)
218  {
219  double yesti = m * tickFifoUnwrap[i];
220  if (this->NearSameTimeStamp(yesti, clockFifoUnwrap[i]))
221  {
222  matchCnt++;
223  }
224  }
225 
226  bool retVal = false;
227  if (matchCnt == FifoSize_)
228  {
230  retVal = true;
231  }
232 
233  return(retVal);
234 }
235 
236 /*
237 Example CMakeLists.txt to generate test-binary-file for testing this class
238 --- CUT ---
239 #
240 #
241 # softwarePLL
242 #
243 #
244 cmake_minimum_required(VERSION 2.8)
245 cmake_policy(SET CMP0015 NEW)
246 project( softwarePLL )
247 #
248 #
249 add_definitions(-D${PROJECT_NAME}_MAINTEST)
250 
251 MESSAGE( STATUS "CMKAKE for " ${PROJECT_NAME} )
252 
253 include_directories( inc)
254 file( GLOB LIB_SOURCES src/ *.cpp )
255 
256 if(WIN32)
257 else()
258 set(CMAKE_CXX_STANDARD 11)
259 endif()
260 
261 add_executable( ${PROJECT_NAME} ${LIB_SOURCES} inc/${PROJECT_NAME}.h)
262 target_link_libraries( ${PROJECT_NAME})
263 --- CUT ---
264 
265 */
SoftwarePLL
class SoftwarePLL implements synchronisation between ticks and timestamp. See https://github....
Definition: softwarePLL.h:21
SoftwarePLL::AllowedTimeDeviation
double AllowedTimeDeviation() const
Definition: softwarePLL.h:84
SoftwarePLL::SoftwarePLL
SoftwarePLL()
Definition: softwarePLL.h:150
SoftwarePLL::~SoftwarePLL
~SoftwarePLL()
Definition: softwarePLL.h:30
SoftwarePLL::Lastcurtick_
uint32_t Lastcurtick_
Definition: SoftwarePLL.h:182
SoftwarePLL::NearSameTimeStamp
bool NearSameTimeStamp(double relTimeStamp1, double relTimeStamp2)
Definition: SoftwarePLL.cpp:157
SoftwarePLL::FirstTick
uint64_t FirstTick() const
Definition: softwarePLL.h:66
SoftwarePLL::ExtraPolateRelativeTimeStamp
double ExtraPolateRelativeTimeStamp(uint32_t tick)
Extrapolates and returns the measurement timestamp in seconds relative to FirstTimeStamp....
Definition: SoftwarePLL.cpp:76
SoftwarePLL::GetCorrectedTimeStamp
bool GetCorrectedTimeStamp(uint32_t &sec, uint32_t &nanoSec, uint32_t tick)
Computes the timestamp of a measurement from sensor ticks.
Definition: SoftwarePLL.cpp:142
SoftwarePLL::FifoSize_
const int FifoSize_
Definition: SoftwarePLL.h:173
SoftwarePLL::PushIntoFifo
bool PushIntoFifo(double curTimeStamp, uint32_t curtick)
Pushes measurement timestamp and sensor ticks to the fifo, updates tick fifo and clock (timestamp) fi...
Definition: SoftwarePLL.cpp:55
SoftwarePLL.h
SoftwarePLL::NumberValInFifo_
int NumberValInFifo_
Definition: SoftwarePLL.h:172
SoftwarePLL::ExtrapolationDivergenceCounter
uint32_t ExtrapolationDivergenceCounter() const
Definition: softwarePLL.h:90
sec
uint32_t sec(const rosTime &time)
Definition: sick_ros_wrapper.h:174
SoftwarePLL::TickFifo_
std::vector< uint32_t > TickFifo_
Definition: SoftwarePLL.h:176
SoftwarePLL::UpdateInterpolationSlope
bool UpdateInterpolationSlope()
Definition: SoftwarePLL.cpp:170
SoftwarePLL::UpdatePLL
bool UpdatePLL(uint32_t sec, uint32_t nanoSec, uint32_t curtick)
Updates PLL internale State should be called only with network send timestamps.
Definition: SoftwarePLL.cpp:85
SoftwarePLL::FirstTimeStamp
double FirstTimeStamp() const
Definition: softwarePLL.h:72
SoftwarePLL::MaxExtrapolationCounter_
static const uint32_t MaxExtrapolationCounter_
Definition: SoftwarePLL.h:175
SoftwarePLL::IsInitialized
bool IsInitialized() const
Definition: softwarePLL.h:47
SoftwarePLL::_instances
static std::map< std::string, SoftwarePLL * > _instances
Definition: SoftwarePLL.h:198
roswrap::start
ROSCPP_DECL void start()
Actually starts the internals of the node (spins up threads, starts the network polling and xmlrpc lo...
SoftwarePLL::ClockFifo_
std::vector< double > ClockFifo_
Definition: SoftwarePLL.h:177
SoftwarePLL::InterpolationSlope
double InterpolationSlope() const
Definition: softwarePLL.h:78
SoftwarePLL::Instance
static SoftwarePLL & Instance(const std::string &id="", int fifo_length=7)
Creates an instance of SoftwarePLL or returns an existing one, given its id.
Definition: SoftwarePLL.cpp:32
SoftwarePLL::MaxAllowedTimeDeviation_
static const double MaxAllowedTimeDeviation_
Definition: SoftwarePLL.h:174


sick_scan_xd
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Fri Oct 25 2024 02:47:12