PMModuleRecipeExecutor.cs 26 KB

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