sbg_ros_helpers.cpp
Go to the documentation of this file.
1 // File header
2 #include "sbg_ros_helpers.h"
3 
4 // SBG headers
5 #include <sbgDefines.h>
6 
7 // STL headers
8 #include <cmath>
9 
10 float sbg::helpers::wrapAnglePi(float angle_rad)
11 {
12  if (angle_rad > SBG_PI_F)
13  {
14  return (SBG_PI_F * 2.0f - fmodf(angle_rad, SBG_PI_F * 2.0f));
15  }
16 
17  if (angle_rad < -SBG_PI_F)
18  {
19  return (SBG_PI_F * 2.0f + fmodf(angle_rad, SBG_PI_F * 2.0f));
20  }
21 
22  return angle_rad;
23 }
24 
25 float sbg::helpers::wrapAngle360(float angle_deg)
26 {
27  float wrapped_angle_deg = angle_deg;
28 
29  if ( (wrapped_angle_deg < -360.0f) || (wrapped_angle_deg > 360.0f) )
30  {
31  wrapped_angle_deg = fmodf(wrapped_angle_deg, 360.0f);
32  }
33 
34  if (wrapped_angle_deg < 0.0f)
35  {
36  wrapped_angle_deg = 360.0f + wrapped_angle_deg;
37  }
38 
39  return wrapped_angle_deg;
40 }
41 
42 uint32_t sbg::helpers::getNumberOfDaysInYear(uint16_t year)
43 {
44  if (isLeapYear(year))
45  {
46  return 366;
47  }
48  else
49  {
50  return 365;
51  }
52 }
53 
54 uint32_t sbg::helpers::getNumberOfDaysInMonth(uint16_t year, uint8_t month_index)
55 {
56  if ((month_index == 4) || (month_index == 6) || (month_index == 9) || (month_index == 11))
57  {
58  return 30;
59  }
60  else if ((month_index == 2))
61  {
62  if (isLeapYear(year))
63  {
64  return 29;
65  }
66  else
67  {
68  return 28;
69  }
70  }
71  else
72  {
73  return 31;
74  }
75 }
76 
77 bool sbg::helpers::isLeapYear(uint16_t year)
78 {
79  return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
80 }
81 
82 int32_t sbg::helpers::getUtcOffset(bool first_valid_utc, uint32_t gps_tow, uint8_t sec)
83 {
84  constexpr int32_t DEFAULT_UTC_OFFSET = 18;
85  int32_t utcOffset;
86 
87  if (first_valid_utc)
88  {
89  // Compute the leap second: GPS = UTC + utcOffset
90  utcOffset = (gps_tow/1000)%60 - sec;
91 
92  if (utcOffset < 0)
93  {
94  utcOffset = 60 + utcOffset;
95  }
96  }
97  else
98  {
99  utcOffset = DEFAULT_UTC_OFFSET;
100  }
101 
102  return utcOffset;
103 }
104 
106 {
107  sbg::helpers::NmeaGGAQuality nmeaQuality = NmeaGGAQuality::INVALID;
108 
109  switch (sbg_gps_type)
110  {
112  nmeaQuality = NmeaGGAQuality::INVALID;
113  break;
114 
116  case SBG_ECOM_POS_SINGLE:
117  case SBG_ECOM_POS_FIXED:
118  nmeaQuality = NmeaGGAQuality::SINGLE;
119  break;
120 
122  case SBG_ECOM_POS_SBAS:
124  nmeaQuality = NmeaGGAQuality::DGPS;
125  break;
126 
129  nmeaQuality = NmeaGGAQuality::PPS;
130  break;
131 
133  nmeaQuality = NmeaGGAQuality::RTK_FIXED;
134  break;
135 
137  nmeaQuality = NmeaGGAQuality::RTK_FLOAT;
138  break;
139  }
140 
141  return nmeaQuality;
142 }
143 
144 sbg::SbgVector3d sbg::helpers::convertLLAtoECEF(double latitude, double longitude, double altitude)
145 {
146  //
147  // Conversion from Geodetic coordinates to ECEF is based on World Geodetic System 1984 (WGS84).
148  // Radius are expressed in meters, and latitude/longitude in radian.
149  //
150  static constexpr double EQUATORIAL_RADIUS = 6378137.0;
151  static constexpr double POLAR_RADIUS = 6356752.314245;
152 
153  double latitude_rad = sbgDegToRadD(latitude);
154  double longitude_rad = sbgDegToRadD(longitude);
155  double compute_cte = pow(POLAR_RADIUS, 2) / pow(EQUATORIAL_RADIUS, 2);
156  double eccentricity = 1.0 - compute_cte;
157  double prime_vertical_radius = EQUATORIAL_RADIUS / sqrt(1.0 - (pow(eccentricity, 2) * pow(sin(latitude_rad), 2)));
158 
159  sbg::SbgVector3d ecef_vector((prime_vertical_radius + altitude) * cos(latitude_rad) * cos(longitude_rad),
160  (prime_vertical_radius + altitude) * cos(latitude_rad) * sin(longitude_rad),
161  fma(compute_cte, prime_vertical_radius, altitude) * sin(latitude_rad));
162  return ecef_vector;
163 }
sbg::SbgVector3
Definition: sbg_vector3.h:72
sbg::helpers::convertSbgGpsTypeToNmeaGpsType
NmeaGGAQuality convertSbgGpsTypeToNmeaGpsType(SbgEComGpsPosType sbg_gps_type)
Definition: sbg_ros_helpers.cpp:105
SBG_ECOM_POS_RTK_FLOAT
@ SBG_ECOM_POS_RTK_FLOAT
Definition: sbgEComBinaryLogGps.h:132
SBG_ECOM_POS_FIXED
@ SBG_ECOM_POS_FIXED
Definition: sbgEComBinaryLogGps.h:136
sbgDegToRadD
SBG_INLINE double sbgDegToRadD(double angle)
Definition: sbgDefines.h:361
sbg_ros_helpers.h
Helpers for various tasks.
SBG_ECOM_POS_UNKNOWN_TYPE
@ SBG_ECOM_POS_UNKNOWN_TYPE
Definition: sbgEComBinaryLogGps.h:127
SbgEComGpsPosType
enum _SbgEComGpsPosType SbgEComGpsPosType
f
f
SBG_ECOM_POS_SBAS
@ SBG_ECOM_POS_SBAS
Definition: sbgEComBinaryLogGps.h:130
SBG_ECOM_POS_SINGLE
@ SBG_ECOM_POS_SINGLE
Definition: sbgEComBinaryLogGps.h:128
SBG_PI_F
#define SBG_PI_F
Definition: sbgDefines.h:293
sbg::helpers::NmeaGGAQuality
NmeaGGAQuality
Definition: sbg_ros_helpers.h:51
sbg::helpers::getNumberOfDaysInMonth
uint32_t getNumberOfDaysInMonth(uint16_t year, uint8_t month_index)
Definition: sbg_ros_helpers.cpp:54
SBG_ECOM_POS_PPP_FLOAT
@ SBG_ECOM_POS_PPP_FLOAT
Definition: sbgEComBinaryLogGps.h:134
sbg::helpers::getUtcOffset
int32_t getUtcOffset(bool first_valid_utc, uint32_t gps_tow, uint8_t sec)
Definition: sbg_ros_helpers.cpp:82
sbg::helpers::convertLLAtoECEF
sbg::SbgVector3d convertLLAtoECEF(double latitude, double longitude, double altitude)
Definition: sbg_ros_helpers.cpp:144
sbg::helpers::wrapAngle360
float wrapAngle360(float angle_deg)
Definition: sbg_ros_helpers.cpp:25
SBG_ECOM_POS_NO_SOLUTION
@ SBG_ECOM_POS_NO_SOLUTION
Definition: sbgEComBinaryLogGps.h:126
sbgDefines.h
sbg::helpers::getNumberOfDaysInYear
uint32_t getNumberOfDaysInYear(uint16_t year)
Definition: sbg_ros_helpers.cpp:42
SBG_ECOM_POS_OMNISTAR
@ SBG_ECOM_POS_OMNISTAR
Definition: sbgEComBinaryLogGps.h:131
SBG_ECOM_POS_PSRDIFF
@ SBG_ECOM_POS_PSRDIFF
Definition: sbgEComBinaryLogGps.h:129
SBG_ECOM_POS_RTK_INT
@ SBG_ECOM_POS_RTK_INT
Definition: sbgEComBinaryLogGps.h:133
sbg::helpers::wrapAnglePi
float wrapAnglePi(float angle_rad)
Definition: sbg_ros_helpers.cpp:10
sbg::helpers::isLeapYear
bool isLeapYear(uint16_t year)
Definition: sbg_ros_helpers.cpp:77
SBG_ECOM_POS_PPP_INT
@ SBG_ECOM_POS_PPP_INT
Definition: sbgEComBinaryLogGps.h:135


sbg_driver
Author(s): SBG Systems
autogenerated on Fri Oct 11 2024 02:13:40