parkspace_allocator.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * @Description: 车位分配算法模块,使用单例模式,接收外部请求并通过调用通信块接口发送反馈
  3. * @Author: yct
  4. * @Date: 2020-07-10 11:02:40
  5. * @LastEditTime: 2020-07-10 16:57:14
  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. return Error_code::PARKSPACE_ALLOCATOR_MSG_REQUEST_TYPE_ERROR;
  115. }
  116. //判断是否为待机,如果已经准备好,则可以执行任务。
  117. bool Parkspace_allocator::is_ready()
  118. {
  119. if ( m_current_status == eParkspace_allocator_normal && m_thread_pool.thread_is_full_load() == false )
  120. {
  121. return true;
  122. }
  123. else
  124. {
  125. return false;
  126. }
  127. }
  128. Parkspace_allocator::parkspace_allocator_status Parkspace_allocator::get_parkspace_allocator_status()
  129. {
  130. return m_current_status;
  131. }
  132. //分配车位线程函数
  133. void Parkspace_allocator::execute_for_allocate(message::Car_info car_info, int terminal_id, int command_id)
  134. {
  135. std::lock_guard<std::mutex> lck(m_mutex);
  136. LOG(INFO) << "分配";
  137. //根据请求的信息反馈分配的车位,并封装发送
  138. message::Parkspace_allocation_response_msg response_msg;
  139. message::Base_info t_response_header;
  140. t_response_header.set_msg_type(message::Message_type::eParkspace_allocation_response_msg);
  141. t_response_header.set_timeout_ms(1000);
  142. t_response_header.set_sender(message::Communicator::eParkspace);
  143. t_response_header.set_receiver(message::Communicator::eMain);
  144. message::Error_manager t_error;
  145. message::Parkspace_info t_allocated_space;
  146. //获取当前所有车位状态,分配车位
  147. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  148. int index = -1;
  149. if(t_current_parkspace_status.parkspace_info_size()<=0)
  150. {
  151. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  152. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  153. LOG(ERROR) << "无车位";
  154. }
  155. else
  156. {
  157. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  158. {
  159. // 找到高于车高且空闲车位,则分配
  160. if (t_current_parkspace_status.parkspace_info(i).height() > car_info.car_height()
  161. && t_current_parkspace_status.parkspace_info(i).width() > car_info.car_width()
  162. && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_empty)
  163. {
  164. index = i;
  165. break;
  166. }
  167. }
  168. if(index<0){
  169. t_error.set_error_code(PARKSPACE_ALLOCATOR_ALLOCATE_FAILED);
  170. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  171. t_allocated_space.CopyFrom(t_current_parkspace_status.parkspace_info(0));
  172. LOG(WARNING) << "分配车位失败";
  173. }else{
  174. t_error.set_error_code(SUCCESS);
  175. t_error.set_error_level(message::Error_level::NORMAL);
  176. message::Parkspace_info t_space_to_lock = t_current_parkspace_status.parkspace_info(index);
  177. t_space_to_lock.set_parkspace_status(message::Parkspace_status::eParkspace_occupied);
  178. t_space_to_lock.mutable_car_info()->CopyFrom(car_info);
  179. t_allocated_space.CopyFrom(t_space_to_lock);
  180. // 分配车位后更新车位状态
  181. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_space_to_lock);
  182. LOG(INFO) << "第"<<index<<"号位占用, id: "<<t_space_to_lock.parkspace_id();
  183. }
  184. }
  185. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  186. response_msg.set_command_id(command_id);
  187. response_msg.mutable_error_manager()->CopyFrom(t_error);
  188. response_msg.mutable_allocated_space_info()->CopyFrom(t_allocated_space);
  189. Communication_message* response=new Communication_message();
  190. response->reset(t_response_header, response_msg.SerializeAsString());
  191. Parkspace_allocation_communicator::get_instance_references().send_response(response);
  192. }
  193. //查询车位线程函数
  194. void Parkspace_allocator::execute_for_search(message::Car_info car_info, int command_id)
  195. {
  196. std::lock_guard<std::mutex> lck(m_mutex);
  197. LOG(INFO) << "查询";
  198. //根据车辆凭证信息查询车辆位置
  199. //!!!!!此处跳过外部处理与调用的过程,直接在内部调用,发送分配结果用于测试,目前一直发布第一个车位
  200. message::Parkspace_search_response_msg response_msg;
  201. message::Base_info t_response_header;
  202. message::Error_manager t_error;
  203. message::Parkspace_info t_car_position;
  204. t_response_header.set_msg_type(message::Message_type::eParkspace_search_response_msg);
  205. t_response_header.set_timeout_ms(1000);
  206. t_response_header.set_sender(message::Communicator::eParkspace);
  207. t_response_header.set_receiver(message::Communicator::eMain);
  208. //获取当前所有车位状态,查询车辆位置
  209. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  210. int index = -1;
  211. if(t_current_parkspace_status.parkspace_info_size()<=0)
  212. {
  213. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  214. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  215. LOG(ERROR) << "无车位";
  216. }
  217. else
  218. {
  219. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  220. {
  221. // 找到凭证号/号牌对应车位,记录
  222. if (t_current_parkspace_status.parkspace_info(i).has_car_info()
  223. && t_current_parkspace_status.parkspace_info(i).car_info().license() == car_info.license()
  224. && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied)
  225. {
  226. index = i;
  227. break;
  228. }
  229. }
  230. if(index<0){
  231. t_error.set_error_code(PARKSPACE_ALLOCATOR_SEARCH_FAILED);
  232. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  233. LOG(INFO) << "查询车位失败";
  234. }else{
  235. t_error.set_error_code(SUCCESS);
  236. t_error.set_error_level(message::Error_level::NORMAL);
  237. message::Parkspace_info t_space_searching = t_current_parkspace_status.parkspace_info(index);
  238. t_car_position.CopyFrom(t_space_searching);
  239. LOG(INFO) << "车辆"<<car_info.license() <<"在第"<<index<<"号位, id: "<<t_space_searching.parkspace_id();
  240. }
  241. }
  242. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  243. response_msg.set_command_id(command_id);
  244. response_msg.mutable_error_manager()->CopyFrom(t_error);
  245. response_msg.mutable_car_position()->CopyFrom(t_car_position);
  246. Communication_message* response=new Communication_message();
  247. response->reset(t_response_header, response_msg.SerializeAsString());
  248. Parkspace_allocation_communicator::get_instance_references().send_response(response);
  249. }
  250. //释放车位线程函数
  251. void Parkspace_allocator::execute_for_release(message::Parkspace_info space_info, int command_id)
  252. {
  253. std::lock_guard<std::mutex> lck(m_mutex);
  254. LOG(INFO) << "释放";
  255. //根据车位信息定位待释放车位位置,车辆凭证号用于校验
  256. //!!!!!此处跳过外部处理与调用的过程,直接在内部调用,发送分配结果用于测试,目前一直发布第一个车位
  257. message::Parkspace_release_response_msg response_msg;
  258. message::Base_info t_response_header;
  259. t_response_header.set_msg_type(message::eParkspace_release_response_msg);
  260. t_response_header.set_sender(message::eParkspace);
  261. t_response_header.set_receiver(message::eMain);
  262. message::Error_manager t_error;
  263. message::Parkspace_info t_release_space;
  264. //获取当前所有车位状态,找到待释放的车位
  265. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  266. int index = -1;
  267. if(t_current_parkspace_status.parkspace_info_size()<=0)
  268. {
  269. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  270. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  271. LOG(ERROR) << "无车位";
  272. }
  273. else if (!space_info.has_car_info())
  274. {
  275. t_error.set_error_code(PARKSPACE_ALLOCATOR_RELEASE_FAILED);
  276. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  277. LOG(WARNING) << "传入待释放车位无车辆信息";
  278. }
  279. else
  280. {
  281. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  282. {
  283. // 找到高于车高且空闲车位,则分配
  284. if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id()
  285. && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied
  286. && t_current_parkspace_status.parkspace_info(i).has_car_info()
  287. && t_current_parkspace_status.parkspace_info(i).car_info().license() == space_info.car_info().license())
  288. {
  289. index = i;
  290. break;
  291. }
  292. }
  293. if(index<0){
  294. t_error.set_error_code(PARKSPACE_ALLOCATOR_RELEASE_FAILED);
  295. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  296. LOG(WARNING) << "释放车位失败";
  297. }else{
  298. t_error.set_error_code(SUCCESS);
  299. t_error.set_error_level(message::Error_level::NORMAL);
  300. message::Parkspace_info t_space_to_release = t_current_parkspace_status.parkspace_info(index);
  301. t_space_to_release.set_parkspace_status(message::Parkspace_status::eParkspace_empty);
  302. t_release_space.CopyFrom(t_space_to_release);
  303. // 分配车位后更新车位状态
  304. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_space_to_release);
  305. LOG(INFO) << "第"<<index<<"号位释放, id: "<<t_space_to_release.parkspace_id();
  306. }
  307. }
  308. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  309. response_msg.set_command_id(command_id);
  310. response_msg.mutable_error_manager()->CopyFrom(t_error);
  311. response_msg.mutable_release_space_info()->CopyFrom(t_release_space);
  312. Communication_message response=Communication_message();
  313. response.reset(t_response_header, response_msg.SerializeAsString());
  314. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  315. }
  316. //强制更新车位信息线程函数
  317. void Parkspace_allocator::execute_for_force_update(message::Parkspace_info space_info, int command_id)
  318. {
  319. std::lock_guard<std::mutex> lck(m_mutex);
  320. LOG(INFO) << "手动";
  321. //根据车位信息定位待释放车位位置,车辆凭证号用于校验
  322. //!!!!!此处跳过外部处理与调用的过程,直接在内部调用,发送分配结果用于测试,目前一直发布第一个车位
  323. message::Parkspace_force_update_response_msg response_msg;
  324. message::Base_info t_response_header;
  325. message::Error_manager t_error;
  326. message::Parkspace_info t_update_space;
  327. //获取当前所有车位状态,找到待释放的车位
  328. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  329. int index = -1;
  330. if(t_current_parkspace_status.parkspace_info_size()<=0)
  331. {
  332. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  333. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  334. LOG(ERROR) << "无车位";
  335. }
  336. else
  337. {
  338. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  339. {
  340. // 找到高于车高且空闲车位,则分配
  341. if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id())
  342. {
  343. index = i;
  344. break;
  345. }
  346. }
  347. if(index<0){
  348. t_error.set_error_code(PARKSPACE_ALLOCATOR_FORCE_UPDATE_FAILED);
  349. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  350. LOG(WARNING) << "手动更新车位失败";
  351. }else{
  352. t_error.set_error_code(SUCCESS);
  353. t_error.set_error_level(message::Error_level::NORMAL);
  354. t_update_space.CopyFrom(space_info);
  355. // 分配车位后更新车位状态
  356. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_update_space);
  357. LOG(INFO) << "第"<<index<<"号位已手动更新, id: "<<t_update_space.parkspace_id();
  358. }
  359. }
  360. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  361. response_msg.set_command_id(command_id);
  362. response_msg.mutable_error_manager()->CopyFrom(t_error);
  363. response_msg.mutable_update_space_info()->CopyFrom(t_update_space);
  364. Communication_message* response=new Communication_message();
  365. response->reset(t_response_header, response_msg.SerializeAsString());
  366. Parkspace_allocation_communicator::get_instance_references().send_response(response);
  367. }