PMModuleRecipeExecutor.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Device.Unit;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.Log;
  5. using Aitex.Core.RT.ParameterCenter;
  6. using Aitex.Core.RT.SCCore;
  7. using Aitex.Core.Util;
  8. using FurnaceRT.Devices;
  9. using FurnaceRT.Equipments.Boats;
  10. using FurnaceRT.Equipments.PMs.RecipeExecutions;
  11. using FurnaceRT.Equipments.Systems;
  12. using MECF.Framework.Common.Equipment;
  13. using System.Collections.Generic;
  14. using System.Diagnostics;
  15. using System.IO;
  16. using System.Linq;
  17. using System.Xml;
  18. namespace FurnaceRT.Equipments.PMs
  19. {
  20. public partial class PMModule
  21. {
  22. public bool IsMainRecipeComplete { get; set; }
  23. public bool IsHeaterProfile { get; set; }
  24. public bool IsHeaterProfileSuccess { get; set; }
  25. public bool IsBoatMoveToLoadPosition { get; private set; }
  26. public bool IsWaitBoatMoveComplete { get; private set; }
  27. private string _boatTargetPosition;
  28. private R_TRIG _profileTrig = new R_TRIG();
  29. public RecipeRunningInfo RecipeRunningInfo
  30. {
  31. get
  32. {
  33. return _recipeRunningInfo;
  34. }
  35. }
  36. public bool IsPaused { get; set; }//按了hold按键
  37. public bool IsHolded { get; set; }//按了hold按键之后,当前step执行完了
  38. public bool IsWait { get; set; }//等待wait条件的结束
  39. public void ResetToleranceChecker()
  40. {
  41. }
  42. public void OnProcessStart(string v1, string recipeName, bool v2)
  43. {
  44. }
  45. public void PauseRecipe(out string reason)
  46. {
  47. reason = string.Empty;
  48. }
  49. public bool CheckEndPoint()
  50. {
  51. return true;
  52. }
  53. public bool CheckAllDevicesStable(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8, float v9)
  54. {
  55. return true;
  56. }
  57. public bool CheckEnableRunProcess(out string reason)
  58. {
  59. reason = string.Empty;
  60. return true;
  61. }
  62. public void AbortRunProcess(out string reason)
  63. {
  64. //GasSticks.ForEach(x => x.SetFlow(out _, 0, 0));
  65. reason = string.Empty;
  66. }
  67. private bool SetBoatManualMotion(object[] param)
  68. {
  69. if (param == null || param.Length < 1)
  70. {
  71. return false;
  72. }
  73. var paramArray = param[0].ToString().Split(';');
  74. var loaderCommand = paramArray[0].ToString();
  75. switch (loaderCommand.ToLower().Replace(" ", ""))
  76. {
  77. case "boatload":
  78. if (paramArray.Length > 3)
  79. {
  80. var boat = Singleton<EquipmentManager>.Instance.Modules[ModuleName.Boat] as BoatModule;
  81. if (!boat.CheckPrepareMove(out string reason))
  82. {
  83. boat.BoatZAxisMoveFailedForInterlock.Set(reason);
  84. return false;
  85. }
  86. float.TryParse(paramArray[1], out float speed1);
  87. float.TryParse(paramArray[2], out float speed2);
  88. float.TryParse(paramArray[3], out float speed3);
  89. ZAxisDevice.SetServoMoveTo("Position1", out _, speed1);
  90. }
  91. break;
  92. case "boatunload":
  93. if (paramArray.Length > 3)
  94. {
  95. var boat = Singleton<EquipmentManager>.Instance.Modules[ModuleName.Boat] as BoatModule;
  96. if (!boat.CheckPrepareMove(out string reason))
  97. {
  98. boat.BoatZAxisMoveFailedForInterlock.Set(reason);
  99. return false;
  100. }
  101. float.TryParse(paramArray[1], out float speed1);
  102. float.TryParse(paramArray[2], out float speed2);
  103. float.TryParse(paramArray[3], out float speed3);
  104. ZAxisDevice.SetServoMoveTo("Position3", out _, speed1);
  105. }
  106. break;
  107. case "boatloaderhome":
  108. {
  109. var boat = Singleton<EquipmentManager>.Instance.Modules[ModuleName.Boat] as BoatModule;
  110. if (!boat.CheckPrepareMove(out string reason))
  111. {
  112. boat.BoatZAxisMoveFailedForInterlock.Set(reason);
  113. return false;
  114. }
  115. }
  116. ZAxisDevice.SetServoMoveTo("HomePosition", out _);
  117. break;
  118. case "boatcap2":
  119. if (paramArray.Length > 1)
  120. {
  121. var boat = Singleton<EquipmentManager>.Instance.Modules[ModuleName.Boat] as BoatModule;
  122. if (!boat.CheckPrepareMove(out string reason))
  123. {
  124. boat.BoatZAxisMoveFailedForInterlock.Set(reason);
  125. return false;
  126. }
  127. float.TryParse(paramArray[1], out float speed);
  128. ZAxisDevice.SetServoMoveTo("CapPosition", out _, speed);
  129. }
  130. break;
  131. case "boatrotate":
  132. if (paramArray.Length > 1)
  133. {
  134. float.TryParse(paramArray[1], out float speed);
  135. RAxisDevice.SetServoMoveTo("CCW", out _, speed);
  136. }
  137. break;
  138. case "boatrotatestop"://r home
  139. RAxisDevice.ServoStop();
  140. RAxisDevice.SetServoHome();
  141. break;
  142. case "stop(includer-axis)":
  143. RAxisDevice.ServoStop();
  144. break;
  145. }
  146. return true;
  147. }
  148. private bool SetValves(object[] param)
  149. {
  150. var stopwatch = new Stopwatch();
  151. stopwatch.Start();
  152. if (param == null || param.Length < 1)
  153. {
  154. return false;
  155. }
  156. var paramArray = param[0].ToString().Split(';');
  157. for (int i = 0; i < paramArray.Length; i++)
  158. {
  159. var item = paramArray[i];
  160. if (string.IsNullOrEmpty(item))
  161. continue;
  162. var valveDatas = item.Split(',');
  163. if (valveDatas != null && valveDatas.Length > 1)
  164. {
  165. var valveName = valveDatas[0];
  166. var valveSet = valveDatas[1];
  167. if (valveSet == "Continue")
  168. continue;
  169. bool.TryParse(valveSet, out bool set);
  170. switch (valveName.ToUpper())
  171. {
  172. case "F2CLN":
  173. IsF2ClnOn = set;
  174. break;
  175. case "HFCLN":
  176. IsHFClnOn = set;
  177. break;
  178. case "HTR1":
  179. //_HTR1Group.ForEach(x => x.SetEnable(set));
  180. SetHTR1Enable(new object[1] { set });
  181. break;
  182. case "HTR2":
  183. //_HTR2Group.ForEach(x => x.SetEnable(set));
  184. SetHTR2Enable(new object[1] { set });
  185. break;
  186. case "HTR3":
  187. SetHTR3Enable(new object[1] { set });
  188. break;
  189. case "DEPO":
  190. SetDEPOEnable(new object[1] { set });
  191. break;
  192. case "DPR":
  193. valveName = "ValveAV93";
  194. if (_valves.Any(x => x.Name == valveName))
  195. {
  196. var valve = _valves.Find(x => x.Name == valveName);
  197. if (valve != null)
  198. valve.TurnValve(set, out _);
  199. }
  200. break;
  201. case "CEXH":
  202. SetCEXHEnable(new object[1] { set });
  203. break;
  204. case "AGV":
  205. valveName = "AGVPump";
  206. if (_valves.Any(x => x.Name == valveName))
  207. {
  208. var valve = _valves.Find(x => x.Name == valveName);
  209. if (valve != null)
  210. valve.TurnValve(set, out _);
  211. }
  212. break;
  213. case "AGV2":
  214. valveName = "AGV2Pump";
  215. if (_valves.Any(x => x.Name == valveName))
  216. {
  217. var valve = _valves.Find(x => x.Name == valveName);
  218. if (valve != null)
  219. valve.TurnValve(set, out _);
  220. }
  221. break;
  222. case "MBP":
  223. case "MBP1":
  224. case "MBP2":
  225. case "DP":
  226. valveName = "BothPump";
  227. if (_valves.Any(x => x.Name == valveName))
  228. {
  229. var valve = _valves.Find(x => x.Name == valveName);
  230. if (valve != null)
  231. valve.TurnValve(set, out _);
  232. }
  233. break;
  234. case "DP1":
  235. valveName = "BothPump1";
  236. if (_valves.Any(x => x.Name == valveName))
  237. {
  238. var valve = _valves.Find(x => x.Name == valveName);
  239. if (valve != null)
  240. valve.TurnValve(set, out _);
  241. }
  242. break;
  243. case "DP2":
  244. valveName = "BothPump2";
  245. if (_valves.Any(x => x.Name == valveName))
  246. {
  247. var valve = _valves.Find(x => x.Name == valveName);
  248. if (valve != null)
  249. valve.TurnValve(set, out _);
  250. }
  251. break;
  252. case "BWR":
  253. valveName = "ValveBlowerPowerOn";
  254. if (_valves.Any(x => x.Name == valveName))
  255. {
  256. var valve = _valves.Find(x => x.Name == valveName);
  257. if (valve != null)
  258. valve.TurnValve(set, out _);
  259. SetVFD(set);
  260. }
  261. break;
  262. default:
  263. if (_valves.Any(x => x.Name == valveName))
  264. {
  265. var valve = _valves.Find(x => x.Name == valveName);
  266. if (valve != null)
  267. valve.TurnValve(set, out _);
  268. }
  269. break;
  270. }
  271. }
  272. }
  273. LOG.Write($"SetValves exec time {stopwatch.ElapsedMilliseconds}");
  274. return true;
  275. }
  276. private bool SetBoatMotion(object[] param)
  277. {
  278. var boatModule = Singleton<EquipmentManager>.Instance.Modules[ModuleName.Boat] as BoatModule;
  279. if (param == null || param.Length < 1 || boatModule == null)
  280. {
  281. return false;
  282. }
  283. var paramArray = param[0].ToString().Split(';');
  284. var loaderCommand = paramArray[0].ToString();
  285. IsWaitBoatMoveComplete = false;
  286. IsBoatMoveToLoadPosition = false;
  287. switch (loaderCommand.ToLower().Replace(" ", ""))
  288. {
  289. case "boatload":
  290. if (paramArray.Length > 3)
  291. {
  292. float.TryParse(paramArray[1], out float speed1);
  293. float.TryParse(paramArray[2], out float speed2);
  294. float.TryParse(paramArray[3], out float speed3);
  295. IsWaitBoatMoveComplete = true;
  296. IsBoatMoveToLoadPosition = true;
  297. _boatTargetPosition = "Position1";
  298. //ZAxisDevice.SetServoMoveTo(_boatTargetPosition, out _, speed1);
  299. boatModule.BoatMove("boatload", _boatTargetPosition, speed1);
  300. }
  301. break;
  302. case "boatunload":
  303. if (paramArray.Length > 3)
  304. {
  305. float.TryParse(paramArray[1], out float speed1);
  306. float.TryParse(paramArray[2], out float speed2);
  307. float.TryParse(paramArray[3], out float speed3);
  308. IsWaitBoatMoveComplete = true;
  309. _boatTargetPosition = "Position3";
  310. //ZAxisDevice.SetServoMoveTo(_boatTargetPosition, out _, speed1);
  311. boatModule.BoatMove("boatunload", _boatTargetPosition, speed1);
  312. }
  313. break;
  314. case "boatloaderhome":
  315. IsWaitBoatMoveComplete = true;
  316. _boatTargetPosition = "HomePosition";
  317. //ZAxisDevice.SetServoMoveTo(_boatTargetPosition, out _);
  318. boatModule.BoatMove("boatloaderhome", _boatTargetPosition, 0);
  319. break;
  320. case "boatcap2":
  321. if (paramArray.Length > 1)
  322. {
  323. float.TryParse(paramArray[1], out float speed);
  324. IsWaitBoatMoveComplete = true;
  325. _boatTargetPosition = "CapPosition";
  326. //ZAxisDevice.SetServoMoveTo(_boatTargetPosition, out _, speed);
  327. boatModule.BoatMove("boatcap2", _boatTargetPosition, speed);
  328. }
  329. break;
  330. case "boatrotate":
  331. if (paramArray.Length > 4)
  332. {
  333. float.TryParse(paramArray[4], out float speed);
  334. //RAxisDevice.SetServoMoveTo("CCW", out _, speed);
  335. //boatModule.BoatMove("boatrotate", "CCW", speed);
  336. boatModule.RAxisDevice.SetServoMoveTo("CCW", out string reason, speed);//旋转直接发
  337. }
  338. break;
  339. case "boatrotatestop"://r home
  340. IsWaitBoatMoveComplete = true;
  341. _boatTargetPosition = "RotateHome";
  342. //RAxisDevice.ServoStop();
  343. //RAxisDevice.SetServoHome();
  344. boatModule.BoatMove("boatrotatestop", _boatTargetPosition, 0);
  345. break;
  346. case "stop(includer-axis)":
  347. //RAxisDevice.ServoStop();
  348. boatModule.BoatMove("stop(includer-axis)", "", 0);
  349. break;
  350. }
  351. return true;
  352. }
  353. public bool CheckBoatWaitCondition(out string reason)
  354. {
  355. reason = "";
  356. if (!IsWaitBoatMoveComplete)
  357. return true;
  358. if (_boatTargetPosition == "RotateHome")
  359. {
  360. if (!RAxisDevice.IsHomeDone)
  361. {
  362. reason = "rotate not home done";
  363. return false;
  364. }
  365. return (Singleton<EquipmentManager>.Instance.Modules[ModuleName.Boat] as BoatModule).IsReady;
  366. }
  367. else
  368. {
  369. if (!ZAxisDevice.CheckServoAtPosition(_boatTargetPosition))
  370. {
  371. reason = $"elevator not at {_boatTargetPosition}";
  372. return false;
  373. }
  374. return (Singleton<EquipmentManager>.Instance.Modules[ModuleName.Boat] as BoatModule).IsReady;
  375. }
  376. }
  377. public bool CheckAPCWaitCondition(out string reason)
  378. {
  379. return APCDevice.CheckWaitCondition(out reason);
  380. }
  381. public bool CheckMFCWaitCondition(out string reason)
  382. {
  383. reason = "";
  384. var ret = true;
  385. foreach (var mfc in _processMFCs)
  386. {
  387. if (!mfc.CheckWaitCondition(out string info))
  388. {
  389. reason += $"{info} \n";
  390. ret = false;
  391. }
  392. }
  393. return ret;
  394. }
  395. public bool CheckHeaterWaitCondition(out string reason)
  396. {
  397. reason = "";
  398. var ret = true;
  399. foreach (var heater in _heaters)
  400. {
  401. if (!heater.CheckWaitCondition(out string info))
  402. {
  403. reason += $"{info} \n";
  404. ret = false;
  405. }
  406. }
  407. return ret;
  408. }
  409. public void AbortRecipe()
  410. {
  411. _processMFCs.ForEach(x => x.Terminate());
  412. _heaters.ForEach(x => x.Terminate());
  413. _valves.ForEach(x => x.Terminate());
  414. ZAxisDevice.ServoStop();
  415. RAxisDevice.ServoStop();
  416. APC.Terminate();
  417. AbortLeakCheck();
  418. IsWait = false;
  419. }
  420. public void HeaterEnable(bool isEnable)
  421. {
  422. _heaters.ForEach(x => x.SetEnable(isEnable));
  423. }
  424. public bool CheckHeaterProfileFinish(out string reason)
  425. {
  426. reason = "";
  427. if (_heaters.Any(x => x.IsProfileMode))
  428. {
  429. IsHeaterProfile = true;
  430. var ret = true;
  431. foreach (var heater in _heaters)
  432. {
  433. if (!heater.CheckProfileFinish(out string info))
  434. {
  435. reason += $"{info} \n";
  436. ret = false;
  437. }
  438. }
  439. if (!ret)
  440. {
  441. foreach (var heater in _heaters)
  442. {
  443. heater.IsProfileSuccess = false;//有任何一个没结束,所有都要接着判断
  444. }
  445. _profileTrig.CLK = false;
  446. return false;//有任何一个没结束
  447. }
  448. if (HeaterU.IsProfileSuccess &&
  449. HeaterCU.IsProfileSuccess &&
  450. HeaterC.IsProfileSuccess &&
  451. HeaterCL.IsProfileSuccess &&
  452. HeaterL.IsProfileSuccess)
  453. {
  454. IsHeaterProfileSuccess = true;
  455. _profileTrig.CLK = true;
  456. _heaters.ForEach(x => x.DeviceData.ProfileStatus = "Normal End");
  457. _heaters.ForEach(x => x.ProfileFinish());
  458. if (_profileTrig.Q)
  459. SaveHeaterProflieToCorrectTable(_heaters[0].CurrentCorrectFileName, _heaters[0].CurrentCorrectIndex);//更新profile table
  460. }
  461. return true;
  462. }
  463. else
  464. {
  465. _heaters.ForEach(x => x.ProfileFinish());
  466. return true;//不处于profile模式
  467. }
  468. }
  469. private void SaveHeaterProflieToCorrectTable(string correctFileName, int tableIndex)
  470. {
  471. var content = ParameterFileManager.Instance.LoadParameter("Parameter\\TempCorrection", correctFileName, false);
  472. if (string.IsNullOrEmpty(content))
  473. {
  474. EV.PostWarningLog(Module, $"{correctFileName} heater temperature correct file is empty");
  475. return;
  476. }
  477. var doc = new XmlDocument();
  478. doc.LoadXml(content);
  479. XmlNodeList nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Module[@Name='']/Step");
  480. if (nodeSteps == null)
  481. nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Step");
  482. if (nodeSteps == null)
  483. {
  484. EV.PostWarningLog(Module, $"Invalid heater temperature correct file {correctFileName}");
  485. return;
  486. }
  487. if (tableIndex < 1 || nodeSteps.Count < tableIndex)
  488. {
  489. EV.PostWarningLog(Module, $"{correctFileName} heater temperature correct file table id={tableIndex} is invalid");
  490. return;
  491. }
  492. XmlElement targetStepNode = nodeSteps[tableIndex - 1] as XmlElement;
  493. if (targetStepNode != null)
  494. {
  495. var correctionDataString = targetStepNode.GetAttribute("CorrectionData");
  496. if (string.IsNullOrEmpty(correctionDataString))
  497. {
  498. EV.PostWarningLog(Module, $"Heater temperature correct file is empty");
  499. return;
  500. }
  501. var correctionDatas = correctionDataString.Split('|');
  502. if (correctionDatas.Length < 5)
  503. {
  504. EV.PostWarningLog(Module, $"Heater temperature correct file data length is invalid");
  505. return;
  506. }
  507. List<string> newCorrectionDatas = new List<string>();
  508. for (int i = 0; i < correctionDatas.Length; i++)
  509. {
  510. var datas = correctionDatas[i];
  511. var dataArry = datas.Split(';');
  512. if (dataArry.Length < 6)
  513. {
  514. EV.PostWarningLog(Module, $"Heater temperature correct file data length is invalid");
  515. return;
  516. }
  517. var correctParameter = new CorrectParameter();
  518. foreach (var item in dataArry)
  519. {
  520. var itemArry = item.Split(':');
  521. if (itemArry.Length < 2)
  522. {
  523. EV.PostWarningLog(Module, $"Heater temperature correct file data length is invalid");
  524. return;
  525. }
  526. switch (itemArry[0].ToLower())
  527. {
  528. case "index":
  529. int.TryParse(itemArry[1], out int no);
  530. correctParameter.No = no;
  531. break;
  532. case "name":
  533. correctParameter.Name = itemArry[1];
  534. break;
  535. case "profiletemp":
  536. float.TryParse(itemArry[1], out float profiletemp);
  537. correctParameter.ProfileTemp = profiletemp;
  538. break;
  539. case "profilecorrect":
  540. float.TryParse(itemArry[1], out float profilecorrect);
  541. correctParameter.ProfileCorrect = profilecorrect;
  542. break;
  543. case "cascadetccorrect":
  544. float.TryParse(itemArry[1], out float cascadetccorrect);
  545. correctParameter.CascadeTCCorrect = cascadetccorrect;
  546. break;
  547. case "profiletccalib":
  548. float.TryParse(itemArry[1], out float profiletccalib);
  549. correctParameter.ProfileTCCalib = profiletccalib;
  550. break;
  551. }
  552. }
  553. FurnaceRT.Devices.IoHeater heater = null;
  554. if (_heaters.Count > i)
  555. {
  556. heater = _heaters[i];
  557. }
  558. if (heater != null)
  559. {
  560. newCorrectionDatas.Add($"Index:{correctParameter.No};Name:{correctParameter.Name};ProfileTemp:{heater.DeviceData.HeaterPV};ProfileCorrect:{(heater.DeviceData.HeaterPV - heater.DeviceData.CascadePV).ToString("f1")};CascadeTCCorrect:{heater.DeviceData.CascadePV};ProfileTCCalib:{correctParameter.ProfileTCCalib}");
  561. heater.DeviceData.ProfileResult = correctParameter.ProfileCorrect;
  562. }
  563. }
  564. if (newCorrectionDatas.Count == correctionDatas.Length)
  565. targetStepNode.SetAttribute("CorrectionData", string.Join("|", newCorrectionDatas.ToArray()));
  566. LOG.Write($"Profile result {correctFileName}:{tableIndex} CorrectionData={string.Join("|", newCorrectionDatas.ToArray())}");
  567. //FileStream fileStream = new FileStream(ParameterFileManager.Instance.GenerateParameterFilePath("Parameter\\TempCorrection", correctFileName), FileMode.Create);
  568. //doc.Save(fileStream);
  569. using (FileStream fileStream = new FileStream(ParameterFileManager.Instance.GenerateParameterFilePath("Parameter\\TempCorrection", correctFileName), FileMode.Create))
  570. {
  571. doc.Save(fileStream);
  572. }
  573. }
  574. }
  575. private bool SetAlarmConditionTable(object[] param)
  576. {
  577. if (param == null || param.Length < 1)
  578. {
  579. return false;
  580. }
  581. var array = param[0].ToString().Split(':');
  582. int.TryParse(array[0], out int index);
  583. lock (_alarmConditionLocker)
  584. {
  585. SetAlarmConditionTableIndex(index);
  586. }
  587. return true;
  588. }
  589. }
  590. }