unpacket.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #pragma once
  2. #include <cmath>
  3. #include <map>
  4. #include "defines.hpp"
  5. class CloudPointUnpacket {
  6. public:
  7. template<typename T>
  8. bool unpacket(unsigned char *data, size_t size, T &cloud) {
  9. pcl::PointCloud<pcl::PointALL>::Ptr all(new pcl::PointCloud<pcl::PointALL>);
  10. return unpacketFactory(data, size, all) && transformed(all, cloud);
  11. }
  12. private:
  13. static bool unpacketFactory(unsigned char *data, size_t size, pcl::PointCloud<pcl::PointALL>::Ptr &cloud) {
  14. if (!checkPacket(data, size)) {
  15. return false;
  16. }
  17. switch (data[2] << 8 | data[3]) {
  18. case ZX::PointXYZ_TYPE:
  19. DLOG(INFO) << "Unpack PointXYZ_TYPE";
  20. return unpacketXYZ(data, size, cloud);
  21. case ZX::PointXYZI_TYPE:
  22. DLOG(INFO) << "Unpack PointXYZ_TYPE";
  23. return unpacketXYZI(data, size, cloud);
  24. case ZX::PointXYZPYR_TYPE:
  25. DLOG(INFO) << "Unpack PointXYZPYR_TYPE";
  26. return unpacketXYZPYR(data, size, cloud);
  27. case ZX::PointRYR_TYPE:
  28. DLOG(INFO) << "Unpack PointRYR_TYPE";
  29. return unpacketRYR(data, size, cloud);
  30. case ZX::LIDAR_RS_HELIOS_16P:
  31. // DLOG(INFO) << "Unpack LIDAR_RS_HELIOS_16P";
  32. return unpacketRYR(data, size, cloud, 0.25);
  33. default:
  34. LOG(WARNING) << "Data types are not compatible.";
  35. return false;
  36. }
  37. }
  38. static bool unpacketXYZ(unsigned char *data, size_t size, pcl::PointCloud<pcl::PointALL>::Ptr &cloud) {
  39. return false;
  40. }
  41. static bool unpacketXYZI(unsigned char *data, size_t size, pcl::PointCloud<pcl::PointALL>::Ptr &cloud) {
  42. return false;
  43. }
  44. static bool unpacketXYZPYR(unsigned char *data, size_t size, pcl::PointCloud<pcl::PointALL>::Ptr &cloud) {
  45. return false;
  46. }
  47. static bool unpacketRYR(const unsigned char *data, size_t size, pcl::PointCloud<pcl::PointALL>::Ptr &cloud, double acc = 1) {
  48. pcl::PointALL point{};
  49. double distance, roll_radian, yaw_radian;
  50. for (int i = ZX::PACKET_HEAD_SIZE; i < size - ZX::PACKET_END_SIZE; i += 7) {
  51. distance = (float) ((data[i + 0] << 8 | data[i + 1]) * acc) * 0.01; // 当前距离精度为m,去掉0.01为cm
  52. point.roll = (double) ((data[i + 2] << 8 | data[i + 3]) * 0.01);
  53. point.yaw = (double) ((data[i + 4] << 8 | data[i + 5]) * 0.01);
  54. point.pitch = 0;
  55. roll_radian = point.roll * M_PI / 180.0;
  56. yaw_radian = point.yaw * M_PI / 180.0;
  57. point.x = distance * cos(roll_radian) * sin(yaw_radian);
  58. point.y = distance * cos(roll_radian) * cos(yaw_radian);
  59. point.z = distance * sin(roll_radian);
  60. point.r = distance;
  61. point.intensity = data[i + 6];
  62. cloud->push_back(point);
  63. }
  64. return true;
  65. }
  66. static bool transformed(pcl::PointCloud<pcl::PointALL>::Ptr &cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr &result) {
  67. pcl::PointXYZ ret;
  68. for (const auto point: *cloud) {
  69. ret.x = point.x;
  70. ret.y = point.y;
  71. ret.z = point.z;
  72. result->push_back(ret);
  73. }
  74. return true;
  75. }
  76. static bool transformed(pcl::PointCloud<pcl::PointALL>::Ptr &cloud, pcl::PointCloud<pcl::PointXYZI>::Ptr &result) {
  77. pcl::PointXYZI ret;
  78. for (const auto point: *cloud) {
  79. ret.x = point.x;
  80. ret.y = point.y;
  81. ret.z = point.z;
  82. ret.intensity = point.intensity;
  83. result->push_back(ret);
  84. }
  85. return true;
  86. }
  87. static bool transformed(pcl::PointCloud<pcl::PointALL>::Ptr &cloud, pcl::PointCloud<pcl::PointRPRY>::Ptr &result) {
  88. pcl::PointRPRY ret{};
  89. for (const auto point: *cloud) {
  90. ret.r = point.r;
  91. ret.pitch = point.pitch;
  92. ret.roll = point.roll;
  93. ret.yaw = point.yaw;
  94. result->push_back(ret);
  95. }
  96. return true;
  97. }
  98. static bool transformed(pcl::PointCloud<pcl::PointALL>::Ptr &cloud, pcl::PointCloud<pcl::PointRYR>::Ptr &result) {
  99. pcl::PointRYR ret{};
  100. for (const auto point: *cloud) {
  101. ret.roll = point.roll;
  102. ret.yaw = point.yaw;
  103. ret.r = point.r;
  104. result->push_back(ret);
  105. }
  106. return true;
  107. }
  108. static bool transformed(pcl::PointCloud<pcl::PointALL>::Ptr &cloud, pcl::PointCloud<pcl::PointALL>::Ptr &result) {
  109. result = cloud;
  110. return true;
  111. }
  112. static bool checkPacket(const unsigned char *data, size_t size) {
  113. if (size < ZX::PACKET_HEAD_SIZE + ZX::PACKET_END_SIZE) {
  114. LOG(WARNING) << "Data size too small.";
  115. return false;
  116. }
  117. if (!(data[0] == '$' && data[1] == '&' && data[size - 2] == '&' && data[size - 1] == '$')) {
  118. LOG(WARNING) << "Data head or end error.";
  119. return false;
  120. }
  121. if ((data[2] << 8 | data[3]) < ZX::UNKNOW_TYPE || (data[2] << 8 | data[3]) > ZX::PointTYPE_MAX) {
  122. LOG(WARNING) << "Data type error.";
  123. return false;
  124. }
  125. return true;
  126. }
  127. };