dispatch_command.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. #include "dispatch_command.h"
  2. #include <google/protobuf/text_format.h>
  3. Dispatch_command::Dispatch_command()
  4. {
  5. m_dispatch_command_status = E_DISPATCH_COMMAND_UNKNOW;
  6. m_unit = 0;
  7. m_device_floor = 0;
  8. m_dispatch_process_type = Common_data::DISPATCH_PROCESS_TYPE_UNKNOW;
  9. m_car_type = Common_data::Car_type::UNKNOW_CAR_TYPE;
  10. }
  11. Dispatch_command::~Dispatch_command()
  12. {
  13. }
  14. //调度开始前, 向数据库发送请求的相关操作, 输入 穿梭机所在的楼层, 调度id 0~2, 空闲出口id, 如果不是0,就表示有空闲的出口
  15. Error_manager Dispatch_command::dispatch_request_to_sql(int device_floor, int dispatch_id, int outlet_ready)
  16. {
  17. Error_manager t_error;
  18. m_device_floor = device_floor;
  19. m_dispatch_id = dispatch_id;
  20. m_unit = dispatch_id+1;
  21. m_outlet_ready = outlet_ready;
  22. //获取调度指令, 与数据库同步 command_queue
  23. t_error = query_all_dispatch_command();
  24. if ( t_error != Error_code::SUCCESS )
  25. {
  26. return t_error;
  27. }
  28. //排序
  29. if ( outlet_ready == 0 )
  30. {
  31. //对调度指令进行排序, 选出最优解, 只比较存车
  32. t_error = sort_dispatch_command_for_park();
  33. }
  34. else
  35. {
  36. //对调度指令进行排序, 选出最优解, 比较存车和取车
  37. t_error = sort_dispatch_command_for_total();
  38. }
  39. if ( t_error != Error_code::SUCCESS )
  40. {
  41. m_dispatch_process_type = Common_data::DISPATCH_PROCESS_TYPE_UNKNOW;
  42. //没有找到合适的指令就返回NODATA, 然后设么也不做
  43. return t_error;
  44. }
  45. else
  46. {
  47. if ( m_dispatch_command_map[m_car_number_optimal].m_type == 1 )//存车
  48. {
  49. //注注注注注意了
  50. //存车自带感测信息,没有车位信息, 需要查询车位表,找到空车位,补全车位信息
  51. //取车自带车位信息,没有感测信息, 需要查询车辆表,补全车辆信息
  52. //查询空闲车位最优解, 存车指令 根据调度指令最优解 获取 空闲车位最优解
  53. t_error = query_dispatch_space_optimal();
  54. if ( t_error != Error_code::SUCCESS )
  55. {
  56. update_command_queue_for_statu(3);
  57. return t_error;
  58. }
  59. else
  60. {
  61. m_dispatch_process_type = Common_data::DISPATCH_PROCESS_STORE;
  62. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_id(m_dispatch_space_info.m_id);
  63. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_unit_id(m_dispatch_space_info.m_unit);
  64. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_floor(m_dispatch_space_info.m_floor);
  65. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_room_id(m_dispatch_space_info.m_subID);
  66. //更新 车位状态, 根据车位ID 写入车牌号即可
  67. t_error = update_parkspace_info_write_car_number();
  68. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  69. t_error = update_command_queue_for_statu(1);
  70. //制作存车表单
  71. t_error = create_park_table();
  72. LOG(INFO) << " create_park_table 创建存车任务单 = "<< m_park_table_msg.DebugString() << " --- " << this;
  73. return Error_code::SUCCESS;
  74. }
  75. }
  76. else if ( m_dispatch_command_map[m_car_number_optimal].m_type == 2 )//取车
  77. {
  78. //注注注注注意了
  79. //存车自带感测信息,没有车位信息, 需要查询车位表,找到空车位,补全车位信息
  80. //取车自带车位信息,没有感测信息, 需要查询车辆表,补全车辆信息
  81. //查询 取车的车辆感测信息 取车指令 根据key 查询感测信息
  82. t_error = query_dispatch_vehicle_for_primary_key();
  83. if ( t_error != Error_code::SUCCESS )
  84. {
  85. update_command_queue_for_statu(3);
  86. return t_error;
  87. }
  88. else
  89. {
  90. //补充出口id
  91. m_dispatch_command_map[m_car_number_optimal].m_export_id = outlet_ready;
  92. m_dispatch_process_type = Common_data::DISPATCH_PROCESS_PICKUP;
  93. m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg = m_dispatch_vehicle_info.m_actually_measure_info_msg;
  94. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  95. t_error = update_command_queue_for_statu(1);
  96. //制作取车表单
  97. t_error = create_pick_table(outlet_ready);
  98. LOG(INFO) << " create_pick_table 创建取车车任务单 = "<< m_pick_table_msg.DebugString() << " --- " << this;
  99. }
  100. }
  101. else
  102. {
  103. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  104. " fun error ");
  105. }
  106. }
  107. return Error_code::SUCCESS;
  108. }
  109. //调度完成后, 向数据库发送答复的相关操作
  110. Error_manager Dispatch_command::dispatch_response_to_sql(Error_manager dispatch_result)
  111. {
  112. Error_manager t_error;
  113. if ( dispatch_result == Error_code::SUCCESS )
  114. {
  115. //调度成功, 完善数据库
  116. if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_STORE )
  117. {
  118. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_STORE 存车答复成功 = "<< t_error << " --- " << this;
  119. //增加 车辆表, 存车指令 完成后添加车辆信息
  120. t_error = insert_vehicle_for_car_number();
  121. //更新 指令队列, 根据车牌号 删除指令
  122. t_error = delete_command_queue_for_statu();
  123. }
  124. else if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_PICKUP )
  125. {
  126. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_PICKUP 取车答复成功 = "<< t_error << " --- " << this;
  127. //删除 车辆表, 取车指令 完成后删除车辆信息
  128. t_error = delete_vehicle_for_car_number();
  129. //更新 车位状态, 找到车牌号, 写NULL
  130. t_error = update_parkspace_info_clear_car_number();
  131. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  132. t_error = update_command_queue_for_statu(2);
  133. // LOG(INFO) << "llllllllllllllllllllllllllllllllllllllllll respons = "<< t_error << " --- " << this;
  134. }
  135. else if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_REALLOCATE )
  136. {
  137. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_REALLOCATE 改道答复成功 = "<< t_error << " --- " << this;
  138. //增加 车辆表, 存车指令 完成后添加车辆信息
  139. t_error = insert_vehicle_for_car_number();
  140. //更新 指令队列, 根据车牌号 删除指令
  141. t_error = delete_command_queue_for_statu();
  142. }
  143. else if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_REVOCATION )
  144. {
  145. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_REVOCATION 撤销答复成功 = "<< t_error << " --- " << this;
  146. //删除 车辆表, 取车指令 完成后删除车辆信息
  147. t_error = delete_vehicle_for_car_number();
  148. //更新 车位状态, 找到车牌号, 写NULL
  149. t_error = update_parkspace_info_clear_car_number();
  150. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  151. t_error = update_command_queue_for_statu(2);
  152. // LOG(INFO) << "llllllllllllllllllllllllllllllllllllllllll respons = "<< t_error << " --- " << this;
  153. }
  154. else
  155. {
  156. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  157. " fun error ");
  158. }
  159. return t_error;
  160. }
  161. else
  162. {
  163. //调度失败, 回退 数据库
  164. if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_STORE )
  165. {
  166. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_STORE 存车答复失败 = "<< t_error << " --- " << this;
  167. //更新 车位状态, 找到车牌号, 写NULL
  168. update_parkspace_info_clear_car_number();
  169. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  170. update_command_queue_for_statu(3);
  171. }
  172. else if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_PICKUP )
  173. {
  174. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_PICKUP 取车答复失败 = "<< t_error << " --- " << this;
  175. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  176. update_command_queue_for_statu(3);
  177. }
  178. else if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_REALLOCATE )
  179. {
  180. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_STORE 改道答复失败 = "<< t_error << " --- " << this;
  181. //更新 车位状态, 找到车牌号, 写NULL
  182. update_parkspace_info_clear_car_number();
  183. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  184. update_command_queue_for_statu(3);
  185. }
  186. else if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_REVOCATION )
  187. {
  188. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_PICKUP 撤销答复失败 = "<< t_error << " --- " << this;
  189. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  190. update_command_queue_for_statu(3);
  191. }
  192. else
  193. {
  194. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  195. " fun error ");
  196. }
  197. }
  198. return Error_code::SUCCESS;
  199. }
  200. //调度 , 向数据库 重新分配车位,
  201. Error_manager Dispatch_command::dispatch_reallocate_to_sql(Common_data::Car_type reallocate_car_type, int outlet_ready)
  202. {
  203. Error_manager t_error;
  204. m_outlet_ready = outlet_ready;
  205. //把之前申请的车位清除 //更新 车位状态, 找到车牌号, 写NULL
  206. t_error = Dispatch_command::update_parkspace_info_clear_car_number();
  207. //重新申请车位
  208. //查询空闲车位最优解, 存车指令 根据调度指令最优解 获取 空闲车位最优解
  209. t_error = query_dispatch_space_optimal(reallocate_car_type);
  210. if ( t_error != Error_code::SUCCESS )
  211. {
  212. //没找到车位, 就把车放到出口
  213. if ( outlet_ready != 0 )
  214. {
  215. m_dispatch_process_type = Common_data::DISPATCH_PROCESS_REVOCATION;
  216. //补充出口id
  217. m_dispatch_command_map[m_car_number_optimal].m_export_id = outlet_ready;
  218. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_id(0);
  219. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_unit_id(0);
  220. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_floor(0);
  221. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_room_id(0);
  222. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  223. // t_error = update_command_queue_for_statu(1);
  224. //制作取车表单
  225. t_error = create_pick_table(outlet_ready);
  226. LOG(INFO) << " create_pick_table 撤销存车, 取车到出口任务单 = "<< m_pick_table_msg.DebugString() << " --- " << this;
  227. return t_error;
  228. }
  229. else
  230. {
  231. //无限等待, 等待出口空闲
  232. return Error_code::NODATA;
  233. }
  234. }
  235. else
  236. {
  237. m_dispatch_process_type = Common_data::DISPATCH_PROCESS_REALLOCATE;
  238. //找到新的车位, 重新执行任务
  239. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_id(m_dispatch_space_info.m_id);
  240. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_unit_id(m_dispatch_space_info.m_unit);
  241. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_floor(m_dispatch_space_info.m_floor);
  242. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_room_id(m_dispatch_space_info.m_subID);
  243. //更新 车位状态, 根据车位ID 写入车牌号即可
  244. t_error = update_parkspace_info_write_car_number();
  245. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  246. // t_error = update_command_queue_for_statu(1);
  247. //制作存车表单
  248. t_error = create_park_table();
  249. LOG(INFO) << " create_park_table 改道存车, 存车新车位任务单 = "<< m_park_table_msg.DebugString() << " --- " << this;
  250. }
  251. return Error_code::SUCCESS;
  252. }
  253. //检查出口是否空闲, 检查指令队列的取车完成的出口id是否存在, 不存在就是空闲,返回成功
  254. Error_manager Dispatch_command::check_export_id_is_ready(int export_id)
  255. {
  256. //检查指令队列, 查询指定单元的取车完成状态指令的 出口id是否存在
  257. char check_export_id_sql[1024];
  258. memset(check_export_id_sql, 0, 1024);
  259. sprintf(check_export_id_sql,"select * from command_queue where statu = 2 and export_id = %d",export_id);
  260. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  261. Error_manager t_error = Database_controller::get_instance_pointer()->sql_query(check_export_id_sql, tp_result);
  262. if(t_error == Error_code::SUCCESS)
  263. {
  264. if (tp_result == nullptr)
  265. {
  266. return DB_RESULT_SET_EMPTY;
  267. }
  268. //如果存在, 就报错, 不存在就是空闲,返回成功
  269. if ( tp_result->next() )
  270. {
  271. return Error_manager(Error_code::DB_QUERY_OUTLET_OCCUPY, Error_level::MINOR_ERROR,
  272. " check_export_id_is_ready fun error, 数据库 查询出口被占用 ");
  273. }
  274. else
  275. {
  276. return Error_code::SUCCESS;
  277. }
  278. }
  279. else
  280. {
  281. return t_error;
  282. }
  283. return Error_code::SUCCESS;
  284. }
  285. //更新调度指令, 与数据库同步 command_queue
  286. Error_manager Dispatch_command::query_all_dispatch_command()
  287. {
  288. //从command_queue获取所有排队的指令,
  289. char query_all_dispatch_command_sql[1024];
  290. memset(query_all_dispatch_command_sql, 0, 1024);
  291. sprintf(query_all_dispatch_command_sql,"select * from command_queue where statu = 0 and unit = %d",m_unit);
  292. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  293. Error_manager t_error = Database_controller::get_instance_pointer()->sql_query(query_all_dispatch_command_sql, tp_result);
  294. m_dispatch_command_map.clear();
  295. if(t_error == Error_code::SUCCESS)
  296. {
  297. if (tp_result == nullptr)
  298. {
  299. return DB_RESULT_SET_EMPTY;
  300. }
  301. //循环检查所有行
  302. while (tp_result->next())
  303. {
  304. Dispatch_command_info t_dispatch_command_info;
  305. char t_error_buf[1024];
  306. memset(t_error_buf, 0, 1024);
  307. try
  308. {
  309. //解析数据
  310. t_dispatch_command_info.m_car_number = tp_result->getString("car_number");
  311. t_dispatch_command_info.m_primary_key = tp_result->getString("primary_key");
  312. t_dispatch_command_info.m_unit = tp_result->getInt("unit");
  313. t_dispatch_command_info.m_queue_id = tp_result->getInt("queue_id");
  314. t_dispatch_command_info.m_type = tp_result->getInt("type");
  315. t_dispatch_command_info.m_statu = tp_result->getInt("statu");
  316. t_dispatch_command_info.m_space_info = tp_result->getString("space_info");
  317. t_dispatch_command_info.m_measure_info = tp_result->getString("measure_info");
  318. // t_dispatch_command_info.m_export_id = tp_result->getInt("export_id");
  319. t_dispatch_command_info.m_export_id = 0;
  320. //m_type指令类型, 0无效, 1存车, 2取车,
  321. if ( t_dispatch_command_info.m_type == 1)
  322. {
  323. //存车, 数据库特有 雷达信息, 没有车位信息, 需要根据车高,再去车位表申请车位
  324. if(! google::protobuf::TextFormat::ParseFromString(t_dispatch_command_info.m_measure_info, &t_dispatch_command_info.m_measure_info_msg))
  325. {
  326. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  327. "ParseFromString fun error, m_measure_info ");
  328. }
  329. t_dispatch_command_info.m_useless_distance = m_device_floor-1;
  330. }
  331. else if ( t_dispatch_command_info.m_type == 2 )
  332. {
  333. //取车, 数据库特有车位信息
  334. if(! google::protobuf::TextFormat::ParseFromString(t_dispatch_command_info.m_space_info, &t_dispatch_command_info.m_parkspace_info_msg))
  335. {
  336. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  337. "ParseFromString fun error, m_space_info ");
  338. }
  339. t_dispatch_command_info.m_useless_distance = t_dispatch_command_info.m_parkspace_info_msg.floor()-m_device_floor;
  340. }
  341. else
  342. {
  343. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  344. "command_queue m_type error ");
  345. }
  346. if ( t_dispatch_command_info.m_useless_distance <0 )
  347. {
  348. t_dispatch_command_info.m_useless_distance = 0-t_dispatch_command_info.m_useless_distance;
  349. }
  350. m_dispatch_command_map[t_dispatch_command_info.m_car_number] = t_dispatch_command_info;
  351. }
  352. catch (sql::SQLException &e)
  353. {
  354. /* Use what() (derived from std::runtime_error) to fetch the error message */
  355. sprintf(t_error_buf, "# ERR: %s\n (MySQL error code: %d, SQLState: %s", e.what(), e.getErrorCode(),
  356. e.getSQLState().c_str());
  357. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, t_error_buf);
  358. }
  359. catch (std::runtime_error &e)
  360. {
  361. sprintf(t_error_buf, "# ERR: %s\n ERR: runtime_error in %s ", e.what(), __FILE__);
  362. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, t_error_buf);
  363. }
  364. }
  365. return SUCCESS;
  366. }
  367. else
  368. {
  369. return t_error;
  370. }
  371. return Error_code::SUCCESS;
  372. }
  373. //对调度指令进行排序, 选出最优解, 比较存车和取车
  374. Error_manager Dispatch_command::sort_dispatch_command_for_total()
  375. {
  376. int t_optimal_loss=0x7fffffff; //最优loss值
  377. m_car_number_optimal.clear();
  378. for (auto iter = m_dispatch_command_map.begin(); iter != m_dispatch_command_map.end(); ++iter)
  379. {
  380. //loss = 空跑路程 + 排队编号, 求最小值
  381. int t_current_loss = iter->second.m_useless_distance + iter->second.m_queue_id;
  382. if ( t_optimal_loss > t_current_loss )
  383. {
  384. t_optimal_loss = t_current_loss;
  385. m_car_number_optimal = iter->first;
  386. }
  387. }
  388. if ( m_car_number_optimal.empty() )
  389. {
  390. return Error_code::NODATA;
  391. }
  392. return Error_code::SUCCESS;
  393. }
  394. //对调度指令进行排序, 选出最优解, 只比较存车
  395. Error_manager Dispatch_command::sort_dispatch_command_for_park()
  396. {
  397. int t_optimal_loss=0x7fffffff; //最优loss值
  398. m_car_number_optimal.clear();
  399. for (auto iter = m_dispatch_command_map.begin(); iter != m_dispatch_command_map.end(); ++iter)
  400. {
  401. //loss = 空跑路程 + 排队编号, 求最小值
  402. int t_current_loss = iter->second.m_useless_distance + iter->second.m_queue_id;
  403. if ( t_optimal_loss > t_current_loss && iter->second.m_type == 1)
  404. {
  405. t_optimal_loss = t_current_loss;
  406. m_car_number_optimal = iter->first;
  407. }
  408. }
  409. if ( m_car_number_optimal.empty() )
  410. {
  411. return Error_code::NODATA;
  412. }
  413. return Error_code::SUCCESS;
  414. }
  415. //存车指令 获取 指定车高 指定单元 的车位信息,用于车位分配
  416. Error_manager Dispatch_command::query_specify_height_unit_parkspace_info(int unit, float height, Dispatch_space_info & dispatch_space_info)
  417. {
  418. //查询车位表
  419. char query_parkspace_sql[1024];
  420. memset(query_parkspace_sql, 0, 1024);
  421. int t_statu = 0; //车位状态, 0可用, 1故障
  422. sprintf(query_parkspace_sql,"select * from space where car_number is NULL and ABS(height- %f) < 1e-5 and statu = %d and unit = %d",height,t_statu,unit);
  423. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  424. Error_manager ec = Database_controller::get_instance_pointer()->sql_query(query_parkspace_sql, tp_result);
  425. if(ec == SUCCESS)
  426. {
  427. if(tp_result == nullptr)
  428. {
  429. return DB_RESULT_SET_EMPTY;
  430. }
  431. //只取第一条结果, 默认是id最小的,
  432. if (tp_result->next())
  433. {
  434. char buf[1024];
  435. memset(buf, 0, 1024);
  436. try
  437. {
  438. //解析数据
  439. dispatch_space_info.m_id = tp_result->getInt("id");
  440. dispatch_space_info.m_floor = tp_result->getInt("floor");
  441. dispatch_space_info.m_subID = tp_result->getInt("subID");
  442. dispatch_space_info.m_height = tp_result->getDouble("height");
  443. dispatch_space_info.m_car_number = tp_result->getString("car_number");
  444. dispatch_space_info.m_unit = tp_result->getInt("unit");
  445. dispatch_space_info.m_statu = tp_result->getInt("statu");
  446. }
  447. catch (sql::SQLException &e)
  448. {
  449. /* Use what() (derived from std::runtime_error) to fetch the error message */
  450. sprintf(buf, "# ERR: %s\n (MySQL error code: %d, SQLState: %s", e.what(), e.getErrorCode(), e.getSQLState().c_str());
  451. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  452. }
  453. catch (std::runtime_error &e)
  454. {
  455. sprintf(buf, "# ERR: %s\n ERR: runtime_error in %s ", e.what(), __FILE__);
  456. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  457. }
  458. }
  459. else
  460. {
  461. return Error_manager(Error_code::DB_NOT_QUERY_EMPTY_PARKSPACE, Error_level::MINOR_ERROR,
  462. "数据库未查询到空车位 Parkspace_operating_function::query_one_empty_parkspace error ");
  463. }
  464. return SUCCESS;
  465. }
  466. else
  467. {
  468. return ec;
  469. }
  470. return SUCCESS;
  471. }
  472. //查询空闲车位最优解, 存车指令 根据调度指令最优解 获取 空闲车位最优解
  473. Error_manager Dispatch_command::query_dispatch_space_optimal()
  474. {
  475. Error_manager t_error;
  476. int t_unit = m_dispatch_command_map[m_car_number_optimal].m_unit;
  477. float t_height = m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.height();
  478. //小车对应小车位 中车对应中车位 大车对应大车位
  479. if ( 0 < t_height && t_height <= CAR_HEIGHT_LIMIT_SMALL )
  480. {
  481. t_error = query_specify_height_unit_parkspace_info(t_unit, CAR_HEIGHT_LIMIT_SMALL, m_dispatch_space_info);
  482. if ( t_error == Error_code::SUCCESS )
  483. {
  484. m_car_type = Common_data::Car_type::MIN_CAR;
  485. return t_error;
  486. }
  487. }
  488. if ( t_height <= CAR_HEIGHT_LIMIT_MIDDLE )
  489. {
  490. t_error = query_specify_height_unit_parkspace_info(t_unit, CAR_HEIGHT_LIMIT_MIDDLE, m_dispatch_space_info);
  491. if ( t_error == Error_code::SUCCESS )
  492. {
  493. m_car_type = Common_data::Car_type::MID_CAR;
  494. return t_error;
  495. }
  496. }
  497. if ( t_height <= CAR_HEIGHT_LIMIT_BIG )
  498. {
  499. t_error = query_specify_height_unit_parkspace_info(t_unit, CAR_HEIGHT_LIMIT_BIG, m_dispatch_space_info);
  500. if ( t_error == Error_code::SUCCESS )
  501. {
  502. m_car_type = Common_data::Car_type::BIG_CAR;
  503. return t_error;
  504. }
  505. }
  506. return Error_manager(Error_code::DB_NOT_QUERY_EMPTY_PARKSPACE, Error_level::MINOR_ERROR,
  507. " query_dispatch_space_optimal error ");
  508. }
  509. //查询空闲车位最优解, 存车指令 根据调度指令最优解 获取 空闲车位最优解
  510. Error_manager Dispatch_command::query_dispatch_space_optimal(Common_data::Car_type reallocate_car_type)
  511. {
  512. Error_manager t_error;
  513. int t_unit = m_dispatch_command_map[m_car_number_optimal].m_unit;
  514. // float t_height = m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.height();
  515. //小车对应小车位 中车对应中车位 大车对应大车位
  516. if ( reallocate_car_type == Common_data::Car_type::MIN_CAR )
  517. {
  518. t_error = query_specify_height_unit_parkspace_info(t_unit, CAR_HEIGHT_LIMIT_SMALL, m_dispatch_space_info);
  519. if ( t_error == Error_code::SUCCESS )
  520. {
  521. m_car_type = Common_data::Car_type::MIN_CAR;
  522. return t_error;
  523. }
  524. }
  525. if ( reallocate_car_type == Common_data::Car_type::MIN_CAR ||
  526. reallocate_car_type == Common_data::Car_type::MID_CAR )
  527. {
  528. t_error = query_specify_height_unit_parkspace_info(t_unit, CAR_HEIGHT_LIMIT_MIDDLE, m_dispatch_space_info);
  529. if ( t_error == Error_code::SUCCESS )
  530. {
  531. m_car_type = Common_data::Car_type::MID_CAR;
  532. return t_error;
  533. }
  534. }
  535. if ( reallocate_car_type == Common_data::Car_type::MIN_CAR ||
  536. reallocate_car_type == Common_data::Car_type::MID_CAR ||
  537. reallocate_car_type == Common_data::Car_type::BIG_CAR )
  538. {
  539. t_error = query_specify_height_unit_parkspace_info(t_unit, CAR_HEIGHT_LIMIT_BIG, m_dispatch_space_info);
  540. if ( t_error == Error_code::SUCCESS )
  541. {
  542. m_car_type = Common_data::Car_type::BIG_CAR;
  543. return t_error;
  544. }
  545. }
  546. return Error_manager(Error_code::DB_NOT_QUERY_EMPTY_PARKSPACE, Error_level::MINOR_ERROR,
  547. " query_dispatch_space_optimal error ");
  548. }
  549. //查询 取车的车位 取车指令 根据车牌号 查询对应的车位
  550. Error_manager Dispatch_command::query_dispatch_space_for_car_number()
  551. {
  552. //查询车位表
  553. char query_parkspace_sql[1024];
  554. memset(query_parkspace_sql, 0, 1024);
  555. int t_statu = 0; //车位状态, 0可用, 1故障
  556. sprintf(query_parkspace_sql,"select * from space where car_number = '%s' ",m_dispatch_command_map[m_car_number_optimal].m_car_number.c_str());
  557. // std::cout<<"query_parkspace_sql = "<<query_parkspace_sql<<std::endl;
  558. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  559. Error_manager ec = Database_controller::get_instance_pointer()->sql_query(query_parkspace_sql, tp_result);
  560. if(ec == SUCCESS)
  561. {
  562. if(tp_result == nullptr)
  563. {
  564. return DB_RESULT_SET_EMPTY;
  565. }
  566. //只取第一条结果, 默认是id最小的,
  567. if (tp_result->next())
  568. {
  569. char buf[1024];
  570. memset(buf, 0, 1024);
  571. try
  572. {
  573. //解析数据
  574. m_dispatch_space_info.m_id = tp_result->getInt("id");
  575. m_dispatch_space_info.m_floor = tp_result->getInt("floor");
  576. m_dispatch_space_info.m_subID = tp_result->getInt("subID");
  577. m_dispatch_space_info.m_height = tp_result->getDouble("height");
  578. m_dispatch_space_info.m_car_number = tp_result->getString("car_number");
  579. m_dispatch_space_info.m_unit = tp_result->getInt("unit");
  580. m_dispatch_space_info.m_statu = tp_result->getInt("statu");
  581. }
  582. catch (sql::SQLException &e)
  583. {
  584. /* Use what() (derived from std::runtime_error) to fetch the error message */
  585. sprintf(buf, "# ERR: %s\n (MySQL error code: %d, SQLState: %s", e.what(), e.getErrorCode(), e.getSQLState().c_str());
  586. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  587. }
  588. catch (std::runtime_error &e)
  589. {
  590. sprintf(buf, "# ERR: %s\n ERR: runtime_error in %s ", e.what(), __FILE__);
  591. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  592. }
  593. }
  594. else
  595. {
  596. return Error_manager(Error_code::DB_QUERY_NOT_DATA, Error_level::MINOR_ERROR,
  597. "数据库未查询到数据 Parkspace_operating_function::query_one_parkspace_with_license error ");
  598. }
  599. return SUCCESS;
  600. }
  601. else
  602. {
  603. return ec;
  604. }
  605. return SUCCESS;
  606. }
  607. //查询 取车的车辆感测信息 取车指令 根据key 查询感测信息
  608. Error_manager Dispatch_command::query_dispatch_vehicle_for_primary_key()
  609. {
  610. //查询 车辆表
  611. char query_parkspace_sql[1024];
  612. memset(query_parkspace_sql, 0, 1024);
  613. int t_statu = 0; //车位状态, 0可用, 1故障
  614. sprintf(query_parkspace_sql,"select * from vehicle where primary_key = '%s' ",m_dispatch_command_map[m_car_number_optimal].m_primary_key.c_str());
  615. // std::cout<<"query_parkspace_sql = "<<query_parkspace_sql<<std::endl;
  616. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  617. Error_manager ec = Database_controller::get_instance_pointer()->sql_query(query_parkspace_sql, tp_result);
  618. if(ec == SUCCESS)
  619. {
  620. if(tp_result == nullptr)
  621. {
  622. return DB_RESULT_SET_EMPTY;
  623. }
  624. //只取第一条结果, 默认是id最小的,
  625. if (tp_result->next())
  626. {
  627. char buf[1024];
  628. memset(buf, 0, 1024);
  629. try
  630. {
  631. //解析数据
  632. m_dispatch_vehicle_info.m_car_number = tp_result->getString("car_number");
  633. m_dispatch_vehicle_info.m_primary_key = tp_result->getString("primary_key");
  634. m_dispatch_vehicle_info.m_actually_measure_info = tp_result->getString("actually_measure_info");
  635. //取车, 数据库特有车位信息
  636. if(! google::protobuf::TextFormat::ParseFromString(m_dispatch_vehicle_info.m_actually_measure_info, &m_dispatch_vehicle_info.m_actually_measure_info_msg))
  637. {
  638. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  639. "ParseFromString fun error, m_space_info ");
  640. }
  641. }
  642. catch (sql::SQLException &e)
  643. {
  644. /* Use what() (derived from std::runtime_error) to fetch the error message */
  645. sprintf(buf, "# ERR: %s\n (MySQL error code: %d, SQLState: %s", e.what(), e.getErrorCode(), e.getSQLState().c_str());
  646. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  647. }
  648. catch (std::runtime_error &e)
  649. {
  650. sprintf(buf, "# ERR: %s\n ERR: runtime_error in %s ", e.what(), __FILE__);
  651. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  652. }
  653. }
  654. else
  655. {
  656. return Error_manager(Error_code::DB_QUERY_NOT_DATA, Error_level::MINOR_ERROR,
  657. "数据库未查询到数据 Parkspace_operating_function::query_one_parkspace_with_license error ");
  658. }
  659. return SUCCESS;
  660. }
  661. else
  662. {
  663. return ec;
  664. }
  665. return SUCCESS;
  666. }
  667. //更新 车位状态, 根据车位ID 写入车牌号即可
  668. Error_manager Dispatch_command::update_parkspace_info_write_car_number()
  669. {
  670. //执行sql操作
  671. char update_space_sql[1024];
  672. memset(update_space_sql, 0, 1024);
  673. sprintf(update_space_sql, "update space set car_number = '%s' where id = %d",
  674. m_dispatch_command_map[m_car_number_optimal].m_car_number.c_str(),
  675. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.id() );
  676. // m_dispatch_space_info.m_id);
  677. Error_manager ec = Database_controller::get_instance_pointer()->sql_update(update_space_sql);
  678. return ec;
  679. }
  680. //更新 车位状态, 找到车牌号, 写NULL
  681. Error_manager Dispatch_command::update_parkspace_info_clear_car_number()
  682. {
  683. //执行sql操作
  684. char update_space_sql[1024];
  685. memset(update_space_sql, 0, 1024);
  686. sprintf(update_space_sql, "update space set car_number = null where car_number = '%s' ",
  687. m_dispatch_command_map[m_car_number_optimal].m_car_number.c_str());
  688. Error_manager ec = Database_controller::get_instance_pointer()->sql_update(update_space_sql);
  689. return ec;
  690. }
  691. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  692. Error_manager Dispatch_command::update_command_queue_for_statu(int statu)
  693. {
  694. char update_command_sql[1024];
  695. memset(update_command_sql, 0, 1024);
  696. sprintf(update_command_sql, "update command_queue set statu = %d, export_id = %d where car_number = '%s'",
  697. statu, m_dispatch_command_map[m_car_number_optimal].m_export_id,
  698. m_dispatch_command_map[m_car_number_optimal].m_car_number.c_str());
  699. LOG(INFO) << "jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj update_command_sql = "<< update_command_sql << " --- " << this;
  700. Error_manager ec = Database_controller::get_instance_pointer()->sql_update(update_command_sql);
  701. return ec;
  702. }
  703. //更新 指令队列, 根据车牌号 删除指令
  704. Error_manager Dispatch_command::delete_command_queue_for_statu()
  705. {
  706. char delete_command_sql[1024];
  707. memset(delete_command_sql, 0, 1024);
  708. sprintf(delete_command_sql, "delete from command_queue where car_number = '%s'",
  709. m_dispatch_command_map[m_car_number_optimal].m_car_number.c_str());
  710. Error_manager ec = Database_controller::get_instance_pointer()->sql_delete(delete_command_sql);
  711. return ec;
  712. }
  713. //制作存车表单
  714. Error_manager Dispatch_command::create_park_table()
  715. {
  716. park_table t_park_table;
  717. t_park_table.mutable_statu()->set_execute_statu(eNormal);
  718. t_park_table.set_queue_id(m_dispatch_command_map[m_car_number_optimal].m_queue_id);
  719. t_park_table.set_car_number(m_dispatch_command_map[m_car_number_optimal].m_car_number);
  720. t_park_table.set_unit_id(m_dispatch_command_map[m_car_number_optimal].m_unit);
  721. t_park_table.set_primary_key(m_dispatch_command_map[m_car_number_optimal].m_primary_key);
  722. t_park_table.mutable_entrance_measure_info()->CopyFrom(m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg);
  723. t_park_table.mutable_allocated_space_info()->CopyFrom(m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg);
  724. //根据雷达x坐标, 计算入口id
  725. int t_terminal = 0;
  726. if (m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.cx()<0)
  727. {
  728. t_terminal = m_dispatch_id*2+1;
  729. }
  730. else if(m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.cx()>0)
  731. {
  732. t_terminal = m_dispatch_id*2+2;
  733. }
  734. t_park_table.set_terminal_id(t_terminal);
  735. // std::cout << " huli test :::: " << " iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii m_park_table_msg.entrance_measure_info().cx() = " << m_park_table_msg.entrance_measure_info().cx() << std::endl;
  736. // std::cout << " huli test :::: " << " iiiiiiiiiiiiiiiiiiiiiiiiiiiiii t_terminal = " << t_terminal << std::endl;
  737. LOG(INFO) << " m_park_table_msg.entrance_measure_info().cx() = "<< m_park_table_msg.entrance_measure_info().cx() << " --- " << this;
  738. LOG(INFO) << " t_terminal = "<< t_terminal << " --- " << this;
  739. LOG(INFO) << " m_device_floor = "<< m_device_floor << " --- " << this;
  740. LOG(INFO) << " m_dispatch_id = "<< m_dispatch_id << " --- " << this;
  741. LOG(INFO) << " m_unit = "<< m_unit << " --- " << this;
  742. LOG(INFO) << " m_outlet_ready = "<< m_outlet_ready << " --- " << this;
  743. m_park_table_msg = t_park_table;
  744. return Error_code::SUCCESS;
  745. }
  746. //制作取车表单
  747. Error_manager Dispatch_command::create_pick_table(int outlet_ready)
  748. {
  749. pick_table t_pick_table;
  750. t_pick_table.mutable_statu()->set_execute_statu(eNormal);
  751. t_pick_table.set_queue_id(m_dispatch_command_map[m_car_number_optimal].m_queue_id);
  752. t_pick_table.set_car_number(m_dispatch_command_map[m_car_number_optimal].m_car_number);
  753. t_pick_table.set_unit_id(m_dispatch_command_map[m_car_number_optimal].m_unit);
  754. t_pick_table.set_primary_key(m_dispatch_command_map[m_car_number_optimal].m_primary_key);
  755. t_pick_table.mutable_actually_measure_info()->CopyFrom(m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg);
  756. t_pick_table.mutable_actually_space_info()->CopyFrom(m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg);
  757. t_pick_table.set_terminal_id(outlet_ready);
  758. LOG(INFO) << " outlet_ready = "<< outlet_ready << " --- " << this;
  759. LOG(INFO) << " m_device_floor = "<< m_device_floor << " --- " << this;
  760. LOG(INFO) << " m_dispatch_id = "<< m_dispatch_id << " --- " << this;
  761. LOG(INFO) << " m_unit = "<< m_unit << " --- " << this;
  762. LOG(INFO) << " m_outlet_ready = "<< m_outlet_ready << " --- " << this;
  763. m_pick_table_msg = t_pick_table;
  764. return Error_code::SUCCESS;
  765. }
  766. //增加 车辆表, 存车指令 完成后添加车辆信息
  767. Error_manager Dispatch_command::insert_vehicle_for_car_number()
  768. {
  769. char insert_vehicle_sql[1024];
  770. memset(insert_vehicle_sql, 0, 1024);
  771. sprintf(insert_vehicle_sql, "INSERT INTO vehicle (car_number,primary_key,actually_measure_info) values ('%s','%s','%s')",
  772. m_car_number_optimal.c_str(), m_dispatch_command_map[m_car_number_optimal].m_primary_key.c_str(),
  773. m_dispatch_command_map[m_car_number_optimal].m_measure_info.c_str() );
  774. Error_manager ec = Database_controller::get_instance_pointer()->sql_insert(insert_vehicle_sql);
  775. return ec;
  776. }
  777. //删除 车辆表, 取车指令 完成后删除车辆信息
  778. Error_manager Dispatch_command::delete_vehicle_for_car_number()
  779. {
  780. char delete_vehicle_sql[1024];
  781. memset(delete_vehicle_sql, 0, 1024);
  782. sprintf(delete_vehicle_sql, "delete from vehicle where car_number = '%s'",
  783. m_dispatch_command_map[m_car_number_optimal].m_car_number.c_str());
  784. Error_manager ec = Database_controller::get_instance_pointer()->sql_delete(delete_vehicle_sql);
  785. return ec;
  786. }