CommonRoutine.cs 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Aitex.Core.Common;
  5. using Aitex.Core.RT.Device;
  6. using Aitex.Core.RT.Device.Unit;
  7. using Aitex.Core.RT.Event;
  8. using Aitex.Core.RT.Routine;
  9. using Aitex.Core.RT.SCCore;
  10. using Aitex.Core.Util;
  11. using EFEM.RT.Devices;
  12. using Aitex.Sorter.Common;
  13. using EFEMSC;
  14. using MECF.Framework.Common.Equipment;
  15. using MECF.Framework.Common.SubstrateTrackings;
  16. using MECF.Framework.Common.Utilities;
  17. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
  18. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.OcrReaders;
  19. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot;
  20. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot.NX100;
  21. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase;
  22. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
  23. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
  24. using Aitex.Core.RT.Log;
  25. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.BufferStations;
  26. namespace EFEM.RT.Routines
  27. {
  28. public class CommonRoutine : SeqenecRoutine
  29. {
  30. protected bool bUINotify;
  31. public string Module { get; set; }
  32. public string Name { get; set; }
  33. public string Display { get; set; }
  34. //protected LoadPort loadportA = null;
  35. //protected LoadPort loadportB = null;
  36. //protected RIDReader ridreaderA = null;
  37. //protected RIDReader ridreaderB = null;
  38. protected RobotBaseDevice robot = null;
  39. protected Aligner aligner = null;
  40. protected OcrReader widreader = null;
  41. protected IoCoolingBuffer buffer1 = null;
  42. protected IoCoolingBuffer buffer2 = null;
  43. protected IoCoolingBuffer aligner1 = null;
  44. protected IoCoolingBuffer aligner2 = null;
  45. protected LoadLockDevice ll1 = null;
  46. protected LoadLockDevice ll2 = null;
  47. protected IoCoolingBuffer _ioCoolBuffer;
  48. protected BufferStation bf = null;
  49. protected BufferStation bf1 = null;
  50. protected BufferStation bf2 = null;
  51. private List<LoadPortBaseDevice> LPs;
  52. protected readonly bool HaveAligner = DeviceDefineManager.Instance.GetValue<bool>("AlignerInstalled") ?? false;
  53. protected readonly bool AlignerNeedMoveUpCommand = DeviceDefineManager.Instance.GetValue<bool>("AlignerNeedMoveUpCommand") ?? false;
  54. protected readonly int LoadPortQuantity = DeviceDefineManager.Instance.GetValue<int>("LoadPortQuantity") ?? 0;
  55. protected readonly string RobotTypeDefine = DeviceDefineManager.Instance.GetValue("RobotType");
  56. protected readonly bool HaveMotionAxis = DeviceDefineManager.Instance.GetValue<bool>("MotionAxisInstalled") ?? false;
  57. protected static readonly bool LoadLockDoorControlByStation = DeviceDefineManager.Instance.GetValue<bool>("LLDoorControlByStation") ?? false;
  58. //protected readonly string LoadPortTypeDefine = DeviceDefineManager.Instance.GetValue("LoadPortType");
  59. protected int OffsetX;
  60. protected int OffsetY;
  61. protected int OffsetZ;
  62. private DeviceTimer _timerQuery = new DeviceTimer();
  63. private int _queryPeriod = 500; //ms
  64. protected bool NeedSetParameter;
  65. protected bool IsStopped;
  66. private int _existInterval = SC.GetValue<int>("Robot.Robot.ExistInterval");
  67. protected bool NeedRobotGripAndUngrip=SC.GetValue<bool>("System.EnableRobotGripAndUngrip");
  68. public bool IsEnableIdentifyThickness
  69. {
  70. get
  71. {
  72. if (SC.ContainsItem("System.IsEnableIdentifyThickness"))
  73. return SC.GetValue<bool>("System.IsEnableIdentifyThickness");
  74. return false;
  75. }
  76. }
  77. public bool IsEnableMultiWaferSize
  78. {
  79. get
  80. {
  81. if (SC.ContainsItem("System.IsEnableMultiWaferSize"))
  82. return SC.GetValue<bool>("System.IsEnableMultiWaferSize");
  83. return false;
  84. }
  85. }
  86. public string EFemNum
  87. {
  88. get
  89. {
  90. if (SC.ContainsItem("System.EFEMNUM"))
  91. return SC.GetStringValue("System.EFEMNUM");
  92. return "001";
  93. }
  94. }
  95. public bool IsVacuumMode
  96. {
  97. get
  98. {
  99. if (SC.ContainsItem("Robot.Robot.IsVacuumMode"))
  100. return SC.GetValue<bool>("Robot.Robot.IsVacuumMode");
  101. return true;
  102. }
  103. }
  104. private DeviceTimer _timerPerf = new DeviceTimer();
  105. public CommonRoutine()
  106. {
  107. robot = DEVICE.GetDevice<RobotBaseDevice>(DeviceName.Robot);
  108. aligner = DEVICE.GetDevice<Aligner>(DeviceName.Aligner);
  109. widreader = DEVICE.GetDevice<OcrReader>(DeviceName.WIDReader);
  110. buffer1 = DEVICE.GetDevice<IoCoolingBuffer>(DeviceName.CoolingBuffer1);
  111. buffer2 = DEVICE.GetDevice<IoCoolingBuffer>(DeviceName.CoolingBuffer2);
  112. aligner1 = DEVICE.GetDevice<IoCoolingBuffer>(DeviceName.Aligner1);
  113. aligner2 = DEVICE.GetDevice<IoCoolingBuffer>(DeviceName.Aligner2);
  114. ll1 = DEVICE.GetDevice<LoadLockDevice>(DeviceName.LL1);
  115. ll2 = DEVICE.GetDevice<LoadLockDevice>(DeviceName.LL2);
  116. bf = DEVICE.GetDevice<BufferStation>(DeviceName.Buffer);
  117. bf1 = DEVICE.GetDevice<BufferStation>(DeviceName.Buffer1);
  118. bf2 = DEVICE.GetDevice<BufferStation>(DeviceName.Buffer2);
  119. var lpNames = new List<ModuleName>(Singleton<DeviceManager>.Instance.LpNames);
  120. LPs = new List<LoadPortBaseDevice>();
  121. lpNames.ForEach(lp =>
  122. {
  123. if(!SC.GetValue<bool>($"LoadPort.{lp}.Disable"))
  124. LPs.Add(DEVICE.GetDevice<LoadPortBaseDevice>(lp.ToString()));
  125. });
  126. }
  127. public bool InitCommon()
  128. {
  129. return true;
  130. }
  131. protected void UpdateSCValue()
  132. {
  133. }
  134. //延时
  135. public void Delay(int id, string name, double time, Action<string> notify, Action<string> error)
  136. {
  137. Tuple<bool, Result> ret = Delay(id, () =>
  138. {
  139. notify(name);
  140. return true;
  141. }, time * 1000);
  142. if (ret.Item1)
  143. {
  144. if (ret.Item2 == Result.RUN)
  145. {
  146. throw (new RoutineBreakException());
  147. }
  148. }
  149. }
  150. #region waferID
  151. #endregion
  152. #region robot
  153. public void RobotReset(int id, RobotBaseDevice device, string name, int time, Action<string> notify, Action<string> error)
  154. {
  155. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  156. {
  157. notify(String.Format("{0} clear error", device.Name));
  158. string reason = string.Empty;
  159. device.RobotReset();
  160. return true;
  161. }, () =>
  162. {
  163. if (!device.IsBusy&& device.RobotState != RobotStateEnum.Error && device.RobotState == RobotStateEnum.Idle)
  164. {
  165. return true;
  166. }
  167. return false;
  168. }, time * 1000);
  169. if (ret.Item1)
  170. {
  171. if (ret.Item2 == Result.FAIL)
  172. {
  173. throw (new RoutineFaildException());
  174. }
  175. else if (ret.Item2 == Result.TIMEOUT) //timeout
  176. {
  177. error(String.Format("{0} timeout, than {1} seconds", name, time));
  178. throw (new RoutineFaildException());
  179. }
  180. else
  181. throw (new RoutineBreakException());
  182. }
  183. }
  184. public void RobotServoOnOff(int id, Robot device, bool trueForOnFalseForOff, Action<string> notify, Action<string> error)
  185. {
  186. Tuple<bool, Result> ret = Execute(id, () =>
  187. {
  188. notify(String.Format("{0} Home", device.Name));
  189. string reason = string.Empty;
  190. return device.SetServoOnOff(trueForOnFalseForOff,out reason);
  191. });
  192. if (ret.Item1)
  193. {
  194. if (ret.Item2 == Result.FAIL)
  195. {
  196. throw (new RoutineFaildException());
  197. }
  198. }
  199. }
  200. public void RobotInit(int id, Robot device, string name, Action<string> notify, Action<string> error)
  201. {
  202. Tuple<bool, Result> ret = Execute(id, () =>
  203. {
  204. notify(String.Format("{0} Home", device.Name));
  205. string reason = string.Empty;
  206. return device.Init(out reason);
  207. });
  208. if (ret.Item1)
  209. {
  210. if (ret.Item2 == Result.FAIL)
  211. {
  212. throw (new RoutineFaildException());
  213. }
  214. }
  215. }
  216. public void RobotHome(int id, RobotBaseDevice device, string name, Action<string> notify, Action<string> error)
  217. {
  218. Tuple<bool, Result> ret = Execute(id, () =>
  219. {
  220. notify(String.Format("{0} Home", device.Name));
  221. string reason = string.Empty;
  222. return device.Home(null);
  223. });
  224. if (ret.Item1)
  225. {
  226. if (ret.Item2 == Result.FAIL)
  227. {
  228. throw (new RoutineFaildException());
  229. }
  230. }
  231. }
  232. public void RobotArmHome(int id, RobotBaseDevice device, string name, Action<string> notify, Action<string> error)
  233. {
  234. Tuple<bool, Result> ret = Execute(id, () =>
  235. {
  236. notify(String.Format("{0} Arm Home", device.Name));
  237. string reason = string.Empty;
  238. return device.Home(null);
  239. });
  240. if (ret.Item1)
  241. {
  242. if (ret.Item2 == Result.FAIL)
  243. {
  244. throw (new RoutineFaildException());
  245. }
  246. }
  247. }
  248. ///等待 Robot Motion
  249. public void WaitRobotMotion(int id, RobotBaseDevice device, string name, int time, Action<string> notify, Action<string> error)
  250. {
  251. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  252. {
  253. notify("Wait robot finish motion");
  254. _timerQuery.Start(_queryPeriod); //开始查询
  255. return true;
  256. }, () =>
  257. {
  258. if (device.IsReady())
  259. {
  260. _timerQuery.Stop();
  261. return true;
  262. }
  263. if (query())
  264. {
  265. // string reason = string.Empty;
  266. // device.QueryState(out reason); //查询位置
  267. }
  268. return false;
  269. }, time * 1000);
  270. if (ret.Item1)
  271. {
  272. if (ret.Item2 == Result.FAIL)
  273. {
  274. throw (new RoutineFaildException());
  275. }
  276. else if (ret.Item2 == Result.TIMEOUT) //timeout
  277. {
  278. error(String.Format("{0} timeout, than {1} seconds", name, time));
  279. throw (new RoutineFaildException());
  280. }
  281. else
  282. throw (new RoutineBreakException());
  283. }
  284. }
  285. ///等待
  286. ///
  287. public void ReserveRobotToBusy(int id, RobotBaseDevice robot, string name,Action<string> notify, Action<string> error)
  288. {
  289. Tuple<bool, Result> ret = Execute(id, () =>
  290. {
  291. notify(String.Format("{0} set robot to busy", robot.Name));
  292. string reason = string.Empty;
  293. robot.IsBusy = true;
  294. return true;
  295. });
  296. if (ret.Item1)
  297. {
  298. if (ret.Item2 == Result.FAIL)
  299. {
  300. throw (new RoutineFaildException());
  301. }
  302. }
  303. }
  304. public void Wait(int id, string name, double time, Action<string> notify, Action<string> error)
  305. {
  306. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  307. {
  308. notify($"Wait {time} seconds");
  309. _timerQuery.Start(_queryPeriod); //开始查询
  310. return true;
  311. }, () =>
  312. {
  313. if (_timerQuery.GetElapseTime() >= time * 1000)
  314. {
  315. _timerQuery.Stop();
  316. return true;
  317. }
  318. return false;
  319. });
  320. if (ret.Item1)
  321. {
  322. if (ret.Item2 == Result.FAIL)
  323. {
  324. throw (new RoutineFaildException());
  325. }
  326. else
  327. throw (new RoutineBreakException());
  328. }
  329. }
  330. public void CoolBufferMoveUP(int id, IoCoolingBuffer device, WaferSize size, int time, Action<string> notify, Action<string> error)
  331. {
  332. Tuple<bool, Result> ret = Execute(id, () =>
  333. {
  334. notify($"Start {device.Name} Move Up");
  335. if (device.CheckPinUp()) return true;
  336. if (!device.Move(size, true, out string reason))
  337. {
  338. Stop(reason);
  339. return false;
  340. }
  341. return true;
  342. });
  343. if (ret.Item1)
  344. {
  345. if (ret.Item2 == Result.FAIL)
  346. {
  347. throw (new RoutineFaildException());
  348. }
  349. }
  350. }
  351. public void RobotBusytoSimif(int id, ModuleName moduleName,bool on,int time, Action<string> notify, Action<string> error)
  352. {
  353. Tuple<bool, Result> ret = Execute(id, () =>
  354. {
  355. notify($"set TrigRBbusytoSIMF of {moduleName} signal {on} ");
  356. if (on)
  357. {
  358. var value = moduleName == ModuleName.LP1 ? DeviceModel.TrigRBbusytoSIMF1.SetTrigger(true, out _) : DeviceModel.TrigRBbusytoSIMF2.SetTrigger(true, out _);
  359. if (!value)
  360. {
  361. Stop(null);
  362. return false;
  363. }
  364. }
  365. else
  366. {
  367. var value = moduleName == ModuleName.LP1 ? DeviceModel.TrigRBbusytoSIMF1.SetTrigger(false, out _) : DeviceModel.TrigRBbusytoSIMF2.SetTrigger(false, out _);
  368. if (!value)
  369. {
  370. Stop(null);
  371. return false;
  372. }
  373. }
  374. return true;
  375. });
  376. if (ret.Item1)
  377. {
  378. if (ret.Item2 == Result.FAIL)
  379. {
  380. throw (new RoutineFaildException());
  381. }
  382. }
  383. }
  384. public void UnGripRobotBlade(int id, Hand blade, RobotBaseDevice device, int time)
  385. {
  386. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  387. {
  388. Notify($"Release robot {blade}");
  389. //IoSensor sensorBlade = blade == Hand.Blade1
  390. // ? DeviceModel.SensorRobotFork1WaferOn
  391. // : DeviceModel.SensorRobotFork2WaferOn;
  392. //var iswaferpersence = blade == Hand.Blade1 ? robot.IsWaferPresenceOnBlade1 : robot.IsWaferPresenceOnBlade2;
  393. //int slot = blade == Hand.Blade1 ? 0 : 1;
  394. //if (WaferManager.Instance.CheckNoWafer(ModuleName.Robot, slot)) //!sensorBlade.Value &&
  395. {
  396. if (!device.Release((RobotArmEnum)blade))
  397. {
  398. Stop(null);
  399. return false;
  400. }
  401. }
  402. return true;
  403. }, () =>
  404. {
  405. if (!device.IsBusy)
  406. {
  407. return true;
  408. }
  409. //此处如果发生错误,忽略
  410. return false;
  411. }, time * 1000);
  412. if (ret.Item1)
  413. {
  414. if (ret.Item2 == Result.FAIL)
  415. {
  416. throw (new RoutineFaildException());
  417. }
  418. else if (ret.Item2 == Result.TIMEOUT) //timeout
  419. {
  420. Stop($"Release robot {blade} timeout, than {time} seconds");
  421. throw (new RoutineFaildException());
  422. }
  423. else
  424. throw (new RoutineBreakException());
  425. }
  426. }
  427. public void GripRobotBlade(int id, Hand blade, RobotBaseDevice device, int time)
  428. {
  429. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  430. {
  431. Notify($"Grip robot {blade}");
  432. //IoSensor sensorBlade = blade == Hand.Blade1
  433. // ? DeviceModel.SensorRobotFork1WaferOn
  434. // : DeviceModel.SensorRobotFork2WaferOn;
  435. //var iswaferpersence = blade == Hand.Blade1 ? robot.IsWaferPresenceOnBlade1 : robot.IsWaferPresenceOnBlade2;
  436. //int slot = blade == Hand.Blade1 ? 0 : 1;
  437. //if (!iswaferpersence && WaferManager.Instance.CheckNoWafer(ModuleName.Robot, slot)) //!sensorBlade.Value &&
  438. //{
  439. if (!device.Grip((RobotArmEnum)blade))
  440. {
  441. Stop(null);
  442. return false;
  443. }
  444. // }
  445. return true;
  446. }, () =>
  447. {
  448. if (device.IsReady())
  449. {
  450. return true;
  451. }
  452. //此处如果发生错误,忽略
  453. return false;
  454. }, time * 1000);
  455. if (ret.Item1)
  456. {
  457. if (ret.Item2 == Result.FAIL)
  458. {
  459. throw (new RoutineFaildException());
  460. }
  461. else if (ret.Item2 == Result.TIMEOUT) //timeout
  462. {
  463. Stop($"Release robot {blade} timeout, than {time} seconds");
  464. throw (new RoutineFaildException());
  465. }
  466. else
  467. throw (new RoutineBreakException());
  468. }
  469. }
  470. public void HomeReleaseRobotBlade(int id, Hand blade, RobotBaseDevice device, int time)
  471. {
  472. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  473. {
  474. Notify($"Release robot {blade}");
  475. //IoSensor sensorBlade = blade == Hand.Blade1
  476. // ? DeviceModel.SensorRobotFork1WaferOn
  477. // : DeviceModel.SensorRobotFork2WaferOn;
  478. //var iswaferpersence = blade == Hand.Blade1 ? robot.IsWaferPresenceOnBlade1 : robot.IsWaferPresenceOnBlade2;
  479. //int slot = blade == Hand.Blade1 ? 0 : 1;
  480. //if (!iswaferpersence&&WaferManager.Instance.CheckNoWafer(ModuleName.Robot, slot)) //!sensorBlade.Value &&
  481. //{
  482. if (!device.Release((RobotArmEnum)blade))
  483. {
  484. Stop(null);
  485. return false;
  486. }
  487. // }
  488. return true;
  489. }, () =>
  490. {
  491. if (device.IsReady())
  492. {
  493. return true;
  494. }
  495. //此处如果发生错误,忽略
  496. return false;
  497. }, time * 1000);
  498. if (ret.Item1)
  499. {
  500. if (ret.Item2 == Result.FAIL)
  501. {
  502. throw (new RoutineFaildException());
  503. }
  504. else if (ret.Item2 == Result.TIMEOUT) //timeout
  505. {
  506. Stop($"Release robot {blade} timeout, than {time} seconds");
  507. throw (new RoutineFaildException());
  508. }
  509. else
  510. throw (new RoutineBreakException());
  511. }
  512. }
  513. public void HomeGripAndUngripRobotBlade(int id, Hand blade, RobotBaseDevice device, int time)
  514. {
  515. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  516. {
  517. Notify($"Grip or Ungrip robot {blade}");
  518. int slot = blade == Hand.Blade1 ? 0 : 1;
  519. if (WaferManager.Instance.CheckHasWafer(ModuleName.Robot, slot))
  520. {
  521. if (!device.Grip((RobotArmEnum)blade))
  522. {
  523. Stop(null);
  524. return false;
  525. }
  526. }
  527. else
  528. {
  529. if (!device.Release((RobotArmEnum)blade))
  530. {
  531. Stop(null);
  532. return false;
  533. }
  534. }
  535. //Thread.Sleep(1000);
  536. return true;
  537. }, () =>
  538. {
  539. if (device.IsReady())
  540. {
  541. return true;
  542. }
  543. //此处如果发生错误,忽略
  544. return false;
  545. }, time * 1000);
  546. if (ret.Item1)
  547. {
  548. if (ret.Item2 == Result.FAIL)
  549. {
  550. throw (new RoutineFaildException());
  551. }
  552. else if (ret.Item2 == Result.TIMEOUT) //timeout
  553. {
  554. Stop($"Grip robot {blade} timeout, than {time} seconds");
  555. throw (new RoutineFaildException());
  556. }
  557. else
  558. throw (new RoutineBreakException());
  559. }
  560. }
  561. public void CheckBladeWaferIsExist(int id, RobotBaseDevice device,Hand blade, int time)
  562. {
  563. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  564. {
  565. Notify($"Check Blade {blade} Wafer Is Exist");
  566. try
  567. {
  568. if (!device.IsReady())
  569. {
  570. LOG.Write($"CheckBladeWaferIsExist:Robot IsReady={device.IsReady()}");
  571. throw (new RoutineBreakException());
  572. }
  573. if (!device.ReadParameter(new object[] { "CheckWaferIsPresence", blade == Hand.Blade1 ? 0 : 1, _existInterval }))
  574. {
  575. Stop(null);
  576. return false;
  577. }
  578. }
  579. catch (Exception ex)
  580. {
  581. LOG.Write(ex);
  582. }
  583. LOG.Write($"Check Blade Wafer Is Exist");
  584. //Thread.Sleep(1000);
  585. return true;
  586. }, () =>
  587. {
  588. // LOG.Write("CheckBladeWaferIsExist1: IsReady=false");
  589. try
  590. {
  591. if (device.IsReady())
  592. {
  593. LOG.Write("CheckBladeWaferIsExist: IsReady=true");
  594. return true;
  595. }
  596. }
  597. catch (Exception ex)
  598. {
  599. LOG.Write(ex);
  600. }
  601. //LOG.Write("CheckBladeWaferIsExist2: IsReady=false");
  602. //此处如果发生错误,忽略
  603. return false;
  604. }, time * 1000);
  605. if (ret.Item1)
  606. {
  607. if (ret.Item2 == Result.FAIL)
  608. {
  609. throw (new RoutineFaildException());
  610. }
  611. else if (ret.Item2 == Result.TIMEOUT) //timeout
  612. {
  613. Stop($"Check robot WaferPresence timeout, than {time} seconds");
  614. throw (new RoutineFaildException());
  615. }
  616. else
  617. throw (new RoutineBreakException());
  618. }
  619. }
  620. public void RobotSignalStatus(int id, RobotBaseDevice device , int time)
  621. {
  622. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  623. {
  624. Notify($"Query robot Signal Status");
  625. if (!device.ReadParameter(new object[] { "SignalStatus"}))
  626. {
  627. Stop(null);
  628. return false;
  629. }
  630. //Thread.Sleep(1000);
  631. return true;
  632. }, () =>
  633. {
  634. if (device.IsReady())
  635. {
  636. return true;
  637. }
  638. //此处如果发生错误,忽略
  639. return false;
  640. }, time * 1000);
  641. if (ret.Item1)
  642. {
  643. if (ret.Item2 == Result.FAIL)
  644. {
  645. throw (new RoutineFaildException());
  646. }
  647. else if (ret.Item2 == Result.TIMEOUT) //timeout
  648. {
  649. throw (new RoutineFaildException());
  650. }
  651. else
  652. throw (new RoutineBreakException());
  653. }
  654. }
  655. public void ConfirmRobotBladeWafer(int id, Hand blade)
  656. {
  657. Execute(id, () =>
  658. {
  659. Notify($"Confirm robot {blade} wafer");
  660. //IoSensor sensorBlade = blade == Hand.Blade1
  661. // ? DeviceModel.SensorRobotFork1WaferOn
  662. // : DeviceModel.SensorRobotFork2WaferOn;
  663. var iswaferpersence = blade == Hand.Blade1 ? robot.IsWaferPresenceOnBlade1 : robot.IsWaferPresenceOnBlade2;
  664. int slot = blade == Hand.Blade1 ? 0 : 1;
  665. if (iswaferpersence)
  666. {
  667. if (WaferManager.Instance.CheckNoWafer(ModuleName.Robot, slot))
  668. {
  669. EV.PostWarningLog(Module, $"Found wafer at robot {blade}");
  670. WaferManager.Instance.CreateWafer(ModuleName.Robot, slot, WaferStatus.Normal);
  671. }
  672. }
  673. else
  674. {
  675. if (WaferManager.Instance.CheckHasWafer(ModuleName.Robot, slot))
  676. {
  677. EV.PostWarningLog(Module, $"Not found wafer at robot {blade}, please manually confirm again.");
  678. WaferManager.Instance.DeleteWafer(ModuleName.Robot, slot);
  679. }
  680. }
  681. return true;
  682. });
  683. }
  684. public void CoolBufferMoveDown(int id, IoCoolingBuffer device, WaferSize size, int time, Action<string> notify, Action<string> error)
  685. {
  686. Tuple<bool, Result> ret = Execute(id, () =>
  687. {
  688. notify($"Start {device.Name} Move Down");
  689. if (device.CheckPinDown()) return true;
  690. if (!device.Move(size, false, out string reason))
  691. {
  692. Stop(reason);
  693. return false;
  694. }
  695. return true;
  696. });
  697. if (ret.Item1)
  698. {
  699. if (ret.Item2 == Result.FAIL)
  700. {
  701. throw (new RoutineFaildException());
  702. }
  703. }
  704. }
  705. public void WaitCoolBufferMoveUp(int id, IoCoolingBuffer device, string name, int time, Action<string> notify,
  706. Action<string> error)
  707. {
  708. var ret = ExecuteAndWait(id, () =>
  709. {
  710. notify(name);
  711. return true;
  712. }, () =>
  713. {
  714. if (device.Error)
  715. {
  716. Stop("Can not move up, device error");
  717. return null;
  718. }
  719. return device.CheckMovedUp() && !device.Busy ;
  720. }, time * 1000);
  721. if (ret.Item1)
  722. {
  723. if (ret.Item2 == Result.FAIL)
  724. throw new RoutineFaildException();
  725. if (ret.Item2 == Result.TIMEOUT) //timeout
  726. {
  727. error($"{name} timeout, than {time} seconds");
  728. throw new RoutineFaildException();
  729. }
  730. bool isMovedUp = device.CheckMovedUp() && !device.Busy && !device.Error;
  731. if (!isMovedUp)
  732. {
  733. throw new RoutineBreakException();
  734. }
  735. }
  736. }
  737. public void WaitCoolBufferMoveDown(int id, IoCoolingBuffer device, string name, int time, Action<string> notify,
  738. Action<string> error)
  739. {
  740. var ret = ExecuteAndWait(id, () =>
  741. {
  742. notify(name);
  743. _timerQuery.Start(_queryPeriod); //开始查询
  744. return true;
  745. }, () =>
  746. {
  747. if (device.Error)
  748. {
  749. Stop("Can not move down, device error");
  750. return null;
  751. }
  752. return device.CheckMovedDown() && !device.Busy;
  753. }, time * 1000);
  754. if (ret.Item1)
  755. {
  756. if (ret.Item2 == Result.FAIL) throw new RoutineFaildException();
  757. if (ret.Item2 == Result.TIMEOUT) //timeout
  758. {
  759. error($"{name} timeout, than {time} seconds");
  760. throw new RoutineFaildException();
  761. }
  762. bool isMovedDown = device.CheckMovedDown() && !device.Busy && !device.Error;
  763. if (!isMovedDown)
  764. {
  765. throw new RoutineBreakException();
  766. }
  767. }
  768. }
  769. public void SetWaferSize(int id, string name, int cmd, ModuleName station, int slot, int time, Action<string> notify, Action<string> error)
  770. {
  771. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  772. {
  773. WaferSize size = WaferSize.WS0;
  774. if (ModuleHelper.IsLoadPort(station))
  775. {
  776. }
  777. else
  778. {
  779. size = WaferManager.Instance.GetWaferSize(station, slot);
  780. }
  781. notify(String.Format($"Set WaferSize parameter {cmd} {size.ToString()}"));
  782. string reason = string.Empty;
  783. //robot.SetWaferSize(cmd, size, out reason);
  784. return true;
  785. }, () =>
  786. {
  787. if (robot.RobotState == RobotStateEnum.Idle)
  788. {
  789. return true;
  790. }
  791. return false;
  792. }, time * 1000);
  793. if (ret.Item1)
  794. {
  795. if (ret.Item2 == Result.FAIL)
  796. {
  797. throw (new RoutineFaildException());
  798. }
  799. else if (ret.Item2 == Result.TIMEOUT) //timeout
  800. {
  801. error(String.Format("Set WaferSize timeout, than {0} seconds", time));
  802. throw (new RoutineFaildException());
  803. }
  804. else
  805. throw (new RoutineBreakException());
  806. }
  807. }
  808. /// <summary>
  809. /// 目前只比对0114 parameter
  810. /// </summary>
  811. /// <param name="id"></param>
  812. /// <param name="name"></param>
  813. /// <param name="parameterNo"></param>
  814. /// <param name="parameterType"></param>
  815. /// <param name="waferSize"></param>
  816. /// <param name="time"></param>
  817. /// <param name="notify"></param>
  818. /// <param name="error"></param>
  819. /// <exception cref="RoutineFaildException"></exception>
  820. /// <exception cref="RoutineBreakException"></exception>
  821. protected void RobotGoto(int id, string name, ModuleName chamber, int slot, Hand blade, RobotPostionEnum postype,
  822. Action<string> notify, Action<string> error)
  823. {
  824. var reason = string.Empty;
  825. var ret = Execute(id, () =>
  826. {
  827. notify(string.Format("pick from {0}", chamber.ToString()));
  828. var obj = new object[] { (RobotArmEnum)(int)blade, chamber.ToString(), slot, postype };
  829. return robot.GoTo(obj);// (RobotArmEnum)(int)blade, chamber.ToString(), slot);
  830. });
  831. if (ret.Item1)
  832. if (ret.Item2 == Result.FAIL)
  833. {
  834. error(reason);
  835. throw new RoutineFaildException();
  836. }
  837. }
  838. protected void CheckTriggerSignalOn(int id,string name,ModuleName module,int time)
  839. {
  840. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  841. {
  842. Notify(String.Format("Check Trigger Signal"));
  843. string reason = string.Empty;
  844. return true;
  845. }, () =>
  846. {
  847. if (SC.GetValue<bool>("System.IsSimulatorMode")) return true;
  848. if (module.Equals(ModuleName.LL1))
  849. {
  850. if (DeviceModel.SensorPMASystemInterlock.Value && DeviceModel.TrigSafetytoPMA.Value)
  851. {
  852. return true;
  853. }
  854. }
  855. if (module.Equals(ModuleName.LL2))
  856. {
  857. if (DeviceModel.SensorPMBSystemInterlock.Value && DeviceModel.TrigSafetytoPMB.Value)
  858. {
  859. return true;
  860. }
  861. }
  862. return false;
  863. }, time * 1000);
  864. if (ret.Item1)
  865. {
  866. if (ret.Item2 == Result.FAIL)
  867. {
  868. throw (new RoutineFaildException());
  869. }
  870. else if (ret.Item2 == Result.TIMEOUT) //timeout
  871. {
  872. Stop(String.Format("Trigger Signal Change timeout, than {0} seconds", time));
  873. throw (new RoutineFaildException());
  874. }
  875. else
  876. throw (new RoutineBreakException());
  877. }
  878. }
  879. protected void PickWafer(int id, string name, ModuleName chamber, int slot, Hand blade, int x, int y, int z,
  880. Action<string> notify, Action<string> error)
  881. {
  882. var reason = string.Empty;
  883. var ret = Execute(id, () =>
  884. {
  885. notify(string.Format("pick from {0}", chamber.ToString()));
  886. if (x == 0 && y == 0 && z == 0)
  887. return robot.Pick((RobotArmEnum)(int)blade,chamber.ToString(), slot);
  888. return robot.PickEx((RobotArmEnum)(int)blade, chamber.ToString(), slot, x, y, z);
  889. });
  890. if (ret.Item1)
  891. if (ret.Item2 == Result.FAIL)
  892. {
  893. error(reason);
  894. throw new RoutineFaildException();
  895. }
  896. }
  897. protected void PlaceWafer(int id, string name, ModuleName chamber, int slot, Hand blade, int x, int y, int z,
  898. Action<string> notify, Action<string> error)
  899. {
  900. var ret = Execute(id, () =>
  901. {
  902. notify(string.Format("Place wafer to {0}", chamber.ToString()));
  903. var reason = string.Empty;
  904. if (x == 0 && y == 0 && z == 0)
  905. return robot.Place((RobotArmEnum)(int)blade, chamber.ToString(), slot);
  906. return robot.PlaceEx((RobotArmEnum)(int)blade, chamber.ToString(), slot, x, y, z);
  907. });
  908. if (ret.Item1)
  909. if (ret.Item2 == Result.FAIL)
  910. throw new RoutineFaildException();
  911. }
  912. #endregion
  913. protected bool CheckRobotMotionInterlock(ModuleName chamber, int slot, out string reason) //Pick/Place/Swap
  914. {
  915. reason = string.Empty;
  916. if (robot.RobotState == RobotStateEnum.Error)
  917. {
  918. reason = "robot is error.";
  919. return false;
  920. }
  921. //if (!robot.IsIdle)
  922. //{
  923. // reason = string.Format("robot is moving.");
  924. // return false;
  925. //}
  926. if (!CheckRobotReady())
  927. {
  928. reason = string.Format("robot isn't Ready.");
  929. return false;
  930. }
  931. if (chamber == ModuleName.Aligner)
  932. {
  933. if (aligner.Moving)
  934. {
  935. reason = string.Format("aligner is moving.");
  936. return false;
  937. }
  938. if (!CheckAlignerReady())
  939. {
  940. reason = string.Format("aligner isn't Ready.");
  941. return false;
  942. }
  943. /*
  944. if (aligner.Busy)
  945. {
  946. reason = string.Format("{0} is busy.", chamber.ToString());
  947. return false;
  948. }
  949. */
  950. return true;
  951. }
  952. else if (ModuleHelper.IsLoadPort(chamber))
  953. {
  954. LoadPortBaseDevice loadport = DEVICE.GetDevice<LoadPortBaseDevice>(chamber.ToString());
  955. if (!loadport.IsEnableTransferWafer(out _))
  956. {
  957. reason = string.Format("{0} isn't Ready.", chamber.ToString());
  958. return false;
  959. }
  960. if (loadport.MapError)
  961. {
  962. reason = string.Format("{0} Map has crossed error.", chamber.ToString());
  963. return false;
  964. }
  965. if (chamber.Equals(ModuleName.LP1))
  966. {
  967. if (SC.GetValue<int>($"LoadPort.LP1.CstType") == 0)
  968. {
  969. if (!DeviceModel.SensorSMIF1PODOPEN.Value)
  970. {
  971. reason = string.Format("{0} SMIF1PODOPEN signal is Off.", chamber.ToString());
  972. return false;
  973. }
  974. if (!DeviceModel.SensorSMIF1PODPRESENT.Value)
  975. {
  976. reason = string.Format("{0} SensorSMIF1PODPRESENT signal is Off,Foup is presence.", chamber.ToString());
  977. return false;
  978. }
  979. if (!DeviceModel.SensorSMIF1READY.Value)
  980. {
  981. reason = string.Format("{0} SensorSMIF1READY signal is Off.", chamber.ToString());
  982. return false;
  983. }
  984. }
  985. else if (SC.GetValue<int>($"LoadPort.LP1.CstType") == 1)
  986. {
  987. if(loadport.CassetteState!=LoadportCassetteState.Normal)// (DeviceModel.Sensor4InchCstPresence.Value&& DeviceModel.Sensor6InchCstPresence.Value&& DeviceModel.Sensor8InchCstPresence.Value)
  988. {
  989. reason = string.Format("{0} Cst Presence signal is Off,Foup is not presence.", chamber.ToString());
  990. return false;
  991. }
  992. }
  993. else if (SC.GetValue<int>($"LoadPort.LP1.CstType") == 2)
  994. {
  995. if (!DeviceModel.SensorLP1FoupOpen.Value)
  996. {
  997. reason = string.Format("{0} SensorLP1FoupOpen signal is Off. Foup is not open.", chamber.ToString());
  998. return false;
  999. }
  1000. if (!DeviceModel.SensorLP1FoupPlacement.Value)
  1001. {
  1002. reason = string.Format("{0} SensorLP1FoupPlacement signal is Off. Foup is not placed.", chamber.ToString());
  1003. return false;
  1004. }
  1005. if (!DeviceModel.SensorLP1OperationStatus.Value)
  1006. {
  1007. reason = string.Format("{0} SensorLP1OperationStatus signal is Off. Foup is not in operation status.", chamber.ToString());
  1008. return false;
  1009. }
  1010. if (!DeviceModel.SensorLP1Ready.Value)
  1011. {
  1012. reason = string.Format("{0} SensorLP1Ready signal is Off. Foup is not ready.", chamber.ToString());
  1013. return false;
  1014. }
  1015. if (!DeviceModel.SensorLP1Presence.Value)
  1016. {
  1017. reason = string.Format("{0} SensorLP1Presence signal is Off. Foup is not present.", chamber.ToString());
  1018. return false;
  1019. }
  1020. }
  1021. if (slot + 1 > loadport.ValidSlotsNumber)
  1022. {
  1023. reason = string.Format("{0} ValidSlotsNumber less than {1}.", chamber.ToString(), slot + 1);
  1024. return false;
  1025. }
  1026. }
  1027. else if (chamber.Equals(ModuleName.LP2))
  1028. {
  1029. if (SC.GetValue<int>($"LoadPort.LP2.CstType") == 0)
  1030. {
  1031. if (!DeviceModel.SensorSMIF2PODOPEN.Value)
  1032. {
  1033. reason = string.Format("{0} SMIF2PODOPEN signal is Off.", chamber.ToString());
  1034. return false;
  1035. }
  1036. if (!DeviceModel.SensorSMIF2PODPRESENT.Value)
  1037. {
  1038. reason = string.Format("{0} SensorSMIF2PODPRESENT signal is Off,Foup is not presence .", chamber.ToString());
  1039. return false;
  1040. }
  1041. if (!DeviceModel.SensorSMIF2READY.Value)
  1042. {
  1043. reason = string.Format("{0} SensorSMIF2READY signal is Off.", chamber.ToString());
  1044. return false;
  1045. }
  1046. }
  1047. else if (SC.GetValue<int>($"LoadPort.LP2.CstType") == 1)
  1048. {
  1049. if (loadport.CassetteState != LoadportCassetteState.Normal)// (DeviceModel.Sensor4InchCstPresence.Value&& DeviceModel.Sensor6InchCstPresence.Value&& DeviceModel.Sensor8InchCstPresence.Value)
  1050. {
  1051. reason = string.Format("{0} Cst Presence signal is Off,Foup is not presence.", chamber.ToString());
  1052. return false;
  1053. }
  1054. }
  1055. else if (SC.GetValue<int>($"LoadPort.LP2.CstType") == 2)
  1056. {
  1057. if (!DeviceModel.SensorLP2FoupOpen.Value)
  1058. {
  1059. reason = string.Format("{0} SensorLP2FoupOpen signal is Off. Foup is not open.", chamber.ToString());
  1060. return false;
  1061. }
  1062. if (!DeviceModel.SensorLP2FoupPlacement.Value)
  1063. {
  1064. reason = string.Format("{0} SensorLP2FoupPlacement signal is Off. Foup is not placed.", chamber.ToString());
  1065. return false;
  1066. }
  1067. if (!DeviceModel.SensorLP2OperationStatus.Value)
  1068. {
  1069. reason = string.Format("{0} SensorLP2OperationStatus signal is Off. Foup is not in operation status.", chamber.ToString());
  1070. return false;
  1071. }
  1072. if (!DeviceModel.SensorLP2Ready.Value)
  1073. {
  1074. reason = string.Format("{0} SensorLP2Ready signal is Off. Foup is not ready.", chamber.ToString());
  1075. return false;
  1076. }
  1077. if (!DeviceModel.SensorLP2Presence.Value)
  1078. {
  1079. reason = string.Format("{0} SensorLP2Presence signal is Off. Foup is not present.", chamber.ToString());
  1080. return false;
  1081. }
  1082. }
  1083. if (slot + 1 > loadport.ValidSlotsNumber)
  1084. {
  1085. reason = string.Format("{0} ValidSlotsNumber less than {1}.", chamber.ToString(), slot + 1);
  1086. return false;
  1087. }
  1088. }
  1089. return true;
  1090. }
  1091. if (ModuleHelper.IsLoadLock(chamber))
  1092. {
  1093. var ll = DEVICE.GetDevice<LoadLockDevice>(chamber.ToString());
  1094. if (ll != null && !ll.IsEnableTransferWafer(out reason))
  1095. return false;
  1096. return true;
  1097. }
  1098. if (ModuleHelper.IsBuffer(chamber))
  1099. {
  1100. var bufferStation = DEVICE.GetDevice<BufferStation>(chamber.ToString());
  1101. if (bufferStation !=null && !bufferStation.IsEnableTransferWafer(out reason))
  1102. return false;
  1103. return true;
  1104. }
  1105. if (ModuleHelper.IsCoolingBuffer(chamber)|| ModuleHelper.IsAligner(chamber))
  1106. {
  1107. IoCoolingBuffer buffer = DEVICE.GetDevice<IoCoolingBuffer>(chamber.ToString());
  1108. if(buffer != null)
  1109. {
  1110. if (buffer.Busy)
  1111. {
  1112. reason = "buffer is not idle";
  1113. return false;
  1114. }
  1115. if (!buffer.CheckPinUp())
  1116. {
  1117. reason = "buffer pin not up position";
  1118. return false;
  1119. }
  1120. }
  1121. return true;
  1122. }
  1123. if (ModuleHelper.IsFlipper(chamber))
  1124. {
  1125. return true;
  1126. }
  1127. reason = "error target";
  1128. return false;
  1129. }
  1130. protected bool CheckRobotReady()
  1131. {
  1132. return robot.IsReady();
  1133. }
  1134. protected bool CheckRobotMotionInterlock(out string reason)
  1135. {
  1136. reason = string.Empty;
  1137. if (robot.RobotState != RobotStateEnum.Idle )
  1138. {
  1139. reason = string.Format("robot is not idle.");
  1140. return false;
  1141. }
  1142. if (!CheckRobotReadySensor())
  1143. {
  1144. reason = string.Format("robot isn't ready.");
  1145. return false;
  1146. }
  1147. return true;
  1148. }
  1149. public void QueryLoadportState(int id, LoadPort device)
  1150. {
  1151. Tuple<bool, Result> ret = Execute(id, () =>
  1152. {
  1153. Notify(String.Format("Query {0} state", device.Name));
  1154. return device.IsIdle;
  1155. });
  1156. if (ret.Item1)
  1157. {
  1158. if (ret.Item2 == Result.FAIL)
  1159. {
  1160. Stop("not idle");
  1161. throw (new RoutineFaildException());
  1162. }
  1163. else
  1164. throw (new RoutineBreakException());
  1165. }
  1166. }
  1167. public void QueryAlignerState(int id, Aligner device)
  1168. {
  1169. Tuple<bool, Result> ret = Execute(id, () =>
  1170. {
  1171. Notify(String.Format("Query {0} state", device.Name));
  1172. return device.State == DeviceState.Idle;
  1173. });
  1174. if (ret.Item1)
  1175. {
  1176. if (ret.Item2 == Result.FAIL)
  1177. {
  1178. Stop("not idle");
  1179. throw (new RoutineFaildException());
  1180. }
  1181. else
  1182. throw (new RoutineBreakException());
  1183. }
  1184. }
  1185. public void QueryCoolBufferState(int id, IoCoolingBuffer device)
  1186. {
  1187. var ret = Execute(id, () =>
  1188. {
  1189. Notify(string.Format("Query {0} state", device.Name));
  1190. return true;
  1191. });
  1192. if (ret.Item1)
  1193. {
  1194. if (ret.Item2 == Result.FAIL)
  1195. {
  1196. Stop("Station wafer status error");
  1197. throw new RoutineFaildException();
  1198. }
  1199. throw new RoutineBreakException();
  1200. }
  1201. }
  1202. public IoCoolingBuffer GetCoolBuffer(ModuleName coolbufferName)
  1203. {
  1204. switch (coolbufferName)
  1205. {
  1206. case ModuleName.CoolingBuffer1:
  1207. _ioCoolBuffer = buffer1;
  1208. break;
  1209. case ModuleName.CoolingBuffer2:
  1210. _ioCoolBuffer = buffer2;
  1211. break;
  1212. case ModuleName.Aligner1:
  1213. _ioCoolBuffer = aligner1;
  1214. break;
  1215. case ModuleName.Aligner2:
  1216. _ioCoolBuffer = aligner2;
  1217. break;
  1218. }
  1219. return _ioCoolBuffer;
  1220. }
  1221. public void QueryLoadportState(int id, string deviceName, int time)
  1222. {
  1223. LoadPortBaseDevice device = DEVICE.GetDevice<LoadPortBaseDevice>(deviceName);
  1224. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1225. {
  1226. Notify(String.Format("{0} query state", deviceName));
  1227. string reason = string.Empty;
  1228. device.QueryState(out reason);
  1229. return true;
  1230. }, () =>
  1231. {
  1232. if (device.IsReady())
  1233. {
  1234. return true;
  1235. }
  1236. return false;
  1237. }, time * 1000);
  1238. if (ret.Item1)
  1239. {
  1240. if (ret.Item2 == Result.FAIL)
  1241. {
  1242. throw (new RoutineFaildException());
  1243. }
  1244. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1245. {
  1246. Stop(String.Format("{0} query timeout, than {1} seconds", device.Name, time));
  1247. throw (new RoutineFaildException());
  1248. }
  1249. else
  1250. throw (new RoutineBreakException());
  1251. }
  1252. }
  1253. public void IsLoadLockReadyToTransfer(string deviceName)
  1254. {
  1255. var device = DEVICE.GetDevice<LoadLockDevice>(deviceName);
  1256. if (!device.IsEnableTransferWafer(out var reason))
  1257. {
  1258. EV.PostMessage(deviceName, EventEnum.DefaultWarning, reason);
  1259. throw new RoutineBreakException();
  1260. }
  1261. }
  1262. public void LoadLockOpenAtmDoor(int id, LoadLockDevice device, string name, int time, Action<string> notify, Action<string> error)
  1263. {
  1264. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1265. {
  1266. notify(name);
  1267. _timerQuery.Start(_queryPeriod); //开始查询
  1268. return LoadLockDevice.LoadLockAtmDoorState == LoadLockDoorState.Opened || LoadLockDevice.OpenAtmDoor(out string reason);
  1269. }, () =>
  1270. {
  1271. if (LoadLockDevice.LoadLockAtmDoorState == LoadLockDoorState.Opened)
  1272. return true;
  1273. return false;
  1274. }, time * 1000);
  1275. if (ret.Item1)
  1276. {
  1277. if (ret.Item2 == Result.FAIL)
  1278. {
  1279. throw (new RoutineFaildException());
  1280. }
  1281. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1282. {
  1283. error(String.Format("{0} timeout, than {1} seconds", name, time));
  1284. throw (new RoutineFaildException());
  1285. }
  1286. else
  1287. throw (new RoutineBreakException());
  1288. }
  1289. }
  1290. public void LoadLockCloseAtmDoor(int id, LoadLockDevice device, string name, int time, Action<string> notify, Action<string> error)
  1291. {
  1292. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1293. {
  1294. notify(name);
  1295. return LoadLockDevice.LoadLockAtmDoorState == LoadLockDoorState.Closed || LoadLockDevice.CloseAtmDoor(out string reason);
  1296. }, () =>
  1297. {
  1298. if (LoadLockDevice.LoadLockAtmDoorState == LoadLockDoorState.Closed)
  1299. return true;
  1300. return false;
  1301. }, time * 1000);
  1302. if (ret.Item1)
  1303. {
  1304. if (ret.Item2 == Result.FAIL)
  1305. {
  1306. throw (new RoutineFaildException());
  1307. }
  1308. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1309. {
  1310. error(String.Format("{0} timeout, than {1} seconds", name, time));
  1311. throw (new RoutineFaildException());
  1312. }
  1313. else
  1314. throw (new RoutineBreakException());
  1315. }
  1316. }
  1317. public void LoadLockOpenVtmDoor(int id, LoadLockDevice device, string name, int time, Action<string> notify, Action<string> error)
  1318. {
  1319. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1320. {
  1321. notify(name);
  1322. _timerQuery.Start(_queryPeriod); //开始查询
  1323. return LoadLockDevice.LoadLockVtmDoorState == LoadLockDoorState.Opened || LoadLockDevice.OpenVtmDoor(out string reason);
  1324. }, () =>
  1325. {
  1326. if (LoadLockDevice.LoadLockVtmDoorState == LoadLockDoorState.Opened)
  1327. return true;
  1328. return false;
  1329. }, time * 1000);
  1330. if (ret.Item1)
  1331. {
  1332. if (ret.Item2 == Result.FAIL)
  1333. {
  1334. throw (new RoutineFaildException());
  1335. }
  1336. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1337. {
  1338. error($"{name} timeout, than {time} seconds");
  1339. throw (new RoutineFaildException());
  1340. }
  1341. else
  1342. throw (new RoutineBreakException());
  1343. }
  1344. }
  1345. public void LoadLockCloseVtmDoor(int id, LoadLockDevice device, string name, int time, Action<string> notify, Action<string> error)
  1346. {
  1347. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1348. {
  1349. notify(name);
  1350. return LoadLockDevice.LoadLockVtmDoorState == LoadLockDoorState.Closed || LoadLockDevice.CloseVtmDoor(out string reason);
  1351. }, () =>
  1352. {
  1353. if (LoadLockDevice.LoadLockVtmDoorState == LoadLockDoorState.Closed)
  1354. return true;
  1355. return false;
  1356. }, time * 1000);
  1357. if (ret.Item1)
  1358. {
  1359. if (ret.Item2 == Result.FAIL)
  1360. {
  1361. throw (new RoutineFaildException());
  1362. }
  1363. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1364. {
  1365. error(String.Format("{0} timeout, than {1} seconds", name, time));
  1366. throw (new RoutineFaildException());
  1367. }
  1368. else
  1369. throw (new RoutineBreakException());
  1370. }
  1371. }
  1372. protected void Default()
  1373. {
  1374. string reason = String.Empty;
  1375. }
  1376. protected virtual void Warning(string message)
  1377. {
  1378. EV.PostMessage(Module, EventEnum.DefaultWarning, message);
  1379. }
  1380. ///等待 Aligner Motion
  1381. public void WaitAlignerMotion(int id, Aligner device, string name, int time, Action<string> notify, Action<string> error)
  1382. {
  1383. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1384. {
  1385. notify(name);
  1386. _timerQuery.Start(_queryPeriod); //开始查询
  1387. return true;
  1388. }, () =>
  1389. {
  1390. // if (device.Moving == false && CheckAlignerReady())
  1391. if (device.Busy == false && CheckAlignerReady())
  1392. {
  1393. _timerQuery.Stop();
  1394. return true;
  1395. }
  1396. if (query())
  1397. {
  1398. // string reason = string.Empty;
  1399. // device.QueryState(out reason); //查询位置
  1400. }
  1401. return false;
  1402. }, time * 1000);
  1403. if (ret.Item1)
  1404. {
  1405. if (ret.Item2 == Result.FAIL)
  1406. {
  1407. throw (new RoutineFaildException());
  1408. }
  1409. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1410. {
  1411. error(String.Format("{0} timeout, than {1} seconds", name, time));
  1412. throw (new RoutineFaildException());
  1413. }
  1414. else
  1415. throw (new RoutineBreakException());
  1416. }
  1417. }
  1418. protected virtual void Notify(string message)
  1419. {
  1420. EV.PostInfoLog(Module, $"{Name}, {message}");
  1421. }
  1422. protected virtual void Stop(string failReason)
  1423. {
  1424. EV.PostAlarmLog(Module, $"{Name}, {failReason}");
  1425. }
  1426. public void Abort()
  1427. {
  1428. }
  1429. private bool query()
  1430. {
  1431. if (_timerQuery.IsTimeout())
  1432. {
  1433. _timerQuery.Start(_queryPeriod);
  1434. return true;
  1435. }
  1436. return false;
  1437. }
  1438. protected bool CheckSeneorHasWafer(ModuleName chamber, int slot)
  1439. {
  1440. if (!SC.GetValue<bool>(SorterCommon.ScPathName.System_IsSimulatorMode))
  1441. {
  1442. if (chamber == ModuleName.Robot)
  1443. {
  1444. if (slot == 0)
  1445. return robot.IsWaferPresenceOnBlade1;//!DeviceModel.SensorRBlowerArmhavewafer.Value;
  1446. return robot.IsWaferPresenceOnBlade2;
  1447. }
  1448. //if (chamber == ModuleName.Aligner)
  1449. //{
  1450. // return !DeviceModel.SensorPreAlignerWaferOn.Value;
  1451. //}
  1452. }
  1453. return WaferManager.Instance.CheckHasWafer(chamber, slot);
  1454. }
  1455. protected bool CheckSensorNoWafer(ModuleName chamber, int slot)
  1456. {
  1457. if (!SC.GetValue<bool>(SorterCommon.ScPathName.System_IsSimulatorMode))
  1458. {
  1459. if (chamber == ModuleName.Robot)
  1460. {
  1461. if (slot == 0)
  1462. return !robot.IsWaferPresenceOnBlade1; //DeviceModel.SensorRBlowerArmhavewafer.Value;
  1463. return !robot.IsWaferPresenceOnBlade2; //DeviceModel.SensorRBupperArmhavewafer.Value;
  1464. }
  1465. //if (chamber == ModuleName.Aligner)
  1466. //{
  1467. // return DeviceModel.SensorPreAlignerWaferOn.Value;
  1468. //}
  1469. }
  1470. return WaferManager.Instance.CheckNoWafer(chamber, slot);
  1471. }
  1472. protected bool CheckRobotReadySensor()
  1473. {
  1474. return (robot.RobotState == RobotStateEnum.Idle);
  1475. }
  1476. protected bool CheckAlignerReady()
  1477. {
  1478. return true;
  1479. }
  1480. ///等待 Loadport
  1481. public void LoadportReset(int id, LoadPortBaseDevice device, string name, int time, Action<string> notify, Action<string> error)
  1482. {
  1483. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1484. {
  1485. notify(String.Format("{0} clear error", device.Name));
  1486. string reason = string.Empty;
  1487. return device.LoadportReset(out reason);
  1488. }, () =>
  1489. {
  1490. if (device.IsReady())
  1491. {
  1492. return true;
  1493. }
  1494. return false;
  1495. }, time * 1000);
  1496. if (ret.Item1)
  1497. {
  1498. if (ret.Item2 == Result.FAIL)
  1499. {
  1500. throw (new RoutineFaildException());
  1501. }
  1502. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1503. {
  1504. error(String.Format("{0} timeout, than {1} seconds", name, time));
  1505. throw (new RoutineFaildException());
  1506. }
  1507. else
  1508. throw (new RoutineBreakException());
  1509. }
  1510. }
  1511. public void LoadportInit(int id, LoadPortBaseDevice device, string name, Action<string> notify, Action<string> error)
  1512. {
  1513. Tuple<bool, Result> ret = Execute(id, () =>
  1514. {
  1515. notify(String.Format("{0} Home", device.Name));
  1516. string reason = string.Empty;
  1517. return device.Home(out reason);
  1518. });
  1519. if (ret.Item1)
  1520. {
  1521. if (ret.Item2 == Result.FAIL)
  1522. {
  1523. throw (new RoutineFaildException());
  1524. }
  1525. }
  1526. }
  1527. protected bool CheckLoadportMotionInterlock(ModuleName chamber, out string reason)
  1528. {
  1529. reason = string.Empty;
  1530. if (robot.RobotState != RobotStateEnum.Idle)
  1531. {
  1532. reason = string.Format("robot is not idle.");
  1533. return false;
  1534. }
  1535. if (!CheckRobotReady())
  1536. {
  1537. reason = string.Format("robot isn't ready.");
  1538. return false;
  1539. }
  1540. return true;
  1541. }
  1542. ///等待 Loadport
  1543. public void WaitLoadportMotion(int id, LoadPortBaseDevice device, string name, int time, Action<string> notify, Action<string> error)
  1544. {
  1545. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1546. {
  1547. notify(name);
  1548. string msg = string.Empty;
  1549. //device.QueryState(out msg); //查询状
  1550. _timerQuery.Start(_queryPeriod); //开始查询
  1551. return true;
  1552. }, () =>
  1553. {
  1554. if (device.CurrentState == LoadPortStateEnum.Error)
  1555. {
  1556. return null;
  1557. }
  1558. if (device.IsReady())
  1559. {
  1560. _timerQuery.Stop();
  1561. return true;
  1562. }
  1563. return false;
  1564. }, time * 1000);
  1565. if (ret.Item1)
  1566. {
  1567. if (ret.Item2 == Result.FAIL)
  1568. {
  1569. throw (new RoutineFaildException());
  1570. }
  1571. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1572. {
  1573. error(String.Format("{0} timeout, than {1} seconds", name, time));
  1574. throw (new RoutineFaildException());
  1575. }
  1576. else
  1577. throw (new RoutineBreakException());
  1578. }
  1579. }
  1580. protected void LoadportAllReset(int id, int time)
  1581. {
  1582. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1583. {
  1584. Notify(String.Format("clear error for all loadports"));
  1585. string reason = string.Empty;
  1586. LPs.ForEach(lp => lp.ClearError(out reason));
  1587. return true;
  1588. }, () =>
  1589. {
  1590. if (LPs.Any(lp => lp.IsBusy))
  1591. {
  1592. return false;
  1593. }
  1594. return true;
  1595. }, time * 1000);
  1596. if (ret.Item1)
  1597. {
  1598. if (ret.Item2 == Result.FAIL)
  1599. {
  1600. throw (new RoutineFaildException());
  1601. }
  1602. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1603. {
  1604. Stop(String.Format("LoadportAllReset timeout, than {0} seconds", time));
  1605. throw (new RoutineFaildException());
  1606. }
  1607. else
  1608. throw (new RoutineBreakException());
  1609. }
  1610. }
  1611. protected void LoadportAllInit(int id, int time)
  1612. {
  1613. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1614. {
  1615. Notify(String.Format("All loadports Homing"));
  1616. string reason = string.Empty;
  1617. LPs.ForEach(lp =>lp.Home(out reason));
  1618. _timerQuery.Start(_queryPeriod); //开始查询
  1619. return true;
  1620. }, () =>
  1621. {
  1622. if (LPs.Any(lp => lp.CurrentState == LoadPortStateEnum.Error))
  1623. {
  1624. return null;
  1625. }
  1626. if (LPs.Any(lp => !lp.IsHomed)) //!lp.IsReady() &&
  1627. {
  1628. return false;
  1629. }
  1630. LPs.ForEach(m=>LOG.Write($"{m.Name}:{m.IsHomed }"));
  1631. return true;
  1632. }, time * 1000);
  1633. if (ret.Item1)
  1634. {
  1635. if (ret.Item2 == Result.FAIL)
  1636. {
  1637. throw (new RoutineFaildException());
  1638. }
  1639. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1640. {
  1641. Stop(String.Format("LoadportAllInit timeout, than {0} seconds", time));
  1642. throw (new RoutineFaildException());
  1643. }
  1644. else
  1645. throw (new RoutineBreakException());
  1646. }
  1647. }
  1648. protected void PostMessage(int id, string v)
  1649. {
  1650. Tuple<bool, Result> ret = Execute(id, () =>
  1651. {
  1652. EV.PostMessage(ModuleName.System.ToString(), EventEnum.GeneralInfo, v);
  1653. return true;
  1654. });
  1655. if (ret.Item1)
  1656. {
  1657. if (ret.Item2 == Result.FAIL)
  1658. {
  1659. throw (new RoutineFaildException());
  1660. }
  1661. }
  1662. }
  1663. public void TimeDelay(int id, int timeMs)
  1664. {
  1665. Tuple<bool, Result> ret = Delay(id, () =>
  1666. {
  1667. Notify($"Delay {timeMs} milliseconds");
  1668. return true;
  1669. }, timeMs);
  1670. if (ret.Item1)
  1671. {
  1672. if (ret.Item2 == Result.RUN)
  1673. {
  1674. throw (new RoutineBreakException());
  1675. }
  1676. }
  1677. }
  1678. }
  1679. }