GSLAM  3.0.0
GPS.h
1 #ifndef GSLAM_GPS_H
2 #define GSLAM_GPS_H
3 
4 #include <vector>
5 #include <iomanip>
6 #include <iostream>
7 
8 #include "Point.h"
9 
10 namespace GSLAM{
11 
12 // WGS84 Ellipsoid
13 static const double WGS84_A = 6378137.0; // major axis
14 static const double WGS84_B = 6356752.314245; // minor axis
15 static const double WGS84_E = 0.0818191908; // first eccentricity
16 
17 template<typename T> inline T Square( T x ){return x * x;}
18 inline double D2R( double degree ){return degree * M_PI / 180.0;}
19 inline double R2D( double radian ){return radian / M_PI * 180.0;}
20 
21 template <typename T=Point3d>
22 class GPS
23 {
24 public:
25  GPS(const std::string& nameGPS="GPS"):name(nameGPS){}
26  virtual ~GPS(){}
27 
28  virtual bool insert(double time,const T& gpsData){return false;}
29  virtual size_t size()const{return 0;}
30  virtual bool getArray(std::vector<T>& gpsArray){return false;} /// return all data
31  virtual T at(size_t idx){return T();}
32  virtual T atTime(const double& time=-1,bool nearist=true){return T();}
33  virtual void getTimeRange(double& minTime, double& maxTime){minTime=-1;maxTime=-1;}
34 
35  virtual bool load(const std::string& filename){return false;}
36  virtual bool save(const std::string& filename){return false;}
37 
38  inline bool hasTime(const double& time){
39  double minTime,maxTime;
40  getTimeRange(minTime,maxTime);
41  return time>=minTime&&time<=maxTime;
42  }
43 
44  /**
45  ** Convert WGS84 lon,lat,alt data to ECEF data (Earth Centered Earth Fixed)
46  ** @param lat Latitude in degree
47  ** @param lon Longitude in degree
48  ** @param alt Altitude relative to the WGS84 ellipsoid
49  ** @return ECEF corresponding coordinates
50  **
51  ** http://fr.mathworks.com/matlabcentral/newsreader/view_thread/142629
52  **/
53  static Point3d GPS2XYZ(double lat,double lon,double alt)
54  {
55  const double clat = cos( D2R(lat) );
56  const double slat = sin( D2R(lat) );
57  const double clon = cos( D2R(lon) );
58  const double slon = sin( D2R(lon) );
59 
60  const double a2 = Square(WGS84_A);
61  const double b2 = Square(WGS84_B);
62 
63  const double L = 1.0 / sqrt(a2 * Square(clat) + b2 * Square(slat));
64  const double x = (a2 * L + alt) * clat * clon;
65  const double y = (a2 * L + alt) * clat * slon;
66  const double z = (b2 * L + alt) * slat;
67 
68  return Point3d(x, y, z);
69  }
70 
71  static Point3d XYZ2GPS(double x,double y,double z)
72  {
73  const double b = sqrt(WGS84_A*WGS84_A*(1-WGS84_E*WGS84_E));
74  const double ep = sqrt((WGS84_A*WGS84_A-b*b)/(b*b));
75  const double p = sqrt(x*x+y*y);
76  const double th = atan2(WGS84_A*z,b*p);
77  const double lon = atan2(y,x);
78  const double lat = atan2((z+ep*ep*b* pow(sin(th),3)),(p-WGS84_E*WGS84_E*WGS84_A*pow(cos(th),3)));
79  const double N = WGS84_A/sqrt(1-WGS84_E*WGS84_E*sin(lat)*sin(lat));
80  const double alt = p/cos(lat)-N;
81 
82  return Point3d(R2D(lat), R2D(lon), alt);
83  }
84 
85  static Point3d GPS2XYZ(Point3d gps){return GPS2XYZ(gps.x,gps.y,gps.z);}
86  static Point3d XYZ2GPS(Point3d xyz){return XYZ2GPS(xyz.x,xyz.y,xyz.z);}
87 
88  std::string name;
89 };
90 
91 template <typename T>
92 class GPSArray:public GPS<T>
93 {
94 public:
95  GPSArray(const std::string& nameGPS="GPS"):GPS<T>(nameGPS){}
96 
97  virtual bool insert(double time,const T& gpsData){
98  if(time>data.back().first)
99  {
100  data.push_back(gpsData);
101  return true;
102  }
103  return false;
104  }
105 
106  virtual size_t size()const{return data.size();}
107  virtual bool getArray(std::vector<T>& gpsArray){
108  gpsArray.clear();
109  gpsArray.reserve(data.size());
110  for(std::pair<double,T>& d:data) gpsArray.push_back(d.second);
111  return true;
112  } /// return all data
113 
114  virtual T at(size_t idx){return data[idx].second;}
115  virtual T atTime(const double& time=-1,bool nearist=true);
116  virtual void getTimeRange(double& minTime, double& maxTime){
117  if(!data.size())
118  {
119  minTime=-1;maxTime=-1;
120  }
121  else{
122  minTime=data.front().first;
123  maxTime=data.back().first;
124  }
125  }
126 
127 private:
128  std::vector<std::pair<double,T> > data;
129 };
130 
131 template <typename T>
132 T GPSArray<T>::atTime(const double& time,bool nearist)
133 {
134  if(!data.size()) return false;
135 
136  if(!GPS<T>::hasTime(time)) return T();
137 
138  int idxMin=0,idxMax=data.size()-2;
139 
140 
141  while(idxMax-idxMin>16)// fast up with idx approciate
142  {
143  int idx=idxMin+(idxMax-idxMin)*(time-data[idxMin].first)/(data[idxMax].first-data[idxMin].first);
144  if(data[idx].first>=time) idxMax=idx;
145  else idxMin=idx;
146  }
147 
148  while(idxMax-idxMin>1)
149  {
150  int idx=(idxMax+idxMin)>>1;
151  if(data[idx].first>time) idxMax=idx;
152  else idxMin=idx;
153  }
154 
155 
156  if(nearist)
157  {
158  double timeDiffLow =time-data[idxMin].first;
159  double timeDiffHigh=data[idxMax].first-time;
160  if(timeDiffLow<timeDiffHigh)
161  {
162  if(timeDiffLow>1.0) return T();
163  //less than one second
164  return data[idxMin].second;
165  }
166  else
167  {
168  if(timeDiffHigh>1.0) return T();
169  return data[idxMax].second;
170  }
171  }
172  else
173  {
174  std::pair<double,T>& low=data[idxMin];
175  std::pair<double,T>& up =data[idxMax];
176  double timeDiffAll=up.first-low.first;
177  if(timeDiffAll>1.0) return false;
178 
179  double kLow=((double)(time-low.first))/timeDiffAll;
180  double kUp =1.-kLow;
181  return (low.second*kLow+up.second*kUp);
182  }
183  return T();
184 }
185 
186 }
187 #endif
Definition: Point.h:162
Definition: GPS.h:92
virtual T at(size_t idx)
return all data
Definition: GPS.h:31
virtual T at(size_t idx)
return all data
Definition: GPS.h:114
Definition: Camera.h:45
Definition: GPS.h:22
static Point3d GPS2XYZ(double lat, double lon, double alt)
Convert WGS84 lon,lat,alt data to ECEF data (Earth Centered Earth Fixed)
Definition: GPS.h:53