PMModuleRecipeExecutor.cs 27 KB

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