CommonRoutine.cs 79 KB

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