locate_manager.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. //
  2. // Created by zx on 2019/12/30.
  3. //
  4. #include "locate_manager.h"
  5. #include "../tool/proto_tool.h"
  6. #include "locate_parameter.pb.h"
  7. #include <pcl/filters//voxel_grid.h>
  8. #include <pcl/filters/passthrough.h>
  9. #include <glog/logging.h>
  10. #include <string.h>
  11. Locate_manager::Locate_manager()
  12. {
  13. mp_point_sift = NULL;
  14. mp_cnn3d = NULL;
  15. m_locate_manager_status = LOCATE_MANAGER_UNKNOW;
  16. m_locate_manager_working_flag = false;
  17. mp_locate_manager_thread = NULL;
  18. mp_locate_manager_task = NULL;
  19. mp_locate_information = NULL;
  20. m_save_flag = false;
  21. // m_save_path = "";
  22. }
  23. Locate_manager::~Locate_manager()
  24. {
  25. Locate_manager_uninit();
  26. }
  27. //初始化 定位 管理模块。如下三选一LOCATE_PARAMETER_PATH
  28. Error_manager Locate_manager::Locate_manager_init()
  29. {
  30. return Locate_manager_init_from_protobuf(LOCATE_PARAMETER_PATH);
  31. }
  32. //初始化 定位 管理模块。从文件读取
  33. Error_manager Locate_manager::Locate_manager_init_from_protobuf(std::string prototxt_path)
  34. {
  35. Measure::LocateParameter t_locate_parameters;
  36. if(! proto_tool::read_proto_param(prototxt_path,t_locate_parameters) )
  37. {
  38. return Error_manager(LOCATER_MANAGER_READ_PROTOBUF_ERROR,MINOR_ERROR,"Locate_manager read_proto_param failed");
  39. }
  40. return Locate_manager_init_from_protobuf(t_locate_parameters);
  41. }
  42. //初始化 定位 管理模块。从protobuf读取
  43. Error_manager Locate_manager::Locate_manager_init_from_protobuf(Measure::LocateParameter& locate_parameters)
  44. {
  45. //huli huli huli test test test
  46. /*
  47. m_locate_manager_working_flag = false;
  48. m_locate_manager_status = LOCATE_MANAGER_READY;
  49. // 启动雷达管理模块的内部线程。默认wait。
  50. m_locate_manager_condition.reset(false, false, false);
  51. mp_locate_manager_thread = new std::thread(&Locate_manager::thread_work, this);
  52. return Error_code::SUCCESS;
  53. */
  54. LOG(INFO) << " ---Locate_manager_init_from_protobuf run--- "<< this;
  55. Error_manager t_error;
  56. m_locate_manager_working_flag = false;
  57. int point_size = locate_parameters.seg_parameter().point_size();
  58. int cls_num = locate_parameters.seg_parameter().cls_num();
  59. double freq = locate_parameters.seg_parameter().freq();
  60. std::string graph = locate_parameters.seg_parameter().graph();
  61. std::string cpkt = locate_parameters.seg_parameter().cpkt();
  62. Measure::Area3d area = locate_parameters.seg_parameter().area();
  63. Cloud_box t_cloud_box;
  64. t_cloud_box.x_min = area.x_min();
  65. t_cloud_box.x_max = area.x_max();
  66. t_cloud_box.y_min = area.y_min();
  67. t_cloud_box.y_max = area.y_max();
  68. t_cloud_box.z_min = area.z_min();
  69. t_cloud_box.z_max = area.z_max();
  70. mp_point_sift = new Point_sift_segmentation(point_size,cls_num,freq,t_cloud_box);
  71. std::string graph_file = graph;
  72. std::string cpkt_file = cpkt;
  73. std::cout << "graph_file" << graph_file << std::endl;
  74. std::cout << "cpkt_file" << cpkt_file << std::endl;
  75. t_error=mp_point_sift->init(graph_file,cpkt_file);
  76. if(t_error!=SUCCESS)
  77. {
  78. LOG(ERROR)<<t_error.to_string();
  79. return t_error;
  80. }
  81. LOG(INFO)<<" pointSift init SUCCESS, graph = "<< graph;
  82. int t_cnn3d_length = locate_parameters.net_3dcnn_parameter().length();
  83. int t_cnn3d_width = locate_parameters.net_3dcnn_parameter().width();
  84. int t_cnn3d_height = locate_parameters.net_3dcnn_parameter().height();
  85. int t_cnn3d_nclass = locate_parameters.net_3dcnn_parameter().nclass();
  86. int t_cnn3d_freq = locate_parameters.net_3dcnn_parameter().freq();
  87. mp_cnn3d = new Cnn3d_segmentation(t_cnn3d_length, t_cnn3d_width, t_cnn3d_height, t_cnn3d_freq, t_cnn3d_nclass);
  88. std::string weights = locate_parameters.net_3dcnn_parameter().weights_file();
  89. t_error=mp_cnn3d->init(weights);
  90. if(t_error!=SUCCESS)
  91. {
  92. LOG(ERROR)<<t_error.to_string();
  93. return t_error;
  94. }
  95. LOG(INFO)<<" 3dcnn Init SUCCESS ";
  96. m_locate_manager_status = LOCATE_MANAGER_READY;
  97. //启动雷达管理模块的内部线程。默认wait。
  98. m_locate_manager_condition.reset(false, false, false);
  99. mp_locate_manager_thread = new std::thread(&Locate_manager::thread_work, this);
  100. return SUCCESS;
  101. }
  102. //反初始化 定位 管理模块。
  103. Error_manager Locate_manager::Locate_manager_uninit()
  104. {
  105. LOG(INFO) << " ---Locate_manager_uninit run--- "<< this;
  106. //关闭线程
  107. if (mp_locate_manager_thread)
  108. {
  109. m_locate_manager_condition.kill_all();
  110. }
  111. //回收线程的资源
  112. if (mp_locate_manager_thread)
  113. {
  114. mp_locate_manager_thread->join();
  115. delete mp_locate_manager_thread;
  116. mp_locate_manager_thread = NULL;
  117. }
  118. //回收内存
  119. if ( mp_point_sift !=NULL )
  120. {
  121. delete mp_point_sift;
  122. mp_point_sift = NULL;
  123. }
  124. if ( mp_cnn3d !=NULL )
  125. {
  126. delete mp_cnn3d;
  127. mp_cnn3d = NULL;
  128. }
  129. m_locate_manager_status = LOCATE_MANAGER_UNKNOW;
  130. m_locate_manager_working_flag = false;
  131. return Error_code::SUCCESS;
  132. }
  133. //对外的接口函数,负责接受并处理任务单,
  134. //input:p_locate_task 定位任务单,基类的指针,指向子类的实例,(多态)
  135. Error_manager Locate_manager::execute_task(Task_Base* p_locate_task)
  136. {
  137. LOG(INFO) << " ---Locate_manager::execute_task run--- "<< this;
  138. Error_manager t_error;
  139. Error_manager t_result;
  140. //检查指针
  141. if (p_locate_task == NULL) {
  142. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  143. "Laser_manager::execute_task failed, POINTER_IS_NULL");
  144. }
  145. //检查任务类型,
  146. if (p_locate_task->get_task_type() != LOCATE_MANGER_TASK)
  147. {
  148. return Error_manager(Error_code::LOCATER_MANAGER_TASK_TYPE_ERROR, Error_level::MINOR_ERROR,
  149. "Locate_manager::execute_task get_task_type() != LOCATE_MANGER_TASK ");
  150. }
  151. //检查接收方的状态
  152. t_error = check_status();
  153. if ( t_error != SUCCESS )
  154. {
  155. t_result.compare_and_cover_error(t_error);
  156. }
  157. else
  158. {
  159. //接受任务,并将任务的状态改为TASK_SIGNED已签收
  160. mp_locate_manager_task = (Locate_manager_task *) p_locate_task;
  161. mp_locate_manager_task->set_task_statu(TASK_SIGNED);
  162. //检查消息内容是否正确,
  163. //检查三维点云指针
  164. if (mp_locate_manager_task->get_task_point_cloud_map() == NULL)
  165. {
  166. t_error.error_manager_reset(Error_code::POINTER_IS_NULL,
  167. Error_level::MINOR_ERROR,
  168. "execute_task mp_task_point_cloud is null");
  169. t_result.compare_and_cover_error(t_error);
  170. }
  171. else if ( mp_locate_manager_task->get_task_cloud_lock() == NULL )
  172. {
  173. t_error.error_manager_reset(Error_code::POINTER_IS_NULL,
  174. Error_level::MINOR_ERROR,
  175. "execute_task mp_task_cloud_lock is null");
  176. t_result.compare_and_cover_error(t_error);
  177. }
  178. else
  179. {
  180. //校验map的大小
  181. if ( (mp_locate_manager_task->get_task_point_cloud_map()->size() ==1 && mp_locate_manager_task->get_cloud_aggregation_flag() == true)
  182. || ( (mp_locate_manager_task->get_task_point_cloud_map()->size() == CNN3D_WHEEL_NUMBER
  183. || mp_locate_manager_task->get_task_point_cloud_map()->size() == CNN3D_WHEEL_NUMBER-1 )
  184. && mp_locate_manager_task->get_cloud_aggregation_flag() == false) )
  185. {
  186. //解析任务单,将任务单的数据保存在本地.
  187. mp_locate_information = mp_locate_manager_task->get_task_locate_information_ex();
  188. m_save_flag = mp_locate_manager_task->get_task_save_flag();
  189. m_save_path = mp_locate_manager_task->get_task_save_path();
  190. //启动定位管理模块,的核心工作线程
  191. m_locate_manager_status = LOCATE_MANAGER_SIFT;
  192. m_locate_manager_working_flag = true;
  193. m_locate_manager_condition.notify_all(true);
  194. //通知 thread_work 子线程启动。
  195. //将任务的状态改为 TASK_WORKING 处理中
  196. mp_locate_manager_task->set_task_statu(TASK_WORKING);
  197. }
  198. else
  199. {
  200. t_error.error_manager_reset(Error_code::LOCATER_MANAGER_CLOUD_MAP_ERROR,
  201. Error_level::MINOR_ERROR,
  202. "execute_task input map error");
  203. t_result.compare_and_cover_error(t_error);
  204. }
  205. }
  206. //return 之前要填充任务单里面的错误码.
  207. if (t_result != Error_code::SUCCESS)
  208. {
  209. //忽略轻微故障
  210. if ( t_result.get_error_level() >= Error_level::MINOR_ERROR)
  211. {
  212. //将任务的状态改为 TASK_ERROR 结束错误
  213. mp_locate_manager_task->set_task_statu(TASK_ERROR);
  214. }
  215. //返回错误码
  216. mp_locate_manager_task->set_task_error_manager(t_result);
  217. }
  218. }
  219. return t_result;
  220. }
  221. //检查状态,是否正常运行
  222. Error_manager Locate_manager::check_status()
  223. {
  224. if ( m_locate_manager_status == LOCATE_MANAGER_READY )
  225. {
  226. return Error_code::SUCCESS;
  227. }
  228. else if ( m_locate_manager_status == LOCATE_MANAGER_SIFT
  229. || m_locate_manager_status == LOCATE_MANAGER_CAR
  230. || m_locate_manager_status == LOCATE_MANAGER_WHEEL)
  231. {
  232. return Error_manager(Error_code::LOCATER_MANAGER_STATUS_BUSY, Error_level::NEGLIGIBLE_ERROR,
  233. " Locate_manager::check_status error ");
  234. }
  235. else
  236. {
  237. return Error_manager(Error_code::LOCATER_MANAGER_STATUS_ERROR, Error_level::MINOR_ERROR,
  238. " Locate_manager::check_status error ");
  239. }
  240. return Error_code::SUCCESS;
  241. }
  242. //结束任务单,里面会根据任务的故障等级修正雷达管理模块的状态和任务单的状态
  243. Error_manager Locate_manager::end_task()
  244. {
  245. LOG(INFO) << " ---Locate_manager::end_task run---"<< this;
  246. //关闭子线程
  247. m_locate_manager_working_flag=false;
  248. m_locate_manager_condition.notify_all(false);
  249. //释放缓存
  250. mp_locate_information = NULL;
  251. m_cloud_wheel_map.clear();
  252. m_cloud_car_map.clear();
  253. if ( m_locate_manager_status == LOCATE_MANAGER_SIFT
  254. || m_locate_manager_status == LOCATE_MANAGER_CAR
  255. || m_locate_manager_status == LOCATE_MANAGER_WHEEL)
  256. {
  257. m_locate_manager_status = LOCATE_MANAGER_READY;
  258. }
  259. //else 状态不变
  260. //在结束任务单时,将雷达任务状态改为 TASK_OVER 已结束
  261. if(mp_locate_manager_task !=NULL)
  262. {
  263. //判断任务单的错误等级,
  264. if ( mp_locate_manager_task->get_task_error_manager().get_error_level() < Error_level::MINOR_ERROR)
  265. {
  266. //强制改为TASK_OVER,不管它当前在做什么。
  267. mp_locate_manager_task->set_task_statu(TASK_OVER);
  268. }
  269. else
  270. {
  271. //强制改为 TASK_ERROR,不管它当前在做什么。
  272. mp_locate_manager_task->set_task_statu(TASK_ERROR);
  273. }
  274. }
  275. return Error_code::SUCCESS;
  276. }
  277. //取消任务单,由发送方提前取消任务单
  278. Error_manager Locate_manager::cancel_task()
  279. {
  280. //关闭子线程
  281. m_locate_manager_working_flag=false;
  282. m_locate_manager_condition.notify_all(false);
  283. //确保内部线程已经停下
  284. while (m_locate_manager_condition.is_working())
  285. {
  286. }
  287. //释放缓存
  288. mp_locate_information = NULL;
  289. m_cloud_wheel_map.clear();
  290. m_cloud_car_map.clear();
  291. //强制改为 TASK_DEAD,不管它当前在做什么。
  292. mp_locate_manager_task->set_task_statu(TASK_DEAD);
  293. if ( m_locate_manager_status == LOCATE_MANAGER_SIFT
  294. || m_locate_manager_status == LOCATE_MANAGER_CAR
  295. || m_locate_manager_status == LOCATE_MANAGER_WHEEL)
  296. {
  297. m_locate_manager_status = LOCATE_MANAGER_READY;
  298. }
  299. //else 状态不变
  300. return Error_code::SUCCESS;
  301. }
  302. //判断是否为待机,如果已经准备好,则可以执行任务。
  303. bool Locate_manager::is_ready()
  304. {
  305. return m_locate_manager_status == LOCATE_MANAGER_READY;;
  306. }
  307. Locate_manager::Locate_manager_status Locate_manager::get_locate_manager_status()
  308. {
  309. return m_locate_manager_status;
  310. }
  311. Point_sift_segmentation* Locate_manager::get_point_sift()
  312. {
  313. return mp_point_sift;
  314. }
  315. //mp_locate_manager_thread 线程执行函数,
  316. //thread_work 内部线程负责locate定位分析整车的信息,并且回收汇总雷达的数据
  317. void Locate_manager::thread_work()
  318. {
  319. LOG(INFO) << " -------------------------mp_locate_manager_thread start "<< this;
  320. Error_manager t_error;
  321. Error_manager t_result;
  322. //定位管理的独立线程,
  323. while (m_locate_manager_condition.is_alive())
  324. {
  325. m_locate_manager_condition.wait();
  326. if ( m_locate_manager_condition.is_alive() )
  327. {
  328. std::this_thread::yield();
  329. //重新循环必须清除错误码.
  330. t_error.error_manager_clear_all();
  331. t_result.error_manager_clear_all();
  332. //检查任务单
  333. if ( mp_locate_manager_task == NULL )
  334. {
  335. m_locate_manager_status = LOCATE_MANAGER_FAULT;
  336. m_locate_manager_working_flag = false;
  337. m_locate_manager_condition.notify_all(false);
  338. }
  339. else if (mp_locate_manager_task->get_task_point_cloud_map() == NULL)
  340. {
  341. t_error.error_manager_reset(Error_code::POINTER_IS_NULL,
  342. Error_level::MINOR_ERROR,
  343. "thread_work mp_task_point_cloud is null");
  344. t_result.compare_and_cover_error(t_error);
  345. //因为故障,而提前结束任务.
  346. mp_locate_manager_task->compare_and_cover_task_error_manager(t_result);
  347. end_task();
  348. }
  349. else if ( mp_locate_manager_task->get_task_cloud_lock() == NULL )
  350. {
  351. t_error.error_manager_reset(Error_code::POINTER_IS_NULL,
  352. Error_level::MINOR_ERROR,
  353. "thread_work mp_task_cloud_lock is null");
  354. t_result.compare_and_cover_error(t_error);
  355. //因为故障,而提前结束任务.
  356. mp_locate_manager_task->compare_and_cover_task_error_manager(t_result);
  357. end_task();
  358. }
  359. //第一步
  360. //point_sift 点筛选分割 , 将输入点云分割为车身和轮胎,
  361. //注:地面会在box切割的时候,使用z轴 z_min 直接切除
  362. else if(m_locate_manager_status == LOCATE_MANAGER_SIFT)
  363. {
  364. m_cloud_wheel_map.clear();
  365. m_cloud_car_map.clear();
  366. //定位筛选,将输入点云map拆分为车轮和车身的map
  367. t_error = locate_manager_sift();
  368. t_result.compare_and_cover_error(t_error);
  369. //故障汇总, 只处理2级以上的故障
  370. if(t_result.get_error_level() >= MINOR_ERROR)
  371. {
  372. m_locate_manager_status = LOCATE_MANAGER_FAULT;
  373. mp_locate_manager_task->set_task_statu(TASK_ERROR);
  374. //因为故障,而提前结束任务.
  375. mp_locate_manager_task->compare_and_cover_task_error_manager(t_result);
  376. end_task();
  377. }
  378. else
  379. {
  380. //成功则 进入到下一个阶段,
  381. m_locate_manager_status = LOCATE_MANAGER_CAR;
  382. }
  383. }
  384. //第二步
  385. //_measure_height 计算汽车的长宽高
  386. else if(m_locate_manager_status == LOCATE_MANAGER_CAR)
  387. {
  388. //计算汽车长宽高,
  389. t_error = locate_manager_locate_car();
  390. t_result.compare_and_cover_error(t_error);
  391. //故障汇总, 只处理2级以上的故障
  392. if(t_result.get_error_level() >= MINOR_ERROR)
  393. {
  394. m_locate_manager_status = LOCATE_MANAGER_FAULT;
  395. mp_locate_manager_task->set_task_statu(TASK_ERROR);
  396. //因为故障,而提前结束任务.
  397. mp_locate_manager_task->compare_and_cover_task_error_manager(t_result);
  398. end_task();
  399. }
  400. else
  401. {
  402. //成功则 进入到下一个阶段,
  403. m_locate_manager_status = LOCATE_MANAGER_WHEEL;
  404. }
  405. }
  406. //第三步
  407. //locate_wheel 解析车轮信息
  408. else if(m_locate_manager_status == LOCATE_MANAGER_WHEEL)
  409. {
  410. //解析车轮信息,
  411. t_error = locate_manager_locate_wheel();
  412. t_result.compare_and_cover_error(t_error);
  413. //故障汇总, 只处理2级以上的故障
  414. if(t_result.get_error_level() >= MINOR_ERROR)
  415. {
  416. m_locate_manager_status = LOCATE_MANAGER_FAULT;
  417. mp_locate_manager_task->set_task_statu(TASK_ERROR);
  418. //因为故障,而提前结束任务.
  419. mp_locate_manager_task->compare_and_cover_task_error_manager(t_result);
  420. end_task();
  421. }
  422. else
  423. {
  424. m_locate_manager_working_flag = false;
  425. m_locate_manager_condition.set_pass_ever(false);
  426. //正常结束任务
  427. mp_locate_manager_task->compare_and_cover_task_error_manager(t_result);
  428. end_task();
  429. }
  430. }
  431. }
  432. }
  433. LOG(INFO) << " ---------------------------mp_locate_manager_thread end :"<<this;
  434. return;
  435. }
  436. //定位筛选,将输入点云map拆分为车轮和车身的map.(数据可以直接从locate_manager内部获取)
  437. Error_manager Locate_manager::locate_manager_sift()
  438. {
  439. if ( mp_locate_manager_task == NULL )
  440. {
  441. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  442. " Locate_manager::locate_manager_sift() error ");
  443. }
  444. else if (mp_locate_manager_task->get_task_point_cloud_map() == NULL)
  445. {
  446. return Error_manager(Error_code::POINTER_IS_NULL,
  447. Error_level::MINOR_ERROR,
  448. "locate_manager_sift mp_task_point_cloud is null");
  449. }
  450. else if ( mp_locate_manager_task->get_task_cloud_lock() == NULL )
  451. {
  452. return Error_manager(Error_code::POINTER_IS_NULL,
  453. Error_level::MINOR_ERROR,
  454. "locate_manager_sift mp_task_cloud_lock is null");
  455. }
  456. Error_manager t_error;
  457. Error_manager t_result;
  458. //获取任务单的输入点云
  459. std::unique_lock<std::mutex> lck (*(mp_locate_manager_task->get_task_cloud_lock()));
  460. std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr> *tp_task_point_cloud_map = mp_locate_manager_task->get_task_point_cloud_map();
  461. //清除map
  462. m_cloud_wheel_map.clear();
  463. m_cloud_car_map.clear();
  464. //遍历任务单的输入点云map
  465. for (const auto &map_iter : *tp_task_point_cloud_map)
  466. {
  467. if (map_iter.second.get() == NULL)
  468. {
  469. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  470. " Locate_manager::locate_manager_sift() pcl::PointCloud<pcl::PointXYZ>::Ptr is NULL ");
  471. }
  472. //提前为拆分之后的点云分配内存.
  473. pcl::PointCloud<pcl::PointXYZRGB>::Ptr tp_cloud_wheel(new pcl::PointCloud<pcl::PointXYZRGB>);
  474. pcl::PointCloud<pcl::PointXYZRGB>::Ptr tp_cloud_car(new pcl::PointCloud<pcl::PointXYZRGB>);
  475. //利用PointSift从场景中分割车辆点云
  476. t_error = locate_sift(map_iter.first, map_iter.second, tp_cloud_wheel, tp_cloud_car, m_save_flag, m_save_path);
  477. if (t_error != Error_code::SUCCESS)
  478. {
  479. char buf[256] = {0};
  480. sprintf(buf, " map.id = %d, locate_sift error", map_iter.first );
  481. t_error.add_error_description(buf, strlen(buf) );
  482. t_result.compare_and_cover_error(t_error);
  483. //注:这里不直接return,而是要把map全部执行完成
  484. }
  485. else
  486. {
  487. //将结果存入本地的中间缓存,此时map点云是有内存的,后续要记得回收
  488. m_cloud_wheel_map[map_iter.first] = tp_cloud_wheel;
  489. m_cloud_car_map[map_iter.first] = tp_cloud_car;
  490. }
  491. }
  492. return t_result;
  493. }
  494. //定位筛选,对具体的点云进行操作,分离出车轮和车身.
  495. //input::lidar_id 雷达id, 默认为0
  496. //input::cloud输入点云
  497. //output::cloud_wheel输出车轮点云
  498. //output::cloud_car输出车身点云
  499. //work_dir:中间文件保存路径
  500. Error_manager Locate_manager::locate_sift(int lidar_id, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_in,
  501. pcl::PointCloud<pcl::PointXYZRGB>::Ptr& p_cloud_wheel,pcl::PointCloud<pcl::PointXYZRGB>::Ptr& p_cloud_car,
  502. bool save_flag, std::string work_dir)
  503. {
  504. if(p_cloud_in.get()==0)
  505. {
  506. return Error_manager(LOCATER_SIFT_INPUT_CLOUD_UNINIT,MINOR_ERROR,"sift input cloud uninit");
  507. }
  508. if(p_cloud_in->size()==0)
  509. {
  510. return Error_manager(LOCATER_SIFT_INPUT_CLOUD_EMPTY,MINOR_ERROR,"locate_sift input cloud empty");
  511. }
  512. if(mp_point_sift==NULL)
  513. {
  514. return Error_manager(LOCATER_POINTSIFT_UNINIT,MINOR_ERROR,"Point Sift unInit");
  515. }
  516. Error_manager t_error;
  517. //分割车辆点云
  518. std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> segmentation_clouds;
  519. t_error=mp_point_sift->segmentation( lidar_id, p_cloud_in, segmentation_clouds, save_flag, work_dir);
  520. if(t_error!=SUCCESS)
  521. {
  522. return t_error;
  523. }
  524. //第0类即是轮胎点云,第1类为车身点云
  525. pcl::copyPointCloud(*segmentation_clouds[0], *p_cloud_wheel);
  526. pcl::copyPointCloud(*segmentation_clouds[1], *p_cloud_car);
  527. return SUCCESS;
  528. }
  529. //计算汽车高度,
  530. Error_manager Locate_manager::locate_manager_locate_car()
  531. {
  532. if ( mp_locate_manager_task == NULL )
  533. {
  534. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  535. " Locate_manager::locate_manager_locate_car() error ");
  536. }
  537. else if (mp_locate_manager_task->get_task_point_cloud_map() == NULL)
  538. {
  539. return Error_manager(Error_code::POINTER_IS_NULL,
  540. Error_level::MINOR_ERROR,
  541. "locate_manager_locate_car mp_task_point_cloud is null");
  542. }
  543. else if ( mp_locate_manager_task->get_task_cloud_lock() == NULL )
  544. {
  545. return Error_manager(Error_code::POINTER_IS_NULL,
  546. Error_level::MINOR_ERROR,
  547. "locate_manager_locate_car mp_task_cloud_lock is null");
  548. }
  549. Error_manager t_error;
  550. pcl::PointXYZRGB t_point3d_min, t_point3d_max;
  551. std::unique_lock<std::mutex> lck (*(mp_locate_manager_task->get_task_cloud_lock()));
  552. for (auto iter = m_cloud_car_map.begin(); iter != m_cloud_car_map.end(); ++iter)
  553. {
  554. pcl::PointXYZRGB min, max;
  555. t_error = locate_car(iter->second, min, max);
  556. if ( t_error != Error_code::SUCCESS )
  557. {
  558. return t_error;
  559. }
  560. if ( iter == m_cloud_car_map.begin() )
  561. {
  562. t_point3d_min.x = min.x;
  563. t_point3d_min.y = min.y;
  564. t_point3d_min.z = min.z;
  565. t_point3d_max.x = max.x;
  566. t_point3d_max.y = max.y;
  567. t_point3d_max.z = max.z;
  568. }
  569. else
  570. {
  571. //比较选出整个map点云的边界
  572. if ( t_point3d_min.x <= min.x )
  573. {
  574. t_point3d_min.x = min.x;
  575. }
  576. if ( t_point3d_min.y <= min.y )
  577. {
  578. t_point3d_min.y = min.y;
  579. }
  580. if ( t_point3d_min.z <= min.z )
  581. {
  582. t_point3d_min.z = min.z;
  583. }
  584. if ( t_point3d_max.x >= max.x )
  585. {
  586. t_point3d_max.x = max.x;
  587. }
  588. if ( t_point3d_max.y >= max.y )
  589. {
  590. t_point3d_max.y = max.y;
  591. }
  592. if ( t_point3d_max.z >= max.z )
  593. {
  594. t_point3d_max.z = max.z;
  595. }
  596. }
  597. }
  598. mp_locate_information->locate_length = t_point3d_max.y - t_point3d_min.y;
  599. mp_locate_information->locate_width = t_point3d_max.x - t_point3d_min.x;;
  600. mp_locate_information->locate_height = t_point3d_max.z;
  601. //注意了:在雷达扫描时, 就已经将地面标定位为 z = 0
  602. return Error_code::SUCCESS;
  603. }
  604. //根据汽车点云计算汽车的边界
  605. Error_manager Locate_manager::locate_car(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_car, pcl::PointXYZRGB& min, pcl::PointXYZRGB& max)
  606. {
  607. if(cloud_car.get()==0)
  608. {
  609. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  610. " POINTER IS NULL ");
  611. // return Error_manager(LOCATER_MEASURE_HEIGHT_CLOUD_UNINIT,MINOR_ERROR,"measure height input cloud uninit");
  612. }
  613. if(cloud_car->size()==0)
  614. {
  615. return Error_manager(LOCATER_MEASURE_HEIGHT_CLOUD_EMPTY,MINOR_ERROR,"measure height input cloud is empty");
  616. }
  617. //获取点云的边界
  618. pcl::getMinMax3D(*cloud_car,min,max);
  619. return SUCCESS;
  620. }
  621. //计算汽车的车轮信息
  622. Error_manager Locate_manager::locate_manager_locate_wheel()
  623. {
  624. if ( mp_locate_manager_task == NULL )
  625. {
  626. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  627. " Locate_manager::locate_manager_locate_car() error ");
  628. }
  629. else if (mp_locate_manager_task->get_task_point_cloud_map() == NULL)
  630. {
  631. return Error_manager(Error_code::POINTER_IS_NULL,
  632. Error_level::MINOR_ERROR,
  633. "locate_manager_locate_car mp_task_point_cloud is null");
  634. }
  635. else if ( mp_locate_manager_task->get_task_cloud_lock() == NULL )
  636. {
  637. return Error_manager(Error_code::POINTER_IS_NULL,
  638. Error_level::MINOR_ERROR,
  639. "locate_manager_locate_car mp_task_cloud_lock is null");
  640. }
  641. if(mp_cnn3d==NULL)
  642. {
  643. return Error_manager(LOCATER_3DCNN_UNINIT,MINOR_ERROR,"locate_wheel 3dcnn is not init");
  644. }
  645. Error_manager t_error;
  646. std::unique_lock<std::mutex> lck (*(mp_locate_manager_task->get_task_cloud_lock()));
  647. //解析车轮
  648. t_error=mp_cnn3d->analytic_wheel(m_cloud_wheel_map,mp_locate_manager_task->get_cloud_aggregation_flag(),
  649. mp_locate_manager_task->get_task_locate_information_ex(),
  650. m_save_flag,m_save_path);
  651. if ( t_error != Error_code::SUCCESS )
  652. {
  653. return t_error;
  654. }
  655. return Error_code::SUCCESS;
  656. }
  657. //保存点云成txt到文件
  658. void Locate_manager::save_cloud_txt(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,std::string save_file)
  659. {
  660. FILE* pfile=fopen(save_file.c_str(),"w");
  661. for(int i=0;i<cloud->size();++i)
  662. {
  663. fprintf(pfile,"%.3f %.3f %.3f\n",cloud->points[i].x,cloud->points[i].y,cloud->points[i].z);
  664. }
  665. fclose(pfile);
  666. }