data_sets.c
Go to the documentation of this file.
1 /*
2 MIT LICENSE
3 
4 Copyright (c) 2014-2021 Inertial Sense, Inc. - http://inertialsense.com
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
7 
8 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9 
10 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 */
12 
13 #include "data_sets.h"
14 #include <stddef.h>
15 #include <math.h>
16 
17 // Reversed bytes in a float.
18 // compiler will likely inline this as it's a tiny function
19 void flipFloat(uint8_t* ptr)
20 {
21  uint8_t tmp1 = *ptr++;
22  uint8_t tmp2 = *ptr++;
23  uint8_t tmp3 = *ptr++;
24  uint8_t tmp4 = *ptr;
25  *ptr-- = tmp1;
26  *ptr-- = tmp2;
27  *ptr-- = tmp3;
28  *ptr = tmp4;
29 }
30 
31 float flipFloatCopy(float val)
32 {
33  float flippedFloat;
34  uint8_t* ptr = (uint8_t*)&val;
35  uint8_t* ptr2 = (uint8_t*)&flippedFloat;
36  uint8_t tmp1 = *ptr++;
37  uint8_t tmp2 = *ptr++;
38  uint8_t tmp3 = *ptr++;
39  uint8_t tmp4 = *ptr;
40  *ptr2++ = tmp4;
41  *ptr2++ = tmp3;
42  *ptr2++ = tmp2;
43  *ptr2 = tmp1;
44  return flippedFloat;
45 }
46 
47 void flipDouble(void* ptr)
48 {
49  const uint32_t* w = (const uint32_t*)(ptr);
50  union
51  {
52  double v;
53  uint32_t w[2];
54  } u;
55  u.w[0] = w[1];
56  u.w[1] = w[0];
57  *(double*)ptr = u.v;
58 }
59 
60 double flipDoubleCopy(double val)
61 {
62  union
63  {
64  double v;
65  uint32_t w[2];
66  } u1, u2;
67  u1.v = val;
68  u2.w[1] = SWAP32(u1.w[0]);
69  u2.w[0] = SWAP32(u1.w[1]);
70  return u2.v;
71 }
72 
73 void flipEndianess32(uint8_t* data, int dataLength)
74 {
75  // data must be 4 byte aligned to swap endian-ness
76  if (dataLength & 0x00000003)
77  {
78  return;
79  }
80 
81  uint32_t* dataPtr = (void*)data;
82  uint32_t* dataPtrEnd = (void*)(data + dataLength);
83  uint32_t tmp;
84  while (dataPtr < dataPtrEnd)
85  {
86  tmp = *dataPtr;
87  *dataPtr++ = SWAP32(tmp);
88  }
89 }
90 
91 void flipDoubles(uint8_t* data, int dataLength, int offset, uint16_t* offsets, uint16_t offsetsLength)
92 {
93  uint16_t* doubleOffsetsEnd = offsets + offsetsLength;
94  int offsetToDouble;
95  int maxDoubleOffset = dataLength - 8;
96  int isDouble;
97  while (offsets < doubleOffsetsEnd)
98  {
99  offsetToDouble = (*offsets++);
100  isDouble = ((offsetToDouble & 0x8000) == 0);
101  offsetToDouble = (offsetToDouble & 0x7FFF) - offset;
102  if (offsetToDouble >= 0 && offsetToDouble <= maxDoubleOffset)
103  {
104  if (isDouble)
105  {
106  flipDouble(data + offsetToDouble);
107  }
108  else
109  {
110  uint64_t* ptr = (void*)(data + offsetToDouble);
111  *ptr = SWAP64(*ptr);
112  }
113  }
114  }
115 }
116 
117 void flipStrings(uint8_t* data, int dataLength, int offset, uint16_t* offsets, uint16_t offsetsLength)
118 {
119  uint16_t* stringOffsetsEnd = offsets + offsetsLength;
120  int offsetToString;
121  int lengthOfString;
122  int maxStringOffset;
123 
124  while (offsets < stringOffsetsEnd)
125  {
126  offsetToString = (*offsets++) - offset;
127  lengthOfString = (*offsets++);
128  maxStringOffset = dataLength - lengthOfString;
129  if (offsetToString >= 0 && offsetToString <= maxStringOffset)
130  {
131  flipEndianess32(data + offsetToString, lengthOfString);
132  }
133  }
134 }
135 
136 #ifdef _MSC_VER
137 #pragma warning(push)
138 #pragma warning(disable: 4267)
139 #endif
140 
141 uint16_t* getDoubleOffsets(eDataIDs dataId, uint16_t* offsetsLength)
142 {
143  /* Offset arrays contain:
144  {
145  array size,
146  byte offset,
147  byte offset,
148  ...
149  } */
150 
151  // first offset is the number of offsets
152  static uint16_t offsetsIns1[] =
153  {
154  4,
155  offsetof(ins_1_t, timeOfWeek),
156  offsetof(ins_1_t, lla[0]),
157  offsetof(ins_1_t, lla[1]),
158  offsetof(ins_1_t, lla[2])
159  };
160 
161  static uint16_t offsetsIns2[] =
162  {
163  4,
164  offsetof(ins_2_t, timeOfWeek),
165  offsetof(ins_2_t, lla[0]),
166  offsetof(ins_2_t, lla[1]),
167  offsetof(ins_2_t, lla[2])
168  };
169 
170  static uint16_t offsetsIns3[] =
171  {
172  4,
173  offsetof(ins_3_t, timeOfWeek),
174  offsetof(ins_3_t, lla[0]),
175  offsetof(ins_3_t, lla[1]),
176  offsetof(ins_3_t, lla[2])
177  };
178 
179  static uint16_t offsetsIns4[] =
180  {
181  4,
182  offsetof(ins_4_t, timeOfWeek),
183  offsetof(ins_4_t, ecef[0]),
184  offsetof(ins_4_t, ecef[1]),
185  offsetof(ins_4_t, ecef[2])
186  };
187 
188  static uint16_t offsetsSysParams[] =
189  {
190  1,
191  offsetof(sys_params_t, sensorTruePeriod),
192  };
193 
194  static uint16_t offsetsPreImuMag[] =
195  {
196  3,
197  offsetof(pimu_mag_t, pimu.time),
198  offsetof(pimu_mag_t, mag1.time),
199  offsetof(pimu_mag_t, mag2.time)
200  };
201 
202  static uint16_t offsetsDualImuMag[] =
203  {
204  3,
205  offsetof(imu_mag_t, imu.time),
206  offsetof(imu_mag_t, mag1.time),
207  offsetof(imu_mag_t, mag2.time)
208  };
209 
210  static uint16_t offsetsGps[] =
211  {
212  7,
213  offsetof(gps_pos_t, lla[0]),
214  offsetof(gps_pos_t, lla[1]),
215  offsetof(gps_pos_t, lla[2]),
216  offsetof(gps_pos_t, towOffset),
217  offsetof(gps_pos_t, ecef[0]),
218  offsetof(gps_pos_t, ecef[1]),
219  offsetof(gps_pos_t, ecef[2])
220  };
221 
222  static uint16_t offsetsRmc[] =
223  {
224  1,
225  // 0x8000 denotes a 64 bit int vs a double
226  offsetof(rmc_t, bits) | 0x8000
227  };
228 
229  static uint16_t offsetsInl2States[] =
230  {
231  4, 0, 36, 44, 52
232  };
233 
234  static uint16_t offsetsRtkNav[] =
235  {
236  3,
237  offsetof(gps_rtk_misc_t, baseLla[0]),
238  offsetof(gps_rtk_misc_t, baseLla[1]),
239  offsetof(gps_rtk_misc_t, baseLla[2]),
240  };
241 
242  static uint16_t offsetsFlashConfig[] =
243  {
244  6,
245  offsetof( nvm_flash_cfg_t, refLla[0] ),
246  offsetof( nvm_flash_cfg_t, refLla[1] ),
247  offsetof( nvm_flash_cfg_t, refLla[2] ),
248  offsetof( nvm_flash_cfg_t, lastLla[0] ),
249  offsetof( nvm_flash_cfg_t, lastLla[1] ),
250  offsetof( nvm_flash_cfg_t, lastLla[2] )
251  };
252 
253  static uint16_t offsetsOnlyTimeFirst[] = { 1, 0 };
254  static uint16_t offsetsDebugArray[] = { 3, 72, 80, 88 };
255  static uint16_t offsetsSurveyIn[] =
256  {
257  3,
258  offsetof(survey_in_t, lla[0]),
259  offsetof(survey_in_t, lla[1]),
260  offsetof(survey_in_t, lla[2])
261  };
262 
263  static uint16_t* s_doubleOffsets[] =
264  {
265  0, // 0: DID_NULL
266  0, // 1: DID_DEV_INFO
267  0, // 2: DID_SYS_FAULT
268  offsetsOnlyTimeFirst, // 3: DID_PREINTEGRATED_IMU
269  offsetsIns1, // 4: DID_INS_1
270  offsetsIns2, // 5: DID_INS_2
271  offsetsGps, // 6: DID_GPS1_POS
272  0, // 7: DID_SYS_CMD
273  0, // 8: DID_ASCII_BCAST_PERIOD
274  offsetsRmc, // 9: DID_RMC
275  offsetsSysParams, // 10: DID_SYS_PARAMS
276  offsetsOnlyTimeFirst, // 11: DID_SYS_SENSORS
277  offsetsFlashConfig, // 12: DID_FLASH_CONFIG
278  offsetsGps, // 13: DID_GPS1_UBX_POS
279  offsetsGps, // 14: DID_GPS2_POS
280  0, // 15: DID_GPS1_SAT
281  0, // 16: DID_GPS2_SAT
282  0, // 17: DID_GPS1_VERSION
283  0, // 18: DID_GPS2_VERSION
284  0, // 19: DID_MAG_CAL
285  0, // 20: DID_INTERNAL_DIAGNOSTIC
286  0, // 21: DID_GPS1_RTK_POS_REL
287  offsetsRtkNav, // 22: DID_GPS1_RTK_POS_MISC
288  0, // 23: DID_FEATURE_BITS
289  0, // 24: DID_SENSORS_IS1
290  0, // 25: DID_SENSORS_IS2
291  0, // 26: DID_SENSORS_TC_BIAS
292  0, // 27: DID_IO
293  offsetsOnlyTimeFirst, // 28: DID_SENSORS_ADC
294  0, // 29: DID_SCOMP
295  0, // 30: DID_GPS1_VEL
296  0, // 31: DID_GPS2_VEL
297  0, // 32: DID_HDW_PARAMS
298  0, // 33: DID_NVR_MANAGE_USERPAGE
299  0, // 34: DID_NVR_USERPAGE_SN
300  0, // 35: DID_NVR_USERPAGE_G0
301  0, // 36: DID_NVR_USERPAGE_G1
302  0, // 37: DID_NVR_MANAGE_PROTECTED
303  0, // 38: DID_RTOS_INFO
304  offsetsDebugArray, // 39: DID_DEBUG_ARRAY
305  0, // 40: DID_SENSORS_CAL1
306  0, // 41: DID_SENSORS_CAL2
307  0, // 42: DID_CAL_SC
308  0, // 43: DID_CAL_SC1
309  0, // 44: DID_CAL_SC2
310  offsetsOnlyTimeFirst, // 45: DID_SYS_SENSORS_SIGMA
311  offsetsOnlyTimeFirst, // 46: DID_SENSORS_ADC_SIGMA
312  0, // 47: DID_INS_DEV_1
313  offsetsInl2States, // 48: DID_INL2_STATES
314  0, // 49: DID_INL2_COVARIANCE_LD
315  0, // 50: DID_INL2_MISC
316  0, // 51: DID_INL2_STATUS,
317  offsetsOnlyTimeFirst, // 52: DID_MAGNETOMETER_1
318  offsetsOnlyTimeFirst, // 53: DID_BAROMETER
319  0, // 54: DID_GPS1_RTK_POS
320  offsetsOnlyTimeFirst, // 55: DID_MAGNETOMETER_2
321  0, // 56: DID_COMMUNICATIONS_LOOPBACK
322  offsetsOnlyTimeFirst, // 57: DID_DUAL_IMU_RAW
323  offsetsOnlyTimeFirst, // 58: DID_DUAL_IMU
324  0, // 59: DID_INL2_MAG_OBS_INFO
325  0, // 60: DID_GPS_BASE_RAW
326  0, // 61: DID_GPS_RTK_OPT
327  0, // 62: DID_NVR_USERPAGE_INTERNAL
328  0, // 63: DID_MANUFACTURING_INFO
329  0, // 64: DID_BIT
330  offsetsIns3, // 65: DID_INS_3
331  offsetsIns4, // 66: DID_INS_4
332  0, // 67: DID_INL2_NED_SIGMA
333  0, // 68: DID_STROBE_IN_TIME
334  0, // 69: DID_GPS1_RAW
335  0, // 70: DID_GPS2_RAW
336  offsetsOnlyTimeFirst, // 71: DID_WHEEL_ENCODER
337  0, // 72: DID_DIAGNOSTIC_MESSAGE
338  offsetsSurveyIn, // 73: DID_SURVEY_IN
339  0, // 74: EMPTY
340  0, // 75: DID_PORT_MONITOR
341  0, // 76: DID_RTK_STATE
342  0, // 77: DID_RTK_RESIDUAL
343  0, // 78: DID_RTK_PHASE_RESIDUAL
344  0, // 79: DID_RTK_CODE_RESIDUAL
345  0, // 80: DID_EVB_STATUS
346  0, // 81: DID_EVB_FLASH_CFG
347  offsetsDebugArray, // 82: DID_EVB_DEBUG_ARRAY
348  0, // 83: DID_EVB_RTOS_INFO
349  offsetsDualImuMag, // 84: DID_DUAL_IMU_RAW_MAG
350  offsetsDualImuMag, // 85: DID_DUAL_IMU_MAG
351  offsetsPreImuMag, // 86: DID_PREINTEGRATED_IMU_MAG
352  0, // 87:
353  0, // 88:
354  0, // 89:
355  0, // 90:
356  0, // 91: DID_GPS2_RTK_CMP_REL
357  offsetsRtkNav, // 92: DID_GPS2_RTK_CMP_MISC
358  0, // 93:
359  0, // 94:
360  0 // 95:
361  };
362 
363  STATIC_ASSERT(_ARRAY_ELEMENT_COUNT(s_doubleOffsets) == DID_COUNT);
364  STATIC_ASSERT((DID_COUNT%4) == 0);
365 
366  if (dataId < DID_COUNT)
367  {
368  uint16_t* offsets;
369  if ((offsets = s_doubleOffsets[dataId]))
370  {
371  *offsetsLength = (*offsets++);
372  return offsets;
373  }
374  }
375  return 0;
376 }
377 
378 #ifdef _MSC_VER
379 #pragma warning(pop)
380 #endif
381 
382 uint16_t* getStringOffsetsLengths(eDataIDs dataId, uint16_t* offsetsLength)
383 {
384  /* Offset arrays contain:
385  {
386  array size, // number of pairs
387  byte offset, byte size, // 1st pair
388  byte offset, byte size, // 2nd pair
389  ...
390  } */
391 
392  static uint16_t debugStringOffsets[] = { 2, 0, 80 };
393 
394  static uint16_t rtosTaskOffsets[] =
395  {
396  12,
398  32, MAX_TASK_NAME_LEN,
399  64, MAX_TASK_NAME_LEN,
400  96, MAX_TASK_NAME_LEN,
401  128, MAX_TASK_NAME_LEN,
402  160, MAX_TASK_NAME_LEN
403  };
404 
405  static uint16_t manufInfoOffsets[] =
406  {
407  2,
409  };
410 
411  static uint16_t diagMsgOffsets[] =
412  {
413  2,
414  offsetof(diag_msg_t, message), _MEMBER_ARRAY_ELEMENT_COUNT(diag_msg_t, message)
415  };
416 
417  static uint16_t* s_stringOffsets[] =
418  {
419  0, // 0: DID_NULL
420  0, // 1: DID_DEV_INFO
421  0, // 2: DID_SYS_FAULT
422  0, // 3: DID_PREINTEGRATED_IMU
423  0, // 4: DID_INS_1
424  0, // 5: DID_INS_2
425  0, // 6: DID_GPS1_POS
426  0, // 7: DID_SYS_CMD
427  0, // 8: DID_ASCII_BCAST_PERIOD
428  0, // 9: DID_RMC
429  0, // 10: DID_SYS_PARAMS
430  0, // 11: DID_SYS_SENSORS
431  0, // 12: DID_FLASH_CONFIG
432  0, // 13: DID_GPS1_UBX_POS
433  0, // 14: DID_GPS2_POS
434  0, // 15: DID_GPS1_SAT
435  0, // 16: DID_GPS2_SAT
436  0, // 17: DID_GPS1_VERSION
437  0, // 18: DID_GPS2_VERSION
438  0, // 19: DID_MAG_CAL
439  0, // 20: DID_INTERNAL_DIAGNOSTIC
440  0, // 21: DID_GPS1_RTK_POS_REL
441  0, // 22: DID_GPS1_RTK_POS_MISC,
442  0, // 23: DID_FEATURE_BITS
443  0, // 24: DID_SENSORS_IS1
444  0, // 25: DID_SENSORS_IS2
445  0, // 26: DID_SENSORS_TC_BIAS
446  0, // 27: DID_IO
447  0, // 28: DID_SENSORS_ADC
448  0, // 29: DID_SCOMP
449  0, // 30: DID_GPS1_VEL
450  0, // 31: DID_GPS2_VEL
451  0, // 32: DID_HDW_PARAMS,
452  0, // 33: DID_NVR_MANAGE_USERPAGE
453  0, // 34: DID_NVR_USERPAGE_SN
454  0, // 35: DID_NVR_USERPAGE_G0
455  0, // 36: DID_NVR_USERPAGE_G1
456  debugStringOffsets, // 37: DID_DEBUG_STRING
457  rtosTaskOffsets, // 38: DID_RTOS_INFO
458  0, // 39: DID_DEBUG_ARRAY
459  0, // 40: DID_SENSORS_CAL1
460  0, // 41: DID_SENSORS_CAL2
461  0, // 42: DID_CAL_SC
462  0, // 43: DID_CAL_SC1
463  0, // 44: DID_CAL_SC2
464  0, // 45: DID_SYS_SENSORS_SIGMA
465  0, // 46: DID_SENSORS_ADC_SIGMA
466  0, // 47: DID_INS_DEV_1
467  0, // 48: DID_INL2_STATES
468  0, // 49: DID_INL2_COVARIANCE_LD
469  0, // 50: DID_INL2_MISC
470  0, // 51: DID_INL2_STATUS
471  0, // 52: DID_MAGNETOMETER_1
472  0, // 53: DID_BAROMETER
473  0, // 54: DID_GPS1_RTK_POS
474  0, // 55: DID_MAGNETOMETER_2
475  0, // 56: DID_COMMUNICATIONS_LOOPBACK
476  0, // 57: DID_DUAL_IMU_RAW
477  0, // 58: DID_DUAL_IMU
478  0, // 59: DID_INL2_MAG_OBS_INFO
479  0, // 60: DID_GPS_BASE_RAW
480  0, // 61: DID_GPS_RTK_OPT
481  0, // 62: DID_NVR_USERPAGE_INTERNAL
482  manufInfoOffsets, // 63: DID_MANUFACTURING_INFO
483  0, // 64: DID_BIT
484  0, // 65: DID_INS_3
485  0, // 66: DID_INS_4
486  0, // 67: DID_INL2_NED_SIGMA
487  0, // 68: DID_STROBE_IN_TIME
488  0, // 69: DID_GPS1_RAW
489  0, // 70: DID_GPS2_RAW
490  0, // 71: DID_WHEEL_ENCODER
491  diagMsgOffsets, // 72: DID_DIAGNOSTIC_MESSAGE
492  0, // 73: DID_SURVEY_IN
493  0, // 74: DID_CAL_SC_INFO
494  0, // 75: DID_PORT_MONITOR
495  0, // 76: DID_RTK_STATE
496  0, // 77: DID_RTK_RESIDUAL
497  0, // 78: DID_RTK_PHASE_RESIDUAL
498  0, // 79: DID_RTK_CODE_RESIDUAL
499  0, // 80: DID_EVB_STATUS
500  0, // 81: DID_EVB_FLASH_CFG
501  0, // 82: DID_EVB_DEBUG_ARRAY
502  0, // 83: DID_EVB_RTOS_INFO
503  0, // 84: DID_DUAL_IMU_RAW_MAG
504  0, // 85: DID_DUAL_IMU_MAG
505  0, // 86: DID_PREINTEGRATED_IMU_MAG
506  0, // 87: DID_WHEEL_CONFIG
507  0, // 88: DID_POSITION_MEASUREMENT
508  0, // 89: DID_RTK_DEBUG_2
509  0, // 90: DID_CAN_CONFIG
510  0, // 91: DID_GPS2_RTK_CMP_REL
511  0, // 92: DID_GPS2_RTK_CMP_MISC
512  0, // 93:
513  0, // 94:
514  0 // 95:
515  };
516 
517  STATIC_ASSERT(_ARRAY_ELEMENT_COUNT(s_stringOffsets) == DID_COUNT);
518 
519  if (dataId < DID_COUNT)
520  {
521  uint16_t* offsets;
522  if ((offsets = s_stringOffsets[dataId]))
523  {
524  *offsetsLength = (*offsets++);
525  return offsets;
526  }
527  }
528  return 0;
529 }
530 
531 uint32_t checksum32(const void* data, int count)
532 {
533  if (count < 1 || count % 4 != 0)
534  {
535  return 0;
536  }
537 
538  uint32_t checksum = 0;
539  uint32_t* dataPtr = (uint32_t*)data;
540  uint32_t* dataEnd = dataPtr + (count / 4);
541 
542  while (dataPtr < dataEnd)
543  {
544  checksum ^= *dataPtr++;
545  }
546 
547  return checksum;
548 }
549 
550 // This function skips the first 4 bytes (one 4 byte word), which are assumed to be the checksum in the serial number flash memory data structure.
551 uint32_t serialNumChecksum32(const void* data, int size)
552 {
553  return checksum32((const uint8_t*)data + 4, size - 4);
554 }
555 
556 // This function skips the first 8 bytes (two 4 byte words), which are assumed to be the size and checksum in flash memory data structures.
557 uint32_t flashChecksum32(const void* data, int size)
558 {
559  return checksum32((const uint8_t*)data + 8, size - 8);
560 }
561 
562 // Convert DID to message out control mask
563 uint64_t didToRmcBit(uint32_t dataId, uint64_t defaultRmcBits)
564 {
565  switch (dataId)
566  {
567  case DID_INS_1: return RMC_BITS_INS1;
568  case DID_INS_2: return RMC_BITS_INS2;
569  case DID_INS_3: return RMC_BITS_INS3;
570  case DID_INS_4: return RMC_BITS_INS4;
572  case DID_DUAL_IMU: return RMC_BITS_DUAL_IMU;
574  case DID_BAROMETER: return RMC_BITS_BAROMETER;
577  case DID_GPS1_POS: return RMC_BITS_GPS1_POS;
578  case DID_GPS2_POS: return RMC_BITS_GPS2_POS;
579  case DID_GPS1_VEL: return RMC_BITS_GPS1_VEL;
580  case DID_GPS2_VEL: return RMC_BITS_GPS2_VEL;
581  case DID_GPS1_SAT: return RMC_BITS_GPS1_SAT;
582  case DID_GPS2_SAT: return RMC_BITS_GPS2_SAT;
583  case DID_GPS1_RAW: return RMC_BITS_GPS1_RAW;
584  case DID_GPS2_RAW: return RMC_BITS_GPS2_RAW;
595  case DID_RTK_STATE: return RMC_BITS_RTK_STATE;
603  default: return defaultRmcBits;
604  }
605 }
606 
607 void julianToDate(double julian, int32_t* year, int32_t* month, int32_t* day, int32_t* hour, int32_t* minute, int32_t* second, int32_t* millisecond)
608 {
609  double j1, j2, j3, j4, j5;
610  double intgr = floor(julian);
611  double frac = julian - intgr;
612  double gregjd = 2299161.0;
613  if (intgr >= gregjd)
614  {
615  //Gregorian calendar correction
616  double tmp = floor(((intgr - 1867216.0) - 0.25) / 36524.25);
617  j1 = intgr + 1.0 + tmp - floor(0.25 * tmp);
618  }
619  else
620  {
621  j1 = intgr;
622  }
623 
624  //correction for half day offset
625  double dayfrac = frac + 0.5;
626  if (dayfrac >= 1.0)
627  {
628  dayfrac -= 1.0;
629  ++j1;
630  }
631 
632  j2 = j1 + 1524.0;
633  j3 = floor(6680.0 + ((j2 - 2439870.0) - 122.1) / 365.25);
634  j4 = floor(j3 * 365.25);
635  j5 = floor((j2 - j4) / 30.6001);
636 
637  double d = floor(j2 - j4 - floor(j5 * 30.6001));
638  double m = floor(j5 - 1);
639  if (m > 12)
640  {
641  m -= 12;
642  }
643  double y = floor(j3 - 4715.0);
644  if (m > 2)
645  {
646  --y;
647  }
648  if (y <= 0)
649  {
650  --y;
651  }
652 
653  //
654  // get time of day from day fraction
655  //
656  double hr = floor(dayfrac * 24.0);
657  double mn = floor((dayfrac * 24.0 - hr) * 60.0);
658  double f = ((dayfrac * 24.0 - hr) * 60.0 - mn) * 60.0;
659  double sc = f;
660  if (f - sc > 0.5)
661  {
662  ++sc;
663  }
664 
665  if (y < 0)
666  {
667  y = -y;
668  }
669  if (year)
670  {
671  *year = (int32_t)y;
672  }
673  if (month)
674  {
675  *month = (int32_t)m;
676  }
677  if (day)
678  {
679  *day = (int32_t)d;
680  }
681  if (hour)
682  {
683  *hour = (int32_t)hr;
684  }
685  if (minute)
686  {
687  *minute = (int32_t)mn;
688  }
689  if (second)
690  {
691  *second = (int32_t)sc;
692  }
693  if (millisecond)
694  {
695  *millisecond = (int32_t)((sc - floor(sc)) * 1000.0);
696  }
697 }
698 
699 double gpsToUnix(uint32_t gpsWeek, uint32_t gpsTimeofWeekMS, uint8_t leapSeconds)
700 {
701  double gpsSeconds = gpsWeek * SECONDS_PER_WEEK;
702  gpsSeconds += (gpsTimeofWeekMS / 1000);
703  double unixSeconds = gpsSeconds + GPS_TO_UNIX_OFFSET - leapSeconds;
704 
705  return unixSeconds;
706 }
707 
708 double gpsToJulian(int32_t gpsWeek, int32_t gpsMilliseconds, int32_t leapSeconds)
709 {
710  double gpsDays = (double)gpsWeek * 7.0;
711  gpsDays += ((((double)gpsMilliseconds / 1000.0) - (double)leapSeconds) / 86400.0);
712  return (2444244.500000) + gpsDays; // 2444244.500000 Julian date for Jan 6, 1980 midnight - start of gps time
713 }
714 
715 static void appendGPSTimeOfLastFix(const gps_pos_t* gps, char** buffer, int* bufferLength)
716 {
717  unsigned int millisecondsToday = gps->timeOfWeekMs % 86400000;
718  unsigned int hours = millisecondsToday / 1000 / 60 / 60;
719  unsigned int minutes = (millisecondsToday / (1000 * 60)) % 60;
720  unsigned int seconds = (millisecondsToday / 1000) % 60;
721  int written = SNPRINTF(*buffer, *bufferLength, ",%02u%02u%02u", hours, minutes, seconds);
722  *bufferLength -= written;
723  *buffer += written;
724 }
725 
726 static void appendGPSCoord(const gps_pos_t* gps, char** buffer, int* bufferLength, double v, const char* degreesFormat, char posC, char negC)
727 {
728  (void)gps;
729  int degrees = (int)(v);
730  double minutes = (v - ((double)degrees)) * 60.0;
731 
732  int written = SNPRINTF(*buffer, *bufferLength, degreesFormat, abs(degrees));
733  *bufferLength -= written;
734  *buffer += written;
735 
736  written = SNPRINTF(*buffer, *bufferLength, "%07.4f,", fabs(minutes));
737  *bufferLength -= written;
738  *buffer += written;
739 
740  written = SNPRINTF(*buffer, *bufferLength, "%c", (degrees >= 0 ? posC : negC));
741  *bufferLength -= written;
742  *buffer += written;
743 }
744 
745 int gpsToNmeaGGA(const gps_pos_t* gps, char* buffer, int bufferLength)
746 {
747  // NMEA GGA line - http://www.gpsinformation.org/dale/nmea.htm#GGA
748  /*
749  GGA Global Positioning System Fix Data
750  123519 Fix taken at 12:35:19 UTC
751  4807.038,N Latitude 48 deg 07.038' N
752  01131.000,E Longitude 11 deg 31.000' E
753  . Fix quality: 0 = invalid
754  . 1 = GPS fix (SPS)
755  . 2 = DGPS fix
756  . 3 = PPS fix
757  . 4 = Real Time Kinematic
758  . 5 = Float RTK
759  . 6 = estimated (dead reckoning) (2.3 feature)
760  . 7 = Manual input mode
761  . 8 = Simulation mode
762  08 Number of satellites being tracked
763  0.9 Horizontal dilution of position
764  545.4,M MSL altitude in meters
765  46.9,M HAE altitude (above geoid / WGS84 ellipsoid)
766  ellipsoid
767  (empty field) time in seconds since last DGPS update
768  (empty field) DGPS station ID number
769  *47 the checksum data, always begins with *
770  */
771 
772  if (bufferLength < 128)
773  {
774  return 0;
775  }
776 
777  unsigned int checkSum = 0;
778  int fixQuality;
779  switch((gps->status & GPS_STATUS_FIX_MASK))
780  {
781  default:
782  case GPS_STATUS_FIX_NONE:
783  fixQuality = 0;
784  break;
785 
786  case GPS_STATUS_FIX_SBAS:
787  case GPS_STATUS_FIX_2D:
789  case GPS_STATUS_FIX_3D:
790  fixQuality = 1;
791  break;
792 
793  case GPS_STATUS_FIX_DGPS:
794  fixQuality = 2;
795  break;
796 
798  fixQuality = 3;
799  break;
800 
802  fixQuality = 4;
803  break;
804 
806  fixQuality = 5;
807  break;
808 
811  fixQuality = 6;
812  break;
813  }
814 
815  // write message
816  int written = 1;
817  char* bufferStart = buffer;
818  *buffer++ = '$';
819  bufferLength--;
820  written = SNPRINTF(buffer, bufferLength, "%s", "GPGGA");
821  buffer += written;
822  bufferLength -= written;
823 
824  appendGPSTimeOfLastFix(gps, &buffer, &bufferLength);
825  appendGPSCoord(gps, &buffer, &bufferLength, gps->lla[0], ",%02d", 'N', 'S');
826  appendGPSCoord(gps, &buffer, &bufferLength, gps->lla[1], ",%03d", 'E', 'W');
827 
828  written = SNPRINTF(buffer, bufferLength, ",%u,%02u,%.2f,%.2f,M,%.2f,M,,",
829  (unsigned)fixQuality,
830  (unsigned)(gps->status & GPS_STATUS_NUM_SATS_USED_MASK),
831  gps->pDop,
832  gps->hMSL,
833  gps->hMSL - gps->lla[2]);
834  buffer += written;
835  bufferLength -= written;
836 
837  // compute checksum
838  for (char* ptr = bufferStart + 1; ptr < buffer; ptr++)
839  {
840  checkSum ^= *ptr;
841  }
842 
843  written = SNPRINTF(buffer, bufferLength, "*%.2x\r\n", checkSum);
844  buffer += written;
845  return (int)(buffer - bufferStart);
846 }
847 
848 /* ubx gnss indicator (ref [2] 25) -------------------------------------------*/
849 int ubxSys(int gnssID)
850 {
851  switch (gnssID) {
852  case 0: return SYS_GPS;
853  case 1: return SYS_SBS;
854  case 2: return SYS_GAL;
855  case 3: return SYS_CMP;
856  case 5: return SYS_QZS;
857  case 6: return SYS_GLO;
858  }
859  return 0;
860 }
861 
862 /* satellite system+prn/slot number to satellite number ------------------------
863 * convert satellite system+prn/slot number to satellite number
864 * args : int sys I satellite system (SYS_GPS,SYS_GLO,...)
865 * int prn I satellite prn/slot number
866 * return : satellite number (0:error)
867 *-----------------------------------------------------------------------------*/
868 int satNo(int sys, int prn)
869 {
870  if (prn <= 0) return 0;
871  switch (sys) {
872  case SYS_GPS:
873  if (prn < MINPRNGPS || MAXPRNGPS < prn) return 0;
874  return prn - MINPRNGPS + 1;
875  case SYS_GLO:
876  if (prn < MINPRNGLO || MAXPRNGLO < prn) return 0;
877  return NSATGPS + prn - MINPRNGLO + 1;
878  case SYS_GAL:
879  if (prn < MINPRNGAL || MAXPRNGAL < prn) return 0;
880  return NSATGPS + NSATGLO + prn - MINPRNGAL + 1;
881  case SYS_QZS:
882  if (prn < MINPRNQZS || MAXPRNQZS < prn) return 0;
883  return NSATGPS + NSATGLO + NSATGAL + prn - MINPRNQZS + 1;
884  case SYS_CMP:
885  if (prn < MINPRNCMP || MAXPRNCMP < prn) return 0;
886  return NSATGPS + NSATGLO + NSATGAL + NSATQZS + prn - MINPRNCMP + 1;
887  case SYS_IRN:
888  if (prn < MINPRNIRN || MAXPRNIRN < prn) return 0;
889  return NSATGPS + NSATGLO + NSATGAL + NSATQZS + NSATCMP + prn - MINPRNIRN + 1;
890  case SYS_LEO:
891  if (prn < MINPRNLEO || MAXPRNLEO < prn) return 0;
892  return NSATGPS + NSATGLO + NSATGAL + NSATQZS + NSATCMP + NSATIRN +
893  prn - MINPRNLEO + 1;
894  case SYS_SBS:
895  if (prn < MINPRNSBS || MAXPRNSBS < prn) return 0;
896  return NSATGPS + NSATGLO + NSATGAL + NSATQZS + NSATCMP + NSATIRN + NSATLEO +
897  prn - MINPRNSBS + 1;
898  }
899  return 0;
900 }
901 
902 /* satellite gnssID+svID to satellite number ------------------------
903 * convert satellite gnssID + svID to satellite number
904 * args : int gnssID I satellite system
905 * int svID I satellite vehicle ID within system
906 * return : satellite number (0:error)
907 *-----------------------------------------------------------------------------*/
908 int satNumCalc(int gnssID, int svID) {
909  int sys = ubxSys(gnssID);
910  int prn = svID + (sys == SYS_QZS ? 192 : 0);
911  return satNo(sys, prn);
912 }
uint16_t * getDoubleOffsets(eDataIDs dataId, uint16_t *offsetsLength)
Definition: data_sets.c:141
d
#define DID_DUAL_IMU
Definition: data_sets.h:92
#define RMC_BITS_INL2_NED_SIGMA
Definition: data_sets.h:1305
#define MINPRNCMP
Definition: data_sets.h:3854
#define _MEMBER_ARRAY_ELEMENT_COUNT(type, member)
Definition: ISConstants.h:330
#define RMC_BITS_GPS1_POS
Definition: data_sets.h:1289
uint32_t bufferLength
Definition: USBD.h:91
#define RMC_BITS_PREINTEGRATED_IMU_MAG
Definition: data_sets.h:1313
#define RMC_BITS_GPS1_RTK_POS
Definition: data_sets.h:1302
#define DID_WHEEL_CONFIG
Definition: data_sets.h:121
#define RMC_BITS_GPS1_UBX_POS
Definition: data_sets.h:1301
#define MINPRNSBS
Definition: data_sets.h:3785
static void appendGPSTimeOfLastFix(const gps_pos_t *gps, char **buffer, int *bufferLength)
Definition: data_sets.c:715
int satNumCalc(int gnssID, int svID)
Definition: data_sets.c:908
#define RMC_BITS_GPS1_RTK_POS_REL
Definition: data_sets.h:1303
uint32_t serialNumChecksum32(const void *data, int size)
Definition: data_sets.c:551
#define MINPRNGAL
Definition: data_sets.h:3823
#define RMC_BITS_GPS2_RAW
Definition: data_sets.h:1292
#define RMC_BITS_GPS1_RAW
Definition: data_sets.h:1291
#define RMC_BITS_GPS2_POS
Definition: data_sets.h:1290
#define MINPRNQZS
Definition: data_sets.h:3841
#define SWAP64(v)
Definition: ISConstants.h:286
#define SECONDS_PER_WEEK
Definition: data_sets.h:3688
#define RMC_BITS_DUAL_IMU_MAG_RAW
Definition: data_sets.h:1311
#define DID_GPS1_VEL
Definition: data_sets.h:64
#define RMC_BITS_GPS1_RTK_HDG_REL
Definition: data_sets.h:1314
#define RMC_BITS_GPS2_VEL
Definition: data_sets.h:1300
#define DID_INS_1
Definition: data_sets.h:38
#define RMC_BITS_MAGNETOMETER2
Definition: data_sets.h:1287
#define RMC_BITS_GPS1_RTK_HDG_MISC
Definition: data_sets.h:1315
#define DID_GPS2_RTK_CMP_REL
Definition: data_sets.h:125
uint16_t * getStringOffsetsLengths(eDataIDs dataId, uint16_t *offsetsLength)
Definition: data_sets.c:382
#define DID_DUAL_IMU_MAG
Definition: data_sets.h:119
#define DID_GPS1_UBX_POS
Definition: data_sets.h:40
#define MINPRNLEO
Definition: data_sets.h:3876
void flipFloat(uint8_t *ptr)
Definition: data_sets.c:19
#define SYS_GLO
Definition: data_sets.h:3714
size_t count(InputIterator first, InputIterator last, T const &item)
Definition: catch.hpp:3206
float timeOfWeekMs
Definition: CAN_comm.h:29
#define DID_COUNT
Definition: data_sets.h:138
#define MAXPRNSBS
Definition: data_sets.h:3788
#define MAXPRNGPS
Definition: data_sets.h:3807
#define DID_INS_2
Definition: data_sets.h:39
#define MINPRNGLO
Definition: data_sets.h:3812
#define RMC_BITS_GPS_BASE_RAW
Definition: data_sets.h:1295
uint32_t eDataIDs
Definition: data_sets.h:32
#define DID_PREINTEGRATED_IMU
Definition: data_sets.h:37
static void appendGPSCoord(const gps_pos_t *gps, char **buffer, int *bufferLength, double v, const char *degreesFormat, char posC, char negC)
Definition: data_sets.c:726
#define DID_PREINTEGRATED_IMU_MAG
Definition: data_sets.h:120
int satNo(int sys, int prn)
Definition: data_sets.c:868
#define DID_GPS_BASE_RAW
Definition: data_sets.h:94
void flipDoubles(uint8_t *data, int dataLength, int offset, uint16_t *offsets, uint16_t offsetsLength)
Definition: data_sets.c:91
uint64_t didToRmcBit(uint32_t dataId, uint64_t defaultRmcBits)
Definition: data_sets.c:563
#define SYS_LEO
Definition: data_sets.h:3719
void flipEndianess32(uint8_t *data, int dataLength)
Definition: data_sets.c:73
void flipDouble(void *ptr)
Definition: data_sets.c:47
#define DID_MAGNETOMETER_2
Definition: data_sets.h:89
#define SYS_SBS
Definition: data_sets.h:3713
float hMSL
Definition: data_sets.h:772
#define RMC_BITS_DUAL_IMU_RAW
Definition: data_sets.h:1298
#define RMC_BITS_GPS1_VEL
Definition: data_sets.h:1299
#define MINPRNGPS
Definition: data_sets.h:3806
#define RMC_BITS_MAGNETOMETER1
Definition: data_sets.h:1286
#define MAXPRNGAL
Definition: data_sets.h:3824
#define DID_GPS1_SAT
Definition: data_sets.h:49
#define RMC_BITS_INS4
Definition: data_sets.h:1282
#define SYS_GAL
Definition: data_sets.h:3715
float pDop
Definition: data_sets.h:781
float flipFloatCopy(float val)
Definition: data_sets.c:31
#define DID_GPS2_RAW
Definition: data_sets.h:104
double gpsToJulian(int32_t gpsWeek, int32_t gpsMilliseconds, int32_t leapSeconds)
Definition: data_sets.c:708
#define MAXPRNCMP
Definition: data_sets.h:3855
#define RMC_BITS_WHEEL_CONFIG
Definition: data_sets.h:1310
#define GPS_TO_UNIX_OFFSET
Definition: data_sets.h:3690
#define RMC_BITS_RTK_STATE
Definition: data_sets.h:1306
#define DID_GPS2_RTK_CMP_MISC
Definition: data_sets.h:126
#define RMC_BITS_BAROMETER
Definition: data_sets.h:1285
#define DID_GPS1_RAW
Definition: data_sets.h:103
#define DID_GPS2_POS
Definition: data_sets.h:48
#define DID_DIAGNOSTIC_MESSAGE
Definition: data_sets.h:106
#define RMC_BITS_WHEEL_ENCODER
Definition: data_sets.h:1309
#define NSATQZS
Definition: data_sets.h:3845
#define MAXPRNLEO
Definition: data_sets.h:3877
uint32_t flashChecksum32(const void *data, int size)
Definition: data_sets.c:557
double lla[3]
Definition: data_sets.h:511
#define SYS_IRN
Definition: data_sets.h:3718
uint32_t status
Definition: CAN_comm.h:114
#define RMC_BITS_GPS2_SAT
Definition: data_sets.h:1294
void flipStrings(uint8_t *data, int dataLength, int offset, uint16_t *offsets, uint16_t offsetsLength)
Definition: data_sets.c:117
int gpsToNmeaGGA(const gps_pos_t *gps, char *buffer, int bufferLength)
Definition: data_sets.c:745
#define DID_MAGNETOMETER_1
Definition: data_sets.h:86
#define SNPRINTF
Definition: ISConstants.h:146
#define MAXPRNQZS
Definition: data_sets.h:3842
#define DID_RTK_CODE_RESIDUAL
Definition: data_sets.h:112
#define RMC_BITS_INS1
Definition: data_sets.h:1279
#define MAXPRNIRN
Definition: data_sets.h:3866
#define RMC_BITS_GPS1_SAT
Definition: data_sets.h:1293
USBInterfaceDescriptor data
#define SWAP32(v)
Definition: ISConstants.h:282
#define DID_DUAL_IMU_RAW_MAG
Definition: data_sets.h:118
#define RMC_BITS_DUAL_IMU
Definition: data_sets.h:1283
#define RMC_BITS_GPS1_RTK_POS_MISC
Definition: data_sets.h:1304
#define MAXPRNGLO
Definition: data_sets.h:3813
#define RMC_BITS_RTK_PHASE_RESIDUAL
Definition: data_sets.h:1308
double gpsToUnix(uint32_t gpsWeek, uint32_t gpsTimeofWeekMS, uint8_t leapSeconds)
Definition: data_sets.c:699
#define MAX_TASK_NAME_LEN
Definition: data_sets.h:3408
#define SYS_CMP
Definition: data_sets.h:3717
#define DID_GPS1_POS
Definition: data_sets.h:47
#define NSATGAL
Definition: data_sets.h:3825
#define DID_GPS2_SAT
Definition: data_sets.h:50
#define DID_INS_3
Definition: data_sets.h:99
#define DID_DUAL_IMU_RAW
Definition: data_sets.h:91
#define RMC_BITS_DUAL_IMU_MAG
Definition: data_sets.h:1312
#define STATIC_ASSERT(exp)
Definition: ISConstants.h:416
#define SYS_GPS
Definition: data_sets.h:3712
#define DID_WHEEL_ENCODER
Definition: data_sets.h:105
#define RMC_BITS_STROBE_IN_TIME
Definition: data_sets.h:1296
#define DID_GPS1_RTK_POS
Definition: data_sets.h:88
#define NSATGPS
Definition: data_sets.h:3808
#define DID_STROBE_IN_TIME
Definition: data_sets.h:102
#define RMC_BITS_PREINTEGRATED_IMU
Definition: data_sets.h:1284
#define DID_INL2_NED_SIGMA
Definition: data_sets.h:101
uint32_t checksum32(const void *data, int count)
Definition: data_sets.c:531
double flipDoubleCopy(double val)
Definition: data_sets.c:60
#define DID_GPS1_RTK_POS_REL
Definition: data_sets.h:55
#define NSATLEO
Definition: data_sets.h:3878
#define NSATCMP
Definition: data_sets.h:3856
#define _ARRAY_ELEMENT_COUNT(a)
Definition: ISConstants.h:326
#define SYS_QZS
Definition: data_sets.h:3716
int ubxSys(int gnssID)
Definition: data_sets.c:849
is_can_time time
Definition: CAN_comm.h:252
#define RMC_BITS_INS3
Definition: data_sets.h:1281
#define MINPRNIRN
Definition: data_sets.h:3865
#define DID_INS_4
Definition: data_sets.h:100
#define DID_RTK_STATE
Definition: data_sets.h:110
#define DID_BAROMETER
Definition: data_sets.h:87
#define RMC_BITS_RTK_CODE_RESIDUAL
Definition: data_sets.h:1307
void julianToDate(double julian, int32_t *year, int32_t *month, int32_t *day, int32_t *hour, int32_t *minute, int32_t *second, int32_t *millisecond)
Definition: data_sets.c:607
#define RMC_BITS_INS2
Definition: data_sets.h:1280
#define DID_GPS2_VEL
Definition: data_sets.h:65
#define RMC_BITS_DIAGNOSTIC_MESSAGE
Definition: data_sets.h:1297
#define NSATIRN
Definition: data_sets.h:3867
#define DID_RTK_PHASE_RESIDUAL
Definition: data_sets.h:111
#define DID_GPS1_RTK_POS_MISC
Definition: data_sets.h:56
#define NSATGLO
Definition: data_sets.h:3814


inertial_sense_ros
Author(s):
autogenerated on Sun Feb 28 2021 03:17:57