LivoxLaser.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. #include "LivoxLaser.h"
  2. #include "../common.h"
  3. RegisterLaser(Livox)
  4. CLivoxLaser::DeviceItem CLivoxLaser::g_devices[kMaxLidarCount] = { 0 };
  5. std::map<uint8_t, std::string> CLivoxLaser::g_handle_sn= std::map<uint8_t, std::string>();
  6. std::map<std::string, uint8_t> CLivoxLaser::g_sn_handle = std::map<std::string, uint8_t>();
  7. std::map<std::string, CLivoxLaser*> CLivoxLaser::g_sn_laser= std::map<std::string, CLivoxLaser*>();
  8. CLivoxLaser* CLivoxLaser::g_all_laser[kMaxLidarCount] = { 0 };
  9. unsigned int CLivoxLaser::g_count[kMaxLidarCount] = { 0 };
  10. void CLivoxLaser::UpdataHandle()
  11. {
  12. std::string sn = m_laser_param.sn();
  13. if (g_sn_handle.find(sn) != g_sn_handle.end())
  14. {
  15. m_handle = g_sn_handle[sn];
  16. }
  17. }
  18. bool CLivoxLaser::IsScanComplete()
  19. {
  20. return g_count[m_handle] >= m_frame_maxnum;
  21. }
  22. void CLivoxLaser::InitLivox()
  23. {
  24. static bool g_init = false;
  25. if (g_init == false)
  26. {
  27. if (!Init()) {
  28. LOG(INFO) << "livox sdk init failed...";
  29. }
  30. else
  31. {
  32. LivoxSdkVersion _sdkversion;
  33. GetLivoxSdkVersion(&_sdkversion);
  34. char buf[255] = { 0 };
  35. sprintf(buf, "Livox SDK version %d.%d.%d .\n", _sdkversion.major, _sdkversion.minor, _sdkversion.patch);
  36. LOG(INFO) << buf;
  37. SetBroadcastCallback(OnDeviceBroadcast);
  38. SetDeviceStateUpdateCallback(OnDeviceChange);
  39. g_init = true;
  40. }
  41. }
  42. }
  43. CLivoxLaser::CLivoxLaser(int id, Automatic::stLaserCalibParam laser_param)
  44. :CLaser(id, laser_param)
  45. {
  46. m_frame_maxnum = laser_param.frame_num();
  47. if(laser_param.type()=="Livox")
  48. g_sn_laser.insert(std::make_pair(laser_param.sn(), this));
  49. InitLivox();
  50. }
  51. CLivoxLaser::~CLivoxLaser()
  52. {
  53. }
  54. void CLivoxLaser::OnSampleCallback(uint8_t status, uint8_t handle, uint8_t response, void *data) {
  55. CLivoxLaser* laser = (CLivoxLaser*)data;
  56. if (status == kStatusSuccess) {
  57. if (response != 0) {
  58. g_devices[handle].device_state = kDeviceStateConnect;
  59. }
  60. }
  61. else if (status == kStatusTimeout) {
  62. g_devices[handle].device_state = kDeviceStateConnect;
  63. }
  64. }
  65. void CLivoxLaser::OnDeviceChange(const DeviceInfo *info, DeviceEvent type)
  66. {
  67. if (info == NULL) {
  68. return;
  69. }
  70. uint8_t handle = info->handle;
  71. if (handle >= kMaxLidarCount) {
  72. return;
  73. }
  74. /*std::cout<<"-----------------------------------------------------------------"<<std::endl;
  75. std::cout<<" OnDeviceChange handle : "<<info->broadcast_code<<" type : "<<type <<" device_state : "
  76. <<g_devices[handle].device_state<<std::endl;*/
  77. if (type == kEventConnect) {
  78. //QueryDeviceInformation(handle, OnDeviceInformation, NULL);
  79. if (g_devices[handle].device_state == kDeviceStateDisconnect)
  80. {
  81. g_devices[handle].device_state = kDeviceStateConnect;
  82. g_devices[handle].info = *info;
  83. }
  84. }
  85. else if (type == kEventDisconnect) {
  86. g_devices[handle].device_state = kDeviceStateDisconnect;
  87. }
  88. else if (type == kEventStateChange) {
  89. g_devices[handle].info = *info;
  90. }
  91. if (g_devices[handle].device_state == kDeviceStateConnect)
  92. {
  93. if (g_devices[handle].info.state == kLidarStateNormal) {
  94. if (g_devices[handle].info.type == kDeviceTypeHub) {
  95. HubStartSampling(OnSampleCallback, NULL);
  96. }
  97. else {
  98. LidarStartSampling(handle, OnSampleCallback, NULL);
  99. }
  100. g_devices[handle].device_state = kDeviceStateSampling;
  101. }
  102. }
  103. }
  104. void CLivoxLaser::OnDeviceBroadcast(const BroadcastDeviceInfo *info)
  105. {
  106. if (info == NULL) {
  107. return;
  108. }
  109. //printf("Receive Broadcast Code %s\n", info->broadcast_code);
  110. LOG(INFO) << " broadcast sn : " << info->broadcast_code;
  111. bool result = false;
  112. uint8_t handle = 0;
  113. result = AddLidarToConnect(info->broadcast_code, &handle);
  114. if (result == kStatusSuccess) {
  115. /** Set the point cloud data for a specific Livox LiDAR. */
  116. SetDataCallback(handle, LidarDataCallback, NULL);
  117. g_devices[handle].handle = handle;
  118. g_devices[handle].device_state = kDeviceStateDisconnect;
  119. std::string sn = info->broadcast_code;
  120. if (g_handle_sn.find(handle) != g_handle_sn.end())
  121. g_handle_sn[handle] = sn;
  122. else
  123. g_handle_sn.insert(std::make_pair(handle,sn));
  124. if (g_sn_handle.find(sn) != g_sn_handle.end())
  125. g_sn_handle[sn] = handle;
  126. else
  127. g_sn_handle.insert(std::make_pair(sn,handle));
  128. }
  129. }
  130. void CLivoxLaser::LidarDataCallback(uint8_t handle, LivoxEthPacket *data, uint32_t data_num, void *client_data)
  131. {
  132. ///?????????????? ?????????handle
  133. CLivoxLaser* livox = g_all_laser[handle];
  134. if (livox == 0)
  135. {
  136. if (g_handle_sn.find(handle) != g_handle_sn.end())
  137. {
  138. std::string sn = g_handle_sn[handle];
  139. if (g_sn_laser.find(sn) != g_sn_laser.end())
  140. {
  141. livox = g_sn_laser[sn];
  142. g_all_laser[handle] = livox;
  143. if (livox)
  144. livox->UpdataHandle();
  145. }
  146. }
  147. }
  148. if (data && livox)
  149. {
  150. if (livox->m_bStart_capture.WaitFor(1))
  151. {
  152. if (livox->IsScanComplete())
  153. {
  154. livox->Stop();
  155. return;
  156. }
  157. if (g_count[handle] >= livox->m_frame_maxnum)
  158. return;
  159. uint64_t cur_timestamp = *((uint64_t *)(data->timestamp));
  160. LivoxRawPoint *p_point_data = (LivoxRawPoint *)data->data;
  161. CBinaryData* data_bin = new CBinaryData((char*)p_point_data, data_num * sizeof(LivoxRawPoint));
  162. livox->m_queue_livox_data.push(data_bin);
  163. g_count[handle]++;
  164. }
  165. else if(livox->m_statu!=eLaser_ready)
  166. {
  167. //?????????????????
  168. livox->m_statu = eLaser_ready;
  169. usleep(10*1000);
  170. }
  171. }
  172. }
  173. eLaserStatu CLivoxLaser::GetStatu()
  174. {
  175. if(g_devices[m_handle].device_state == kDeviceStateConnect||
  176. g_devices[m_handle].device_state == kDeviceStateSampling)
  177. {
  178. m_statu=eLaser_ready;
  179. }
  180. if(g_devices[m_handle].device_state == kDeviceStateDisconnect)
  181. {
  182. m_statu=eLaser_disconnect;
  183. }
  184. return m_statu;
  185. }
  186. bool CLivoxLaser::Connect()
  187. {
  188. return CLaser::Connect();
  189. }
  190. void CLivoxLaser::Disconnect()
  191. {
  192. CLaser::Disconnect();
  193. }
  194. bool CLivoxLaser::Start()
  195. {
  196. LOG(INFO) << " livox start :"<<this;
  197. //???????????
  198. m_queue_livox_data.clear();
  199. g_count[m_handle] = 0;
  200. return CLaser::Start();
  201. }
  202. bool CLivoxLaser::Stop()
  203. {
  204. return CLaser::Stop();
  205. }
  206. bool CLivoxLaser::RecvData(CBinaryData& data)
  207. {
  208. CBinaryData* livox_data;
  209. if (m_queue_livox_data.try_pop(livox_data))
  210. {
  211. data = *livox_data;
  212. delete livox_data;
  213. return true;
  214. }
  215. return false;
  216. }
  217. DATA_type CLivoxLaser::Data2PointXYZ(CBinaryData* pData, std::vector<CPoint3D>& points)
  218. {
  219. LivoxRawPoint *p_point_data = (LivoxRawPoint *)pData->Data();
  220. int count = pData->Length() / (sizeof(LivoxRawPoint));
  221. if (count <= 0)
  222. return eUnknow;
  223. for (int i = 0; i < count; ++i)
  224. {
  225. LivoxRawPoint point = p_point_data[i];
  226. CPoint3D pt;
  227. pt.x = point.x;
  228. pt.y = point.y;
  229. pt.z = point.z;
  230. points.push_back(pt);
  231. }
  232. return eData;
  233. }