AbstractCmd.cs 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using parkMonitor.LOG;
  7. using parkMonitor.entity;
  8. using parkMonitor.model;
  9. using System.Configuration;
  10. using System.Threading;
  11. using parkMonitor.server.uiLogServer;
  12. using parkMonitor.tools;
  13. using parkMonitor.Database2;
  14. using MySql.Data.MySqlClient;
  15. using parkMonitor.server.NumMachine;
  16. namespace parkMonitor.server.CoreThread
  17. {
  18. /// <summary>
  19. /// 核心对命令处理父类
  20. /// </summary>
  21. public abstract class AbstractCmd
  22. {
  23. public static bool isClosing { get; set; }
  24. /// <summary>
  25. /// 设备总状态PLC地址
  26. /// </summary>
  27. public int equipmentStatus_address { set; get; }
  28. /// <summary>
  29. /// 停车完成PLC地址
  30. /// </summary>
  31. public int park_completed_address { set; get; }
  32. /// <summary>
  33. /// 停车入口X坐标
  34. /// </summary>
  35. public int parkingEntX { set; get; }
  36. /// <summary>
  37. /// 停车入口Y坐标
  38. /// </summary>
  39. public int parkingEntY { set; get; }
  40. /// <summary>
  41. /// 停车入口Z坐标
  42. /// </summary>
  43. public int parkingEntZ { set; get; }
  44. /// <summary>
  45. /// 取车完成PLC地址
  46. /// </summary>
  47. public int fetch_completed_address { set; get; }
  48. /// <summary>
  49. /// 轮距测量状态PLC地址
  50. /// </summary>
  51. public int wheelbase_status_address { get; set; }
  52. /// <summary>
  53. /// 停车启动机械手PLC地址
  54. /// </summary>
  55. public int parking_startRobot_address { get; set; }
  56. /// <summary>
  57. /// 取车启动机械手PLC地址
  58. /// </summary>
  59. public int fetching_startRobot_address { get; set; }
  60. /// <summary>
  61. /// 前轮距PLC地址
  62. /// </summary>
  63. public int frontWheelbase_address { get; set; }
  64. /// <summary>
  65. /// 后轮距PLC地址
  66. /// </summary>
  67. public int rearWheelbase_address { get; set; }
  68. /// <summary>
  69. /// PLC句柄
  70. /// </summary>
  71. public IEquipments PLC { set; get; }
  72. /// <summary>
  73. /// 队列线程句柄
  74. /// </summary>
  75. public IEquipments queuingThread { set; get; }
  76. /// <summary>
  77. /// 数据库操作句柄
  78. /// </summary>
  79. public DBOperation oper { set; get; }
  80. /// <summary>
  81. /// 号牌机线程句柄
  82. /// </summary>
  83. public IEquipments NumMachine { set; get; }
  84. /// <summary>
  85. /// 车库中心
  86. /// </summary>
  87. public CEntrance cEntrance { set; get; }
  88. public AbstractCmd()
  89. {
  90. parking_startRobot_address = EntityForCore.ins.parking_startRobot_address;
  91. fetching_startRobot_address = EntityForCore.ins.fetching_startRobot_address;
  92. equipmentStatus_address = EntityForCore.ins.equipmentStatus_address;
  93. park_completed_address = EntityForCore.ins.park_completed_address;
  94. parkingEntX = EntityForCore.ins.parkingEntX;
  95. parkingEntY = EntityForCore.ins.parkingEntY;
  96. parkingEntZ = EntityForCore.ins.parkingEntZ;
  97. //轮距
  98. frontWheelbase_address = EntityForCore.ins.frontWheelbase_address;
  99. rearWheelbase_address = EntityForCore.ins.rearWheelbase_address;
  100. wheelbase_status_address = EntityForCore.ins.wheelbase_status_address;
  101. //取车完成
  102. fetch_completed_address = EntityForCore.ins.fetch_completed_address;
  103. //获取PLC句柄
  104. PLC = EquipmentSimpleFactory.ins.FindEquipment(EquipmentName.PLC);
  105. //获取队列句柄
  106. queuingThread = EquipmentSimpleFactory.ins.FindEquipment(EquipmentName.Queue);
  107. //获取号牌机线程句柄
  108. NumMachine = EquipmentSimpleFactory.ins.FindEquipment(EquipmentName.NumMachine);
  109. //数据库
  110. oper = new DBOperation();
  111. //车位分配
  112. cEntrance = new CEntrance();
  113. Robot.robot1.parking_start_addr = parking_startRobot_address;
  114. Robot.robot1.fetching_start_addr = fetching_startRobot_address;
  115. //locationOper = new DBLocationOperator();
  116. }
  117. public abstract void executeCmd(Command queueCmd);
  118. /// <summary>
  119. /// 等待机械手空闲资源
  120. /// </summary>
  121. /// <param name="robotID"></param>
  122. /// <returns></returns>
  123. public bool WaitForRobotResource(int robotID)
  124. {
  125. PLCMessage PLCMsg = null;
  126. MyTimer mt = new MyTimer();
  127. mt.StartTiming();
  128. lock (Robot.robot1)
  129. {
  130. while (!isClosing)
  131. {
  132. PLCMsg = (PLCMessage)PLC.GetMessage();
  133. bool occupied = true;
  134. if (PLCMsg != null)
  135. {
  136. if (robotID == 1)
  137. {
  138. try
  139. {
  140. Robot.robot1.parking_start_value = Convert.ToInt32(PLCMsg.originalPlcList[parking_startRobot_address].Value);
  141. Robot.robot1.fetching_start_value = Convert.ToInt32(PLCMsg.originalPlcList[fetching_startRobot_address].Value);
  142. //刷新机械手资源状态值
  143. if (Robot.robot1.parking_start_value == 0 && Robot.robot1.fetching_start_value == 0 && !Robot.robot1.occupied)
  144. {
  145. occupied = false;
  146. }
  147. else
  148. {
  149. occupied = true;
  150. }
  151. }
  152. catch { }
  153. }
  154. }
  155. if (occupied)
  156. {
  157. Thread.Sleep(3000);
  158. }
  159. else
  160. {
  161. Robot.robot1.occupied = true;
  162. //UILogServer.ins.log("获得机械手资源");
  163. Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "获得机械手资源");
  164. break;
  165. }
  166. mt.EndTiming();
  167. int activationCount = 0;
  168. if (mt.IsLonger(60, 1, false, out activationCount))
  169. {
  170. if (activationCount == 1)
  171. {
  172. UILogServer.ins.info("无空闲机械手资源,继续等待");
  173. }
  174. if (MyTimer.restart && !mt.rolledBack)
  175. {
  176. mt.rolledBack = true;
  177. Robot.robot1.occupied = false;
  178. UILogServer.ins.error("启动机械手资源超时,已启动回滚");
  179. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "启动机械手资源超时,已启动回滚");
  180. return false;
  181. }
  182. Thread.Sleep(100);
  183. }
  184. }
  185. }
  186. return true;
  187. }
  188. /// /// <summary>
  189. /// 流程回滚函数
  190. /// </summary>
  191. /// <param name="queueCmd"></param>
  192. /// <param name="parkingSpaceID"></param>
  193. /// <param name="robotAllocated"></param>
  194. /// <param name="isParking"></param>
  195. public void Rollback(Command queueCmd, int parkingSpaceID, bool robotAllocated, bool isParking, LaserMessage lm)
  196. {
  197. //命令回退
  198. queueCmd.returnedCount += 1;
  199. queuingThread.SetMessage(queueCmd);
  200. //线程计数调整
  201. if (robotAllocated)
  202. {
  203. Robot.robot1.occupied = false;
  204. }
  205. Robot.robot1.waitCount -= 1;
  206. //释放激光
  207. if (lm != null)
  208. {
  209. lm.occupied = false;
  210. }
  211. if (parkingSpaceID == 0)
  212. {
  213. return;
  214. }
  215. //复位车辆状态;若已更新过车位则还需复位总车位数,车位状态
  216. if (!queueCmd.manual)
  217. {
  218. if (isParking)
  219. {
  220. //释放已分配车位
  221. if (!ParkingSpaceManager.ins.SetParkingSpace(parkingSpaceID, 0))
  222. {
  223. EntityForCore.ins.globalStatus = false;
  224. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "车位分配出现异常,需要重启");
  225. return;
  226. }
  227. }
  228. else
  229. {
  230. //复原已释放的车位
  231. if (!ParkingSpaceManager.ins.SetParkingSpace(parkingSpaceID, 1))
  232. {
  233. EntityForCore.ins.globalStatus = false;
  234. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "车位分配出现异常,需要重启");
  235. return;
  236. }
  237. }
  238. }
  239. else
  240. {
  241. if (isParking)
  242. {
  243. oper.UpdateVehicleParkState(EntityForCore.remoteBQ, queueCmd.LicenseNum, 0);
  244. if (robotAllocated)
  245. {
  246. oper.UpdateParkingSpaceState(EntityForCore.remoteBQ, parkingSpaceID, 0);
  247. }
  248. }
  249. else
  250. {
  251. oper.UpdateVehicleParkState(EntityForCore.remoteBQ, queueCmd.LicenseNum, 1);
  252. if (robotAllocated)
  253. {
  254. oper.UpdateParkingSpaceState(EntityForCore.remoteBQ, parkingSpaceID, 1);
  255. }
  256. }
  257. }
  258. }
  259. }
  260. /// <summary>
  261. /// 停车命令处理类
  262. /// </summary>
  263. public class StopCmd : AbstractCmd
  264. {
  265. /// <summary>
  266. /// 停车数据库事务
  267. /// </summary>
  268. private void StopParkingSubmit()
  269. {
  270. }
  271. /// <summary>
  272. /// 命令中号牌与对应号牌机中当前号牌比对,确认车辆
  273. /// </summary>
  274. private bool NumValidation(Command queueCmd, int countdown, float ratio)
  275. {
  276. List<NumberMachineNode> numList = ((NumberMachineMessage)NumMachine.GetMessage()).data;
  277. bool result = false;
  278. Task numberCheck = Task.Factory.StartNew(() =>
  279. {
  280. int myCountdown = countdown, count = 0;
  281. while (myCountdown-- > 0)
  282. {
  283. foreach (NumberMachineNode node in numList)
  284. {
  285. if (queueCmd.ip.Equals(node.ip) && queueCmd.LicenseNum.Equals(node.LicenseNum))
  286. {
  287. count += 1;
  288. }
  289. }
  290. Thread.Sleep(500);
  291. }
  292. if (count >= (int)(countdown * ratio))
  293. {
  294. result = true;
  295. }
  296. else
  297. {
  298. result = false;
  299. }
  300. });
  301. numberCheck.Wait();
  302. return result;
  303. }
  304. /// <summary>
  305. /// 号牌复位
  306. /// </summary>
  307. private void NumReset(Command queueCmd)
  308. {
  309. NumberMachineMessage numberMachineMessage = new NumberMachineMessage();
  310. numberMachineMessage.aNode = new NumberMachineNode();
  311. numberMachineMessage.aNode.ip = "";
  312. numberMachineMessage.aNode.LicenseNum = queueCmd.LicenseNum;
  313. queuingThread.SetMessage(numberMachineMessage);
  314. }
  315. /// <summary>
  316. /// 车位资源
  317. /// </summary>
  318. /// <param name="queueCmd"></param>
  319. /// <returns></returns>
  320. private Parking_Space WaitForParkingSpaceResource(Command queueCmd, out int count)
  321. {
  322. //中心点
  323. cEntrance.parkingEntX = parkingEntX;
  324. cEntrance.parkingEntY = parkingEntY;
  325. cEntrance.parkingEntZ = parkingEntZ;
  326. Parking_Space ppp = new Parking_Space();
  327. MyTimer mt = new MyTimer();
  328. mt.StartTiming();
  329. count = 0;
  330. while (!isClosing && ParkingSpaceManager.ins != null)
  331. {
  332. if (!queueCmd.manual)
  333. {
  334. ppp = ParkingSpaceManager.ins.MallocParkingSpace(cEntrance, queueCmd, false, out count);//自动
  335. }
  336. else
  337. {
  338. ppp = ParkingSpaceManager.ins.MallocParkingSpace(cEntrance, queueCmd, false, out count);//手动
  339. }
  340. if (ppp != null)
  341. {
  342. Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "停车流程:" + queueCmd.LicenseNum + "已分配车位");
  343. break;
  344. }
  345. Thread.Sleep(200);
  346. mt.EndTiming();
  347. int activationCount = 0;
  348. if (mt.IsLonger(5, 1, false, out activationCount))
  349. {
  350. if (activationCount == 1)
  351. {
  352. UILogServer.ins.info("停车流程:" + queueCmd.LicenseNum + "未获得车位");
  353. }
  354. if (MyTimer.restart && !mt.rolledBack)
  355. {
  356. mt.rolledBack = true;
  357. UILogServer.ins.error(queueCmd.LicenseNum + "超时未获得车位,指令退回");
  358. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, queueCmd.LicenseNum + "超时未获得车位,指令退回");
  359. return null;
  360. }
  361. Thread.Sleep(100);
  362. }
  363. }
  364. return ppp;
  365. }
  366. /// <summary>
  367. /// 等待激光数据
  368. /// </summary>
  369. /// <param name="queueCmd">传入的命令</param>
  370. /// <param name="disappeared">车辆是否已驶离</param>
  371. /// <returns></returns>
  372. private Data WaitForLaserResource(Command queueCmd, bool disappeared, out LaserMessage lmRelease)
  373. {
  374. //激光数据
  375. Data data = new Data();
  376. bool jumpOut = false;
  377. int disconnectionCount = 0;
  378. int laserID = queueCmd.id / 6 + 1;
  379. PLCMessage PLCMsg = null;
  380. jumpOut = false;
  381. lmRelease = null;
  382. MyTimer mt = new MyTimer();
  383. mt.StartTiming();
  384. while (!isClosing)
  385. {
  386. PLCMsg = (PLCMessage)PLC.GetMessage();
  387. if (PLCMsg != null)
  388. {
  389. foreach (LaserMessage lm in PLCMsg.laserMsgList)
  390. {
  391. if (lm.id == laserID && lm.data != null)
  392. {
  393. lock (lm)
  394. {
  395. //判断车辆检测结果,
  396. if (disappeared)
  397. {
  398. lm.abort_rescan = true;
  399. jumpOut = true;
  400. break;
  401. }
  402. //存储相应激光数据
  403. if (lm.recorded && lm.licenseNum == queueCmd.LicenseNum)
  404. {
  405. data.angleA = lm.data.angleA;
  406. data.centerX = lm.data.centerX;
  407. data.centerY = lm.data.centerY;
  408. data.length = lm.data.length;
  409. data.width = lm.data.width;
  410. data.height = lm.data.height;
  411. jumpOut = true;
  412. lm.recorded = false;
  413. //lm.occupied = false;
  414. lmRelease = lm;
  415. lm.licenseNum = "";
  416. break;
  417. }
  418. else if (lm.status == 5)
  419. {
  420. disconnectionCount += 1;
  421. if (disconnectionCount == 1)
  422. {
  423. UILogServer.ins.error("激光" + lm.id + "连接异常");
  424. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "激光" + lm.id + "连接异常");
  425. }
  426. Thread.Sleep(10000);
  427. }
  428. }
  429. }
  430. Thread.Sleep(500);
  431. }
  432. if (jumpOut)
  433. {
  434. //UILogServer.ins.log("停车流程:" + queueCmd.LicenseNum + "激光数据已获得");
  435. Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "停车流程:" + queueCmd.LicenseNum + "激光数据已获得");
  436. break;
  437. }
  438. }
  439. Thread.Sleep(1000);
  440. mt.EndTiming();
  441. int activationCount = 0;
  442. if (mt.IsLonger(30, 1, false, out activationCount))
  443. {
  444. if (activationCount == 1)
  445. {
  446. UILogServer.ins.info("停车流程:" + queueCmd.LicenseNum + "未获取激光数据,继续等待");
  447. }
  448. if (MyTimer.restart && !mt.rolledBack)
  449. {
  450. mt.rolledBack = true;
  451. UILogServer.ins.error(queueCmd.LicenseNum + "超时未获取激光数据,指令退回");
  452. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, queueCmd.LicenseNum + "超时未获取激光数据,指令退回");
  453. return null;
  454. }
  455. Thread.Sleep(100);
  456. }
  457. }
  458. return data;
  459. }
  460. /// <summary>
  461. /// 停车完成
  462. /// </summary>
  463. private bool WaitForStoreCompletionSignal(Command queueCmd, int parkingSpaceID, ref bool robotError, int status)
  464. {
  465. string connectionStr = null;
  466. PLCMessage PLCMsg = null;
  467. MyTimer mt = new MyTimer();
  468. mt.StartTiming();
  469. while (!isClosing)
  470. {
  471. Thread.Sleep(1000);
  472. PLCMsg = (PLCMessage)PLC.GetMessage();
  473. int storeStatus = Convert.ToInt32(PLCMsg.originalPlcList[park_completed_address].Value);
  474. //停车完成信号
  475. if (storeStatus == status)
  476. {
  477. //UILogServer.ins.log("停车流程:" + queueCmd.LicenseNum + "已获得停车完成信号" + status);
  478. Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "停车流程:" + queueCmd.LicenseNum + "已获得停车完成信号" + status);
  479. break;
  480. }
  481. else if (1 == 2)//机械手异常,则退指令,写数据库归位,判断条件需之后补充
  482. {
  483. robotError = true;
  484. queueCmd.returnedCount += 1;
  485. queuingThread.SetMessage(queueCmd);
  486. if (!queueCmd.manual)
  487. {
  488. oper.UpdateParkingSpaceState(EntityForCore.remoteBQ, parkingSpaceID, 0);
  489. }
  490. else
  491. {
  492. connectionStr = "SqlConnectionLocation";
  493. oper.UpdateParkingSpaceState(EntityForCore.localBQ, parkingSpaceID, 0);
  494. }
  495. break;
  496. }
  497. mt.EndTiming();
  498. int activationCount = 0;
  499. if (mt.IsLonger(120, 1, false, out activationCount))
  500. {
  501. if (activationCount == 1)
  502. {
  503. UILogServer.ins.info("停车流程:" + queueCmd.LicenseNum + "未获得停车完成信号" + status + ",继续等待");
  504. }
  505. if (MyTimer.restart && !mt.rolledBack)
  506. {
  507. mt.rolledBack = true;
  508. UILogServer.ins.error(queueCmd.LicenseNum + "等待停车完成信号" + status + "超时,流程回滚");
  509. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, queueCmd.LicenseNum + "等待停车完成信号" + status + "超时,流程回滚");
  510. return false;
  511. }
  512. Thread.Sleep(100);
  513. }
  514. }
  515. return true;
  516. }
  517. /// <summary>
  518. /// 等待轮距信息
  519. /// </summary>
  520. /// <param name="frontWheelbase">前轮距</param>
  521. /// <param name="rearWheelbase">后轮距</param>
  522. private bool WaitWheelbase(ref int frontWheelbase, ref int rearWheelbase)
  523. {
  524. PLCMessage PLCMsg = null;
  525. MyTimer mt = new MyTimer();
  526. mt.StartTiming();
  527. while (!isClosing)
  528. {
  529. PLCMsg = (PLCMessage)PLC.GetMessage();
  530. int wheelbaseStatus = Convert.ToInt32(PLCMsg.originalPlcList[wheelbase_status_address].Value);
  531. //停车完成信号
  532. if (wheelbaseStatus == 3)
  533. {
  534. frontWheelbase = Convert.ToInt32(PLCMsg.originalPlcList[frontWheelbase_address].Value);
  535. rearWheelbase = Convert.ToInt32(PLCMsg.originalPlcList[rearWheelbase_address].Value);
  536. //UILogServer.ins.log("轮距雷达完成状态已获取");
  537. Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "轮距雷达完成状态已获取");
  538. break;
  539. }
  540. Thread.Sleep(1000);
  541. mt.EndTiming();
  542. int activationCount = 0;
  543. if (mt.IsLonger(60, 1, false, out activationCount))
  544. {
  545. if (activationCount == 1)
  546. {
  547. UILogServer.ins.info("未获取轮距雷达完成状态,继续等待");
  548. }
  549. if (MyTimer.restart && !mt.rolledBack)
  550. {
  551. mt.rolledBack = true;
  552. UILogServer.ins.error("超时未获取轮距雷达数据,流程回滚");
  553. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "超时未获取轮距雷达数据,流程回滚");
  554. return false;
  555. }
  556. Thread.Sleep(100);
  557. }
  558. }
  559. return true;
  560. }
  561. /// <summary>
  562. /// 停车流程
  563. /// </summary>
  564. /// <param name="queueCmd"></param>
  565. public override void executeCmd(Command queueCmd)
  566. {
  567. //UILogServer.ins.info("停车流程:" + queueCmd.LicenseNum + "开始");
  568. Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "停车流程:" + queueCmd.LicenseNum + "开始");
  569. string connectionStr = null; //数据库连接字符串
  570. bool disappeared = false; //车辆检测结果
  571. bool stopChecking = false; //是否停止检测
  572. bool robotError = false; //机械手是否异常
  573. int userID = 0; //用户ID
  574. //第一步,激光与车位:
  575. int status = 1;//停车
  576. ControlMessage cm = new ControlMessage();
  577. cm.status = status;
  578. //根据号牌机id启动对应激光
  579. cm.laserID = queueCmd.id / 6 + 1;
  580. cm.LicenseNum = queueCmd.LicenseNum;
  581. PLC.SetMessage(cm);
  582. Log.WriteLog(LogType.NOT_DATABASE, "停车流程:车牌号为" + queueCmd.LicenseNum + "的车辆准备开启激光");
  583. //UILogServer.ins.info("停车流程:车牌号为" + queueCmd.LicenseNum + "的车辆准备开启激光");
  584. //车位分配数据库操作加锁,直到启动机械手
  585. Parking_Space ppp = new Parking_Space();
  586. ParkingBuffer pb = null;
  587. Data dataReal = new Data();
  588. int garageID; //车库ID(Web发送)
  589. string realParkTime; //停车时间(可执行队列)
  590. LaserMessage lmToBeReleased; //激光
  591. int freeSpaceCount = 0; //剩余空闲车位
  592. dataReal = WaitForLaserResource(queueCmd, disappeared, out lmToBeReleased);
  593. //判断激光资源有效性,无效代表超时且已点击回滚按钮
  594. if (dataReal == null)
  595. {
  596. Rollback(queueCmd, 0, false, true, lmToBeReleased);
  597. return;
  598. }
  599. //车位分配锁
  600. lock (Parking_Space.spaceLock)
  601. {
  602. bool displayed = false;
  603. //等待获取缓冲位资源
  604. //获取车位资源
  605. ppp = WaitForParkingSpaceResource(queueCmd, out freeSpaceCount);
  606. //过期号牌判断
  607. if (queueCmd.userID != "")
  608. {
  609. userID = Convert.ToInt32(queueCmd.userID);
  610. }
  611. garageID = queueCmd.garageID;
  612. realParkTime = queueCmd.TimeRecord;
  613. //定义号牌验证与机械手异常标志
  614. //Task checkNum = Task.Factory.StartNew(() =>
  615. //{
  616. // DateTime startTime = DateTime.Now;
  617. // DateTime endTime = DateTime.Now;
  618. // TimeSpan t = startTime - endTime;
  619. // while (!stopChecking && t.TotalSeconds <= 600)
  620. // {
  621. // //号牌验证,异常则退回队列
  622. // Func<Command, int, float, bool> numValidationResult = new Func<Command, int, float, bool>(NumValidation);
  623. // IAsyncResult result = numValidationResult.BeginInvoke(queueCmd, 10, 0.7f, null, null);
  624. // bool checkResult = numValidationResult.EndInvoke(result);
  625. // if (stopChecking)
  626. // {
  627. // return;
  628. // }
  629. // if (!checkResult)
  630. // {
  631. // UILogServer.ins.info("停车命令" + queueCmd.LicenseNum + " 与当前车辆不一致");
  632. // disappeared = true;
  633. // return;
  634. // //未能停车,将车辆状态复位
  635. // //oper.UpdateVehicleParkState(queueCmd.LicenseNum, 0);
  636. // }
  637. // endTime = DateTime.Now;
  638. // t = startTime - endTime;
  639. // }
  640. //});
  641. //判断车位资源有效性,无效则回滚
  642. if (ppp == null)
  643. {
  644. Rollback(queueCmd, 0, false, true, lmToBeReleased);
  645. return;
  646. }
  647. while (pb == null && !MyTimer.restart)
  648. {
  649. //pb = ParkingBufferManager.ins.MallocParkingBuffer(queueCmd.id);
  650. pb = new ParkingBuffer(ppp.parkingSpaceX, true);
  651. ParkingBufferManager.ins.SetParkingBuffer(ppp.parkingSpaceX, true);
  652. if (pb != null)
  653. {
  654. Log.WriteLog(LogType.NOT_DATABASE, LogFile.INFO, queueCmd.LicenseNum + "分配缓冲位:" + pb.bufferID);
  655. break;
  656. }
  657. else if (!displayed)
  658. {
  659. UILogServer.ins.error(queueCmd.LicenseNum + "缓冲位已满");
  660. Log.WriteLog(LogType.NOT_DATABASE, LogFile.WARNING, queueCmd.LicenseNum + "缓冲位分配失败");
  661. displayed = true;
  662. }
  663. Thread.Sleep(2000);
  664. }
  665. if (pb == null)
  666. {
  667. UILogServer.ins.error("缓冲位分配失败,流程已回滚");
  668. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "缓冲位分配失败,流程已回滚");
  669. Rollback(queueCmd, 0, false, true, lmToBeReleased);
  670. return;
  671. }
  672. //车位赋值与写数据库
  673. if (!queueCmd.manual)
  674. {
  675. }
  676. else
  677. {
  678. //更新本地车位表车位状态
  679. oper.UpdateParkingSpaceState(EntityForCore.localBQ, ppp.parkingSpaceID, 1);
  680. //更新车库表剩余车位数
  681. //int freeSpaceCount = oper.getGarageFreeSpace(connectionStr, garageID);
  682. //freeSpaceCount = freeSpaceCount - 1;
  683. //oper.UpdateGarageFreeSpace(CoreThreadTest2.localBQ, freeSpaceCount, garageID);
  684. }
  685. //号牌失效,数据库回滚
  686. if (disappeared)
  687. {
  688. NumReset(queueCmd);
  689. if (!queueCmd.manual)
  690. {
  691. oper.UpdateVehicleParkState(EntityForCore.remoteBQ, queueCmd.LicenseNum, 0);
  692. }
  693. else
  694. {
  695. oper.UpdateVehicleParkState(EntityForCore.localBQ, queueCmd.LicenseNum, 0);
  696. }
  697. return;
  698. }
  699. }
  700. //开始启动机械手,停止检测号牌
  701. stopChecking = true;
  702. //UILogServer.ins.log("停车流程:" + queueCmd.LicenseNum + "停止号牌核对,准备启动机械手");
  703. Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "停车流程:" + queueCmd.LicenseNum + "停止号牌核对,准备启动机械手");
  704. int robotID = 0;
  705. robotID = queueCmd.id / 6 + 1;
  706. int frontWheelbase = 0;
  707. int rearWheelbase = 0;
  708. //需要先遍历robot数组,根据id找到对应机械手
  709. if (!WaitForRobotResource(robotID))
  710. {
  711. Rollback(queueCmd, ppp.parkingSpaceID, false, true, lmToBeReleased);
  712. return;
  713. }
  714. //第二步,机械手:
  715. status = 2;
  716. cm.status = status;
  717. cm.RobotID = robotID;//启动对应机械手
  718. //激光数据
  719. cm.centerX = Convert.ToString(dataReal.centerX);
  720. cm.centerY = Convert.ToString(dataReal.centerY);
  721. cm.angleA = Convert.ToString(dataReal.angleA);
  722. cm.length = Convert.ToString(dataReal.length);
  723. cm.width = Convert.ToString(dataReal.width);
  724. cm.height = Convert.ToString(dataReal.height);
  725. //分配的车位数据
  726. cm.parkingSpaceID = Convert.ToString(ppp.parkingSpaceID);
  727. //!!!之前把停车位X坐标当做缓冲位ID,现修改为被管理的缓冲位ID,之后PLC地址需调整!!!
  728. cm.parkingSpaceX = Convert.ToString(ppp.parkingSpaceX);
  729. //cm.parkingSpaceX = Convert.ToString(pb.bufferID);
  730. cm.parkingSpaceY = Convert.ToString(ppp.parkingSpaceY);
  731. cm.parkingSpaceZ = Convert.ToString(ppp.parkingSpaceZ);
  732. PLC.SetMessage(cm);
  733. Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "停车流程:抓车:" + queueCmd.LicenseNum + "\n车辆数据:" + cm.angleA + " ," + cm.centerX + " ," + cm.centerY + " ," + cm.length + " ," + cm.width + " ," + cm.height + " ," + cm.parkingSpaceID + " ," + cm.parkingSpaceX + " ," + cm.parkingSpaceY + " ," + cm.parkingSpaceZ);
  734. UILogServer.ins.info("停车流程:抓车:" + queueCmd.LicenseNum);
  735. if (!WaitWheelbase(ref frontWheelbase, ref rearWheelbase))
  736. {
  737. Rollback(queueCmd, ppp.parkingSpaceID, true, true, lmToBeReleased);
  738. return;
  739. }
  740. if (!WaitForStoreCompletionSignal(queueCmd, ppp.parkingSpaceID, ref robotError, 1))
  741. {
  742. Rollback(queueCmd, ppp.parkingSpaceID, true, true, lmToBeReleased);
  743. return;
  744. }
  745. //第三步,停车完成:
  746. status = 3;
  747. cm.status = status;
  748. PLC.SetMessage(cm);
  749. //机械手异常则回滚
  750. if (!WaitForStoreCompletionSignal(queueCmd, ppp.parkingSpaceID, ref robotError, 0))
  751. {
  752. Rollback(queueCmd, ppp.parkingSpaceID, true, true, lmToBeReleased);
  753. return;
  754. }
  755. //停车流程结束,将相应车牌复位,从号牌队列中出队
  756. NumReset(queueCmd);
  757. Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "停车流程:" + queueCmd.LicenseNum + "停车完成,状态复位");
  758. UILogServer.ins.info("停车流程:" + queueCmd.LicenseNum + "停车完成,状态复位");
  759. //释放机械手与激光
  760. if (lmToBeReleased != null)
  761. {
  762. lmToBeReleased.occupied = false;
  763. }
  764. Robot.robot1.occupied = false;
  765. Robot.robot1.waitCount -= 1;
  766. //自动化测试用
  767. //ManualParkingSimul.ins.Update(Int32.Parse(queueCmd.LicenseNum.Substring(2, 1)));
  768. //ParkingSimul.ins.Update(Int32.Parse(queueCmd.LicenseNum.Substring(2, 1)));
  769. //根据号牌查找车型
  770. //int vehicleTypeID = oper.getVehicleTypeID(numberPlate);
  771. //判断测量数据是否准确
  772. //bool isDataRight = oper.IsDataRight(vehicleTypeLength, vehicleTypeWidth, vehicleTypeHeight, vehicleTypeWheelbase, vehicleTypeID);
  773. //正常写入数据库
  774. if (userID != 0)
  775. {
  776. lock (Parking_Space.RecordLock)
  777. {
  778. if (!queueCmd.manual)
  779. {
  780. //事务,写入停车记录, 更新车辆信息
  781. int parkingRecordsID = 0;
  782. string insertRecordSql = "";
  783. try
  784. {
  785. insertRecordSql = "insert into parkingrecords(userID,numberPlate,parkingSpaceID,garageID,parkingRecordsState,realParkTime) values('" + userID + "','" + queueCmd.LicenseNum + "','" + ppp.parkingSpaceID + "','" + garageID + "',3,'" + realParkTime + "')";
  786. List<string> strs = new List<string>();
  787. strs.Add(insertRecordSql);
  788. parkingRecordsID = DBOperation.InsertParkingRecords(EntityForCore.remoteBQ, strs);
  789. }
  790. catch (Exception ex)
  791. {
  792. Console.WriteLine(ex.Message + "插入停车记录表失败");
  793. //数据库操作失败写日志
  794. Log.WriteLog(LogType.DATABASE, "1", insertRecordSql);
  795. }
  796. string updateParkingSpaceStateSql = "";
  797. string updateFreeSpaceSql = "";
  798. string updateVehicleSql = "";
  799. try
  800. {
  801. int freeSpace = ParkingSpaceManager.ins.GetFreeSpaceCount();
  802. List<string> strs = new List<string>();
  803. updateParkingSpaceStateSql = "update parkingspace set parkingSpaceState = 1 where parkingSpaceID = '" + ppp.parkingSpaceID + "'";
  804. updateFreeSpaceSql = "update garage set garageFreeSpace = '" + freeSpace + "' where garageID = '" + garageID + "'";
  805. updateVehicleSql = "update vehicle set vehiclepParkState = 1,scanEntryTime = '" + queueCmd.TimeRecord + "',parkingRecordsID = '" + parkingRecordsID + "',parkingSpaceID = '" + ppp.parkingSpaceID + "',vehicleTypeConfirm = 1,frontwheelbase = '" + frontWheelbase + "',rearwheelbase = '" + rearWheelbase + "' where numberPlate = '" + queueCmd.LicenseNum + "'";
  806. strs.Add(updateParkingSpaceStateSql);
  807. strs.Add(updateFreeSpaceSql);
  808. strs.Add(updateVehicleSql);
  809. DBOperation.UpdateTransaction(EntityForCore.remoteBQ, strs);
  810. }
  811. catch (Exception ex)
  812. {
  813. Console.WriteLine(ex.Message + "停车事务处理失败");
  814. //数据库操作失败写日志
  815. Log.WriteLog(LogType.DATABASE, "0", updateParkingSpaceStateSql);
  816. Log.WriteLog(LogType.DATABASE, "0", updateFreeSpaceSql);
  817. Log.WriteLog(LogType.DATABASE, "0", updateVehicleSql);
  818. }
  819. }
  820. else
  821. {
  822. //事务,写入停车记录, 更新车辆信息
  823. int parkingRecordsID = 0;
  824. string insertRecordSql = "";
  825. try
  826. {
  827. insertRecordSql = "insert into parkingrecords(userID,numberPlate,parkingSpaceID,garageID,parkingRecordsState,realParkTime) values('" + userID + "','" + queueCmd.LicenseNum + "','" + ppp.parkingSpaceID + "','" + garageID + "',3,'" + realParkTime + "')";
  828. List<string> strs = new List<string>();
  829. strs.Add(insertRecordSql);
  830. parkingRecordsID = DBOperation.InsertParkingRecords(EntityForCore.localBQ, strs);
  831. if (parkingRecordsID == 0)
  832. {
  833. //数据库操作失败写日志
  834. Log.WriteLog(LogType.DATABASE, "1", insertRecordSql);
  835. }
  836. }
  837. catch (Exception ex)
  838. {
  839. Console.WriteLine(ex.Message + "插入停车记录表失败");
  840. }
  841. string updateParkingSpaceStateSql = "";
  842. string updateFreeSpaceSql = "";
  843. string updateVehicleSql = "";
  844. try
  845. {
  846. int freeSpace = ParkingSpaceManager.ins.GetFreeSpaceCount();
  847. List<string> strs = new List<string>();
  848. updateParkingSpaceStateSql = "update parkingspace set parkingSpaceState = 1 where parkingSpaceID = '" + ppp.parkingSpaceID + "'";
  849. updateFreeSpaceSql = "update garage set garageFreeSpace = '" + freeSpace + "' where garageID = '" + garageID + "'";
  850. updateVehicleSql = "update vehicle set vehiclepParkState = 1,scanEntryTime = '" + queueCmd.TimeRecord + "',parkingRecordsID = '" + parkingRecordsID + "',parkingSpaceID = '" + ppp.parkingSpaceID + "',vehicleTypeConfirm = 1,frontwheelbase = '" + frontWheelbase + "',rearwheelbase = '" + rearWheelbase + "' where numberPlate = '" + queueCmd.LicenseNum + "'";
  851. strs.Add(updateParkingSpaceStateSql);
  852. strs.Add(updateFreeSpaceSql);
  853. strs.Add(updateVehicleSql);
  854. object result = DBOperation.UpdateTransaction(EntityForCore.localBQ, strs);
  855. if (!(bool)result)
  856. {
  857. //数据库操作失败写日志
  858. Log.WriteLog(LogType.DATABASE, "0", updateParkingSpaceStateSql);
  859. Log.WriteLog(LogType.DATABASE, "0", updateFreeSpaceSql);
  860. Log.WriteLog(LogType.DATABASE, "0", updateVehicleSql);
  861. }
  862. }
  863. catch (Exception ex)
  864. {
  865. Console.WriteLine(ex.Message + "停车事务处理失败");
  866. }
  867. }
  868. }
  869. }
  870. //异常写入日志文件
  871. else
  872. {
  873. LogFile logFile = LogFile.ERROR_NUMBERPLATE;
  874. Log.WriteLog(LogType.NOT_DATABASE, logFile, "号牌:" + queueCmd.LicenseNum);
  875. Log.WriteLog(LogType.NOT_DATABASE, logFile, "入库时间:" + realParkTime);
  876. Log.WriteLog(LogType.NOT_DATABASE, logFile, "车位id:" + ppp.parkingSpaceID);
  877. Log.WriteLog(LogType.NOT_DATABASE, logFile, "车位x:" + ppp.parkingSpaceX);
  878. Log.WriteLog(LogType.NOT_DATABASE, logFile, "车位y:" + ppp.parkingSpaceY);
  879. Log.WriteLog(LogType.NOT_DATABASE, logFile, "车位z:" + ppp.parkingSpaceZ);
  880. //异常情况处理有待讨论
  881. }
  882. }
  883. }
  884. /// <summary>
  885. /// 取车命令处理类
  886. /// </summary>
  887. public class FetchCmd : AbstractCmd
  888. {
  889. /// <summary>
  890. /// 等待取车完成信号
  891. /// </summary>
  892. /// <param name="queueCmd"></param>
  893. /// <param name="parkingSpaceID"></param>
  894. /// <param name="robotError"></param>
  895. /// <param name="status"></param>
  896. /// <returns></returns>
  897. private bool waitForFetchCompletionSignal(Command queueCmd, int parkingSpaceID, ref bool robotError, int status)
  898. {
  899. string connectionStr = null;
  900. PLCMessage PLCMsg = null;
  901. MyTimer mt = new MyTimer();
  902. mt.StartTiming();
  903. while (!isClosing)
  904. {
  905. Thread.Sleep(2000);
  906. PLCMsg = (PLCMessage)PLC.GetMessage();
  907. int fetchingStatus = Convert.ToInt32(PLCMsg.originalPlcList[fetch_completed_address].Value);
  908. //取车完成信号
  909. if (fetchingStatus == status)
  910. {
  911. //取车完成后或可归零
  912. //UILogServer.ins.log("取车流程:" + queueCmd.LicenseNum + "获得取车完成信号" + status);
  913. Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "取车流程:" + queueCmd.LicenseNum + "获得取车完成信号" + status);
  914. break;
  915. }
  916. else if (1 == 2)//机械手异常,则退指令,写数据库归位,判断条件需之后补充
  917. {
  918. robotError = true;
  919. queueCmd.returnedCount += 1;
  920. queuingThread.SetMessage(queueCmd);
  921. if (!queueCmd.manual)
  922. {
  923. oper.UpdateParkingSpaceState(EntityForCore.remoteBQ, parkingSpaceID, 0);
  924. }
  925. else
  926. {
  927. oper.UpdateParkingSpaceState(EntityForCore.localBQ, parkingSpaceID, 0);
  928. }
  929. break;
  930. }
  931. mt.EndTiming();
  932. int activationCount = 0;
  933. if (mt.IsLonger(120, 1, false, out activationCount))
  934. {
  935. if (activationCount == 1)
  936. {
  937. UILogServer.ins.info("取车流程:" + queueCmd.LicenseNum + "未获得取车完成信号" + status + ",继续等待");
  938. }
  939. if (MyTimer.restart && !mt.rolledBack)
  940. {
  941. mt.rolledBack = true;
  942. UILogServer.ins.error(queueCmd.LicenseNum + "等待取车完成信号" + status + "超时,流程回滚");
  943. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, queueCmd.LicenseNum + "等待取车完成信号" + status + "超时,流程回滚");
  944. return false;
  945. }
  946. Thread.Sleep(100);
  947. }
  948. }
  949. return true;
  950. }
  951. public override void executeCmd(Command queueCmd)
  952. {
  953. //UILogServer.ins.info("取车流程:" + queueCmd.LicenseNum + "开始");
  954. Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "取车流程:" + queueCmd.LicenseNum + "开始");
  955. string connectionStr = null; //数据库连接字符串
  956. Vehicle vehiclelist = null; //待取车辆信息
  957. ControlMessage cm = null;
  958. Parking_Space ps = null; //车位信息
  959. int frontwheelbase; //前轮距
  960. int rearwheelbase; //后轮距
  961. int garageID; //车库ID
  962. bool robotError = false; //机械手是否异常
  963. //获取车辆表中车辆相关信息
  964. if (queueCmd.manual)
  965. {
  966. //vehiclelist = oper.GetLocalVehicle(connectionStr, queueCmd.LicenseNum, queueCmd.garageID);
  967. }
  968. else
  969. {
  970. vehiclelist = oper.GetVehicle(EntityForCore.remoteBQ, queueCmd.LicenseNum);
  971. }
  972. if (vehiclelist == null)
  973. {
  974. //无法获取车辆信息,流程中止
  975. EntityForCore.ins.globalStatus = false;
  976. int count = 0;
  977. while (!MyTimer.restart)
  978. {
  979. count++;
  980. if (count == 1)
  981. {
  982. UILogServer.ins.error("无法获取车辆信息");
  983. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "无法从数据库获取车辆信息,流程中止");
  984. }
  985. Thread.Sleep(5000);
  986. }
  987. Rollback(queueCmd, 0, false, false, null);
  988. return;
  989. }
  990. int parkingSpaceID = vehiclelist.parkingSpaceID;
  991. garageID = vehiclelist.garageID;
  992. frontwheelbase = vehiclelist.frontwheelbase;
  993. rearwheelbase = vehiclelist.rearwheelbase;
  994. queueCmd.parkingRecordsID = vehiclelist.parkingRecordsID;
  995. if (!ParkingSpaceManager.ins.parkingSpaceStatusMap.TryGetValue(parkingSpaceID, out ps) || ps == null)
  996. {
  997. EntityForCore.ins.globalStatus = false;
  998. int count = 0;
  999. while (!MyTimer.restart)
  1000. {
  1001. count++;
  1002. if (count == 1)
  1003. {
  1004. UILogServer.ins.error("车位分配出现异常!!!");
  1005. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "车位分配出现异常!!!");
  1006. }
  1007. Thread.Sleep(5000);
  1008. }
  1009. Rollback(queueCmd, parkingSpaceID, false, false, null);
  1010. return;
  1011. }
  1012. cm = new ControlMessage();
  1013. //启动机械手
  1014. int robotID = 0;
  1015. robotID = parkingSpaceID / 50 + 1;
  1016. if (!WaitForRobotResource(robotID))
  1017. {
  1018. Rollback(queueCmd, parkingSpaceID, false, false, null);
  1019. return;
  1020. }
  1021. //取车
  1022. int status = 4;
  1023. cm.status = status;
  1024. //先手动赋值
  1025. cm.RobotID = 1; //1号机械手
  1026. cm.fetchPosition = 1; //放置地址
  1027. cm.parkingSpaceID = Convert.ToString(ps.parkingSpaceID);
  1028. cm.parkingSpaceX = Convert.ToString(ps.parkingSpaceX);
  1029. cm.parkingSpaceY = Convert.ToString(ps.parkingSpaceY);
  1030. cm.parkingSpaceZ = Convert.ToString(ps.parkingSpaceZ);
  1031. cm.frontWheelbase = frontwheelbase;
  1032. cm.rearWheelbase = rearwheelbase;
  1033. PLC.SetMessage(cm);
  1034. Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "取车流程:" + queueCmd.LicenseNum + "取车");
  1035. UILogServer.ins.info("取车流程:" + queueCmd.LicenseNum + "取车");
  1036. //等待PLC取车完成信号
  1037. if (!waitForFetchCompletionSignal(queueCmd, ps.parkingSpaceID, ref robotError, 1))
  1038. {
  1039. Rollback(queueCmd, ps.parkingSpaceID, true, false, null);
  1040. return;
  1041. }
  1042. //取车完成
  1043. status = 5;
  1044. ControlMessage cm2 = new ControlMessage();
  1045. cm2.status = status;
  1046. //先手动赋值
  1047. cm2.RobotID = 1; //机械手复位
  1048. PLC.SetMessage(cm2);
  1049. if (!waitForFetchCompletionSignal(queueCmd, ps.parkingSpaceID, ref robotError, 0))
  1050. {
  1051. Rollback(queueCmd, ps.parkingSpaceID, true, false, null);
  1052. return;
  1053. }
  1054. //释放机械手
  1055. Robot.robot1.occupied = false;
  1056. Robot.robot1.waitCount -= 1;
  1057. //释放缓冲位与车位,缓冲位ID暂用车位X代替
  1058. if (ParkingSpaceManager.ins == null || !ParkingSpaceManager.ins.SetParkingSpace(ps.parkingSpaceID, 0) || ParkingBufferManager.ins == null || !ParkingBufferManager.ins.ReleaseParkingBuffer(ps.parkingSpaceX))
  1059. {
  1060. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "车位异常,请检查"); UILogServer.ins.error("车位异常,请检查");
  1061. }
  1062. Log.WriteLog(LogType.NOT_DATABASE, "取车流程:号牌:" + queueCmd.LicenseNum + "取车完成");
  1063. UILogServer.ins.info("取车流程:号牌:" + queueCmd.LicenseNum + "取车完成");
  1064. //自动化测试用
  1065. //ManualParkingSimul.ins.Update(Int32.Parse(queueCmd.LicenseNum.Substring(2, 1)));
  1066. //ParkingSimul.ins.Update(Int32.Parse(queueCmd.LicenseNum.Substring(2, 1)));
  1067. int freeSpaceCount = ParkingSpaceManager.ins.GetFreeSpaceCount();
  1068. //数据库更新
  1069. lock (Parking_Space.RecordLock)
  1070. {
  1071. lock (Parking_Space.spaceLock)
  1072. {
  1073. if (!queueCmd.manual)
  1074. {
  1075. string updateParkingSpaceStateSql = "";
  1076. string updateFreeSpaceSql = "";
  1077. string updateVehicleStateSql = "";
  1078. string updateParkingRecordsSql = "";
  1079. //取车事务
  1080. try
  1081. {
  1082. List<string> strs = new List<string>();
  1083. updateParkingSpaceStateSql = "update parkingspace set parkingSpaceState = 1 where parkingSpaceID = '" + ps.parkingSpaceID + "'";
  1084. updateFreeSpaceSql = "update garage set garageFreeSpace = '" + freeSpaceCount + "' where garageID = '" + garageID + "'";
  1085. updateVehicleStateSql = "update vehicle set vehiclepParkState = 0 where numberPlate = '" + queueCmd.LicenseNum + "'";
  1086. updateParkingRecordsSql = "update parkingrecords set parkingRecordsState = 6,realGetTime = '" + queueCmd.TimeRecord + "'where parkingRecordsID = '" + queueCmd.parkingRecordsID + "'";
  1087. strs.Add(updateParkingSpaceStateSql);
  1088. strs.Add(updateFreeSpaceSql);
  1089. strs.Add(updateVehicleStateSql);
  1090. strs.Add(updateParkingRecordsSql);
  1091. object result = DBOperation.UpdateTransaction(EntityForCore.remoteBQ, strs);
  1092. if (!(bool)result)
  1093. {
  1094. //写日志记录sql,以待之后处理
  1095. Log.WriteLog(LogType.DATABASE, "0", updateParkingSpaceStateSql);
  1096. Log.WriteLog(LogType.DATABASE, "0", updateFreeSpaceSql);
  1097. Log.WriteLog(LogType.DATABASE, "0", updateVehicleStateSql);
  1098. Log.WriteLog(LogType.DATABASE, "0", updateParkingRecordsSql);
  1099. }
  1100. }
  1101. catch (Exception ex)
  1102. {
  1103. Console.WriteLine(ex.Message + "取车事务处理失败");
  1104. }
  1105. }
  1106. else
  1107. {
  1108. string updateParkingSpaceStateSql = "";
  1109. string updateFreeSpaceSql = "";
  1110. string updateVehicleStateSql = "";
  1111. string updateParkingRecordsSql = "";
  1112. //取车事务
  1113. try
  1114. {
  1115. List<string> strs = new List<string>();
  1116. updateParkingSpaceStateSql = "update parkingspace set parkingSpaceState = 0 where parkingSpaceID = '" + ps.parkingSpaceID + "'";
  1117. updateFreeSpaceSql = "update garage set garageFreeSpace = '" + freeSpaceCount + "' where garageID = '" + garageID + "'";
  1118. updateVehicleStateSql = "update vehicle set vehiclepParkState = 0 where numberPlate = '" + queueCmd.LicenseNum + "'";
  1119. updateParkingRecordsSql = "update parkingrecords set parkingRecordsState = 6,realGetTime = '" + queueCmd.TimeRecord + "'where parkingRecordsID = '" + queueCmd.parkingRecordsID + "'";
  1120. strs.Add(updateParkingSpaceStateSql);
  1121. strs.Add(updateFreeSpaceSql);
  1122. strs.Add(updateVehicleStateSql);
  1123. strs.Add(updateParkingRecordsSql);
  1124. DBOperation.UpdateTransaction(EntityForCore.localBQ, strs);
  1125. }
  1126. catch (Exception ex)
  1127. {
  1128. Console.WriteLine(ex.Message + "取车事务处理失败");
  1129. //写日志记录sql,以待之后处理
  1130. Log.WriteLog(LogType.DATABASE, "0", updateParkingSpaceStateSql);
  1131. Log.WriteLog(LogType.DATABASE, "0", updateFreeSpaceSql);
  1132. Log.WriteLog(LogType.DATABASE, "0", updateVehicleStateSql);
  1133. Log.WriteLog(LogType.DATABASE, "0", updateParkingRecordsSql);
  1134. }
  1135. }
  1136. }
  1137. Thread.Sleep(1000);
  1138. }
  1139. }
  1140. }
  1141. /// <summary>
  1142. /// 异常命令处理类
  1143. /// </summary>
  1144. public class ExceptionCmd : AbstractCmd
  1145. {
  1146. public override void executeCmd(Command queueCmd)
  1147. {
  1148. if (queueCmd.commandType == 'e')
  1149. {
  1150. //int userId = Convert.ToInt32(queueCmd.userID);
  1151. ////过期用户指令
  1152. //oper.InsertToMessageQueue(DBConnection.remoteConf, userId, "停车异常,请联系管理员!", 2);
  1153. ////未能停车,将车辆状态复位
  1154. //oper.UpdateVehicleParkState(DBConnection.remoteConf, queueCmd.LicenseNum, 0);
  1155. //Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "过期用户指令,车牌号:" + queueCmd.LicenseNum);
  1156. //UILogServer.ins.error("过期用户指令,车牌号:" + queueCmd.LicenseNum);
  1157. ////continue;
  1158. }
  1159. }
  1160. }
  1161. /// <summary>
  1162. /// 简单命令工厂
  1163. /// </summary>
  1164. public class SimpleCMDFactory
  1165. {
  1166. //DBOperation oper = new DBOperation();
  1167. public AbstractCmd createCmd(Command queueCmd)
  1168. {
  1169. AbstractCmd abstractCmd = null;
  1170. if (queueCmd.commandType == 's')
  1171. {
  1172. abstractCmd = new StopCmd();
  1173. }
  1174. if (queueCmd.commandType == 'f')
  1175. {
  1176. abstractCmd = new FetchCmd();
  1177. }
  1178. if (queueCmd.commandType == 'e')
  1179. {
  1180. abstractCmd = new ExceptionCmd();
  1181. }
  1182. return abstractCmd;
  1183. }
  1184. }
  1185. }