CommonRoutine.cs 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897
  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. reason = "error target";
  1124. return false;
  1125. }
  1126. protected bool CheckRobotReady()
  1127. {
  1128. return robot.IsReady();
  1129. }
  1130. protected bool CheckRobotMotionInterlock(out string reason)
  1131. {
  1132. reason = string.Empty;
  1133. if (robot.RobotState != RobotStateEnum.Idle )
  1134. {
  1135. reason = string.Format("robot is not idle.");
  1136. return false;
  1137. }
  1138. if (!CheckRobotReadySensor())
  1139. {
  1140. reason = string.Format("robot isn't ready.");
  1141. return false;
  1142. }
  1143. return true;
  1144. }
  1145. public void QueryLoadportState(int id, LoadPort device)
  1146. {
  1147. Tuple<bool, Result> ret = Execute(id, () =>
  1148. {
  1149. Notify(String.Format("Query {0} state", device.Name));
  1150. return device.IsIdle;
  1151. });
  1152. if (ret.Item1)
  1153. {
  1154. if (ret.Item2 == Result.FAIL)
  1155. {
  1156. Stop("not idle");
  1157. throw (new RoutineFaildException());
  1158. }
  1159. else
  1160. throw (new RoutineBreakException());
  1161. }
  1162. }
  1163. public void QueryAlignerState(int id, Aligner device)
  1164. {
  1165. Tuple<bool, Result> ret = Execute(id, () =>
  1166. {
  1167. Notify(String.Format("Query {0} state", device.Name));
  1168. return device.State == DeviceState.Idle;
  1169. });
  1170. if (ret.Item1)
  1171. {
  1172. if (ret.Item2 == Result.FAIL)
  1173. {
  1174. Stop("not idle");
  1175. throw (new RoutineFaildException());
  1176. }
  1177. else
  1178. throw (new RoutineBreakException());
  1179. }
  1180. }
  1181. public void QueryCoolBufferState(int id, IoCoolingBuffer device)
  1182. {
  1183. var ret = Execute(id, () =>
  1184. {
  1185. Notify(string.Format("Query {0} state", device.Name));
  1186. return true;
  1187. });
  1188. if (ret.Item1)
  1189. {
  1190. if (ret.Item2 == Result.FAIL)
  1191. {
  1192. Stop("Station wafer status error");
  1193. throw new RoutineFaildException();
  1194. }
  1195. throw new RoutineBreakException();
  1196. }
  1197. }
  1198. public IoCoolingBuffer GetCoolBuffer(ModuleName coolbufferName)
  1199. {
  1200. switch (coolbufferName)
  1201. {
  1202. case ModuleName.CoolingBuffer1:
  1203. _ioCoolBuffer = buffer1;
  1204. break;
  1205. case ModuleName.CoolingBuffer2:
  1206. _ioCoolBuffer = buffer2;
  1207. break;
  1208. case ModuleName.Aligner1:
  1209. _ioCoolBuffer = aligner1;
  1210. break;
  1211. case ModuleName.Aligner2:
  1212. _ioCoolBuffer = aligner2;
  1213. break;
  1214. }
  1215. return _ioCoolBuffer;
  1216. }
  1217. public void QueryLoadportState(int id, string deviceName, int time)
  1218. {
  1219. LoadPortBaseDevice device = DEVICE.GetDevice<LoadPortBaseDevice>(deviceName);
  1220. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1221. {
  1222. Notify(String.Format("{0} query state", deviceName));
  1223. string reason = string.Empty;
  1224. device.QueryState(out reason);
  1225. return true;
  1226. }, () =>
  1227. {
  1228. if (device.IsReady())
  1229. {
  1230. return true;
  1231. }
  1232. return false;
  1233. }, time * 1000);
  1234. if (ret.Item1)
  1235. {
  1236. if (ret.Item2 == Result.FAIL)
  1237. {
  1238. throw (new RoutineFaildException());
  1239. }
  1240. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1241. {
  1242. Stop(String.Format("{0} query timeout, than {1} seconds", device.Name, time));
  1243. throw (new RoutineFaildException());
  1244. }
  1245. else
  1246. throw (new RoutineBreakException());
  1247. }
  1248. }
  1249. public void IsLoadLockReadyToTransfer(string deviceName)
  1250. {
  1251. var device = DEVICE.GetDevice<LoadLockDevice>(deviceName);
  1252. if (!device.IsEnableTransferWafer(out var reason))
  1253. {
  1254. EV.PostMessage(deviceName, EventEnum.DefaultWarning, reason);
  1255. throw new RoutineBreakException();
  1256. }
  1257. }
  1258. public void LoadLockOpenAtmDoor(int id, LoadLockDevice device, string name, int time, Action<string> notify, Action<string> error)
  1259. {
  1260. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1261. {
  1262. notify(name);
  1263. _timerQuery.Start(_queryPeriod); //开始查询
  1264. return LoadLockDevice.LoadLockAtmDoorState == LoadLockDoorState.Opened || LoadLockDevice.OpenAtmDoor(out string reason);
  1265. }, () =>
  1266. {
  1267. if (LoadLockDevice.LoadLockAtmDoorState == LoadLockDoorState.Opened)
  1268. return true;
  1269. return false;
  1270. }, time * 1000);
  1271. if (ret.Item1)
  1272. {
  1273. if (ret.Item2 == Result.FAIL)
  1274. {
  1275. throw (new RoutineFaildException());
  1276. }
  1277. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1278. {
  1279. error(String.Format("{0} timeout, than {1} seconds", name, time));
  1280. throw (new RoutineFaildException());
  1281. }
  1282. else
  1283. throw (new RoutineBreakException());
  1284. }
  1285. }
  1286. public void LoadLockCloseAtmDoor(int id, LoadLockDevice device, string name, int time, Action<string> notify, Action<string> error)
  1287. {
  1288. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1289. {
  1290. notify(name);
  1291. return LoadLockDevice.LoadLockAtmDoorState == LoadLockDoorState.Closed || LoadLockDevice.CloseAtmDoor(out string reason);
  1292. }, () =>
  1293. {
  1294. if (LoadLockDevice.LoadLockAtmDoorState == LoadLockDoorState.Closed)
  1295. return true;
  1296. return false;
  1297. }, time * 1000);
  1298. if (ret.Item1)
  1299. {
  1300. if (ret.Item2 == Result.FAIL)
  1301. {
  1302. throw (new RoutineFaildException());
  1303. }
  1304. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1305. {
  1306. error(String.Format("{0} timeout, than {1} seconds", name, time));
  1307. throw (new RoutineFaildException());
  1308. }
  1309. else
  1310. throw (new RoutineBreakException());
  1311. }
  1312. }
  1313. public void LoadLockOpenVtmDoor(int id, LoadLockDevice device, string name, int time, Action<string> notify, Action<string> error)
  1314. {
  1315. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1316. {
  1317. notify(name);
  1318. _timerQuery.Start(_queryPeriod); //开始查询
  1319. return LoadLockDevice.LoadLockVtmDoorState == LoadLockDoorState.Opened || LoadLockDevice.OpenVtmDoor(out string reason);
  1320. }, () =>
  1321. {
  1322. if (LoadLockDevice.LoadLockVtmDoorState == LoadLockDoorState.Opened)
  1323. return true;
  1324. return false;
  1325. }, time * 1000);
  1326. if (ret.Item1)
  1327. {
  1328. if (ret.Item2 == Result.FAIL)
  1329. {
  1330. throw (new RoutineFaildException());
  1331. }
  1332. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1333. {
  1334. error($"{name} timeout, than {time} seconds");
  1335. throw (new RoutineFaildException());
  1336. }
  1337. else
  1338. throw (new RoutineBreakException());
  1339. }
  1340. }
  1341. public void LoadLockCloseVtmDoor(int id, LoadLockDevice device, string name, int time, Action<string> notify, Action<string> error)
  1342. {
  1343. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1344. {
  1345. notify(name);
  1346. return LoadLockDevice.LoadLockVtmDoorState == LoadLockDoorState.Closed || LoadLockDevice.CloseVtmDoor(out string reason);
  1347. }, () =>
  1348. {
  1349. if (LoadLockDevice.LoadLockVtmDoorState == LoadLockDoorState.Closed)
  1350. return true;
  1351. return false;
  1352. }, time * 1000);
  1353. if (ret.Item1)
  1354. {
  1355. if (ret.Item2 == Result.FAIL)
  1356. {
  1357. throw (new RoutineFaildException());
  1358. }
  1359. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1360. {
  1361. error(String.Format("{0} timeout, than {1} seconds", name, time));
  1362. throw (new RoutineFaildException());
  1363. }
  1364. else
  1365. throw (new RoutineBreakException());
  1366. }
  1367. }
  1368. protected void Default()
  1369. {
  1370. string reason = String.Empty;
  1371. }
  1372. protected virtual void Warning(string message)
  1373. {
  1374. EV.PostMessage(Module, EventEnum.DefaultWarning, message);
  1375. }
  1376. ///等待 Aligner Motion
  1377. public void WaitAlignerMotion(int id, Aligner device, string name, int time, Action<string> notify, Action<string> error)
  1378. {
  1379. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1380. {
  1381. notify(name);
  1382. _timerQuery.Start(_queryPeriod); //开始查询
  1383. return true;
  1384. }, () =>
  1385. {
  1386. // if (device.Moving == false && CheckAlignerReady())
  1387. if (device.Busy == false && CheckAlignerReady())
  1388. {
  1389. _timerQuery.Stop();
  1390. return true;
  1391. }
  1392. if (query())
  1393. {
  1394. // string reason = string.Empty;
  1395. // device.QueryState(out reason); //查询位置
  1396. }
  1397. return false;
  1398. }, time * 1000);
  1399. if (ret.Item1)
  1400. {
  1401. if (ret.Item2 == Result.FAIL)
  1402. {
  1403. throw (new RoutineFaildException());
  1404. }
  1405. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1406. {
  1407. error(String.Format("{0} timeout, than {1} seconds", name, time));
  1408. throw (new RoutineFaildException());
  1409. }
  1410. else
  1411. throw (new RoutineBreakException());
  1412. }
  1413. }
  1414. protected virtual void Notify(string message)
  1415. {
  1416. EV.PostInfoLog(Module, $"{Name}, {message}");
  1417. }
  1418. protected virtual void Stop(string failReason)
  1419. {
  1420. EV.PostAlarmLog(Module, $"{Name}, {failReason}");
  1421. }
  1422. public void Abort()
  1423. {
  1424. }
  1425. private bool query()
  1426. {
  1427. if (_timerQuery.IsTimeout())
  1428. {
  1429. _timerQuery.Start(_queryPeriod);
  1430. return true;
  1431. }
  1432. return false;
  1433. }
  1434. protected bool CheckSeneorHasWafer(ModuleName chamber, int slot)
  1435. {
  1436. if (!SC.GetValue<bool>(SorterCommon.ScPathName.System_IsSimulatorMode))
  1437. {
  1438. if (chamber == ModuleName.Robot)
  1439. {
  1440. if (slot == 0)
  1441. return robot.IsWaferPresenceOnBlade1;//!DeviceModel.SensorRBlowerArmhavewafer.Value;
  1442. return robot.IsWaferPresenceOnBlade2;
  1443. }
  1444. //if (chamber == ModuleName.Aligner)
  1445. //{
  1446. // return !DeviceModel.SensorPreAlignerWaferOn.Value;
  1447. //}
  1448. }
  1449. return WaferManager.Instance.CheckHasWafer(chamber, slot);
  1450. }
  1451. protected bool CheckSensorNoWafer(ModuleName chamber, int slot)
  1452. {
  1453. if (!SC.GetValue<bool>(SorterCommon.ScPathName.System_IsSimulatorMode))
  1454. {
  1455. if (chamber == ModuleName.Robot)
  1456. {
  1457. if (slot == 0)
  1458. return !robot.IsWaferPresenceOnBlade1; //DeviceModel.SensorRBlowerArmhavewafer.Value;
  1459. return !robot.IsWaferPresenceOnBlade2; //DeviceModel.SensorRBupperArmhavewafer.Value;
  1460. }
  1461. //if (chamber == ModuleName.Aligner)
  1462. //{
  1463. // return DeviceModel.SensorPreAlignerWaferOn.Value;
  1464. //}
  1465. }
  1466. return WaferManager.Instance.CheckNoWafer(chamber, slot);
  1467. }
  1468. protected bool CheckRobotReadySensor()
  1469. {
  1470. return (robot.RobotState == RobotStateEnum.Idle);
  1471. }
  1472. protected bool CheckAlignerReady()
  1473. {
  1474. return true;
  1475. }
  1476. ///等待 Loadport
  1477. public void LoadportReset(int id, LoadPortBaseDevice device, string name, int time, Action<string> notify, Action<string> error)
  1478. {
  1479. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1480. {
  1481. notify(String.Format("{0} clear error", device.Name));
  1482. string reason = string.Empty;
  1483. return device.LoadportReset(out reason);
  1484. }, () =>
  1485. {
  1486. if (device.IsReady())
  1487. {
  1488. return true;
  1489. }
  1490. return false;
  1491. }, time * 1000);
  1492. if (ret.Item1)
  1493. {
  1494. if (ret.Item2 == Result.FAIL)
  1495. {
  1496. throw (new RoutineFaildException());
  1497. }
  1498. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1499. {
  1500. error(String.Format("{0} timeout, than {1} seconds", name, time));
  1501. throw (new RoutineFaildException());
  1502. }
  1503. else
  1504. throw (new RoutineBreakException());
  1505. }
  1506. }
  1507. public void LoadportInit(int id, LoadPortBaseDevice device, string name, Action<string> notify, Action<string> error)
  1508. {
  1509. Tuple<bool, Result> ret = Execute(id, () =>
  1510. {
  1511. notify(String.Format("{0} Home", device.Name));
  1512. string reason = string.Empty;
  1513. return device.Home(out reason);
  1514. });
  1515. if (ret.Item1)
  1516. {
  1517. if (ret.Item2 == Result.FAIL)
  1518. {
  1519. throw (new RoutineFaildException());
  1520. }
  1521. }
  1522. }
  1523. protected bool CheckLoadportMotionInterlock(ModuleName chamber, out string reason)
  1524. {
  1525. reason = string.Empty;
  1526. if (robot.RobotState != RobotStateEnum.Idle)
  1527. {
  1528. reason = string.Format("robot is not idle.");
  1529. return false;
  1530. }
  1531. if (!CheckRobotReady())
  1532. {
  1533. reason = string.Format("robot isn't ready.");
  1534. return false;
  1535. }
  1536. return true;
  1537. }
  1538. ///等待 Loadport
  1539. public void WaitLoadportMotion(int id, LoadPortBaseDevice device, string name, int time, Action<string> notify, Action<string> error)
  1540. {
  1541. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1542. {
  1543. notify(name);
  1544. string msg = string.Empty;
  1545. //device.QueryState(out msg); //查询状
  1546. _timerQuery.Start(_queryPeriod); //开始查询
  1547. return true;
  1548. }, () =>
  1549. {
  1550. if (device.CurrentState == LoadPortStateEnum.Error)
  1551. {
  1552. return null;
  1553. }
  1554. if (device.IsReady())
  1555. {
  1556. _timerQuery.Stop();
  1557. return true;
  1558. }
  1559. return false;
  1560. }, time * 1000);
  1561. if (ret.Item1)
  1562. {
  1563. if (ret.Item2 == Result.FAIL)
  1564. {
  1565. throw (new RoutineFaildException());
  1566. }
  1567. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1568. {
  1569. error(String.Format("{0} timeout, than {1} seconds", name, time));
  1570. throw (new RoutineFaildException());
  1571. }
  1572. else
  1573. throw (new RoutineBreakException());
  1574. }
  1575. }
  1576. protected void LoadportAllReset(int id, int time)
  1577. {
  1578. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1579. {
  1580. Notify(String.Format("clear error for all loadports"));
  1581. string reason = string.Empty;
  1582. LPs.ForEach(lp => lp.ClearError(out reason));
  1583. return true;
  1584. }, () =>
  1585. {
  1586. if (LPs.Any(lp => lp.IsBusy))
  1587. {
  1588. return false;
  1589. }
  1590. return true;
  1591. }, time * 1000);
  1592. if (ret.Item1)
  1593. {
  1594. if (ret.Item2 == Result.FAIL)
  1595. {
  1596. throw (new RoutineFaildException());
  1597. }
  1598. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1599. {
  1600. Stop(String.Format("LoadportAllReset timeout, than {0} seconds", time));
  1601. throw (new RoutineFaildException());
  1602. }
  1603. else
  1604. throw (new RoutineBreakException());
  1605. }
  1606. }
  1607. protected void LoadportAllInit(int id, int time)
  1608. {
  1609. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  1610. {
  1611. Notify(String.Format("All loadports Homing"));
  1612. string reason = string.Empty;
  1613. LPs.ForEach(lp =>lp.Home(out reason));
  1614. _timerQuery.Start(_queryPeriod); //开始查询
  1615. return true;
  1616. }, () =>
  1617. {
  1618. if (LPs.Any(lp => lp.CurrentState == LoadPortStateEnum.Error))
  1619. {
  1620. return null;
  1621. }
  1622. if (LPs.Any(lp => !lp.IsHomed)) //!lp.IsReady() &&
  1623. {
  1624. return false;
  1625. }
  1626. LPs.ForEach(m=>LOG.Write($"{m.Name}:{m.IsHomed }"));
  1627. return true;
  1628. }, time * 1000);
  1629. if (ret.Item1)
  1630. {
  1631. if (ret.Item2 == Result.FAIL)
  1632. {
  1633. throw (new RoutineFaildException());
  1634. }
  1635. else if (ret.Item2 == Result.TIMEOUT) //timeout
  1636. {
  1637. Stop(String.Format("LoadportAllInit timeout, than {0} seconds", time));
  1638. throw (new RoutineFaildException());
  1639. }
  1640. else
  1641. throw (new RoutineBreakException());
  1642. }
  1643. }
  1644. protected void PostMessage(int id, string v)
  1645. {
  1646. Tuple<bool, Result> ret = Execute(id, () =>
  1647. {
  1648. EV.PostMessage(ModuleName.System.ToString(), EventEnum.GeneralInfo, v);
  1649. return true;
  1650. });
  1651. if (ret.Item1)
  1652. {
  1653. if (ret.Item2 == Result.FAIL)
  1654. {
  1655. throw (new RoutineFaildException());
  1656. }
  1657. }
  1658. }
  1659. public void TimeDelay(int id, int timeMs)
  1660. {
  1661. Tuple<bool, Result> ret = Delay(id, () =>
  1662. {
  1663. Notify($"Delay {timeMs} milliseconds");
  1664. return true;
  1665. }, timeMs);
  1666. if (ret.Item1)
  1667. {
  1668. if (ret.Item2 == Result.RUN)
  1669. {
  1670. throw (new RoutineBreakException());
  1671. }
  1672. }
  1673. }
  1674. }
  1675. }