69 #include <boost/spirit/include/qi.hpp>
240 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129,
241 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252,
242 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c,
243 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
244 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672,
245 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738,
246 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861,
247 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
248 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc,
249 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5,
250 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b,
251 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
252 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9,
253 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3,
254 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c,
255 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
256 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3,
257 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
258 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676,
259 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
260 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c,
261 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16,
262 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b,
263 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
264 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36,
265 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
267 namespace qi = boost::spirit::qi;
273 template <
typename T>
276 static_assert(std::is_same<uint16_t, T>::value ||
277 std::is_same<uint32_t, T>::value ||
278 std::is_same<float, T>::value || std::is_same<double, T>::value);
279 if (std::is_same<uint16_t, T>::value)
281 return (
s !=
static_cast<uint16_t
>(65535));
282 }
else if (std::is_same<uint32_t, T>::value)
284 return (
s != 4294967295u);
285 }
else if (std::is_same<float, T>::value)
287 return (
s != -2e10f);
288 }
else if (std::is_same<double, T>::value)
298 template <
typename T>
301 static_assert(std::is_same<float, T>::value || std::is_same<double, T>::value);
302 if (std::is_same<float, T>::value)
305 }
else if (std::is_same<double, T>::value)
315 template <
typename It,
typename Val>
319 std::is_same<int8_t, Val>::value || std::is_same<uint8_t, Val>::value ||
320 std::is_same<int16_t, Val>::value || std::is_same<uint16_t, Val>::value ||
321 std::is_same<int32_t, Val>::value || std::is_same<uint32_t, Val>::value ||
322 std::is_same<int64_t, Val>::value || std::is_same<uint64_t, Val>::value ||
323 std::is_same<float, Val>::value || std::is_same<double, Val>::value);
325 if (std::is_same<int8_t, Val>::value)
327 return qi::parse(it, it + 1, qi::char_, val);
328 }
else if (std::is_same<uint8_t, Val>::value)
330 return qi::parse(it, it + 1, qi::byte_, val);
331 }
else if ((std::is_same<int16_t, Val>::value) ||
332 (std::is_same<uint16_t, Val>::value))
334 return qi::parse(it, it + 2, qi::little_word, val);
335 }
else if ((std::is_same<int32_t, Val>::value) ||
336 (std::is_same<uint32_t, Val>::value))
338 return qi::parse(it, it + 4, qi::little_dword, val);
339 }
else if ((std::is_same<int64_t, Val>::value) ||
340 (std::is_same<uint64_t, Val>::value))
342 return qi::parse(it, it + 8, qi::little_qword, val);
343 }
else if (std::is_same<float, Val>::value)
345 return qi::parse(it, it + 4, qi::little_bin_float, val);
346 }
else if (std::is_same<double, Val>::value)
348 return qi::parse(it, it + 8, qi::little_bin_double, val);
356 template <
typename It>
359 bool success =
false;
361 success = qi::parse(it, it + num, qi::repeat(num)[qi::char_], val);
363 val.erase(std::remove(val.begin(), val.end(),
'\0'), val.end());
371 template <
typename It,
typename Hdr>
389 block_header.id = ID & 8191;
390 block_header.revision = ID >> 13;
401 template <
typename It>
409 std::advance(it, sb2_length - 8);
416 template <
typename It>
418 uint8_t sb1_length, uint8_t sb2_length)
430 std::to_string(msg.
n2));
435 std::advance(it, sb1_length - 12);
448 template <
typename It>
463 "Parse error: Too many ChannelSatInfo " + std::to_string(msg.
n));
470 for (
auto& satInfo : msg.
satInfo)
487 template <
typename It>
503 msg.
pdop = temp / 100.0;
505 msg.
tdop = temp / 100.0;
507 msg.
hdop = temp / 100.0;
509 msg.
vdop = temp / 100.0;
524 template <
typename It>
537 std::advance(it, sb2_length - 12);
544 template <
typename It>
561 std::advance(it, sb1_length - 20);
565 std::to_string(msg.n2));
568 msg.type2.resize(msg.n2);
569 for (
auto& type2 : msg.type2)
580 template <
typename It>
585 if (msg.block_header.id != 4027)
588 std::to_string(msg.block_header.id));
595 std::to_string(msg.n));
601 if (msg.block_header.revision > 0)
604 msg.type1.resize(msg.n);
605 for (
auto& type1 : msg.type1)
623 template <
typename It>
680 template <
typename It>
685 if (msg.block_header.id != 5914)
688 std::to_string(msg.block_header.id));
711 template <
typename It>
716 if (msg.block_header.id != 4006)
719 std::to_string(msg.block_header.id));
742 if (msg.block_header.revision > 0)
747 if (msg.block_header.revision > 1)
766 template <
typename It>
771 if (msg.block_header.id != 4007)
774 std::to_string(msg.block_header.id));
797 if (msg.block_header.revision > 0)
802 if (msg.block_header.revision > 1)
821 template <
typename It>
823 bool use_ros_axis_orientation)
827 if (msg.block_header.id != 5938)
830 std::to_string(msg.block_header.id));
843 if (use_ros_axis_orientation)
846 msg.heading = -msg.heading + 90;
848 msg.pitch = -msg.pitch;
850 msg.pitch_dot = -msg.pitch_dot;
852 msg.heading_dot = -msg.heading_dot;
866 template <
typename It>
868 bool use_ros_axis_orientation)
872 if (msg.block_header.id != 5939)
875 std::to_string(msg.block_header.id));
886 if (use_ros_axis_orientation)
889 msg.cov_headroll = -msg.cov_headroll;
891 msg.cov_pitchroll = -msg.cov_pitchroll;
905 template <
typename It>
923 std::advance(it, sb_length - 52);
930 template <
typename It>
936 if (msg.block_header.id != 4043)
939 std::to_string(msg.block_header.id));
946 "Parse error: Too many VectorInfoCart " + std::to_string(msg.n));
950 msg.vector_info_cart.resize(msg.n);
951 for (
auto& vector_info_cart : msg.vector_info_cart)
967 template <
typename It>
985 std::advance(it, sb_length - 52);
992 template <
typename It>
998 if (msg.block_header.id != 4028)
1001 std::to_string(msg.block_header.id));
1008 "Parse error: Too many VectorInfoGeod " + std::to_string(msg.n));
1012 msg.vector_info_geod.resize(msg.n);
1013 for (
auto& vector_info_geod : msg.vector_info_geod)
1029 template <
typename It>
1031 bool use_ros_axis_orientation)
1035 if ((msg.block_header.id != 4225) && (msg.block_header.id != 4229))
1038 std::to_string(msg.block_header.id));
1053 if ((msg.sb_list & 1) != 0)
1064 if ((msg.sb_list & 2) != 0)
1069 if (use_ros_axis_orientation)
1072 msg.heading = -msg.heading + 90;
1074 msg.pitch = -msg.pitch;
1082 if ((msg.sb_list & 4) != 0)
1093 if ((msg.sb_list & 8) != 0)
1104 if ((msg.sb_list & 16) != 0)
1115 if ((msg.sb_list & 32) != 0)
1126 if ((msg.sb_list & 64) != 0)
1131 if (use_ros_axis_orientation)
1134 msg.heading_roll_cov = -msg.heading_roll_cov;
1136 msg.pitch_roll_cov = -msg.pitch_roll_cov;
1144 if ((msg.sb_list & 128) != 0)
1167 template <
typename It>
1173 if (msg.block_header.id != 5905)
1176 std::to_string(msg.block_header.id));
1203 template <
typename It>
1209 if (msg.block_header.id != 5906)
1212 std::to_string(msg.block_header.id));
1239 template <
typename It>
1245 if (msg.block_header.id != 5907)
1248 std::to_string(msg.block_header.id));
1275 template <
typename It>
1281 if (msg.block_header.id != 5908)
1284 std::to_string(msg.block_header.id));
1311 template <
typename It>
1326 "Parse error: Too many indicators " + std::to_string(msg.
n));
1331 std::vector<uint16_t> indicators;
1348 template <
typename It>
1355 std::advance(it, sb_length - 4);
1362 template <
typename It>
1382 "Parse error: Too many AGCState " + std::to_string(msg.
n));
1405 template <
typename It>
1410 if (msg.block_header.id != 5914)
1413 std::to_string(msg.block_header.id));
1436 template <
typename It>
1438 bool use_ros_axis_orientation)
1442 if ((msg.block_header.id != 4226) && (msg.block_header.id != 4230))
1445 std::to_string(msg.block_header.id));
1461 if ((msg.sb_list & 1) != 0)
1472 if ((msg.sb_list & 2) != 0)
1477 if (use_ros_axis_orientation)
1480 msg.heading = -msg.heading + 90;
1482 msg.pitch = -msg.pitch;
1490 if ((msg.sb_list & 4) != 0)
1501 if ((msg.sb_list & 8) != 0)
1512 if ((msg.sb_list & 16) != 0)
1523 if ((msg.sb_list & 32) != 0)
1534 if ((msg.sb_list & 64) != 0)
1539 if (use_ros_axis_orientation)
1542 msg.heading_roll_cov = -msg.heading_roll_cov;
1544 msg.pitch_roll_cov = -msg.pitch_roll_cov;
1552 if ((msg.sb_list & 128) != 0)
1575 template <
typename It>
1577 bool use_ros_axis_orientation)
1581 if (msg.block_header.id != 4224)
1584 std::to_string(msg.block_header.id));
1595 if (use_ros_axis_orientation)
1597 msg.ant_lever_arm_y = -msg.ant_lever_arm_y;
1598 msg.ant_lever_arm_z = -msg.ant_lever_arm_z;
1613 template <
typename It>
1619 if (msg.block_header.id != 4244)
1622 std::to_string(msg.block_header.id));
1630 if (use_ros_axis_orientation)
1632 msg.lever_arm_y = -msg.lever_arm_y;
1633 msg.lever_arm_z = -msg.lever_arm_z;
1647 template <
typename It>
1654 if (msg.block_header.id != 4050)
1657 std::to_string(msg.block_header.id));
1662 if (msg.sb_length != 28)
1665 "Parse error: Wrong sb_length " + std::to_string(msg.sb_length));
1669 msg.acceleration_x = std::numeric_limits<double>::quiet_NaN();
1670 msg.acceleration_y = std::numeric_limits<double>::quiet_NaN();
1671 msg.acceleration_z = std::numeric_limits<double>::quiet_NaN();
1673 msg.angular_rate_x = std::numeric_limits<double>::quiet_NaN();
1674 msg.angular_rate_y = std::numeric_limits<double>::quiet_NaN();
1675 msg.angular_rate_z = std::numeric_limits<double>::quiet_NaN();
1677 msg.velocity_x = std::numeric_limits<double>::quiet_NaN();
1678 msg.velocity_y = std::numeric_limits<double>::quiet_NaN();
1679 msg.velocity_z = std::numeric_limits<double>::quiet_NaN();
1681 msg.std_dev_x = std::numeric_limits<double>::quiet_NaN();
1682 msg.std_dev_y = std::numeric_limits<double>::quiet_NaN();
1683 msg.std_dev_z = std::numeric_limits<double>::quiet_NaN();
1685 msg.sensor_temperature = -32768.0f;
1686 msg.zero_velocity_flag = std::numeric_limits<double>::quiet_NaN();
1688 msg.source.resize(msg.n);
1689 msg.sensor_model.resize(msg.n);
1690 msg.type.resize(msg.n);
1691 msg.obs_info.resize(msg.n);
1692 bool hasAcc =
false;
1693 bool hasOmega =
false;
1695 for (
size_t i = 0; i < msg.n; i++)
1702 switch (msg.type[i])
1709 if (!use_ros_axis_orientation)
1712 msg.acceleration_y = -msg.acceleration_y;
1714 msg.acceleration_z = -msg.acceleration_z;
1724 if (!use_ros_axis_orientation)
1727 msg.angular_rate_y = -msg.angular_rate_y;
1729 msg.angular_rate_z = -msg.angular_rate_z;
1736 qi::parse(it, it + 2, qi::little_word, msg.sensor_temperature);
1737 msg.sensor_temperature /= 100.0f;
1738 std::advance(it, 22);
1749 if (use_ros_axis_orientation)
1752 msg.velocity_y = -msg.velocity_y;
1754 msg.velocity_z = -msg.velocity_z;
1761 std::advance(it, 16);
1768 "Unknown external sensor measurement type in SBF ExtSensorMeas.");
1769 std::advance(it, 24);
1779 hasImuMeas = hasAcc && hasOmega;