PMModuleRecipeExecutor.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  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.Util;
  7. using FurnaceRT.Devices;
  8. using FurnaceRT.Equipments.Boats;
  9. using FurnaceRT.Equipments.PMs.RecipeExecutions;
  10. using FurnaceRT.Equipments.Systems;
  11. using MECF.Framework.Common.Equipment;
  12. using System.Collections.Generic;
  13. using System.Diagnostics;
  14. using System.IO;
  15. using System.Linq;
  16. using System.Xml;
  17. using static Aitex.Core.RT.Device.Unit.IoBoat;
  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 = "ValveAV91";
  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 "AGV":
  202. valveName = "AGVPump";
  203. if (_valves.Any(x => x.Name == valveName))
  204. {
  205. var valve = _valves.Find(x => x.Name == valveName);
  206. if (valve != null)
  207. valve.TurnValve(set, out _);
  208. }
  209. break;
  210. case "AGV2":
  211. valveName = "AGV2Pump";
  212. if (_valves.Any(x => x.Name == valveName))
  213. {
  214. var valve = _valves.Find(x => x.Name == valveName);
  215. if (valve != null)
  216. valve.TurnValve(set, out _);
  217. }
  218. break;
  219. case "MBP":
  220. case "MBP1":
  221. case "MBP2":
  222. case "DP":
  223. valveName = "BothPump";
  224. if (_valves.Any(x => x.Name == valveName))
  225. {
  226. var valve = _valves.Find(x => x.Name == valveName);
  227. if (valve != null)
  228. valve.TurnValve(set, out _);
  229. }
  230. break;
  231. case "DP1":
  232. valveName = "BothPump1";
  233. if (_valves.Any(x => x.Name == valveName))
  234. {
  235. var valve = _valves.Find(x => x.Name == valveName);
  236. if (valve != null)
  237. valve.TurnValve(set, out _);
  238. }
  239. break;
  240. case "DP2":
  241. valveName = "BothPump2";
  242. if (_valves.Any(x => x.Name == valveName))
  243. {
  244. var valve = _valves.Find(x => x.Name == valveName);
  245. if (valve != null)
  246. valve.TurnValve(set, out _);
  247. }
  248. break;
  249. case "BWR":
  250. valveName = "ValveBlowerPowerOn";
  251. if (_valves.Any(x => x.Name == valveName))
  252. {
  253. var valve = _valves.Find(x => x.Name == valveName);
  254. if (valve != null)
  255. valve.TurnValve(set, out _);
  256. }
  257. break;
  258. default:
  259. if (_valves.Any(x => x.Name == valveName))
  260. {
  261. var valve = _valves.Find(x => x.Name == valveName);
  262. if (valve != null)
  263. valve.TurnValve(set, out _);
  264. }
  265. break;
  266. }
  267. }
  268. }
  269. LOG.Write($"SetValves exec time {stopwatch.ElapsedMilliseconds}");
  270. return true;
  271. }
  272. private bool SetBoatMotion(object[] param)
  273. {
  274. var boatModule = Singleton<EquipmentManager>.Instance.Modules[ModuleName.Boat] as BoatModule;
  275. if (param == null || param.Length < 1 || boatModule == null)
  276. {
  277. return false;
  278. }
  279. var paramArray = param[0].ToString().Split(';');
  280. var loaderCommand = paramArray[0].ToString();
  281. IsWaitBoatMoveComplete = false;
  282. IsBoatMoveToLoadPosition = false;
  283. switch (loaderCommand.ToLower().Replace(" ", ""))
  284. {
  285. case "boatload":
  286. if (paramArray.Length > 3)
  287. {
  288. float.TryParse(paramArray[1], out float speed1);
  289. float.TryParse(paramArray[2], out float speed2);
  290. float.TryParse(paramArray[3], out float speed3);
  291. IsWaitBoatMoveComplete = true;
  292. IsBoatMoveToLoadPosition = true;
  293. _boatTargetPosition = BoatPosition.Position1.ToString();
  294. //ZAxisDevice.SetServoMoveTo(_boatTargetPosition, out _, speed1);
  295. boatModule.BoatMove("boatload", _boatTargetPosition, speed1);
  296. }
  297. break;
  298. case "boatunload":
  299. if (paramArray.Length > 3)
  300. {
  301. float.TryParse(paramArray[1], out float speed1);
  302. float.TryParse(paramArray[2], out float speed2);
  303. float.TryParse(paramArray[3], out float speed3);
  304. IsWaitBoatMoveComplete = true;
  305. _boatTargetPosition = BoatPosition.Position3.ToString();
  306. //ZAxisDevice.SetServoMoveTo(_boatTargetPosition, out _, speed1);
  307. boatModule.BoatMove("boatunload", _boatTargetPosition, speed1);
  308. }
  309. break;
  310. case "boatloaderhome":
  311. IsWaitBoatMoveComplete = true;
  312. _boatTargetPosition = BoatPosition.HomePosition.ToString();
  313. //ZAxisDevice.SetServoMoveTo(_boatTargetPosition, out _);
  314. boatModule.BoatMove("boatloaderhome", _boatTargetPosition, 0);
  315. break;
  316. case "boatcap2":
  317. if (paramArray.Length > 1)
  318. {
  319. float.TryParse(paramArray[1], out float speed);
  320. IsWaitBoatMoveComplete = true;
  321. _boatTargetPosition = BoatPosition.CapPosition.ToString();
  322. //ZAxisDevice.SetServoMoveTo(_boatTargetPosition, out _, speed);
  323. boatModule.BoatMove("boatcap2", _boatTargetPosition, speed);
  324. }
  325. break;
  326. case "boatrotate":
  327. if (paramArray.Length > 4)
  328. {
  329. float.TryParse(paramArray[4], out float speed);
  330. //RAxisDevice.SetServoMoveTo("CCW", out _, speed);
  331. //boatModule.BoatMove("boatrotate", "CCW", speed);
  332. boatModule.RAxisDevice.SetServoMoveTo("CCW", out string reason, speed);//旋转直接发
  333. }
  334. break;
  335. case "boatrotatestop"://r home
  336. IsWaitBoatMoveComplete = true;
  337. _boatTargetPosition = "RotateHome";
  338. //RAxisDevice.ServoStop();
  339. //RAxisDevice.SetServoHome();
  340. boatModule.BoatMove("boatrotatestop", _boatTargetPosition, 0);
  341. break;
  342. case "stop(includer-axis)":
  343. //RAxisDevice.ServoStop();
  344. boatModule.BoatMove("stop(includer-axis)", "", 0);
  345. break;
  346. }
  347. return true;
  348. }
  349. public bool CheckBoatWaitCondition(out string reason)
  350. {
  351. reason = "";
  352. if (!IsWaitBoatMoveComplete)
  353. return true;
  354. if (_boatTargetPosition == "RotateHome")
  355. {
  356. if (!RAxisDevice.IsHomeDone)
  357. {
  358. reason = "rotate not home done";
  359. return false;
  360. }
  361. return (Singleton<EquipmentManager>.Instance.Modules[ModuleName.Boat] as BoatModule).IsReady;
  362. }
  363. else
  364. {
  365. if (!ZAxisDevice.CheckServoAtPosition(_boatTargetPosition))
  366. {
  367. reason = $"elevator not at {_boatTargetPosition}";
  368. return false;
  369. }
  370. return (Singleton<EquipmentManager>.Instance.Modules[ModuleName.Boat] as BoatModule).IsReady;
  371. }
  372. }
  373. public bool CheckAPCWaitCondition(out string reason)
  374. {
  375. return APCDevice.CheckWaitCondition(out reason);
  376. }
  377. public bool CheckMFCWaitCondition(out string reason)
  378. {
  379. reason = "";
  380. var ret = true;
  381. foreach (var mfc in _processMFCs)
  382. {
  383. if (!mfc.CheckWaitCondition(out string info))
  384. {
  385. reason += $"{info} \n";
  386. ret = false;
  387. }
  388. }
  389. return ret;
  390. }
  391. public bool CheckHeaterWaitCondition(out string reason)
  392. {
  393. reason = "";
  394. var ret = true;
  395. foreach (var heater in _heaters)
  396. {
  397. if (!heater.CheckWaitCondition(out string info))
  398. {
  399. reason += $"{info} \n";
  400. ret = false;
  401. }
  402. }
  403. return ret;
  404. }
  405. public void AbortRecipe()
  406. {
  407. _processMFCs.ForEach(x => x.Terminate());
  408. _heaters.ForEach(x => x.Terminate());
  409. _valves.ForEach(x => x.Terminate());
  410. ZAxisDevice.ServoStop();
  411. RAxisDevice.ServoStop();
  412. APC.Terminate();
  413. AbortLeakCheck();
  414. IsWait = false;
  415. }
  416. public void HeaterEnable(bool isEnable)
  417. {
  418. _heaters.ForEach(x => x.SetEnable(isEnable));
  419. }
  420. public bool CheckHeaterProfileFinish(out string reason)
  421. {
  422. reason = "";
  423. if (_heaters.Any(x => x.IsProfileMode))
  424. {
  425. IsHeaterProfile = true;
  426. var ret = true;
  427. foreach (var heater in _heaters)
  428. {
  429. if (!heater.CheckProfileFinish(out string info))
  430. {
  431. reason += $"{info} \n";
  432. ret = false;
  433. }
  434. }
  435. if (!ret)
  436. {
  437. foreach (var heater in _heaters)
  438. {
  439. heater.IsProfileSuccess = false;//有任何一个没结束,所有都要接着判断
  440. }
  441. _profileTrig.CLK = false;
  442. return false;//有任何一个没结束
  443. }
  444. if (HeaterU.IsProfileSuccess &&
  445. HeaterCU.IsProfileSuccess &&
  446. HeaterC.IsProfileSuccess &&
  447. HeaterCL.IsProfileSuccess &&
  448. HeaterL.IsProfileSuccess)
  449. {
  450. IsHeaterProfileSuccess = true;
  451. _profileTrig.CLK = true;
  452. _heaters.ForEach(x => x.DeviceData.ProfileStatus = "Normal End");
  453. _heaters.ForEach(x => x.ProfileFinish());
  454. if (_profileTrig.Q)
  455. SaveHeaterProflieToCorrectTable(_heaters[0].CurrentCorrectFileName, _heaters[0].CurrentCorrectIndex);//更新profile table
  456. }
  457. return true;
  458. }
  459. else
  460. {
  461. _heaters.ForEach(x => x.ProfileFinish());
  462. return true;//不处于profile模式
  463. }
  464. }
  465. private void SaveHeaterProflieToCorrectTable(string correctFileName, int tableIndex)
  466. {
  467. var content = ParameterFileManager.Instance.LoadParameter("Parameter\\TempCorrection", correctFileName, false);
  468. if (string.IsNullOrEmpty(content))
  469. {
  470. EV.PostWarningLog(Module, $"{correctFileName} heater temperature correct file is empty");
  471. return;
  472. }
  473. var doc = new XmlDocument();
  474. doc.LoadXml(content);
  475. XmlNodeList nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Module[@Name='']/Step");
  476. if (nodeSteps == null)
  477. nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Step");
  478. if (nodeSteps == null)
  479. {
  480. EV.PostWarningLog(Module, $"Invalid heater temperature correct file {correctFileName}");
  481. return;
  482. }
  483. if (tableIndex < 1 || nodeSteps.Count < tableIndex)
  484. {
  485. EV.PostWarningLog(Module, $"{correctFileName} heater temperature correct file table id={tableIndex} is invalid");
  486. return;
  487. }
  488. XmlElement targetStepNode = nodeSteps[tableIndex - 1] as XmlElement;
  489. if (targetStepNode != null)
  490. {
  491. var correctionDataString = targetStepNode.GetAttribute("CorrectionData");
  492. if (string.IsNullOrEmpty(correctionDataString))
  493. {
  494. EV.PostWarningLog(Module, $"Heater temperature correct file is empty");
  495. return;
  496. }
  497. var correctionDatas = correctionDataString.Split('|');
  498. if (correctionDatas.Length < 5)
  499. {
  500. EV.PostWarningLog(Module, $"Heater temperature correct file data length is invalid");
  501. return;
  502. }
  503. List<string> newCorrectionDatas = new List<string>();
  504. for (int i = 0; i < correctionDatas.Length; i++)
  505. {
  506. var datas = correctionDatas[i];
  507. var dataArry = datas.Split(';');
  508. if (dataArry.Length < 6)
  509. {
  510. EV.PostWarningLog(Module, $"Heater temperature correct file data length is invalid");
  511. return;
  512. }
  513. var correctParameter = new CorrectParameter();
  514. foreach (var item in dataArry)
  515. {
  516. var itemArry = item.Split(':');
  517. if (itemArry.Length < 2)
  518. {
  519. EV.PostWarningLog(Module, $"Heater temperature correct file data length is invalid");
  520. return;
  521. }
  522. switch (itemArry[0].ToLower())
  523. {
  524. case "index":
  525. int.TryParse(itemArry[1], out int no);
  526. correctParameter.No = no;
  527. break;
  528. case "name":
  529. correctParameter.Name = itemArry[1];
  530. break;
  531. case "profiletemp":
  532. float.TryParse(itemArry[1], out float profiletemp);
  533. correctParameter.ProfileTemp = profiletemp;
  534. break;
  535. case "profilecorrect":
  536. float.TryParse(itemArry[1], out float profilecorrect);
  537. correctParameter.ProfileCorrect = profilecorrect;
  538. break;
  539. case "cascadetccorrect":
  540. float.TryParse(itemArry[1], out float cascadetccorrect);
  541. correctParameter.CascadeTCCorrect = cascadetccorrect;
  542. break;
  543. case "profiletccalib":
  544. float.TryParse(itemArry[1], out float profiletccalib);
  545. correctParameter.ProfileTCCalib = profiletccalib;
  546. break;
  547. }
  548. }
  549. FurnaceRT.Devices.IoHeater heater = null;
  550. if (_heaters.Count > i)
  551. {
  552. heater = _heaters[i];
  553. }
  554. if (heater != null)
  555. {
  556. 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}");
  557. heater.DeviceData.ProfileResult = correctParameter.ProfileCorrect;
  558. }
  559. }
  560. if (newCorrectionDatas.Count == correctionDatas.Length)
  561. targetStepNode.SetAttribute("CorrectionData", string.Join("|", newCorrectionDatas.ToArray()));
  562. LOG.Write($"Profile result {correctFileName}:{tableIndex} CorrectionData={string.Join("|", newCorrectionDatas.ToArray())}");
  563. //FileStream fileStream = new FileStream(ParameterFileManager.Instance.GenerateParameterFilePath("Parameter\\TempCorrection", correctFileName), FileMode.Create);
  564. //doc.Save(fileStream);
  565. using (FileStream fileStream = new FileStream(ParameterFileManager.Instance.GenerateParameterFilePath("Parameter\\TempCorrection", correctFileName), FileMode.Create))
  566. {
  567. doc.Save(fileStream);
  568. }
  569. }
  570. }
  571. private bool SetAlarmConditionTable(object[] param)
  572. {
  573. if (param == null || param.Length < 1)
  574. {
  575. return false;
  576. }
  577. var array = param[0].ToString().Split(':');
  578. int.TryParse(array[0], out int index);
  579. lock (_alarmConditionLocker)
  580. {
  581. SetAlarmConditionTableIndex(index);
  582. }
  583. return true;
  584. }
  585. }
  586. }