parsing_utilities.cpp
Go to the documentation of this file.
1 // *****************************************************************************
2 //
3 // © Copyright 2020, Septentrio NV/SA.
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // 1. Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // 2. Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // 3. Neither the name of the copyright holder nor the names of its
14 // contributors may be used to endorse or promote products derived
15 // from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
28 //
29 // *****************************************************************************
30 
31 // ROSaic includes
34 // C++ library includes
35 #include <limits>
36 // Boost
37 #include <boost/spirit/include/qi_binary.hpp>
38 
45 namespace parsing_utilities {
46 
47  const double pihalf = boost::math::constants::pi<double>() / 2.0;
48 
49  namespace qi = boost::spirit::qi;
50 
51  [[nodiscard]] double wrapAngle180to180(double angle)
52  {
53  return std::remainder(angle, 360.0);
54  }
55 
56  [[nodiscard]] double parseDouble(const uint8_t* buffer)
57  {
58  double val;
59  qi::parse(buffer, buffer + 8, qi::little_bin_double, val);
60  return val;
61  }
62 
68  [[nodiscard]] bool parseDouble(const std::string& string, double& value)
69  {
70  return string_utilities::toDouble(string, value) || string.empty();
71  }
72 
73  [[nodiscard]] float parseFloat(const uint8_t* buffer)
74  {
75  float val;
76  qi::parse(buffer, buffer + 4, qi::little_bin_float, val);
77  return val;
78  }
79 
85  [[nodiscard]] bool parseFloat(const std::string& string, float& value)
86  {
87  return string_utilities::toFloat(string, value) || string.empty();
88  }
89 
97  [[nodiscard]] int16_t parseInt16(const uint8_t* buffer)
98  {
99  int16_t val;
100  qi::parse(buffer, buffer + 2, qi::little_word, val);
101  return val;
102  }
103 
109  [[nodiscard]] bool parseInt16(const std::string& string, int16_t& value,
110  int32_t base)
111  {
112  value = 0;
113  if (string.empty())
114  {
115  return true;
116  }
117 
118  int32_t intermd;
119  if (string_utilities::toInt32(string, intermd, base) &&
120  intermd <= std::numeric_limits<int16_t>::max() &&
121  intermd >= std::numeric_limits<int16_t>::min())
122  {
123  value = static_cast<int16_t>(intermd);
124  return true;
125  }
126 
127  return false;
128  }
129 
130  [[nodiscard]] int32_t parseInt32(const uint8_t* buffer)
131  {
132  int32_t val;
133  qi::parse(buffer, buffer + 4, qi::little_dword, val);
134  return val;
135  }
136 
142  [[nodiscard]] bool parseInt32(const std::string& string, int32_t& value,
143  int32_t base)
144  {
145  return string_utilities::toInt32(string, value, base) || string.empty();
146  }
147 
153  [[nodiscard]] bool parseUInt8(const std::string& string, uint8_t& value,
154  int32_t base)
155  {
156  value = 0;
157  if (string.empty())
158  {
159  return true;
160  }
161 
162  uint32_t intermd;
163  if (string_utilities::toUInt32(string, intermd, base) &&
164  intermd <= std::numeric_limits<uint8_t>::max())
165  {
166  value = static_cast<uint8_t>(intermd);
167  return true;
168  }
169 
170  return false;
171  }
172 
173  [[nodiscard]] uint16_t parseUInt16(const uint8_t* buffer)
174  {
175  uint16_t val;
176  qi::parse(buffer, buffer + 2, qi::little_word, val);
177  return val;
178  }
179 
185  [[nodiscard]] bool parseUInt16(const std::string& string, uint16_t& value,
186  int32_t base)
187  {
188  value = 0;
189  if (string.empty())
190  {
191  return true;
192  }
193 
194  uint32_t intermd;
195  if (string_utilities::toUInt32(string, intermd, base) &&
196  intermd <= std::numeric_limits<uint16_t>::max())
197  {
198  value = static_cast<uint16_t>(intermd);
199  return true;
200  }
201 
202  return false;
203  }
204 
205  [[nodiscard]] uint32_t parseUInt32(const uint8_t* buffer)
206  {
207  uint32_t val;
208  qi::parse(buffer, buffer + 4, qi::little_dword, val);
209  return val;
210  }
211 
217  [[nodiscard]] bool parseUInt32(const std::string& string, uint32_t& value,
218  int32_t base)
219  {
220  return string_utilities::toUInt32(string, value, base) || string.empty();
221  }
222 
228  [[nodiscard]] double convertUTCDoubleToSeconds(double utc_double)
229  {
230  uint32_t hours = static_cast<uint32_t>(utc_double) / 10000;
231  uint32_t minutes = (static_cast<uint32_t>(utc_double) - hours * 10000) / 100;
232 
233  return utc_double - static_cast<double>(hours * 10000 + minutes * 100) +
234  static_cast<double>(hours * 3600 + minutes * 60);
235  }
236 
242  [[nodiscard]] double convertDMSToDegrees(double dms)
243  {
244  uint32_t whole_degrees = static_cast<uint32_t>(dms) / 100;
245  double minutes = dms - static_cast<double>(whole_degrees * 100);
246  return static_cast<double>(whole_degrees) + minutes / 60.0;
247  }
248 
265  [[nodiscard]] time_t convertUTCtoUnix(double utc_double)
266  {
267  time_t time_now = time(0);
268  struct tm* timeinfo;
269 
270  // The function gmtime uses the value at &time_now to fill a tm structure
271  // with the values that represent the corresponding time, expressed as a UTC
272  // time.
273  timeinfo = gmtime(&time_now);
274 
275  uint32_t hours = static_cast<uint32_t>(utc_double) / 10000;
276  uint32_t minutes = (static_cast<uint32_t>(utc_double) - hours * 10000) / 100;
277  uint32_t seconds =
278  (static_cast<uint32_t>(utc_double) - hours * 10000 - minutes * 100);
279 
280  // Overwriting timeinfo with UTC time as extracted from utc_double..
281  timeinfo->tm_hour = hours; // hours since midnight - [0,23]
282  timeinfo->tm_min = minutes; // minutes after the hour - [0,59]
283  timeinfo->tm_sec = seconds; // seconds after the minute - [0,59]
284 
285  /* // If you are doing a simulation, add year, month and day here:
286  uint32_t year; // year, starting from 1900
287  uint32_t month; // months since January - [0,11]
288  uint32_t day; //day of the month - [1,31]
289  timeinfo->tm_year = year;
290  timeinfo->tm_mon = month;
291  timeinfo->tm_mday = day;
292  */
293 
294  // Inverse of gmtime, the latter converts time_t (Unix time) to tm (UTC time)
295  return timegm(timeinfo);
296  }
297 
302  [[nodiscard]] Eigen::Quaterniond
303  convertEulerToQuaternion(double roll, double pitch, double yaw)
304  {
305  double cy = std::cos(yaw * 0.5);
306  double sy = std::sin(yaw * 0.5);
307  double cp = std::cos(pitch * 0.5);
308  double sp = std::sin(pitch * 0.5);
309  double cr = std::cos(roll * 0.5);
310  double sr = std::sin(roll * 0.5);
311 
312  return Eigen::Quaterniond(
313  cr * cp * cy + sr * sp * sy, sr * cp * cy - cr * sp * sy,
314  cr * sp * cy + sr * cp * sy, cr * cp * sy - sr * sp * cy);
315  }
316 
317  [[nodiscard]] QuaternionMsg
318  quaternionToQuaternionMsg(const Eigen::Quaterniond& q)
319  {
320  QuaternionMsg qm;
321 
322  qm.w = q.w();
323  qm.x = q.x();
324  qm.y = q.y();
325  qm.z = q.z();
326 
327  return qm;
328  }
329 
330  [[nodiscard]] QuaternionMsg convertEulerToQuaternionMsg(double roll,
331  double pitch, double yaw)
332  {
333  return quaternionToQuaternionMsg(convertEulerToQuaternion(roll, pitch, yaw));
334  }
335 
336  [[nodiscard]] Eigen::Quaterniond q_enu_ecef(double lat, double lon)
337  {
338  double sr = sin((pihalf - lat) / 2.0);
339  double cr = cos((pihalf - lat) / 2.0);
340  double sy = sin((lon + pihalf) / 2.0);
341  double cy = cos((lon + pihalf) / 2.0);
342 
343  return Eigen::Quaterniond(cr * cy, sr * cy, sr * sy, cr * sy);
344  }
345 
346  [[nodiscard]] Eigen::Quaterniond q_ned_ecef(double lat, double lon)
347  {
348  double sp = sin((-lat - pihalf) / 2.0);
349  double cp = cos((-lat - pihalf) / 2.0);
350  double sy = sin(lon / 2.0);
351  double cy = cos(lon / 2.0);
352 
353  return Eigen::Quaterniond(cp * cy, -sp * sy, sp * cy, cp * sy);
354  }
355 
356  [[nodiscard]] Eigen::Matrix3d R_enu_ecef(double lat, double lon)
357  {
358  Eigen::Matrix3d R;
359 
360  double sin_lat = sin(lat);
361  double cos_lat = cos(lat);
362  double sin_lon = sin(lon);
363  double cos_lon = cos(lon);
364 
365  R(0, 0) = -sin_lon;
366  R(0, 1) = -cos_lon * sin_lat;
367  R(0, 2) = cos_lon * cos_lat;
368  R(1, 0) = cos_lon;
369  R(1, 1) = -sin_lon * sin_lat;
370  R(1, 2) = sin_lon * cos_lat;
371  R(2, 0) = 0.0;
372  R(2, 1) = cos_lat;
373  R(2, 2) = sin_lat;
374 
375  return R;
376  }
377 
378  [[nodiscard]] Eigen::Matrix3d R_ned_ecef(double lat, double lon)
379  {
380  Eigen::Matrix3d R;
381 
382  double sin_lat = sin(lat);
383  double cos_lat = cos(lat);
384  double sin_lon = sin(lon);
385  double cos_lon = cos(lon);
386 
387  R(0, 0) = -cos_lon * sin_lat;
388  R(0, 1) = -sin_lon;
389  R(0, 2) = -cos_lon * cos_lat;
390  R(1, 0) = -sin_lon * sin_lat;
391  R(1, 1) = cos_lon;
392  R(1, 2) = -sin_lon * cos_lat;
393  R(2, 0) = cos_lat;
394  R(2, 1) = 0.0;
395  R(2, 2) = -sin_lat;
396 
397  return R;
398  }
399 
400  [[nodiscard]] std::string convertUserPeriodToRxCommand(uint32_t period_user)
401  {
402  std::string cmd;
403 
404  if (period_user == 0)
405  return "OnChange";
406  else if (period_user < 1000)
407  return "msec" + std::to_string(period_user);
408  else if (period_user <= 60000)
409  return "sec" + std::to_string(period_user / 1000);
410  else
411  return "min" + std::to_string(period_user / 60000);
412  }
413 
414  [[nodiscard]] uint16_t getCrc(const std::vector<uint8_t>& message)
415  {
416  return parseUInt16(message.data() + 2);
417  }
418 
419  [[nodiscard]] uint16_t getId(const std::vector<uint8_t>& message)
420  {
421  // Defines bit mask..
422  // Highest three bits are for revision and rest for block number
423  static uint16_t mask = 8191;
424  // Bitwise AND gives us all but highest 3 bits set to zero, rest unchanged
425 
426  return parseUInt16(message.data() + 4) & mask;
427  }
428 
429  [[nodiscard]] uint16_t getLength(const std::vector<uint8_t>& message)
430  {
431  return parseUInt16(message.data() + 6);
432  }
433 
434  [[nodiscard]] uint32_t getTow(const std::vector<uint8_t>& message)
435  {
436  return parseUInt32(message.data() + 8);
437  }
438 
439  [[nodiscard]] uint16_t getWnc(const std::vector<uint8_t>& message)
440  {
441  return parseUInt16(message.data() + 12);
442  }
443 
444 } // namespace parsing_utilities
string_utilities::toInt32
bool toInt32(const std::string &string, int32_t &value, int32_t base=10)
Interprets the contents of "string" as a floating point number of whatever integer type your system h...
Definition: string_utilities.cpp:104
parsing_utilities::quaternionToQuaternionMsg
QuaternionMsg quaternionToQuaternionMsg(const Eigen::Quaterniond &q)
Convert Eigen quaternion to a QuaternionMsg.
Definition: parsing_utilities.cpp:318
string_utilities::toDouble
bool toDouble(const std::string &string, double &value)
Interprets the contents of "string" as a floating point number of type double It stores the "string"'...
Definition: string_utilities.cpp:53
parsing_utilities::getTow
uint32_t getTow(const std::vector< uint8_t > &message)
Get the time of week in ms of the SBF message.
Definition: parsing_utilities.cpp:434
parsing_utilities::wrapAngle180to180
double wrapAngle180to180(double angle)
Wraps an angle between -180 and 180 degrees.
Definition: parsing_utilities.cpp:51
parsing_utilities::convertUTCtoUnix
std::time_t convertUTCtoUnix(double utc_double)
Converts UTC time from the without-colon-delimiter format to Unix Epoch time (a number-of-seconds-sin...
Definition: parsing_utilities.cpp:265
parsing_utilities::convertUserPeriodToRxCommand
std::string convertUserPeriodToRxCommand(uint32_t period_user)
Transforms the input polling period [milliseconds] into a std::string number that can be appended to ...
Definition: parsing_utilities.cpp:400
parsing_utilities::getWnc
uint16_t getWnc(const std::vector< uint8_t > &message)
Get the GPS week counter of the SBF message.
Definition: parsing_utilities.cpp:439
parsing_utilities::parseInt32
int32_t parseInt32(const uint8_t *buffer)
Converts a 4-byte-buffer into a signed 32-bit integer.
Definition: parsing_utilities.cpp:130
parsing_utilities::parseFloat
float parseFloat(const uint8_t *buffer)
Converts a 4-byte-buffer into a float.
Definition: parsing_utilities.cpp:73
parsing_utilities::R_enu_ecef
Eigen::Matrix3d R_enu_ecef(double lat, double lon)
Generates the matrix to rotate from local ENU to ECEF.
Definition: parsing_utilities.cpp:356
parsing_utilities
Definition: parsing_utilities.hpp:52
parsing_utilities::convertEulerToQuaternion
Eigen::Quaterniond convertEulerToQuaternion(double roll, double pitch, double yaw)
Transforms Euler angles to a quaternion.
Definition: parsing_utilities.cpp:303
parsing_utilities::getLength
uint16_t getLength(const std::vector< uint8_t > &message)
Get the length of the SBF message.
Definition: parsing_utilities.cpp:429
parsing_utilities::convertUTCDoubleToSeconds
double convertUTCDoubleToSeconds(double utc_double)
Converts UTC time from the without-colon-delimiter format to the number-of-seconds-since-midnight for...
Definition: parsing_utilities.cpp:228
parsing_utilities::pihalf
const double pihalf
Definition: parsing_utilities.cpp:47
parsing_utilities::getCrc
uint16_t getCrc(const std::vector< uint8_t > &message)
Get the CRC of the SBF message.
Definition: parsing_utilities.cpp:414
parsing_utilities::parseUInt32
uint32_t parseUInt32(const uint8_t *buffer)
Converts a 4-byte-buffer into an unsigned 32-bit integer.
Definition: parsing_utilities.cpp:205
parsing_utilities::parseUInt16
uint16_t parseUInt16(const uint8_t *buffer)
Converts a 2-byte-buffer into an unsigned 16-bit integer.
Definition: parsing_utilities.cpp:173
parsing_utilities::convertEulerToQuaternionMsg
QuaternionMsg convertEulerToQuaternionMsg(double roll, double pitch, double yaw)
Transforms Euler angles to a QuaternionMsg.
Definition: parsing_utilities.cpp:330
parsing_utilities::R_ned_ecef
Eigen::Matrix3d R_ned_ecef(double lat, double lon)
Generates the matrix to rotate from local NED to ECEF.
Definition: parsing_utilities.cpp:378
parsing_utilities.hpp
Declares utility functions used when parsing messages.
parsing_utilities::getId
uint16_t getId(const std::vector< uint8_t > &message)
Get the ID of the SBF message.
Definition: parsing_utilities.cpp:419
parsing_utilities::convertDMSToDegrees
double convertDMSToDegrees(double dms)
Converts latitude or longitude from the DMS notation (in the without-colon-delimiter format),...
Definition: parsing_utilities.cpp:242
string_utilities::toUInt32
bool toUInt32(const std::string &string, uint32_t &value, int32_t base=10)
Interprets the contents of "string" as a floating point number of whatever unsigned integer type your...
Definition: string_utilities.cpp:136
string_utilities.hpp
Declares lower-level string utility functions used when parsing messages.
parsing_utilities::q_ned_ecef
Eigen::Quaterniond q_ned_ecef(double lat, double lon)
Generates the quaternion to rotate from local NED to ECEF.
Definition: parsing_utilities.cpp:346
parsing_utilities::q_enu_ecef
Eigen::Quaterniond q_enu_ecef(double lat, double lon)
Generates the quaternion to rotate from local ENU to ECEF.
Definition: parsing_utilities.cpp:336
angle
TF2SIMD_FORCE_INLINE tf2Scalar angle(const Quaternion &q1, const Quaternion &q2)
QuaternionMsg
geometry_msgs::Quaternion QuaternionMsg
Definition: typedefs.hpp:99
parsing_utilities::parseUInt8
bool parseUInt8(const std::string &string, uint8_t &value, int32_t base=10)
Interprets the contents of "string" as a unsigned integer number of type uint8_t.
Definition: parsing_utilities.cpp:153
parsing_utilities::parseInt16
int16_t parseInt16(const uint8_t *buffer)
Converts a 2-byte-buffer into a signed 16-bit integer.
Definition: parsing_utilities.cpp:97
parsing_utilities::parseDouble
double parseDouble(const uint8_t *buffer)
Converts an 8-byte-buffer into a double.
Definition: parsing_utilities.cpp:56
string_utilities::toFloat
bool toFloat(const std::string &string, float &value)
Interprets the contents of "string" as a floating point number of type float.
Definition: string_utilities.cpp:79


septentrio_gnss_driver
Author(s): Tibor Dome
autogenerated on Wed Nov 22 2023 04:04:27