TerminalSimul.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. using Communication;
  2. using Google.Protobuf;
  3. using Message;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. namespace communicate_module.communication
  11. {
  12. class TerminalSimul : Communication.Communicator
  13. {
  14. protected TerminalSimul() : base()
  15. {
  16. map_lock = new object();
  17. license_status_map = new Dictionary<string, CAR_STATUS>();
  18. for (int i = 0; i < 10; i++)
  19. {
  20. string str = String.Format("鄂A{0:D5}", i);
  21. license_status_map.Add(str, CAR_STATUS.eCAR_IDEL);
  22. //Console.WriteLine(str);
  23. }
  24. park_terminal_status_map = new Dictionary<int, int>();
  25. for (int i = 0; i < 6; i++)
  26. {
  27. park_terminal_status_map.Add(i, 0);
  28. }
  29. fetch_terminal_status_map = new Dictionary<int, int>();
  30. for (int i = 0; i < 6; i++)
  31. {
  32. fetch_terminal_status_map.Add(i, 0);
  33. }
  34. park_license_map = new Dictionary<int, string>();
  35. fetch_license_map = new Dictionary<int, string>();
  36. }
  37. /// <summary>
  38. /// 单例访问
  39. /// </summary>
  40. public new static TerminalSimul GetInstance()
  41. {
  42. if (instance == null)
  43. {
  44. lock (lockObj)
  45. {
  46. if (instance == null)
  47. {
  48. instance = new TerminalSimul();
  49. }
  50. }
  51. }
  52. return (TerminalSimul)instance;
  53. }
  54. /// <summary>
  55. /// 检查消息
  56. /// </summary>
  57. /// <param name="header"></param>
  58. /// <returns></returns>
  59. public override bool CheckMsg(Base_info header)
  60. {
  61. if (header.HasMsgType && header.HasSender
  62. && ((header.MsgType == Message_type.EStoreCommandResponseMsg && header.Sender == Message.Communicator.EMain)
  63. || (header.MsgType == Message_type.EPickupCommandResponseMsg && header.Sender == Message.Communicator.EMain)
  64. || (header.MsgType == Message_type.EStoringProcessStatuMsg && header.Sender == Message.Communicator.EMain)
  65. || (header.MsgType == Message_type.EPickingProcessStatuMsg && header.Sender == Message.Communicator.EMain)
  66. )
  67. )
  68. return true;
  69. else
  70. return false;
  71. }
  72. /// <summary>
  73. /// 检查执行器状态
  74. /// </summary>
  75. /// <param name="header"></param>
  76. /// <param name="receiveTime"></param>
  77. /// <returns></returns>
  78. public override CheckExecuterReturn CheckExecuter(Base_info header, DateTime receiveTime)
  79. {
  80. if ((DateTime.Now - receiveTime).Milliseconds > header.TimeoutMs)
  81. return CheckExecuterReturn.MSG_TIMEOUT;
  82. else
  83. return CheckExecuterReturn.EXECUTER_READY;
  84. }
  85. /// <summary>
  86. /// 执行消息
  87. /// </summary>
  88. /// <param name="msgStamped"></param>
  89. /// <returns></returns>
  90. public override bool ExecuteMsg(MsgStamped msgStamped)
  91. {
  92. if (msgStamped == null || msgStamped.header==null)
  93. return false;
  94. switch(msgStamped.header.MsgType)
  95. {
  96. case Message_type.EStoreCommandResponseMsg:
  97. Store_command_response_msg store_Command_Response_Msg = Store_command_response_msg.Parser.ParseFrom(msgStamped.msg);
  98. Console.WriteLine("停车终端 " + store_Command_Response_Msg.TerminalId + " 签收, " + (store_Command_Response_Msg.Code.ErrorCode == 0?"成功":"失败"));
  99. break;
  100. case Message_type.EPickupCommandResponseMsg:
  101. Pickup_command_response_msg pickup_Command_Response_Msg = Pickup_command_response_msg.Parser.ParseFrom(msgStamped.msg);
  102. Console.WriteLine("取车终端 " + pickup_Command_Response_Msg.TerminalId + " 签收, " + (pickup_Command_Response_Msg.Code.ErrorCode == 0 ? "成功" : "失败"));
  103. break;
  104. case Message_type.EStoringProcessStatuMsg:
  105. Storing_process_statu_msg storing_Process_Statu_Msg = Storing_process_statu_msg.Parser.ParseFrom(msgStamped.msg);
  106. if (storing_Process_Statu_Msg.Completed || storing_Process_Statu_Msg.BackCompleted)
  107. {
  108. bool forward = storing_Process_Statu_Msg.Completed;
  109. lock (map_lock)
  110. {
  111. if (park_license_map.ContainsKey(storing_Process_Statu_Msg.TerminalId))
  112. {
  113. string lic = park_license_map[storing_Process_Statu_Msg.TerminalId];
  114. if (license_status_map.ContainsKey(lic))
  115. {
  116. string whether_success = "";
  117. if (forward)
  118. {
  119. // 车辆状态修改
  120. license_status_map[lic] = CAR_STATUS.eCAR_PARKED;
  121. whether_success = "成功";
  122. }
  123. else
  124. {
  125. license_status_map[lic] = CAR_STATUS.eCAR_IDEL;
  126. whether_success = "失败";
  127. }
  128. // 停车流程结束,删除记录
  129. park_license_map.Remove(storing_Process_Statu_Msg.TerminalId);
  130. // 停车终端复位
  131. park_terminal_status_map[storing_Process_Statu_Msg.TerminalId] = 0;
  132. Console.WriteLine("停车 " + lic + " 完成, " + whether_success);
  133. }
  134. }
  135. else
  136. {
  137. //Console.WriteLine("未找到与反馈对应停车流程???");
  138. }
  139. }
  140. }
  141. break;
  142. case Message_type.EPickingProcessStatuMsg:
  143. Picking_process_statu_msg picking_Process_Statu_Msg = Picking_process_statu_msg.Parser.ParseFrom(msgStamped.msg);
  144. if (picking_Process_Statu_Msg.Completed || picking_Process_Statu_Msg.BackCompleted)
  145. {
  146. bool forward = picking_Process_Statu_Msg.Completed;
  147. lock (map_lock)
  148. {
  149. if (fetch_license_map.ContainsKey(picking_Process_Statu_Msg.TerminalId))
  150. {
  151. string lic = fetch_license_map[picking_Process_Statu_Msg.TerminalId];
  152. if (license_status_map.ContainsKey(lic))
  153. {
  154. string whether_success = "";
  155. if (forward)
  156. {
  157. license_status_map[lic] = CAR_STATUS.eCAR_IDEL;
  158. whether_success = "成功";
  159. }
  160. else
  161. {
  162. license_status_map[lic] = CAR_STATUS.eCAR_PARKED;
  163. whether_success = "失败";
  164. }
  165. fetch_license_map.Remove(picking_Process_Statu_Msg.TerminalId);
  166. fetch_terminal_status_map[picking_Process_Statu_Msg.TerminalId] = 0;
  167. Console.WriteLine("取车 " + lic + " 完成, " + whether_success);
  168. }
  169. }
  170. else
  171. {
  172. //Console.WriteLine("未找到与反馈对应取车流程???");
  173. }
  174. }
  175. }
  176. break;
  177. }
  178. return true;
  179. }
  180. /// <summary>
  181. /// 模拟终端与主控发送消息
  182. /// </summary>
  183. public void CreateSimulThread()
  184. {
  185. Task.Factory.StartNew(()=> {
  186. Random rnd = new Random();
  187. while(!mb_exit)
  188. {
  189. int act = rnd.Next(1, 4);
  190. lock (map_lock) {
  191. switch (act)
  192. {
  193. // 停车
  194. case 1:
  195. // 找一辆空闲车发送停车指令
  196. string park_lic = "";
  197. KeyValuePair<string, CAR_STATUS> t_park_lic_pair;
  198. for (int i = 0; i < license_status_map.Count; i++)
  199. {
  200. t_park_lic_pair = license_status_map.ElementAt(i);
  201. if (t_park_lic_pair.Value == CAR_STATUS.eCAR_IDEL)
  202. {
  203. park_lic = t_park_lic_pair.Key;
  204. break;
  205. }
  206. }
  207. if(park_lic != "")
  208. {
  209. Store_command_request_msg t_store_req = new Store_command_request_msg();
  210. t_store_req.BaseInfo = new Base_info();
  211. t_store_req.BaseInfo.MsgType = Message_type.EStoreCommandRequestMsg;
  212. t_store_req.BaseInfo.TimeoutMs = 5000;
  213. t_store_req.BaseInfo.Sender = Message.Communicator.ETerminor;
  214. t_store_req.BaseInfo.Receiver = Message.Communicator.EMain;
  215. // 寻找空闲终端
  216. int termId = GetParkTerminalId();
  217. if(termId>=0)
  218. {
  219. t_store_req.TerminalId = termId;
  220. t_store_req.LocateInformation = new Locate_information();
  221. t_store_req.LocateInformation.LocateX = 0.01f;
  222. t_store_req.LocateInformation.LocateY = 0.01f;
  223. t_store_req.LocateInformation.LocateAngle = 90.5f;
  224. t_store_req.LocateInformation.LocateLength = 0f;
  225. t_store_req.LocateInformation.LocateWidth = 0f;
  226. t_store_req.LocateInformation.LocateHeight = 0f;
  227. t_store_req.LocateInformation.LocateWheelBase = 2.64f;
  228. t_store_req.LocateInformation.LocateWheelWidth = 1.65f;
  229. t_store_req.LocateInformation.LocateCorrect = true;
  230. t_store_req.LocateInformation.LocateFrontTheta = 0f;
  231. t_store_req.CarInfo = new Car_info();
  232. t_store_req.CarInfo.License = park_lic;
  233. t_store_req.CarInfo.CarHeight = 1.7f;
  234. t_store_req.CarInfo.CarWheelWidth = t_store_req.LocateInformation.LocateWheelWidth;
  235. t_store_req.CarInfo.CarWheelBase = t_store_req.LocateInformation.LocateWheelBase;
  236. // 发送停车指令
  237. Console.WriteLine("停车 "+park_lic);
  238. Send_msg(t_store_req.ToByteString());
  239. license_status_map[park_lic] = CAR_STATUS.eCAR_PARKING;
  240. park_license_map.Add(termId, park_lic);
  241. }
  242. }
  243. break;
  244. // 取车
  245. case 2:
  246. // 找一辆占用车发送取车指令
  247. string fetch_lic = "";
  248. KeyValuePair<string, CAR_STATUS> t_fetch_lic_pair;
  249. for (int i = 0; i < license_status_map.Count; i++)
  250. {
  251. t_fetch_lic_pair = license_status_map.ElementAt(i);
  252. if (t_fetch_lic_pair.Value == CAR_STATUS.eCAR_PARKED)
  253. {
  254. fetch_lic = t_fetch_lic_pair.Key;
  255. break;
  256. }
  257. }
  258. if(fetch_lic!="")
  259. {
  260. Pickup_command_request_msg pick_req = new Pickup_command_request_msg();
  261. pick_req.BaseInfo = new Base_info();
  262. pick_req.BaseInfo.MsgType = Message_type.EPickupCommandRequestMsg;
  263. pick_req.BaseInfo.TimeoutMs = 5000;
  264. pick_req.BaseInfo.Sender = Message.Communicator.ETerminor;
  265. pick_req.BaseInfo.Receiver = Message.Communicator.EMain;
  266. // 寻找空闲终端
  267. int termId = GetFetchTerminalId();
  268. if(termId >=0)
  269. {
  270. pick_req.TerminalId = termId;
  271. pick_req.CarInfo = new Car_info();
  272. pick_req.CarInfo.License = fetch_lic;
  273. // 发送取车指令
  274. Console.WriteLine("取车 " + fetch_lic);
  275. Send_msg(pick_req.ToByteString());
  276. license_status_map[fetch_lic] = CAR_STATUS.eCAR_FETCHING;
  277. fetch_license_map.Add(termId, fetch_lic);
  278. }
  279. }
  280. break;
  281. // 不处理
  282. case 3:
  283. break;
  284. }
  285. }
  286. Thread.Sleep(2000);
  287. }
  288. });
  289. }
  290. protected int GetParkTerminalId()
  291. {
  292. int termId = -1;
  293. KeyValuePair<int, int> t_res;
  294. for (int i = 0; i < park_terminal_status_map.Count; i++)
  295. {
  296. t_res = park_terminal_status_map.ElementAt(i);
  297. // 停取终端同时空闲
  298. if (t_res.Value == 0)
  299. {
  300. termId = t_res.Key;
  301. break;
  302. }
  303. }
  304. if(termId>=0)
  305. park_terminal_status_map[termId] = 1;
  306. return termId;
  307. }
  308. protected int GetFetchTerminalId()
  309. {
  310. int termId = -1;
  311. KeyValuePair<int, int> t_res;
  312. for (int i = 0; i < fetch_terminal_status_map.Count; i++)
  313. {
  314. t_res = fetch_terminal_status_map.ElementAt(i);
  315. if (t_res.Value == 0)
  316. {
  317. termId = t_res.Key;
  318. break;
  319. }
  320. }
  321. if (termId >= 0)
  322. fetch_terminal_status_map[termId] = 1;
  323. return termId;
  324. }
  325. public enum CAR_STATUS
  326. {
  327. eCAR_IDEL,
  328. eCAR_PARKED,
  329. eCAR_PARKING,
  330. eCAR_FETCHING,
  331. }
  332. protected object map_lock;
  333. // 车辆状态表
  334. protected Dictionary<string, CAR_STATUS> license_status_map;
  335. // 记录停车终端当前号牌
  336. protected Dictionary<int, string> park_license_map;
  337. // 记录取车终端当前号牌
  338. protected Dictionary<int, string> fetch_license_map;
  339. // 0空闲,非零占用
  340. protected Dictionary<int, int> park_terminal_status_map;
  341. // 0空闲,非零占用
  342. protected Dictionary<int, int> fetch_terminal_status_map;
  343. }
  344. }