PMModuleRecipeExecutor.cs 26 KB

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