parkspace_allocator.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /*
  2. * @Description: 车位分配算法模块,使用单例模式,接收外部请求并通过调用通信块接口发送反馈
  3. * @Author: yct
  4. * @Date: 2020-07-10 11:02:40
  5. * @LastEditTime: 2020-07-17 09:19:38
  6. * @LastEditors: yct
  7. */
  8. #include "parkspace_allocator.h"
  9. #include "parkspace_allocation_communicator.h"
  10. Parkspace_allocator::Parkspace_allocator()
  11. {
  12. }
  13. Parkspace_allocator::~Parkspace_allocator()
  14. {
  15. parkspace_allocator_uninit();
  16. }
  17. //初始化
  18. Error_manager Parkspace_allocator::parkspace_allocator_init(int threads_size)
  19. {
  20. m_thread_pool.thread_pool_init(threads_size);
  21. m_current_status = eParkspace_allocator_normal;
  22. return Error_code::SUCCESS;
  23. }
  24. //反初始化
  25. Error_manager Parkspace_allocator::parkspace_allocator_uninit()
  26. {
  27. m_thread_pool.thread_pool_uninit();
  28. m_current_status = eParkspace_allocator_unknown;
  29. return Error_code::SUCCESS;
  30. }
  31. //检查执行者的状态, 判断能否处理这条消息,
  32. Error_manager Parkspace_allocator::check_executer(Communication_message* p_msg)
  33. {
  34. if ( p_msg == NULL )
  35. {
  36. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  37. " POINTER IS NULL ");
  38. }
  39. Error_manager t_error = SUCCESS;
  40. return t_error;
  41. }
  42. //处理消息的执行函数
  43. Error_manager Parkspace_allocator::execute_msg(Communication_message* p_msg)
  44. {
  45. if ( p_msg == nullptr )
  46. {
  47. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  48. " POINTER IS NULL ");
  49. }
  50. switch ( p_msg->get_message_type() )
  51. {
  52. ///车位分配请求消息
  53. case Communication_message::eParkspace_allocation_request_msg:
  54. {
  55. message::Parkspace_allocation_request_msg request;
  56. bool result = request.ParseFromString(p_msg->get_message_buf());
  57. LOG(INFO)<<"allocation request, car license: "<<request.car_info().license();
  58. if(!result)
  59. {
  60. return Error_manager(Error_code::PARKSPACE_ALLOCATOR_MSG_PARSE_ERROR, Error_level::MINOR_ERROR,
  61. " message::Parkspace_allocation_request_msg ParseFromString error ");
  62. }
  63. //往线程池添加执行任务, 之后会唤醒一个线程去执行他.
  64. m_thread_pool.enqueue(&Parkspace_allocator::execute_for_allocate, this,
  65. request.car_info(), request.terminal_id(), request.command_id());
  66. return SUCCESS;
  67. }
  68. // 车位查询请求消息
  69. case Communication_message::eParkspace_search_request_msg:
  70. {
  71. message::Parkspace_search_request_msg request;
  72. bool result = request.ParseFromString(p_msg->get_message_buf());
  73. LOG(INFO)<<"search request, car license: "<<request.car_info().license();
  74. if(!result)
  75. {
  76. return Error_manager(Error_code::PARKSPACE_ALLOCATOR_MSG_PARSE_ERROR, Error_level::MINOR_ERROR,
  77. " message::Parkspace_search_request_msg ParseFromString error ");
  78. }
  79. //往线程池添加执行任务, 之后会唤醒一个线程去执行他.
  80. m_thread_pool.enqueue(&Parkspace_allocator::execute_for_search, this, request.car_info(), request.command_id());
  81. return SUCCESS;
  82. }
  83. // 车位释放请求消息
  84. case Communication_message::eParkspace_release_request_msg:
  85. {
  86. message::Parkspace_release_request_msg request;
  87. bool result = request.ParseFromString(p_msg->get_message_buf());
  88. LOG(INFO)<<"release request, parkspace id: "<<request.release_space_info().parkspace_id();
  89. if(!result)
  90. {
  91. return Error_manager(Error_code::PARKSPACE_ALLOCATOR_MSG_PARSE_ERROR, Error_level::MINOR_ERROR,
  92. " message::Parkspace_release_request_msg ParseFromString error ");
  93. }
  94. //往线程池添加执行任务, 之后会唤醒一个线程去执行他.
  95. m_thread_pool.enqueue(&Parkspace_allocator::execute_for_release, this, request.release_space_info(), request.command_id());
  96. return SUCCESS;
  97. }
  98. // 车位手动更新请求消息
  99. case Communication_message::eParkspace_force_update_request_msg:
  100. {
  101. message::Parkspace_force_update_request_msg request;
  102. bool result = request.ParseFromString(p_msg->get_message_buf());
  103. LOG(INFO)<<"force update request, parkspace id: "<<request.update_space_info().parkspace_id();
  104. if(!result)
  105. {
  106. return Error_manager(Error_code::PARKSPACE_ALLOCATOR_MSG_PARSE_ERROR, Error_level::MINOR_ERROR,
  107. " message::Parkspace_force_update_request_msg ParseFromString error ");
  108. }
  109. //往线程池添加执行任务, 之后会唤醒一个线程去执行他.
  110. m_thread_pool.enqueue(&Parkspace_allocator::execute_for_force_update, this, request.update_space_info(), request.command_id());
  111. return SUCCESS;
  112. }
  113. // 车位确认占用请求消息
  114. case Communication_message::eParkspace_confirm_alloc_request_msg:
  115. {
  116. message::Parkspace_confirm_alloc_request_msg request;
  117. bool result = request.ParseFromString(p_msg->get_message_buf());
  118. LOG(INFO)<<"confirm alloc request, parkspace id: "<<request.confirm_space_info().parkspace_id();
  119. if(!result)
  120. {
  121. return Error_manager(Error_code::PARKSPACE_ALLOCATOR_MSG_PARSE_ERROR, Error_level::MINOR_ERROR,
  122. " message::Parkspace_force_update_request_msg ParseFromString error ");
  123. }
  124. //往线程池添加执行任务, 之后会唤醒一个线程去执行他.
  125. m_thread_pool.enqueue(&Parkspace_allocator::execute_for_force_update, this, request.confirm_space_info(), request.command_id());
  126. return SUCCESS;
  127. }
  128. }
  129. return Error_code::PARKSPACE_ALLOCATOR_MSG_REQUEST_TYPE_ERROR;
  130. }
  131. //判断是否为待机,如果已经准备好,则可以执行任务。
  132. bool Parkspace_allocator::is_ready()
  133. {
  134. if ( m_current_status == eParkspace_allocator_normal && m_thread_pool.thread_is_full_load() == false )
  135. {
  136. return true;
  137. }
  138. else
  139. {
  140. return false;
  141. }
  142. }
  143. Parkspace_allocator::parkspace_allocator_status Parkspace_allocator::get_parkspace_allocator_status()
  144. {
  145. return m_current_status;
  146. }
  147. //分配车位线程函数
  148. void Parkspace_allocator::execute_for_allocate(message::Car_info car_info, int terminal_id, int command_id)
  149. {
  150. std::lock_guard<std::mutex> lck(m_mutex);
  151. LOG(INFO) << "分配";
  152. //根据请求的信息反馈分配的车位,并封装发送
  153. message::Parkspace_allocation_response_msg response_msg;
  154. message::Base_info t_response_header;
  155. t_response_header.set_msg_type(message::Message_type::eParkspace_allocation_response_msg);
  156. t_response_header.set_timeout_ms(1000);
  157. t_response_header.set_sender(message::Communicator::eParkspace);
  158. t_response_header.set_receiver(message::Communicator::eMain);
  159. message::Error_manager t_error;
  160. message::Parkspace_info t_allocated_space;
  161. //获取当前所有车位状态,分配车位
  162. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  163. int index = -1;
  164. if(t_current_parkspace_status.parkspace_info_size()<=0)
  165. {
  166. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  167. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  168. LOG(ERROR) << "无车位";
  169. }
  170. else
  171. {
  172. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  173. {
  174. // 找到高于车高且空闲车位,则分配
  175. if (t_current_parkspace_status.parkspace_info(i).height() > car_info.car_height()
  176. && t_current_parkspace_status.parkspace_info(i).width() > car_info.car_width()
  177. && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_empty)
  178. {
  179. index = i;
  180. break;
  181. }
  182. }
  183. if(index<0){
  184. t_error.set_error_code(PARKSPACE_ALLOCATOR_ALLOCATE_FAILED);
  185. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  186. t_allocated_space.CopyFrom(t_current_parkspace_status.parkspace_info(0));
  187. LOG(WARNING) << "分配车位失败";
  188. }else{
  189. t_error.set_error_code(SUCCESS);
  190. t_error.set_error_level(message::Error_level::NORMAL);
  191. message::Parkspace_info t_space_to_lock = t_current_parkspace_status.parkspace_info(index);
  192. t_space_to_lock.set_parkspace_status(message::Parkspace_status::eParkspace_locked);
  193. t_space_to_lock.mutable_car_info()->CopyFrom(car_info);
  194. t_allocated_space.CopyFrom(t_space_to_lock);
  195. // 分配车位后更新车位状态
  196. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_space_to_lock);
  197. LOG(INFO) << "第"<<index<<"号位占用, id: "<<t_space_to_lock.parkspace_id();
  198. }
  199. }
  200. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  201. response_msg.set_command_id(command_id);
  202. response_msg.mutable_error_manager()->CopyFrom(t_error);
  203. response_msg.mutable_allocated_space_info()->CopyFrom(t_allocated_space);
  204. Communication_message response=Communication_message();
  205. response.reset(t_response_header, response_msg.SerializeAsString());
  206. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  207. }
  208. //查询车位线程函数
  209. void Parkspace_allocator::execute_for_search(message::Car_info car_info, int command_id)
  210. {
  211. std::lock_guard<std::mutex> lck(m_mutex);
  212. LOG(INFO) << "查询";
  213. //根据车辆凭证信息查询车辆位置
  214. //!!!!!此处跳过外部处理与调用的过程,直接在内部调用,发送分配结果用于测试,目前一直发布第一个车位
  215. message::Parkspace_search_response_msg response_msg;
  216. message::Base_info t_response_header;
  217. message::Error_manager t_error;
  218. message::Parkspace_info t_car_position;
  219. t_response_header.set_msg_type(message::Message_type::eParkspace_search_response_msg);
  220. t_response_header.set_timeout_ms(1000);
  221. t_response_header.set_sender(message::Communicator::eParkspace);
  222. t_response_header.set_receiver(message::Communicator::eMain);
  223. //获取当前所有车位状态,查询车辆位置
  224. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  225. int index = -1;
  226. if(t_current_parkspace_status.parkspace_info_size()<=0)
  227. {
  228. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  229. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  230. LOG(ERROR) << "无车位";
  231. }
  232. else
  233. {
  234. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  235. {
  236. // 找到凭证号/号牌对应车位,记录
  237. if (t_current_parkspace_status.parkspace_info(i).has_car_info()
  238. && t_current_parkspace_status.parkspace_info(i).car_info().license() == car_info.license()
  239. && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied)
  240. {
  241. index = i;
  242. break;
  243. }
  244. }
  245. if(index<0){
  246. t_error.set_error_code(PARKSPACE_ALLOCATOR_SEARCH_FAILED);
  247. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  248. LOG(INFO) << "查询车位失败";
  249. }else{
  250. t_error.set_error_code(SUCCESS);
  251. t_error.set_error_level(message::Error_level::NORMAL);
  252. message::Parkspace_info t_space_searching = t_current_parkspace_status.parkspace_info(index);
  253. t_car_position.CopyFrom(t_space_searching);
  254. LOG(INFO) << "车辆"<<car_info.license() <<"在第"<<index<<"号位, id: "<<t_space_searching.parkspace_id();
  255. }
  256. }
  257. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  258. response_msg.set_command_id(command_id);
  259. response_msg.mutable_error_manager()->CopyFrom(t_error);
  260. response_msg.mutable_car_position()->CopyFrom(t_car_position);
  261. Communication_message response=Communication_message();
  262. response.reset(t_response_header, response_msg.SerializeAsString());
  263. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  264. }
  265. //释放车位线程函数
  266. void Parkspace_allocator::execute_for_release(message::Parkspace_info space_info, int command_id)
  267. {
  268. std::lock_guard<std::mutex> lck(m_mutex);
  269. LOG(INFO) << "释放";
  270. //根据车位信息定位待释放车位位置,车辆凭证号用于校验
  271. //!!!!!此处跳过外部处理与调用的过程,直接在内部调用,发送分配结果用于测试,目前一直发布第一个车位
  272. message::Parkspace_release_response_msg response_msg;
  273. message::Base_info t_response_header;
  274. t_response_header.set_msg_type(message::eParkspace_release_response_msg);
  275. t_response_header.set_sender(message::eParkspace);
  276. t_response_header.set_receiver(message::eMain);
  277. message::Error_manager t_error;
  278. message::Parkspace_info t_release_space;
  279. //获取当前所有车位状态,找到待释放的车位
  280. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  281. int index = -1;
  282. if(t_current_parkspace_status.parkspace_info_size()<=0)
  283. {
  284. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  285. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  286. LOG(ERROR) << "无车位";
  287. }
  288. else if (!space_info.has_car_info())
  289. {
  290. t_error.set_error_code(PARKSPACE_ALLOCATOR_RELEASE_FAILED);
  291. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  292. LOG(WARNING) << "传入待释放车位无车辆信息";
  293. }
  294. else
  295. {
  296. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  297. {
  298. // 找到高于车高且空闲车位,则分配
  299. if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id()
  300. && (t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied
  301. ||t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_locked)
  302. && t_current_parkspace_status.parkspace_info(i).has_car_info()
  303. && t_current_parkspace_status.parkspace_info(i).car_info().license() == space_info.car_info().license())
  304. {
  305. index = i;
  306. break;
  307. }
  308. }
  309. if(index<0){
  310. t_error.set_error_code(PARKSPACE_ALLOCATOR_RELEASE_FAILED);
  311. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  312. LOG(WARNING) << "释放车位失败";
  313. }else{
  314. t_error.set_error_code(SUCCESS);
  315. t_error.set_error_level(message::Error_level::NORMAL);
  316. message::Parkspace_info t_space_to_release = t_current_parkspace_status.parkspace_info(index);
  317. t_space_to_release.set_parkspace_status(message::Parkspace_status::eParkspace_empty);
  318. t_release_space.CopyFrom(t_space_to_release);
  319. // 分配车位后更新车位状态
  320. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_space_to_release);
  321. LOG(INFO) << "第"<<index<<"号位释放, id: "<<t_space_to_release.parkspace_id();
  322. }
  323. }
  324. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  325. response_msg.set_command_id(command_id);
  326. response_msg.mutable_error_manager()->CopyFrom(t_error);
  327. response_msg.mutable_release_space_info()->CopyFrom(t_release_space);
  328. Communication_message response=Communication_message();
  329. response.reset(t_response_header, response_msg.SerializeAsString());
  330. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  331. }
  332. //强制更新车位信息线程函数
  333. void Parkspace_allocator::execute_for_force_update(message::Parkspace_info space_info, int command_id)
  334. {
  335. std::lock_guard<std::mutex> lck(m_mutex);
  336. LOG(INFO) << "手动";
  337. //根据车位信息定位待释放车位位置,车辆凭证号用于校验
  338. //!!!!!此处跳过外部处理与调用的过程,直接在内部调用,发送分配结果用于测试,目前一直发布第一个车位
  339. message::Parkspace_force_update_response_msg response_msg;
  340. message::Base_info t_response_header;
  341. message::Error_manager t_error;
  342. message::Parkspace_info t_update_space;
  343. //获取当前所有车位状态,找到待释放的车位
  344. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  345. int index = -1;
  346. if(t_current_parkspace_status.parkspace_info_size()<=0)
  347. {
  348. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  349. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  350. LOG(ERROR) << "无车位";
  351. }
  352. else
  353. {
  354. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  355. {
  356. // 找到高于车高且空闲车位,则分配
  357. if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id())
  358. {
  359. index = i;
  360. break;
  361. }
  362. }
  363. if(index<0){
  364. t_error.set_error_code(PARKSPACE_ALLOCATOR_FORCE_UPDATE_FAILED);
  365. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  366. LOG(WARNING) << "手动更新车位失败";
  367. }else{
  368. t_error.set_error_code(SUCCESS);
  369. t_error.set_error_level(message::Error_level::NORMAL);
  370. t_update_space.CopyFrom(space_info);
  371. // 分配车位后更新车位状态
  372. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_update_space);
  373. LOG(INFO) << "第"<<index<<"号位已手动更新, id: "<<t_update_space.parkspace_id();
  374. }
  375. }
  376. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  377. response_msg.set_command_id(command_id);
  378. response_msg.mutable_error_manager()->CopyFrom(t_error);
  379. response_msg.mutable_update_space_info()->CopyFrom(t_update_space);
  380. Communication_message response=Communication_message();
  381. response.reset(t_response_header, response_msg.SerializeAsString());
  382. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  383. }
  384. //确认分配车位线程函数
  385. void Parkspace_allocator::execute_for_confirm_alloc(message::Parkspace_info space_info, int command_id)
  386. {
  387. std::lock_guard<std::mutex> lck(m_mutex);
  388. LOG(INFO) << "确认分配";
  389. //根据车位信息定位待确认占用车位
  390. message::Parkspace_confirm_alloc_response_msg response_msg;
  391. message::Base_info t_response_header;
  392. message::Error_manager t_error;
  393. message::Parkspace_info t_confirm_space;
  394. //获取当前所有车位状态,找到待释放的车位
  395. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  396. int index = -1;
  397. if(t_current_parkspace_status.parkspace_info_size()<=0)
  398. {
  399. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  400. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  401. LOG(ERROR) << "无车位";
  402. }
  403. else if (!space_info.has_car_info())
  404. {
  405. t_error.set_error_code(PARKSPACE_ALLOCATOR_PARAM_ERROR);
  406. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  407. LOG(WARNING) << "传入确认占用车位无车辆信息";
  408. }
  409. else
  410. {
  411. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  412. {
  413. // 找到相同车位,且车辆信息匹配
  414. if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id()
  415. && t_current_parkspace_status.parkspace_info(i).has_car_info()
  416. && t_current_parkspace_status.parkspace_info(i).car_info().license() == space_info.car_info().license())
  417. {
  418. index = i;
  419. break;
  420. }
  421. }
  422. if(index<0){
  423. t_error.set_error_code(PARKSPACE_ALLOCATOR_CONFIRM_ALLOC_ERROR);
  424. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  425. LOG(WARNING) << "确认占用车位失败";
  426. }else{
  427. t_error.set_error_code(SUCCESS);
  428. t_error.set_error_level(message::Error_level::NORMAL);
  429. t_confirm_space.CopyFrom(space_info);
  430. t_confirm_space.set_parkspace_status(message::Parkspace_status::eParkspace_occupied);
  431. // 分配车位后更新车位状态
  432. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_confirm_space);
  433. LOG(INFO) << "第"<<index<<"号位已确认占用, id: "<<t_confirm_space.parkspace_id();
  434. }
  435. }
  436. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  437. response_msg.set_command_id(command_id);
  438. response_msg.mutable_error_manager()->CopyFrom(t_error);
  439. response_msg.mutable_confirm_alloc_space_info()->CopyFrom(t_confirm_space);
  440. Communication_message response=Communication_message();
  441. response.reset(t_response_header, response_msg.SerializeAsString());
  442. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  443. }