dispatch_command.cpp 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344
  1. #include "dispatch_command.h"
  2. #include <google/protobuf/text_format.h>
  3. #include "../tool/time_tool.h"
  4. #include "dispatch_manager.h"
  5. Dispatch_command::Dispatch_command()
  6. {
  7. m_dispatch_command_status = E_DISPATCH_COMMAND_UNKNOW;
  8. m_unit = 0;
  9. m_device_floor = 0;
  10. m_dispatch_process_type = Common_data::DISPATCH_PROCESS_TYPE_UNKNOW;
  11. m_car_type = Common_data::Car_type::UNKNOW_CAR_TYPE;
  12. }
  13. Dispatch_command::~Dispatch_command()
  14. {
  15. }
  16. //调度开始前, 向数据库发送请求的相关操作, 输入 穿梭机所在的楼层, 调度id 0~2, 空闲出口id, 如果不是0,就表示有空闲的出口
  17. Error_manager Dispatch_command::dispatch_request_to_sql(int device_floor, int dispatch_id, int outlet_ready)
  18. {
  19. std::unique_lock<std::mutex> t_lock(m_lock);
  20. Error_manager t_error;
  21. m_device_floor = device_floor;
  22. m_dispatch_id = dispatch_id;
  23. m_unit = dispatch_id+1;
  24. m_outlet_ready = outlet_ready;
  25. //获取调度指令, 与数据库同步 command_queue
  26. t_error = query_all_dispatch_command(0);
  27. if ( t_error != Error_code::SUCCESS )
  28. {
  29. return t_error;
  30. }
  31. //排序
  32. if ( outlet_ready == 0 )
  33. {
  34. //对调度指令进行排序, 选出最优解, 只比较存车
  35. t_error = sort_dispatch_command_for_park();
  36. }
  37. else
  38. {
  39. //对调度指令进行排序, 选出最优解, 比较存车和取车
  40. t_error = sort_dispatch_command_for_total();
  41. }
  42. if ( t_error != Error_code::SUCCESS )
  43. {
  44. m_dispatch_process_type = Common_data::DISPATCH_PROCESS_TYPE_UNKNOW;
  45. //没有找到合适的指令就返回NODATA, 然后设么也不做
  46. return t_error;
  47. }
  48. else
  49. {
  50. if ( m_dispatch_command_map[m_car_number_optimal].m_type == 1 )//存车
  51. {
  52. //注注注注注意了
  53. //存车自带感测信息,没有车位信息, 需要查询车位表,找到空车位,补全车位信息
  54. //取车自带车位信息,没有感测信息, 需要查询车辆表,补全车辆信息
  55. //查询空闲车位最优解, 存车指令 根据调度指令最优解 获取 空闲车位最优解
  56. t_error = query_dispatch_space_optimal();
  57. if ( t_error != Error_code::SUCCESS )
  58. {
  59. update_command_queue_for_statu(3);
  60. return t_error;
  61. }
  62. else
  63. {
  64. m_dispatch_process_type = Common_data::DISPATCH_PROCESS_STORE;
  65. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_id(m_dispatch_space_info.m_id);
  66. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_unit_id(m_dispatch_space_info.m_unit);
  67. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_floor(m_dispatch_space_info.m_floor);
  68. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_room_id(m_dispatch_space_info.m_subID);
  69. //更新 车位状态, 根据车位ID 写入车牌号即可
  70. t_error = update_parkspace_info_write_car_number();
  71. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  72. t_error = update_command_queue_for_statu(1);
  73. //制作存车表单
  74. t_error = create_park_table();
  75. //增加 记录表, 存车指令 完成后添加存车记录
  76. t_error = insert_record_for_park_start();
  77. LOG(INFO) << " create_park_table 创建存车任务单 = "<< m_park_table_msg.DebugString() << " --- " << this;
  78. return Error_code::SUCCESS;
  79. }
  80. }
  81. else if ( m_dispatch_command_map[m_car_number_optimal].m_type == 2 )//取车
  82. {
  83. //注注注注注意了
  84. //存车自带感测信息,没有车位信息, 需要查询车位表,找到空车位,补全车位信息
  85. //取车自带车位信息,没有感测信息, 需要查询车辆表,补全车辆信息
  86. //查询 取车的车辆感测信息 取车指令 根据key 查询感测信息
  87. t_error = query_dispatch_vehicle_for_primary_key();
  88. if ( t_error != Error_code::SUCCESS )
  89. {
  90. update_command_queue_for_statu(3);
  91. return t_error;
  92. }
  93. else
  94. {
  95. //补充出口id
  96. m_dispatch_command_map[m_car_number_optimal].m_export_id = outlet_ready;
  97. m_dispatch_process_type = Common_data::DISPATCH_PROCESS_PICKUP;
  98. //查询 取车的车辆plc感测信息 取车指令 根据key 查询感测信息
  99. t_error = query_dispatch_vehicle_for_primary_key_ex();
  100. if ( t_error == Error_code::SUCCESS &&
  101. m_dispatch_vehicle_info.m_plc_measure_info_msg.wheelbase()>1)
  102. {
  103. m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg = m_dispatch_vehicle_info.m_plc_measure_info_msg;
  104. }
  105. else
  106. {
  107. m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg = m_dispatch_vehicle_info.m_actually_measure_info_msg;
  108. }
  109. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  110. t_error = update_command_queue_for_statu(1);
  111. //制作取车表单
  112. t_error = create_pick_table(outlet_ready);
  113. //更新 记录表, 取车指令 完成后更新取车记录
  114. t_error = updata_record_for_pick_start();
  115. LOG(INFO) << " create_pick_table 创建取车车任务单 = "<< m_pick_table_msg.DebugString() << " --- " << this;
  116. }
  117. }
  118. else
  119. {
  120. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  121. " fun error ");
  122. }
  123. }
  124. return Error_code::SUCCESS;
  125. }
  126. //调度完成后, 向数据库发送答复的相关操作
  127. Error_manager Dispatch_command::dispatch_response_to_sql(Error_manager dispatch_result)
  128. {
  129. std::unique_lock<std::mutex> t_lock(m_lock);
  130. Error_manager t_error;
  131. if ( dispatch_result == Error_code::SUCCESS )
  132. {
  133. //调度成功, 完善数据库
  134. if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_STORE )
  135. {
  136. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_STORE 存车答复成功 = "<< t_error << " --- " << this;
  137. //增加 车辆表, 存车指令 完成后添加车辆信息
  138. t_error = insert_vehicle_for_car_number_ex();
  139. //更新 指令队列, 根据车牌号 删除指令
  140. t_error = delete_command_queue_for_statu();
  141. //增加 记录表, 存车指令 完成后添加存车记录
  142. t_error = updata_record_for_park_end();
  143. }
  144. else if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_PICKUP )
  145. {
  146. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_PICKUP 取车答复成功 = "<< t_error << " --- " << this;
  147. //删除 车辆表, 取车指令 完成后删除车辆信息
  148. t_error = delete_vehicle_for_car_number();
  149. //更新 车位状态, 找到车牌号, 写NULL
  150. t_error = update_parkspace_info_clear_car_number();
  151. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  152. t_error = update_command_queue_for_statu(2);
  153. //更新 记录表, 取车指令 完成后更新取车记录
  154. t_error = updata_record_for_pick_end();
  155. }
  156. else if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_REALLOCATE )
  157. {
  158. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_REALLOCATE 改道答复成功 = "<< t_error << " --- " << this;
  159. //增加 车辆表, 存车指令 完成后添加车辆信息
  160. t_error = insert_vehicle_for_car_number_ex();
  161. //更新 指令队列, 根据车牌号 删除指令
  162. t_error = delete_command_queue_for_statu();
  163. //增加 记录表, 存车指令 完成后添加存车记录
  164. t_error = updata_record_for_park_end();
  165. }
  166. else if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_REVOCATION )
  167. {
  168. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_REVOCATION 撤销答复成功 = "<< t_error << " --- " << this;
  169. //删除 车辆表, 取车指令 完成后删除车辆信息
  170. t_error = delete_vehicle_for_car_number();
  171. //更新 车位状态, 找到车牌号, 写NULL
  172. t_error = update_parkspace_info_clear_car_number();
  173. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  174. t_error = update_command_queue_for_statu(2);
  175. // LOG(INFO) << "llllllllllllllllllllllllllllllllllllllllll respons = "<< t_error << " --- " << this;
  176. //更新 记录表, 取车指令 完成后更新取车记录, 撤销指令, 没有取车时间差
  177. t_error = updata_record_for_pick_end_ex();
  178. }
  179. else
  180. {
  181. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  182. " fun error ");
  183. }
  184. return t_error;
  185. }
  186. else
  187. {
  188. //调度失败, 回退 数据库
  189. if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_STORE )
  190. {
  191. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_STORE 存车答复失败 = "<< t_error << " --- " << this;
  192. //更新 车位状态, 找到车牌号, 写NULL
  193. update_parkspace_info_clear_car_number();
  194. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  195. update_command_queue_for_statu(3);
  196. }
  197. else if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_PICKUP )
  198. {
  199. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_PICKUP 取车答复失败 = "<< t_error << " --- " << this;
  200. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  201. update_command_queue_for_statu(3);
  202. }
  203. else if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_REALLOCATE )
  204. {
  205. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_STORE 改道答复失败 = "<< t_error << " --- " << this;
  206. //更新 车位状态, 找到车牌号, 写NULL
  207. update_parkspace_info_clear_car_number();
  208. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  209. update_command_queue_for_statu(3);
  210. }
  211. else if ( m_dispatch_process_type == Common_data::DISPATCH_PROCESS_REVOCATION )
  212. {
  213. LOG(INFO) << " dispatch_response_to_sql DISPATCH_PROCESS_PICKUP 撤销答复失败 = "<< t_error << " --- " << this;
  214. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  215. update_command_queue_for_statu(3);
  216. }
  217. else
  218. {
  219. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  220. " fun error ");
  221. }
  222. }
  223. return Error_code::SUCCESS;
  224. }
  225. //调度 , 向数据库 重新分配车位,
  226. Error_manager Dispatch_command::dispatch_reallocate_to_sql(Common_data::Car_type reallocate_car_type, int outlet_ready)
  227. {
  228. std::unique_lock<std::mutex> t_lock(m_lock);
  229. Error_manager t_error;
  230. m_outlet_ready = outlet_ready;
  231. //把之前申请的车位清除 //更新 车位状态, 找到车牌号, 写NULL
  232. t_error = Dispatch_command::update_parkspace_info_clear_car_number();
  233. //重新申请车位
  234. //查询空闲车位最优解, 存车指令 根据调度指令最优解 获取 空闲车位最优解
  235. t_error = query_dispatch_space_optimal(reallocate_car_type);
  236. if ( t_error != Error_code::SUCCESS )
  237. {
  238. //没找到车位, 就把车放到出口
  239. if ( outlet_ready != 0 )
  240. {
  241. m_dispatch_process_type = Common_data::DISPATCH_PROCESS_REVOCATION;
  242. //补充出口id
  243. m_dispatch_command_map[m_car_number_optimal].m_export_id = outlet_ready;
  244. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_id(0);
  245. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_unit_id(0);
  246. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_floor(0);
  247. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_room_id(0);
  248. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  249. // t_error = update_command_queue_for_statu(1);
  250. //制作取车表单
  251. t_error = create_pick_table(outlet_ready);
  252. LOG(INFO) << " create_pick_table 撤销存车, 取车到出口任务单 = "<< m_pick_table_msg.DebugString() << " --- " << this;
  253. return t_error;
  254. }
  255. else
  256. {
  257. //无限等待, 等待出口空闲
  258. return Error_code::NODATA;
  259. }
  260. }
  261. else
  262. {
  263. m_dispatch_process_type = Common_data::DISPATCH_PROCESS_REALLOCATE;
  264. //找到新的车位, 重新执行任务
  265. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_id(m_dispatch_space_info.m_id);
  266. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_unit_id(m_dispatch_space_info.m_unit);
  267. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_floor(m_dispatch_space_info.m_floor);
  268. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.set_room_id(m_dispatch_space_info.m_subID);
  269. //更新 车位状态, 根据车位ID 写入车牌号即可
  270. t_error = update_parkspace_info_write_car_number();
  271. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  272. // t_error = update_command_queue_for_statu(1);
  273. //制作存车表单
  274. t_error = create_park_table();
  275. LOG(INFO) << " create_park_table 改道存车, 存车新车位任务单 = "<< m_park_table_msg.DebugString() << " --- " << this;
  276. }
  277. return Error_code::SUCCESS;
  278. }
  279. //检查出口是否空闲, 检查指令队列的取车完成的出口id是否存在, 不存在就是空闲,返回成功
  280. Error_manager Dispatch_command::check_export_id_is_ready(int export_id)
  281. {
  282. std::unique_lock<std::mutex> t_lock(m_lock);
  283. //检查指令队列, 查询指定单元的取车完成状态指令的 出口id是否存在
  284. char check_export_id_sql[1024];
  285. memset(check_export_id_sql, 0, 1024);
  286. sprintf(check_export_id_sql,"select * from command_queue where statu = 2 and type = 2 and export_id = %d",export_id);
  287. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  288. Error_manager t_error = Database_controller::get_instance_pointer()->sql_query(check_export_id_sql, tp_result);
  289. if(t_error == Error_code::SUCCESS)
  290. {
  291. if (tp_result == nullptr)
  292. {
  293. return DB_RESULT_SET_EMPTY;
  294. }
  295. //如果存在, 就报错, 不存在就是空闲,返回成功
  296. if ( tp_result->next() )
  297. {
  298. return Error_manager(Error_code::DB_QUERY_OUTLET_OCCUPY, Error_level::MINOR_ERROR,
  299. " check_export_id_is_ready fun error, 数据库 查询出口被占用 ");
  300. }
  301. else
  302. {
  303. return Error_code::SUCCESS;
  304. }
  305. }
  306. else
  307. {
  308. return t_error;
  309. }
  310. return Error_code::SUCCESS;
  311. }
  312. //检查出口取车是否完成, 指定的出口有取车完成指令就返回成功, 否则报错.
  313. Error_manager Dispatch_command::check_pickup_is_finish(int export_id)
  314. {
  315. std::unique_lock<std::mutex> t_lock(m_lock);
  316. //检查指令队列, 查询指定单元的取车完成状态指令的 出口id是否存在
  317. char check_export_id_sql[1024];
  318. memset(check_export_id_sql, 0, 1024);
  319. sprintf(check_export_id_sql,"select * from command_queue where statu = 2 and type = 2 and export_id = %d",export_id);
  320. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  321. Error_manager t_error = Database_controller::get_instance_pointer()->sql_query(check_export_id_sql, tp_result);
  322. if(t_error == Error_code::SUCCESS)
  323. {
  324. if (tp_result == nullptr)
  325. {
  326. return DB_RESULT_SET_EMPTY;
  327. }
  328. //如果存在, 就报错, 不存在就是空闲,返回成功
  329. if ( tp_result->next() )
  330. {
  331. return Error_code::SUCCESS;
  332. }
  333. else
  334. {
  335. return Error_manager(Error_code::DB_QUERY_OUTLET_OCCUPY, Error_level::MINOR_ERROR,
  336. " check_export_id_is_ready fun error, 数据库 查询出口被占用 ");
  337. }
  338. }
  339. else
  340. {
  341. return t_error;
  342. }
  343. return Error_code::SUCCESS;
  344. }
  345. //检查入口存车是否开始, 指定的入口有存车开始指令就返回成功, 否则报错.
  346. Error_manager Dispatch_command::check_park_is_start(int import_id)
  347. {
  348. std::unique_lock<std::mutex> t_lock(m_lock);
  349. //检查指令队列, 查询指定单元的取车完成状态指令的 出口id是否存在
  350. char check_export_id_sql[1024];
  351. memset(check_export_id_sql, 0, 1024);
  352. sprintf(check_export_id_sql,"select * from command_queue where type = 1 and import_id = %d and (statu=0 or statu =1)",import_id);
  353. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  354. Error_manager t_error = Database_controller::get_instance_pointer()->sql_query(check_export_id_sql, tp_result);
  355. if(t_error == Error_code::SUCCESS)
  356. {
  357. if (tp_result == nullptr)
  358. {
  359. return DB_RESULT_SET_EMPTY;
  360. }
  361. //如果存在, 就报错, 不存在就是空闲,返回成功
  362. if ( tp_result->next() )
  363. {
  364. return Error_code::SUCCESS;
  365. }
  366. else
  367. {
  368. return Error_manager(Error_code::DB_QUERY_OUTLET_OCCUPY, Error_level::MINOR_ERROR,
  369. " check_export_id_is_ready fun error, 数据库 查询出口被占用 ");
  370. }
  371. }
  372. else
  373. {
  374. return t_error;
  375. }
  376. return Error_code::SUCCESS;
  377. }
  378. //获取指定入口的 存车流程的 唯一码,
  379. Error_manager Dispatch_command::get_primary_key_for_store(int import_id, std::string & primary_key )
  380. {
  381. std::unique_lock<std::mutex> t_lock(m_lock);
  382. //检查指令队列, 查询指定单元的取车完成状态指令的 出口id是否存在
  383. char check_export_id_sql[1024];
  384. memset(check_export_id_sql, 0, 1024);
  385. sprintf(check_export_id_sql,"select * from command_queue where type = 1 and import_id = %d and (statu=0 or statu =1)",import_id);
  386. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  387. Error_manager t_error = Database_controller::get_instance_pointer()->sql_query(check_export_id_sql, tp_result);
  388. if(t_error == Error_code::SUCCESS)
  389. {
  390. if (tp_result == nullptr)
  391. {
  392. return DB_RESULT_SET_EMPTY;
  393. }
  394. //如果存在, 就报错, 不存在就是空闲,返回成功
  395. if ( tp_result->next() )
  396. {
  397. char buf[1024];
  398. memset(buf, 0, 1024);
  399. try
  400. {
  401. //解析数据
  402. primary_key = tp_result->getString("primary_key");
  403. }
  404. catch (sql::SQLException &e)
  405. {
  406. /* Use what() (derived from std::runtime_error) to fetch the error message */
  407. sprintf(buf, "# ERR: %s\n (MySQL error code: %d, SQLState: %s", e.what(), e.getErrorCode(), e.getSQLState().c_str());
  408. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  409. }
  410. catch (std::runtime_error &e)
  411. {
  412. sprintf(buf, "# ERR: %s\n ERR: runtime_error in %s ", e.what(), __FILE__);
  413. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  414. }
  415. return Error_code::SUCCESS;
  416. }
  417. else
  418. {
  419. return Error_manager(Error_code::DB_QUERY_OUTLET_OCCUPY, Error_level::MINOR_ERROR,
  420. " check_export_id_is_ready fun error, 数据库 查询出口被占用 ");
  421. }
  422. }
  423. else
  424. {
  425. return t_error;
  426. }
  427. return Error_code::SUCCESS;
  428. }
  429. //删除 指令队列, 根据出口编号
  430. Error_manager Dispatch_command::delete_command_queue_for_export_id(int export_id)
  431. {
  432. std::unique_lock<std::mutex> t_lock(m_lock);
  433. char delete_command_sql[1024];
  434. memset(delete_command_sql, 0, 1024);
  435. sprintf(delete_command_sql, "delete from command_queue where statu = 2 and type = 2 and export_id = %d ",
  436. export_id );
  437. Error_manager ec = Database_controller::get_instance_pointer()->sql_delete(delete_command_sql);
  438. return ec;
  439. }
  440. //添加plc数据储存
  441. Error_manager Dispatch_command::insert_plc_data(std::string plc_data, float hearbeat)
  442. {
  443. std::unique_lock<std::mutex> t_lock(m_lock);
  444. char insert_vehicle_sql[4096];
  445. memset(insert_vehicle_sql, 0, 4096);
  446. sprintf(insert_vehicle_sql, "INSERT INTO plc_data (data, hearbeat) values ('%s',%f)",
  447. plc_data.c_str(), hearbeat );
  448. Error_manager ec = Database_controller::get_instance_pointer()->sql_insert(insert_vehicle_sql);
  449. std::cout << " huli test :::: " << " ec = " << ec << std::endl;
  450. return ec;
  451. }
  452. //获取调度指令, 与数据库同步 command_queue, statu指令状态, 0:排队等待, 1正在运行, 2:已经完成
  453. Error_manager Dispatch_command::query_all_dispatch_command(int statu)
  454. {
  455. //从command_queue获取所有排队的指令,
  456. char query_all_dispatch_command_sql[1024];
  457. memset(query_all_dispatch_command_sql, 0, 1024);
  458. sprintf(query_all_dispatch_command_sql,"select * from command_queue where statu = %d and unit = %d",statu, m_unit);
  459. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  460. Error_manager t_error = Database_controller::get_instance_pointer()->sql_query(query_all_dispatch_command_sql, tp_result);
  461. m_dispatch_command_map.clear();
  462. if(t_error == Error_code::SUCCESS)
  463. {
  464. if (tp_result == nullptr)
  465. {
  466. return DB_RESULT_SET_EMPTY;
  467. }
  468. //循环检查所有行
  469. while (tp_result->next())
  470. {
  471. Dispatch_command_info t_dispatch_command_info;
  472. char t_error_buf[1024];
  473. memset(t_error_buf, 0, 1024);
  474. try
  475. {
  476. //解析数据
  477. t_dispatch_command_info.m_car_number = tp_result->getString("car_number");
  478. t_dispatch_command_info.m_primary_key = tp_result->getString("primary_key");
  479. t_dispatch_command_info.m_unit = tp_result->getInt("unit");
  480. t_dispatch_command_info.m_queue_id = tp_result->getInt("queue_id");
  481. t_dispatch_command_info.m_type = tp_result->getInt("type");
  482. t_dispatch_command_info.m_statu = tp_result->getInt("statu");
  483. t_dispatch_command_info.m_space_info = tp_result->getString("space_info");
  484. t_dispatch_command_info.m_measure_info = tp_result->getString("measure_info");
  485. // t_dispatch_command_info.m_export_id = tp_result->getInt("export_id");
  486. t_dispatch_command_info.m_export_id = 0;
  487. //m_type指令类型, 0无效, 1存车, 2取车,
  488. if ( t_dispatch_command_info.m_type == 1)
  489. {
  490. //存车, 数据库特有 雷达信息, 没有车位信息, 需要根据车高,再去车位表申请车位
  491. if(! google::protobuf::TextFormat::ParseFromString(t_dispatch_command_info.m_measure_info, &t_dispatch_command_info.m_measure_info_msg))
  492. {
  493. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  494. "ParseFromString fun error, m_measure_info ");
  495. }
  496. t_dispatch_command_info.m_useless_distance = m_device_floor-1;
  497. }
  498. else if ( t_dispatch_command_info.m_type == 2 )
  499. {
  500. //取车, 数据库特有车位信息
  501. if(! google::protobuf::TextFormat::ParseFromString(t_dispatch_command_info.m_space_info, &t_dispatch_command_info.m_parkspace_info_msg))
  502. {
  503. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  504. "ParseFromString fun error, m_space_info ");
  505. }
  506. t_dispatch_command_info.m_useless_distance = t_dispatch_command_info.m_parkspace_info_msg.floor()-m_device_floor;
  507. }
  508. else
  509. {
  510. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  511. "command_queue m_type error ");
  512. }
  513. if ( t_dispatch_command_info.m_useless_distance <0 )
  514. {
  515. t_dispatch_command_info.m_useless_distance = 0-t_dispatch_command_info.m_useless_distance;
  516. }
  517. m_dispatch_command_map[t_dispatch_command_info.m_car_number] = t_dispatch_command_info;
  518. }
  519. catch (sql::SQLException &e)
  520. {
  521. /* Use what() (derived from std::runtime_error) to fetch the error message */
  522. sprintf(t_error_buf, "# ERR: %s\n (MySQL error code: %d, SQLState: %s", e.what(), e.getErrorCode(),
  523. e.getSQLState().c_str());
  524. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, t_error_buf);
  525. }
  526. catch (std::runtime_error &e)
  527. {
  528. sprintf(t_error_buf, "# ERR: %s\n ERR: runtime_error in %s ", e.what(), __FILE__);
  529. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, t_error_buf);
  530. }
  531. }
  532. return SUCCESS;
  533. }
  534. else
  535. {
  536. return t_error;
  537. }
  538. return Error_code::SUCCESS;
  539. }
  540. //对调度指令进行排序, 选出最优解, 比较存车和取车
  541. Error_manager Dispatch_command::sort_dispatch_command_for_total()
  542. {
  543. int t_optimal_loss=0x7fffffff; //最优loss值
  544. m_car_number_optimal.clear();
  545. for (auto iter = m_dispatch_command_map.begin(); iter != m_dispatch_command_map.end(); ++iter)
  546. {
  547. //loss = 空跑路程 + 排队编号, 求最小值
  548. int t_current_loss = iter->second.m_useless_distance + iter->second.m_queue_id;
  549. if ( t_optimal_loss > t_current_loss )
  550. {
  551. t_optimal_loss = t_current_loss;
  552. m_car_number_optimal = iter->first;
  553. }
  554. }
  555. if ( m_car_number_optimal.empty() )
  556. {
  557. return Error_code::NODATA;
  558. }
  559. return Error_code::SUCCESS;
  560. }
  561. //对调度指令进行排序, 选出最优解, 只比较存车
  562. Error_manager Dispatch_command::sort_dispatch_command_for_park()
  563. {
  564. int t_optimal_loss=0x7fffffff; //最优loss值
  565. m_car_number_optimal.clear();
  566. for (auto iter = m_dispatch_command_map.begin(); iter != m_dispatch_command_map.end(); ++iter)
  567. {
  568. //loss = 空跑路程 + 排队编号, 求最小值
  569. int t_current_loss = iter->second.m_useless_distance + iter->second.m_queue_id;
  570. if ( t_optimal_loss > t_current_loss && iter->second.m_type == 1)
  571. {
  572. t_optimal_loss = t_current_loss;
  573. m_car_number_optimal = iter->first;
  574. }
  575. }
  576. if ( m_car_number_optimal.empty() )
  577. {
  578. return Error_code::NODATA;
  579. }
  580. return Error_code::SUCCESS;
  581. }
  582. //存车指令 获取 指定车高 指定单元 的车位信息,用于车位分配
  583. Error_manager Dispatch_command::query_specify_height_unit_parkspace_info(int unit, float height, Dispatch_space_info & dispatch_space_info)
  584. {
  585. //查询车位表
  586. char query_parkspace_sql[1024];
  587. memset(query_parkspace_sql, 0, 1024);
  588. int t_statu = 0; //车位状态, 0可用, 1故障
  589. 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);
  590. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  591. Error_manager ec = Database_controller::get_instance_pointer()->sql_query(query_parkspace_sql, tp_result);
  592. if(ec == SUCCESS)
  593. {
  594. if(tp_result == nullptr)
  595. {
  596. return DB_RESULT_SET_EMPTY;
  597. }
  598. //只取第一条结果, 默认是id最小的,
  599. if (tp_result->next())
  600. {
  601. char buf[1024];
  602. memset(buf, 0, 1024);
  603. try
  604. {
  605. //解析数据
  606. dispatch_space_info.m_id = tp_result->getInt("id");
  607. dispatch_space_info.m_floor = tp_result->getInt("floor");
  608. dispatch_space_info.m_subID = tp_result->getInt("subID");
  609. dispatch_space_info.m_height = tp_result->getDouble("height");
  610. dispatch_space_info.m_car_number = tp_result->getString("car_number");
  611. dispatch_space_info.m_unit = tp_result->getInt("unit");
  612. dispatch_space_info.m_statu = tp_result->getInt("statu");
  613. }
  614. catch (sql::SQLException &e)
  615. {
  616. /* Use what() (derived from std::runtime_error) to fetch the error message */
  617. sprintf(buf, "# ERR: %s\n (MySQL error code: %d, SQLState: %s", e.what(), e.getErrorCode(), e.getSQLState().c_str());
  618. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  619. }
  620. catch (std::runtime_error &e)
  621. {
  622. sprintf(buf, "# ERR: %s\n ERR: runtime_error in %s ", e.what(), __FILE__);
  623. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  624. }
  625. }
  626. else
  627. {
  628. return Error_manager(Error_code::DB_NOT_QUERY_EMPTY_PARKSPACE, Error_level::MINOR_ERROR,
  629. "数据库未查询到空车位 Parkspace_operating_function::query_one_empty_parkspace error ");
  630. }
  631. return SUCCESS;
  632. }
  633. else
  634. {
  635. return ec;
  636. }
  637. return SUCCESS;
  638. }
  639. //查询空闲车位最优解, 存车指令 根据调度指令最优解 获取 空闲车位最优解
  640. Error_manager Dispatch_command::query_dispatch_space_optimal()
  641. {
  642. Error_manager t_error;
  643. int t_unit = m_dispatch_command_map[m_car_number_optimal].m_unit;
  644. float t_height = m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.height();
  645. //小车对应小车位 中车对应中车位 大车对应大车位
  646. if ( 0 < t_height && t_height <= CAR_HEIGHT_LIMIT_SMALL )
  647. {
  648. t_error = query_specify_height_unit_parkspace_info(t_unit, CAR_HEIGHT_LIMIT_SMALL, m_dispatch_space_info);
  649. if ( t_error == Error_code::SUCCESS )
  650. {
  651. m_car_type = Common_data::Car_type::MIN_CAR;
  652. return t_error;
  653. }
  654. }
  655. if ( t_height <= CAR_HEIGHT_LIMIT_MIDDLE )
  656. {
  657. t_error = query_specify_height_unit_parkspace_info(t_unit, CAR_HEIGHT_LIMIT_MIDDLE, m_dispatch_space_info);
  658. if ( t_error == Error_code::SUCCESS )
  659. {
  660. m_car_type = Common_data::Car_type::MID_CAR;
  661. return t_error;
  662. }
  663. }
  664. if ( t_height <= CAR_HEIGHT_LIMIT_BIG )
  665. {
  666. t_error = query_specify_height_unit_parkspace_info(t_unit, CAR_HEIGHT_LIMIT_BIG, m_dispatch_space_info);
  667. if ( t_error == Error_code::SUCCESS )
  668. {
  669. m_car_type = Common_data::Car_type::BIG_CAR;
  670. return t_error;
  671. }
  672. }
  673. return Error_manager(Error_code::DB_NOT_QUERY_EMPTY_PARKSPACE, Error_level::MINOR_ERROR,
  674. " query_dispatch_space_optimal error ");
  675. }
  676. //查询空闲车位最优解, 存车指令 根据调度指令最优解 获取 空闲车位最优解
  677. Error_manager Dispatch_command::query_dispatch_space_optimal(Common_data::Car_type reallocate_car_type)
  678. {
  679. Error_manager t_error;
  680. int t_unit = m_dispatch_command_map[m_car_number_optimal].m_unit;
  681. // float t_height = m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.height();
  682. //小车对应小车位 中车对应中车位 大车对应大车位
  683. if ( reallocate_car_type == Common_data::Car_type::MIN_CAR )
  684. {
  685. t_error = query_specify_height_unit_parkspace_info(t_unit, CAR_HEIGHT_LIMIT_SMALL, m_dispatch_space_info);
  686. if ( t_error == Error_code::SUCCESS )
  687. {
  688. m_car_type = Common_data::Car_type::MIN_CAR;
  689. return t_error;
  690. }
  691. }
  692. if ( reallocate_car_type == Common_data::Car_type::MIN_CAR ||
  693. reallocate_car_type == Common_data::Car_type::MID_CAR )
  694. {
  695. t_error = query_specify_height_unit_parkspace_info(t_unit, CAR_HEIGHT_LIMIT_MIDDLE, m_dispatch_space_info);
  696. if ( t_error == Error_code::SUCCESS )
  697. {
  698. m_car_type = Common_data::Car_type::MID_CAR;
  699. return t_error;
  700. }
  701. }
  702. if ( reallocate_car_type == Common_data::Car_type::MIN_CAR ||
  703. reallocate_car_type == Common_data::Car_type::MID_CAR ||
  704. reallocate_car_type == Common_data::Car_type::BIG_CAR )
  705. {
  706. t_error = query_specify_height_unit_parkspace_info(t_unit, CAR_HEIGHT_LIMIT_BIG, m_dispatch_space_info);
  707. if ( t_error == Error_code::SUCCESS )
  708. {
  709. m_car_type = Common_data::Car_type::BIG_CAR;
  710. return t_error;
  711. }
  712. }
  713. return Error_manager(Error_code::DB_NOT_QUERY_EMPTY_PARKSPACE, Error_level::MINOR_ERROR,
  714. " query_dispatch_space_optimal error ");
  715. }
  716. //查询 取车的车位 取车指令 根据车牌号 查询对应的车位
  717. Error_manager Dispatch_command::query_dispatch_space_for_car_number()
  718. {
  719. //查询车位表
  720. char query_parkspace_sql[1024];
  721. memset(query_parkspace_sql, 0, 1024);
  722. int t_statu = 0; //车位状态, 0可用, 1故障
  723. sprintf(query_parkspace_sql,"select * from space where car_number = '%s' ",m_dispatch_command_map[m_car_number_optimal].m_car_number.c_str());
  724. // std::cout<<"query_parkspace_sql = "<<query_parkspace_sql<<std::endl;
  725. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  726. Error_manager ec = Database_controller::get_instance_pointer()->sql_query(query_parkspace_sql, tp_result);
  727. if(ec == SUCCESS)
  728. {
  729. if(tp_result == nullptr)
  730. {
  731. return DB_RESULT_SET_EMPTY;
  732. }
  733. //只取第一条结果, 默认是id最小的,
  734. if (tp_result->next())
  735. {
  736. char buf[1024];
  737. memset(buf, 0, 1024);
  738. try
  739. {
  740. //解析数据
  741. m_dispatch_space_info.m_id = tp_result->getInt("id");
  742. m_dispatch_space_info.m_floor = tp_result->getInt("floor");
  743. m_dispatch_space_info.m_subID = tp_result->getInt("subID");
  744. m_dispatch_space_info.m_height = tp_result->getDouble("height");
  745. m_dispatch_space_info.m_car_number = tp_result->getString("car_number");
  746. m_dispatch_space_info.m_unit = tp_result->getInt("unit");
  747. m_dispatch_space_info.m_statu = tp_result->getInt("statu");
  748. }
  749. catch (sql::SQLException &e)
  750. {
  751. /* Use what() (derived from std::runtime_error) to fetch the error message */
  752. sprintf(buf, "# ERR: %s\n (MySQL error code: %d, SQLState: %s", e.what(), e.getErrorCode(), e.getSQLState().c_str());
  753. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  754. }
  755. catch (std::runtime_error &e)
  756. {
  757. sprintf(buf, "# ERR: %s\n ERR: runtime_error in %s ", e.what(), __FILE__);
  758. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  759. }
  760. }
  761. else
  762. {
  763. return Error_manager(Error_code::DB_QUERY_NOT_DATA, Error_level::MINOR_ERROR,
  764. "数据库未查询到数据 Parkspace_operating_function::query_one_parkspace_with_license error ");
  765. }
  766. return SUCCESS;
  767. }
  768. else
  769. {
  770. return ec;
  771. }
  772. return SUCCESS;
  773. }
  774. //查询 取车的车辆感测信息 取车指令 根据key 查询感测信息
  775. Error_manager Dispatch_command::query_dispatch_vehicle_for_primary_key()
  776. {
  777. //查询 车辆表
  778. char query_parkspace_sql[1024];
  779. memset(query_parkspace_sql, 0, 1024);
  780. int t_statu = 0; //车位状态, 0可用, 1故障
  781. sprintf(query_parkspace_sql,"select * from vehicle where primary_key = '%s' ",m_dispatch_command_map[m_car_number_optimal].m_primary_key.c_str());
  782. // std::cout<<"query_parkspace_sql = "<<query_parkspace_sql<<std::endl;
  783. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  784. Error_manager ec = Database_controller::get_instance_pointer()->sql_query(query_parkspace_sql, tp_result);
  785. if(ec == SUCCESS)
  786. {
  787. if(tp_result == nullptr)
  788. {
  789. return DB_RESULT_SET_EMPTY;
  790. }
  791. //只取第一条结果, 默认是id最小的,
  792. if (tp_result->next())
  793. {
  794. char buf[1024];
  795. memset(buf, 0, 1024);
  796. try
  797. {
  798. //解析数据
  799. m_dispatch_vehicle_info.m_car_number = tp_result->getString("car_number");
  800. m_dispatch_vehicle_info.m_primary_key = tp_result->getString("primary_key");
  801. m_dispatch_vehicle_info.m_actually_measure_info = tp_result->getString("actually_measure_info");
  802. //取车, 数据库特有车位信息
  803. if(! google::protobuf::TextFormat::ParseFromString(m_dispatch_vehicle_info.m_actually_measure_info, &m_dispatch_vehicle_info.m_actually_measure_info_msg))
  804. {
  805. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  806. "ParseFromString fun error, m_space_info ");
  807. }
  808. }
  809. catch (sql::SQLException &e)
  810. {
  811. /* Use what() (derived from std::runtime_error) to fetch the error message */
  812. sprintf(buf, "# ERR: %s\n (MySQL error code: %d, SQLState: %s", e.what(), e.getErrorCode(), e.getSQLState().c_str());
  813. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  814. }
  815. catch (std::runtime_error &e)
  816. {
  817. sprintf(buf, "# ERR: %s\n ERR: runtime_error in %s ", e.what(), __FILE__);
  818. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  819. }
  820. }
  821. else
  822. {
  823. return Error_manager(Error_code::DB_QUERY_NOT_DATA, Error_level::MINOR_ERROR,
  824. "数据库未查询到数据 Parkspace_operating_function::query_one_parkspace_with_license error ");
  825. }
  826. return SUCCESS;
  827. }
  828. else
  829. {
  830. return ec;
  831. }
  832. return SUCCESS;
  833. }
  834. //查询 取车的车辆plc感测信息 取车指令 根据key 查询感测信息
  835. Error_manager Dispatch_command::query_dispatch_vehicle_for_primary_key_ex()
  836. {
  837. //查询 车辆表
  838. char query_parkspace_sql[1024];
  839. memset(query_parkspace_sql, 0, 1024);
  840. int t_statu = 0; //车位状态, 0可用, 1故障
  841. sprintf(query_parkspace_sql,"select * from vehicle where primary_key = '%s' ",m_dispatch_command_map[m_car_number_optimal].m_primary_key.c_str());
  842. // std::cout<<"query_parkspace_sql = "<<query_parkspace_sql<<std::endl;
  843. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  844. Error_manager ec = Database_controller::get_instance_pointer()->sql_query(query_parkspace_sql, tp_result);
  845. if(ec == SUCCESS)
  846. {
  847. if(tp_result == nullptr)
  848. {
  849. return DB_RESULT_SET_EMPTY;
  850. }
  851. //只取第一条结果, 默认是id最小的,
  852. if (tp_result->next())
  853. {
  854. char buf[1024];
  855. memset(buf, 0, 1024);
  856. try
  857. {
  858. //解析数据
  859. m_dispatch_vehicle_info.m_car_number = tp_result->getString("car_number");
  860. m_dispatch_vehicle_info.m_primary_key = tp_result->getString("primary_key");
  861. m_dispatch_vehicle_info.m_plc_measure_info = tp_result->getString("plc_measure_info");
  862. //取车, 数据库特有车位信息
  863. if(! google::protobuf::TextFormat::ParseFromString(m_dispatch_vehicle_info.m_plc_measure_info, &m_dispatch_vehicle_info.m_plc_measure_info_msg))
  864. {
  865. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  866. "ParseFromString fun error, m_space_info ");
  867. }
  868. }
  869. catch (sql::SQLException &e)
  870. {
  871. /* Use what() (derived from std::runtime_error) to fetch the error message */
  872. sprintf(buf, "# ERR: %s\n (MySQL error code: %d, SQLState: %s", e.what(), e.getErrorCode(), e.getSQLState().c_str());
  873. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  874. }
  875. catch (std::runtime_error &e)
  876. {
  877. sprintf(buf, "# ERR: %s\n ERR: runtime_error in %s ", e.what(), __FILE__);
  878. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  879. }
  880. }
  881. else
  882. {
  883. return Error_manager(Error_code::DB_QUERY_NOT_DATA, Error_level::MINOR_ERROR,
  884. "数据库未查询到数据 Parkspace_operating_function::query_one_parkspace_with_license error ");
  885. }
  886. return SUCCESS;
  887. }
  888. else
  889. {
  890. return ec;
  891. }
  892. return SUCCESS;
  893. }
  894. //更新 车位状态, 根据车位ID 写入车牌号即可
  895. Error_manager Dispatch_command::update_parkspace_info_write_car_number()
  896. {
  897. //执行sql操作
  898. char update_space_sql[1024];
  899. memset(update_space_sql, 0, 1024);
  900. sprintf(update_space_sql, "update space set car_number = '%s' where id = %d",
  901. m_dispatch_command_map[m_car_number_optimal].m_car_number.c_str(),
  902. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.id() );
  903. // m_dispatch_space_info.m_id);
  904. Error_manager ec = Database_controller::get_instance_pointer()->sql_update(update_space_sql);
  905. return ec;
  906. }
  907. //更新 车位状态, 找到车牌号, 写NULL
  908. Error_manager Dispatch_command::update_parkspace_info_clear_car_number()
  909. {
  910. //执行sql操作
  911. char update_space_sql[1024];
  912. memset(update_space_sql, 0, 1024);
  913. sprintf(update_space_sql, "update space set car_number = null where car_number = '%s' ",
  914. m_dispatch_command_map[m_car_number_optimal].m_car_number.c_str());
  915. Error_manager ec = Database_controller::get_instance_pointer()->sql_update(update_space_sql);
  916. return ec;
  917. }
  918. //更新 指令队列, 根据车牌号 修改状态即可, //指令状态, 0排队中, 1正在工作, 2已完成, 3故障异常
  919. Error_manager Dispatch_command::update_command_queue_for_statu(int statu)
  920. {
  921. char update_command_sql[1024];
  922. memset(update_command_sql, 0, 1024);
  923. sprintf(update_command_sql, "update command_queue set statu = %d, export_id = %d where car_number = '%s'",
  924. statu, m_dispatch_command_map[m_car_number_optimal].m_export_id,
  925. m_dispatch_command_map[m_car_number_optimal].m_car_number.c_str());
  926. // LOG(INFO) << "jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj update_command_sql = "<< update_command_sql << " --- " << this;
  927. Error_manager ec = Database_controller::get_instance_pointer()->sql_update(update_command_sql);
  928. return ec;
  929. }
  930. //删除 指令队列, 根据车牌号 删除指令
  931. Error_manager Dispatch_command::delete_command_queue_for_statu()
  932. {
  933. char delete_command_sql[1024];
  934. memset(delete_command_sql, 0, 1024);
  935. sprintf(delete_command_sql, "delete from command_queue where car_number = '%s'",
  936. m_dispatch_command_map[m_car_number_optimal].m_car_number.c_str());
  937. Error_manager ec = Database_controller::get_instance_pointer()->sql_delete(delete_command_sql);
  938. return ec;
  939. }
  940. //制作存车表单
  941. Error_manager Dispatch_command::create_park_table()
  942. {
  943. park_table t_park_table;
  944. t_park_table.mutable_statu()->set_execute_statu(eNormal);
  945. t_park_table.set_queue_id(m_dispatch_command_map[m_car_number_optimal].m_queue_id);
  946. t_park_table.set_car_number(m_dispatch_command_map[m_car_number_optimal].m_car_number);
  947. t_park_table.set_unit_id(m_dispatch_command_map[m_car_number_optimal].m_unit);
  948. t_park_table.set_primary_key(m_dispatch_command_map[m_car_number_optimal].m_primary_key);
  949. t_park_table.mutable_entrance_measure_info()->CopyFrom(m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg);
  950. t_park_table.mutable_allocated_space_info()->CopyFrom(m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg);
  951. //根据雷达x坐标, 计算入口id
  952. int t_terminal = 0;
  953. if (m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.cx()<0)
  954. {
  955. t_terminal = m_dispatch_id*2+1;
  956. }
  957. else if(m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.cx()>0)
  958. {
  959. t_terminal = m_dispatch_id*2+2;
  960. }
  961. t_park_table.set_terminal_id(t_terminal);
  962. // std::cout << " huli test :::: " << " iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii m_park_table_msg.entrance_measure_info().cx() = " << m_park_table_msg.entrance_measure_info().cx() << std::endl;
  963. // std::cout << " huli test :::: " << " iiiiiiiiiiiiiiiiiiiiiiiiiiiiii t_terminal = " << t_terminal << std::endl;
  964. // LOG(INFO) << " m_park_table_msg.entrance_measure_info().cx() = "<< m_park_table_msg.entrance_measure_info().cx() << " --- " << this;
  965. // LOG(INFO) << " t_terminal = "<< t_terminal << " --- " << this;
  966. // LOG(INFO) << " m_device_floor = "<< m_device_floor << " --- " << this;
  967. // LOG(INFO) << " m_dispatch_id = "<< m_dispatch_id << " --- " << this;
  968. // LOG(INFO) << " m_unit = "<< m_unit << " --- " << this;
  969. // LOG(INFO) << " m_outlet_ready = "<< m_outlet_ready << " --- " << this;
  970. m_park_table_msg = t_park_table;
  971. return Error_code::SUCCESS;
  972. }
  973. //制作取车表单
  974. Error_manager Dispatch_command::create_pick_table(int outlet_ready)
  975. {
  976. pick_table t_pick_table;
  977. t_pick_table.mutable_statu()->set_execute_statu(eNormal);
  978. t_pick_table.set_queue_id(m_dispatch_command_map[m_car_number_optimal].m_queue_id);
  979. t_pick_table.set_car_number(m_dispatch_command_map[m_car_number_optimal].m_car_number);
  980. t_pick_table.set_unit_id(m_dispatch_command_map[m_car_number_optimal].m_unit);
  981. t_pick_table.set_primary_key(m_dispatch_command_map[m_car_number_optimal].m_primary_key);
  982. t_pick_table.mutable_actually_measure_info()->CopyFrom(m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg);
  983. t_pick_table.mutable_actually_space_info()->CopyFrom(m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg);
  984. t_pick_table.set_terminal_id(outlet_ready);
  985. // LOG(INFO) << " outlet_ready = "<< outlet_ready << " --- " << this;
  986. //
  987. // LOG(INFO) << " m_device_floor = "<< m_device_floor << " --- " << this;
  988. // LOG(INFO) << " m_dispatch_id = "<< m_dispatch_id << " --- " << this;
  989. // LOG(INFO) << " m_unit = "<< m_unit << " --- " << this;
  990. // LOG(INFO) << " m_outlet_ready = "<< m_outlet_ready << " --- " << this;
  991. m_pick_table_msg = t_pick_table;
  992. return Error_code::SUCCESS;
  993. }
  994. //增加 车辆表, 存车指令 完成后添加车辆信息
  995. Error_manager Dispatch_command::insert_vehicle_for_car_number()
  996. {
  997. char insert_vehicle_sql[1024];
  998. memset(insert_vehicle_sql, 0, 1024);
  999. sprintf(insert_vehicle_sql, "INSERT INTO vehicle (car_number,primary_key,actually_measure_info) values ('%s','%s','%s')",
  1000. m_car_number_optimal.c_str(), m_dispatch_command_map[m_car_number_optimal].m_primary_key.c_str(),
  1001. m_dispatch_command_map[m_car_number_optimal].m_measure_info.c_str() );
  1002. Error_manager ec = Database_controller::get_instance_pointer()->sql_insert(insert_vehicle_sql);
  1003. return ec;
  1004. }
  1005. //20230213 huli add plc car_wheel_base
  1006. Error_manager Dispatch_command::insert_vehicle_for_car_number_ex()
  1007. {
  1008. //20230213 huli add plc car_wheel_base
  1009. measure_info t_plc_measure_info_msg = m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg;
  1010. t_plc_measure_info_msg.set_wheelbase( Dispatch_manager::get_instance_references().m_dispatch_plc.m_plc_car_wheel_base);
  1011. if ( Dispatch_manager::get_instance_references().m_dispatch_plc.m_plc_car_wheel_base ==0 )
  1012. {
  1013. char insert_vehicle_sql[1024];
  1014. memset(insert_vehicle_sql, 0, 1024);
  1015. sprintf(insert_vehicle_sql, "INSERT INTO vehicle (car_number,primary_key,actually_measure_info, plc_clamp_lidar_deviation_1, plc_clamp_lidar_deviation_2, plc_clamp_lidar_deviation_3, plc_clamp_lidar_deviation_4) values ('%s','%s','%s', %f, %f, %f, %f)",
  1016. m_car_number_optimal.c_str(), m_dispatch_command_map[m_car_number_optimal].m_primary_key.c_str(),
  1017. m_dispatch_command_map[m_car_number_optimal].m_measure_info.c_str() ,
  1018. Dispatch_manager::get_instance_references().m_dispatch_plc.m_plc_clamp_lidar_deviation_1,
  1019. Dispatch_manager::get_instance_references().m_dispatch_plc.m_plc_clamp_lidar_deviation_2,
  1020. Dispatch_manager::get_instance_references().m_dispatch_plc.m_plc_clamp_lidar_deviation_3,
  1021. Dispatch_manager::get_instance_references().m_dispatch_plc.m_plc_clamp_lidar_deviation_4
  1022. );
  1023. Error_manager ec = Database_controller::get_instance_pointer()->sql_insert(insert_vehicle_sql);
  1024. return ec;
  1025. }
  1026. else
  1027. {
  1028. char insert_vehicle_sql[1024];
  1029. memset(insert_vehicle_sql, 0, 1024);
  1030. sprintf(insert_vehicle_sql, "INSERT INTO vehicle (car_number,primary_key,actually_measure_info, plc_measure_info, plc_clamp_lidar_deviation_1, plc_clamp_lidar_deviation_2, plc_clamp_lidar_deviation_3, plc_clamp_lidar_deviation_4) values ('%s','%s','%s', '%s', %f, %f, %f, %f)",
  1031. m_car_number_optimal.c_str(), m_dispatch_command_map[m_car_number_optimal].m_primary_key.c_str(),
  1032. m_dispatch_command_map[m_car_number_optimal].m_measure_info.c_str() ,
  1033. t_plc_measure_info_msg.DebugString().c_str(),
  1034. Dispatch_manager::get_instance_references().m_dispatch_plc.m_plc_clamp_lidar_deviation_1,
  1035. Dispatch_manager::get_instance_references().m_dispatch_plc.m_plc_clamp_lidar_deviation_2,
  1036. Dispatch_manager::get_instance_references().m_dispatch_plc.m_plc_clamp_lidar_deviation_3,
  1037. Dispatch_manager::get_instance_references().m_dispatch_plc.m_plc_clamp_lidar_deviation_4
  1038. );
  1039. Error_manager ec = Database_controller::get_instance_pointer()->sql_insert(insert_vehicle_sql);
  1040. return ec;
  1041. }
  1042. return Error_code::SUCCESS;
  1043. }
  1044. //删除 车辆表, 取车指令 完成后删除车辆信息
  1045. Error_manager Dispatch_command::delete_vehicle_for_car_number()
  1046. {
  1047. char delete_vehicle_sql[1024];
  1048. memset(delete_vehicle_sql, 0, 1024);
  1049. sprintf(delete_vehicle_sql, "delete from vehicle where car_number = '%s'",
  1050. m_dispatch_command_map[m_car_number_optimal].m_car_number.c_str());
  1051. Error_manager ec = Database_controller::get_instance_pointer()->sql_delete(delete_vehicle_sql);
  1052. return ec;
  1053. }
  1054. //增加 记录表, 存车指令 完成后添加存车记录
  1055. Error_manager Dispatch_command::insert_record_for_park_start()
  1056. {
  1057. Time_tool::get_instance_references().time_start(PARK_TIME_FLAG);
  1058. int t_terminal = 0;
  1059. if (m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.cx()<0)
  1060. {
  1061. t_terminal = m_dispatch_id*2+1;
  1062. }
  1063. else if(m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.cx()>0)
  1064. {
  1065. t_terminal = m_dispatch_id*2+2;
  1066. }
  1067. char insert_record_sql[1024];
  1068. memset(insert_record_sql, 0, 1024);
  1069. // sprintf(insert_record_sql, "INSERT INTO record (primary_key,car_number,in_time_start,measure_info,import_id) values ('%s','%s','%s','%s',%d)",
  1070. sprintf(insert_record_sql, "INSERT INTO record (primary_key,car_number,in_time_start,center_x,center_y,theta,width,height,wheelbase,front_theta,import_id) values ('%s','%s','%s',%f,%f,%f,%f,%f,%f,%f,%d)",
  1071. m_dispatch_command_map[m_car_number_optimal].m_primary_key.c_str(),
  1072. m_car_number_optimal.c_str(),
  1073. Time_tool::get_instance_references().get_current_time_seconds().c_str(),
  1074. // m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.id(),
  1075. // m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.DebugString().c_str(),
  1076. // m_dispatch_command_map[m_car_number_optimal].m_measure_info.c_str(),
  1077. m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.cx(),
  1078. m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.cy(),
  1079. m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.theta(),
  1080. m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.width(),
  1081. m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.height(),
  1082. m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.wheelbase(),
  1083. m_dispatch_command_map[m_car_number_optimal].m_measure_info_msg.front_theta(),
  1084. t_terminal );
  1085. LOG(INFO) << " insert_record_sql = "<< insert_record_sql << " --- " << this;
  1086. Error_manager ec = Database_controller::get_instance_pointer()->sql_insert(insert_record_sql);
  1087. return ec;
  1088. }
  1089. //增加 记录表, 存车指令 完成后添加存车记录
  1090. Error_manager Dispatch_command::updata_record_for_park_end()
  1091. {
  1092. Time_tool::get_instance_references().time_end(PARK_TIME_FLAG);
  1093. int in_time_difference = Time_tool::get_instance_references().get_time_seconds(PARK_TIME_FLAG);
  1094. //t_index_id是指定单元的车位id, 1~78
  1095. int t_table_id = (m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.id() - 1 ) % 78;
  1096. t_table_id = t_table_id + 1;
  1097. //执行sql操作
  1098. char update_record_sql[1024];
  1099. memset(update_record_sql, 0, 1024);
  1100. // sprintf(update_record_sql, "update record set in_time_end = '%s', in_time_difference = %d, space_id = %d, space_info = '%s' where primary_key = '%s' ",
  1101. sprintf(update_record_sql, "update record set in_time_end = '%s', in_time_difference = %d, space_id = %d, table_id = %d, unit_id = %d, floor_id = %d, room_id = %d where primary_key = '%s' ",
  1102. Time_tool::get_instance_references().get_current_time_seconds().c_str(),
  1103. in_time_difference,
  1104. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.id(),
  1105. t_table_id,
  1106. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.unit_id(),
  1107. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.floor(),
  1108. m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.room_id(),
  1109. // m_dispatch_command_map[m_car_number_optimal].m_parkspace_info_msg.DebugString().c_str(),
  1110. m_dispatch_command_map[m_car_number_optimal].m_primary_key.c_str() );
  1111. LOG(INFO) << " update_record_sql = "<< update_record_sql << " --- " << this;
  1112. Error_manager ec = Database_controller::get_instance_pointer()->sql_update(update_record_sql);
  1113. return ec;
  1114. }
  1115. //更新 记录表, 取车指令 完成后更新取车记录
  1116. Error_manager Dispatch_command::updata_record_for_pick_start()
  1117. {
  1118. Time_tool::get_instance_references().time_start(PICK_TIME_FLAG);
  1119. //执行sql操作
  1120. char update_record_sql[1024];
  1121. memset(update_record_sql, 0, 1024);
  1122. sprintf(update_record_sql, "update record set out_time_start = '%s', export_id = %d where primary_key = '%s' ",
  1123. Time_tool::get_instance_references().get_current_time_seconds().c_str(),
  1124. m_dispatch_command_map[m_car_number_optimal].m_export_id,
  1125. m_dispatch_command_map[m_car_number_optimal].m_primary_key.c_str() );
  1126. LOG(INFO) << " update_record_sql = "<< update_record_sql << " --- " << this;
  1127. Error_manager ec = Database_controller::get_instance_pointer()->sql_update(update_record_sql);
  1128. return ec;
  1129. }
  1130. //更新 记录表, 取车指令 完成后更新取车记录
  1131. Error_manager Dispatch_command::updata_record_for_pick_end()
  1132. {
  1133. Time_tool::get_instance_references().time_end(PICK_TIME_FLAG);
  1134. int out_time_difference = Time_tool::get_instance_references().get_time_seconds(PICK_TIME_FLAG);
  1135. int parking_time;
  1136. get_parking_time(m_dispatch_command_map[m_car_number_optimal].m_primary_key, parking_time);
  1137. char parking_time_string[256] = "";
  1138. int hour = parking_time / 3600;
  1139. int min = (parking_time / 60)%60;
  1140. int sec = parking_time % 60;
  1141. sprintf(parking_time_string, " %d:%02d:%02d", hour, min, sec);
  1142. //执行sql操作
  1143. char update_record_sql[1024];
  1144. memset(update_record_sql, 0, 1024);
  1145. sprintf(update_record_sql, "update record set out_time_end = '%s', out_time_difference = %d, parking_time = '%s' where primary_key = '%s' ",
  1146. Time_tool::get_instance_references().get_current_time_seconds().c_str(),
  1147. out_time_difference,
  1148. parking_time_string,
  1149. m_dispatch_command_map[m_car_number_optimal].m_primary_key.c_str() );
  1150. LOG(INFO) << " update_record_sql = "<< update_record_sql << " --- " << this;
  1151. Error_manager ec = Database_controller::get_instance_pointer()->sql_update(update_record_sql);
  1152. return ec;
  1153. }
  1154. //更新 记录表, 取车指令 完成后更新取车记录, 撤销指令, 没有取车时间差
  1155. Error_manager Dispatch_command::updata_record_for_pick_end_ex()
  1156. {
  1157. int parking_time;
  1158. get_parking_time(m_dispatch_command_map[m_car_number_optimal].m_primary_key, parking_time);
  1159. char parking_time_string[256] = "";
  1160. int hour = parking_time / 3600;
  1161. int min = parking_time / 60;
  1162. int sec = parking_time % 60;
  1163. sprintf(parking_time_string, " %d:%02d:%02d", hour, min, sec);
  1164. //执行sql操作
  1165. char update_record_sql[1024];
  1166. memset(update_record_sql, 0, 1024);
  1167. sprintf(update_record_sql, "update record set out_time_end = '%s', parking_time = '%s' where primary_key = '%s' ",
  1168. Time_tool::get_instance_references().get_current_time_seconds().c_str(),
  1169. parking_time_string,
  1170. m_dispatch_command_map[m_car_number_optimal].m_primary_key.c_str() );
  1171. LOG(INFO) << " update_record_sql = "<< update_record_sql << " --- " << this;
  1172. Error_manager ec = Database_controller::get_instance_pointer()->sql_update(update_record_sql);
  1173. return ec;
  1174. }
  1175. //计算汽车在车库的存车时间, 从存车开始到取车结束, 返回 parking_time, 单位秒.
  1176. Error_manager Dispatch_command::get_parking_time(std::string primary_key, int & parking_time )
  1177. {
  1178. //查询存车时间 in_time_start
  1179. char query_record_sql[1024];
  1180. memset(query_record_sql, 0, 1024);
  1181. sprintf(query_record_sql,"select * from record where primary_key = '%s' ", primary_key.c_str() );
  1182. boost::shared_ptr<sql::ResultSet> tp_result = nullptr;
  1183. Error_manager ec = Database_controller::get_instance_pointer()->sql_query(query_record_sql, tp_result);
  1184. if(ec == SUCCESS)
  1185. {
  1186. if(tp_result == nullptr)
  1187. {
  1188. return DB_RESULT_SET_EMPTY;
  1189. }
  1190. //只取第一条结果, 默认是id最小的,
  1191. if (tp_result->next())
  1192. {
  1193. char buf[1024];
  1194. memset(buf, 0, 1024);
  1195. try
  1196. {
  1197. //解析数据
  1198. std::string in_time_start_string = tp_result->getString("in_time_start");
  1199. std::chrono::system_clock::time_point in_time_start = Time_tool::get_instance_references().transform_time_string_seconds(in_time_start_string);
  1200. std::chrono::system_clock::time_point out_time_end = std::chrono::system_clock::now();
  1201. double t_parking_time = (out_time_end - in_time_start).count() / 1000000000;
  1202. parking_time = t_parking_time;
  1203. return Error_code::SUCCESS;
  1204. }
  1205. catch (sql::SQLException &e)
  1206. {
  1207. /* Use what() (derived from std::runtime_error) to fetch the error message */
  1208. sprintf(buf, "# ERR: %s\n (MySQL error code: %d, SQLState: %s", e.what(), e.getErrorCode(), e.getSQLState().c_str());
  1209. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  1210. }
  1211. catch (std::runtime_error &e)
  1212. {
  1213. sprintf(buf, "# ERR: %s\n ERR: runtime_error in %s ", e.what(), __FILE__);
  1214. return Error_manager(DB_RESULT_SET_PARSE_ERROR, NEGLIGIBLE_ERROR, buf);
  1215. }
  1216. }
  1217. else
  1218. {
  1219. return Error_manager(Error_code::DB_NOT_QUERY_EMPTY_PARKSPACE, Error_level::MINOR_ERROR,
  1220. "数据库未查询到空车位 Parkspace_operating_function::query_one_empty_parkspace error ");
  1221. }
  1222. return SUCCESS;
  1223. }
  1224. else
  1225. {
  1226. return ec;
  1227. }
  1228. return Error_code::SUCCESS;
  1229. }