Laser.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. #include "Laser.h"
  2. CBinaryData::CBinaryData()
  3. :m_buf(0)
  4. ,m_length(0)
  5. {
  6. }
  7. CBinaryData::CBinaryData(const char* buf, int len, DATA_type type)
  8. :m_buf(0),m_length(0)
  9. {
  10. if (len > 0)
  11. {
  12. m_buf = (char*)malloc(len);
  13. memcpy(m_buf, buf, len);
  14. m_length = len;
  15. }
  16. }
  17. CBinaryData::CBinaryData(const CBinaryData& data)
  18. :m_buf(0),m_length(0)
  19. {
  20. if (m_buf)
  21. {
  22. free(m_buf);
  23. m_buf = 0;
  24. m_length = 0;
  25. }
  26. if (data.Length() > 0)
  27. {
  28. m_buf = (char*)malloc(data.Length());
  29. memcpy(m_buf, data.Data(), data.Length());
  30. m_length = data.Length();
  31. }
  32. }
  33. CBinaryData::~CBinaryData()
  34. {
  35. if (m_buf && m_length)
  36. {
  37. free(m_buf);
  38. m_length = 0;
  39. }
  40. }
  41. char* CBinaryData::Data()const {
  42. return m_buf;
  43. }
  44. int CBinaryData::Length()const {
  45. return m_length;
  46. }
  47. CBinaryData& CBinaryData::operator=(const CBinaryData& data)
  48. {
  49. if (m_buf)
  50. {
  51. free(m_buf);
  52. m_buf = 0;
  53. m_length = 0;
  54. }
  55. if (data.Length() > 0)
  56. {
  57. m_buf = (char*)malloc(data.Length());
  58. memcpy(m_buf, data.Data(), data.Length());
  59. m_length = data.Length();
  60. }
  61. return *this;
  62. }
  63. bool CBinaryData::operator==(const char* str)
  64. {
  65. int length = strlen(str);
  66. return (strncmp((const char*)m_buf, str, length) == 0);
  67. }
  68. const char* CBinaryData::operator+(int n)
  69. {
  70. if (n < m_length)
  71. return m_buf + n;
  72. else
  73. return NULL;
  74. }
  75. CBinaryData& CBinaryData::operator+(CBinaryData& data)
  76. {
  77. if (data.Length() > 0)
  78. {
  79. int length = m_length + data.Length();
  80. char* buf = (char*)malloc(length);
  81. memcpy(buf, m_buf, m_length);
  82. memcpy(buf + m_length, data.Data(), data.Length());
  83. free(m_buf);
  84. m_buf = buf;
  85. m_length = length;
  86. }
  87. return *this;
  88. }
  89. char& CBinaryData::operator[](int n)
  90. {
  91. if (n >= 0 && n < m_length)
  92. return m_buf[n];
  93. }
  94. //////////////
  95. CLaser::CLaser(int id, Automatic::stLaserCalibParam laser_param)
  96. :m_ThreadRcv(0)
  97. ,m_ThreadPro(0)
  98. ,m_ThreadPub(0)
  99. ,m_id(id)
  100. ,m_points_count(0)
  101. ,m_statu(eLaser_disconnect)
  102. ,m_dMatrix(0)
  103. , m_point_callback_fnc(0)
  104. , m_point_callback_pointer(0)
  105. ,m_laser_param(laser_param)
  106. ,m_bSave_file(false)
  107. ,m_bscan_start(false)
  108. {
  109. mp_laser_task = NULL;
  110. }
  111. CLaser::~CLaser()
  112. {
  113. if (m_dMatrix)
  114. {
  115. free(m_dMatrix);
  116. m_dMatrix = 0;
  117. }
  118. }
  119. bool CLaser::Start()
  120. {
  121. m_bscan_start=true;
  122. m_statu = eLaser_busy;
  123. m_bStart_capture.Notify(true);
  124. m_points_count=0;
  125. return true;
  126. }
  127. bool CLaser::Stop()
  128. {
  129. m_bscan_start=false;
  130. m_bStart_capture.Notify(false);
  131. m_binary_log_tool.close();
  132. m_pts_log_tool.close();
  133. m_statu=eLaser_ready;
  134. //在停止雷达时,将雷达任务状态改为 TASK_OVER 已结束
  135. if(mp_laser_task !=NULL)
  136. {
  137. if(mp_laser_task->get_statu() == TASK_WORKING)
  138. {
  139. mp_laser_task->set_task_statu(TASK_OVER);
  140. }
  141. }
  142. return true;
  143. }
  144. void CLaser::SetMetrix(double* data)
  145. {
  146. if (m_dMatrix == 0)
  147. {
  148. m_dMatrix = (double*)malloc(12 * sizeof(double));
  149. }
  150. memcpy(m_dMatrix, data, 12 * sizeof(double));
  151. }
  152. void CLaser::SetPointCallBack(PointCallBack fnc, void* pointer)
  153. {
  154. m_point_callback_fnc = fnc;
  155. m_point_callback_pointer = pointer;
  156. }
  157. bool CLaser::Connect()
  158. {
  159. m_bThreadRcvRun.Notify(true);
  160. if(m_ThreadRcv==0)
  161. m_ThreadRcv = new std::thread(&CLaser::thread_recv, this);
  162. m_ThreadRcv->detach();
  163. m_bThreadProRun.Notify(true);
  164. if(m_ThreadPro==0)
  165. m_ThreadPro = new std::thread(&CLaser::thread_toXYZ, this);
  166. m_ThreadPro->detach();
  167. if(m_ThreadPub==0)
  168. m_ThreadPub = new std::thread(threadPublish, this);
  169. m_ThreadPub->detach();
  170. return true;
  171. }
  172. void CLaser::Disconnect()
  173. {
  174. if (m_ThreadRcv)
  175. {
  176. delete m_ThreadRcv;
  177. m_ThreadRcv = 0;
  178. }
  179. if (m_ThreadPub)
  180. {
  181. delete m_ThreadPub;
  182. m_ThreadPub = 0;
  183. }
  184. if (m_ThreadPro)
  185. {
  186. delete m_ThreadPro;
  187. m_ThreadPro = NULL;
  188. }
  189. m_statu = eLaser_disconnect;
  190. }
  191. //对外的接口函数,负责接受并处理任务单,
  192. //input:laser_task 雷达任务单,必须是子类,并且任务正确。(传引用)
  193. Error_manager CLaser::porform_task(Laser_task* p_laser_task)
  194. {
  195. Error_manager t_error_manager;
  196. //检查指针
  197. if(p_laser_task == NULL)
  198. {
  199. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  200. "CLaser::porform_task failed, POINTER_IS_NULL");
  201. }
  202. else
  203. {
  204. //接受任务,并将任务的状态改为TASK_SIGNED已签收
  205. mp_laser_task = p_laser_task;
  206. mp_laser_task->set_task_statu(TASK_SIGNED);
  207. }
  208. //检查消息内容是否正确,
  209. //检查点云指针
  210. if(p_laser_task->get_task_point3d_cloud_vector() == NULL)
  211. {
  212. t_error_manager.error_manager_reset(Error_code::POINTER_IS_NULL,
  213. Error_level::MINOR_ERROR,
  214. "CLaser::porform_task failed, POINTER_IS_NULL");
  215. }
  216. //检查任务类型
  217. else if(p_laser_task->get_task_type() != LASER_TASK)
  218. {
  219. t_error_manager.error_manager_reset(Error_code::LASER_TASK_PARAMETER_ERROR,
  220. Error_level::MINOR_ERROR,
  221. "CLaser::porform_task failed, task_type is error");
  222. }
  223. else
  224. {
  225. //将任务的状态改为 TASK_WORKING 处理中
  226. mp_laser_task->set_task_statu(TASK_WORKING);
  227. //启动雷达扫描
  228. Start();
  229. }
  230. //返回错误码
  231. if(t_error_manager != Error_code::SUCCESS)
  232. {
  233. mp_laser_task->set_task_error_manager(t_error_manager);
  234. }
  235. return t_error_manager;
  236. }
  237. void CLaser::SetSaveDir(std::string strDir,bool bSaveFile)
  238. {
  239. m_bSave_file = bSaveFile;
  240. m_pts_log_tool.close();
  241. m_binary_log_tool.close();
  242. if (bSaveFile == false)
  243. return;
  244. m_pts_save_path = strDir;
  245. char pts_file[255] = { 0 };
  246. sprintf(pts_file, "%s/pts%d.txt", strDir.c_str(), m_id+1);
  247. m_pts_log_tool.open(pts_file);
  248. char bin_file[255] = { 0 };
  249. sprintf(bin_file, "%s/laser%d.data", strDir.c_str(), m_id+1);
  250. m_binary_log_tool.open(bin_file,true);
  251. }
  252. void CLaser::thread_recv()
  253. {
  254. while (m_bThreadRcvRun.WaitFor(1))
  255. {
  256. if (m_bStart_capture.WaitFor(1) == false)
  257. continue;
  258. CBinaryData* data=new CBinaryData();
  259. if (this->RecvData(*data))
  260. {
  261. m_queue_laser_data.push(data);
  262. }
  263. else
  264. {
  265. delete data;
  266. data=0;
  267. }
  268. }
  269. }
  270. CPoint3D CLaser::transfor(CPoint3D point)
  271. {
  272. if (m_dMatrix)
  273. {
  274. CPoint3D result;
  275. double x = point.x;
  276. double y = point.y;
  277. double z = point.z;
  278. result.x = x * m_dMatrix[0] + y*m_dMatrix[1] + z*m_dMatrix[2] + m_dMatrix[3];
  279. result.y = x * m_dMatrix[4] + y*m_dMatrix[5] + z*m_dMatrix[6] + m_dMatrix[7];
  280. result.z = x * m_dMatrix[8] + y*m_dMatrix[9] + z*m_dMatrix[10] + m_dMatrix[11];
  281. return result;
  282. }
  283. else
  284. {
  285. return point;
  286. }
  287. }
  288. void CLaser::thread_toXYZ()
  289. {
  290. while (m_bThreadProRun.WaitFor(1))
  291. {
  292. if (m_bStart_capture.WaitFor(1) == false)
  293. {
  294. m_queue_laser_data.clear();
  295. continue;
  296. }
  297. CBinaryData* pData=NULL;
  298. bool bPop = m_queue_laser_data.try_pop(pData);
  299. DATA_type type = eUnknow;
  300. if (bPop || m_last_data.Length() != 0)
  301. {
  302. std::vector<CPoint3D> cloud;
  303. if (bPop)
  304. {
  305. if (pData == NULL)
  306. continue;
  307. m_binary_log_tool.write(pData->Data(), pData->Length());
  308. type= this->Data2PointXYZ(pData, cloud);
  309. }
  310. else
  311. {
  312. type = this->Data2PointXYZ(NULL, cloud);
  313. }
  314. if (type == eUnknow)
  315. {
  316. delete pData;
  317. continue;
  318. }
  319. if (type == eData || type == eStart || type == eStop)
  320. {
  321. for (int i = 0; i < cloud.size(); ++i)
  322. {
  323. CPoint3D point = transfor(cloud[i]);
  324. if (m_point_callback_fnc)
  325. m_point_callback_fnc(point, m_point_callback_pointer);
  326. if(m_bSave_file) {
  327. char buf[64] = {0};
  328. sprintf(buf, "%f %f %f\n", point.x, point.y, point.z);
  329. m_pts_log_tool.write(buf, strlen(buf));
  330. }
  331. //此时cloud为雷达采集数据的结果,转换后的三维点云。
  332. //将每个点存入任务单里面的点云容器。
  333. mp_laser_task->get_task_point3d_cloud_vector()->push_back(point);
  334. }
  335. m_points_count+=cloud.size();
  336. if (type == eStop)
  337. {
  338. if(m_bSave_file) {
  339. m_pts_log_tool.close();
  340. m_binary_log_tool.close();
  341. }
  342. m_statu = eLaser_ready;
  343. //在停止雷达时,将雷达任务状态改为 TASK_OVER 已结束
  344. if(mp_laser_task !=NULL)
  345. {
  346. if(mp_laser_task->get_statu() == TASK_WORKING)
  347. {
  348. mp_laser_task->set_task_statu(TASK_OVER);
  349. }
  350. }
  351. }
  352. }
  353. else if (type == eReady)
  354. {
  355. if(m_bSave_file) {
  356. m_pts_log_tool.close();
  357. m_binary_log_tool.close();
  358. }
  359. m_statu = eLaser_ready;
  360. }
  361. delete pData;
  362. }
  363. }
  364. }
  365. #include "unistd.h"
  366. void CLaser::threadPublish(CLaser *laser)
  367. {
  368. if(laser==0) return ;
  369. while(laser->m_bThreadRcvRun.WaitFor(1))
  370. {
  371. laser->PublishMsg();
  372. usleep(1000*300);
  373. }
  374. }
  375. #include "../common.h"
  376. void CLaser::PublishMsg()
  377. {
  378. globalmsg::msg msg;
  379. msg.set_msg_type(globalmsg::eLaser);
  380. globalmsg::laserStatus status;
  381. if(GetStatu()==eLaser_ready) status=globalmsg::eLaserConnected;
  382. else if(GetStatu()==eLaser_disconnect) status=globalmsg::eLaserDisconnected;
  383. else if(GetStatu()==eLaser_busy) status=globalmsg::eLaserBusy;
  384. else status=globalmsg::eLaserUnknown;
  385. msg.mutable_laser_msg()->set_id(m_id);
  386. msg.mutable_laser_msg()->set_laser_status(status);
  387. msg.mutable_laser_msg()->set_queue_data_count(m_queue_laser_data.size());
  388. msg.mutable_laser_msg()->set_cloud_count(m_points_count);
  389. MeasureTopicPublisher::GetInstance()->Publish(msg.SerializeAsString());
  390. }