AutoCycle.cs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  1. using Aitex.Core.Common;
  2. using Aitex.Core.RT.Device;
  3. using Aitex.Core.RT.SCCore;
  4. using Aitex.Core.Util;
  5. using Aitex.Sorter.Common;
  6. using athosRT.Devices;
  7. using athosRT.FSM;
  8. using athosRT.Modules.EFEMs.Routine;
  9. using athosRT.Modules.LPs;
  10. using athosRT.tool;
  11. using Common.DataCenter;
  12. using MECF.Framework.Common.Equipment;
  13. using MECF.Framework.Common.SubstrateTrackings;
  14. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.BufferStations;
  15. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
  16. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Linq;
  20. using static athosRT.Modules.FLP.FlipperEntity;
  21. using MoveItem = athosRT.Modules.SchedulerEfemRobot.MoveItem;
  22. namespace athosRT.Modules
  23. {
  24. public enum MovingStatus
  25. {
  26. Waiting,//等待开始
  27. WaitAlign,//需要去Align
  28. Aligning,//Align执行
  29. AlignDone,//Align完成
  30. WaitFlip,//需要Flip
  31. Flipping,//Flip执行
  32. FlipDone,//Flip完成
  33. WaitProcess,//需要PM
  34. Processing,// PM执行
  35. ProcessDone,//PM完成
  36. WaitCool,//需要Cooling
  37. Cooling,// Cool执行
  38. CoolDone,//Cool完成
  39. Idle,//最后一步 回到LP后置
  40. None,//空位
  41. }
  42. public class AutoCycle : ModuleRoutineBase, IRoutine
  43. {
  44. enum EFEMCycle
  45. {
  46. start,
  47. End
  48. }
  49. enum ModuleType
  50. {
  51. //LP,
  52. Align,
  53. Flip,
  54. Cool,
  55. PM
  56. }
  57. ModuleName _source = ModuleName.LP1;
  58. ModuleName _destination = ModuleName.LP1;
  59. private LoadPortBaseDevice m_soucelp;
  60. private LoadPortBaseDevice m_destlp;
  61. private RobotBaseDevice m_Robot = null;
  62. private int cyclewafernum;
  63. private bool cyclecreated = false;
  64. Queue<MoveItem> _moveQueue = new Queue<MoveItem>();
  65. SchedulerEfemRobot _efemRobot;
  66. List<MoveItem> _efemMovingItems = new List<MoveItem>();
  67. private PickRoutine m_pickRoutine = null;
  68. private PlaceRoutine m_placeRoutine = null;
  69. private SwapRoutine m_swapRoutine = null;
  70. private LoadFoupRoutine m_sourceLoadRoutine = null;
  71. private LoadFoupRoutine m_destLoadRoutine = null;
  72. private string _name;
  73. private bool _isLowerArmEnable = true;
  74. private bool _isUpperArmEnable = true;
  75. private RState _cycleState;
  76. //两条基线 一是foup的计划点 二是设备需要经过的点
  77. private List<MovingStatus> _movingStatus = new List<MovingStatus>();
  78. private List<ModuleName> _lstPass = new List<ModuleName>();
  79. //需要经过什么类型的点
  80. private List<MovingStatus> _taskQueue = new List<MovingStatus>();
  81. private List<bool> _hasFlipper = new List<bool>();
  82. private List<int> _flippertimes = new List<int>();
  83. private int CycleIndex;
  84. private int cyclenumber=0;
  85. public AutoCycle(ModuleName module) : base(module)
  86. {
  87. _name = "AutoCycle";
  88. _cycleState = RState.Init;
  89. cyclenumber= SC.GetValue<int>("Process.CycleCount");
  90. DATA.Subscribe("Process.cyclenumber", () => cyclenumber);
  91. DATA.Subscribe("Process.CycleIndex", () => CycleIndex);
  92. //_efemRobot = (SchedulerEfemRobot)Singleton<TransferModule>.Instance.GetScheduler(ModuleName.EfemRobot) ;
  93. }
  94. Dictionary<ModuleName, ModuleType> module2type = new Dictionary<ModuleName, ModuleType>();
  95. /// <summary>
  96. /// objs 结构 要去的模块 起点 终点 经过点
  97. /// </summary>
  98. /// <param name="objs"></param>
  99. /// <returns></returns>
  100. public RState Start(params object[] objs)
  101. {
  102. m_Robot = DEVICE.GetDevice<RobotBaseDevice>("Robot");
  103. CycleIndex = 0;
  104. if (!SC.GetValue<bool>("Process.CycleEnable"))
  105. cyclenumber = 1;
  106. else
  107. cyclenumber = SC.GetValue<int>("Process.CycleCount");
  108. LogObject.Info("Cycle",$"cycle圈数:{cyclenumber}");
  109. if (objs.Length == 3)
  110. {
  111. if (!Enum.TryParse(objs[0].ToString(), out _source))
  112. {
  113. LogObject.Error(_name, $"{objs[0]} is invalid ModuleName, source undefined");
  114. _cycleState = RState.Failed;
  115. }
  116. if (!Enum.TryParse(objs[1].ToString(), out _destination))
  117. {
  118. LogObject.Error(_name, $"{objs[1]} is invalid ModuleName, destination undefined");
  119. _cycleState = RState.Failed;
  120. }
  121. m_soucelp = DEVICE.GetDevice<LoadPortBaseDevice>(_source.ToString());
  122. m_destlp = DEVICE.GetDevice<LoadPortBaseDevice>(_destination.ToString());
  123. if (!m_soucelp.IsPlacement)
  124. {
  125. LogObject.Error(_name, $"{m_soucelp} is not Placed");
  126. return RState.Failed;
  127. }
  128. else
  129. {
  130. m_sourceLoadRoutine = new LoadFoupRoutine(_source);
  131. }
  132. if (!m_destlp.IsPlacement)
  133. {
  134. LogObject.Error(_name, $"{m_destlp} is not Placed");
  135. return RState.Failed;
  136. }
  137. else
  138. {
  139. m_destLoadRoutine = new LoadFoupRoutine(_destination);
  140. }
  141. _taskQueue = new List<MovingStatus>();
  142. _taskQueue.Add(MovingStatus.Waiting);
  143. //路过的模块 模块的类型决定其是否需要经过
  144. List<ModuleName> pathmodules = (List<ModuleName>)objs[2];
  145. module2type.Clear();
  146. _lstPass = (List<ModuleName>)objs[2];
  147. _lstPass.ForEach(x => LogObject.Info("cycle",$"Module=>{x}"));
  148. _taskQueue.Add(MovingStatus.Waiting);
  149. m_pickRoutine = new PickRoutine(ModuleName.System);
  150. m_placeRoutine = new PlaceRoutine(ModuleName.System);
  151. m_swapRoutine = new SwapRoutine(ModuleName.System);
  152. _isLowerArmEnable = SC.GetValue<bool>("Robot.Blade1Enable");
  153. _isUpperArmEnable = SC.GetValue<bool>("Robot.Blade2Enable");
  154. if (!_isLowerArmEnable && !_isUpperArmEnable)
  155. {
  156. LogObject.Error(_name, $"Robot both cannot Work");
  157. return RState.Failed;
  158. }
  159. if (pathmodules.Exists(x => ModuleHelper.IsAligner(x)))
  160. {
  161. _taskQueue.Add(MovingStatus.WaitAlign);
  162. pathmodules.FindAll(x => ModuleHelper.IsAligner(x)).ForEach(x => module2type.Add(x, ModuleType.Align));
  163. }
  164. if (pathmodules.Exists(x => ModuleHelper.IsLoadLock(x)))
  165. {
  166. _taskQueue.Add(MovingStatus.WaitProcess);
  167. pathmodules.FindAll(x => ModuleHelper.IsLoadLock(x)).ForEach(x => module2type.Add(x, ModuleType.PM));
  168. }
  169. if (pathmodules.Exists(x => ModuleHelper.IsBuffer(x)))
  170. {
  171. _taskQueue.Add(MovingStatus.WaitCool);
  172. pathmodules.FindAll(x => ModuleHelper.IsBuffer(x)).ForEach(x => module2type.Add(x, ModuleType.Cool));
  173. }
  174. if (pathmodules.Exists(x => ModuleHelper.IsTurnOverStation(x)))
  175. {
  176. _taskQueue.Add(MovingStatus.WaitFlip);
  177. pathmodules.FindAll(x => ModuleHelper.IsTurnOverStation(x)).ForEach(x => module2type.Add(x, ModuleType.Flip));
  178. }
  179. cyclecreated = false;
  180. Reset();
  181. _cycleState = RState.Running;
  182. }
  183. else
  184. {
  185. LogObject.Error(_name, $"illegal params length, cannot start");
  186. _cycleState = RState.Failed;
  187. }
  188. return _cycleState;
  189. }
  190. public RState Monitor()
  191. {
  192. if (_cycleState == RState.Running)
  193. {
  194. if (!cyclecreated)
  195. {
  196. if(!LPTaskDone())
  197. return _cycleState;
  198. else
  199. PrepareTask();
  200. }
  201. RunOtherTask();
  202. //与代码有所不同
  203. //是利用各种逻辑进行的 主要依赖的waferinfo的nextstation以及robot的禁用状态 以及各个站点的状态
  204. RunEFEMRobotTask();
  205. }
  206. return _cycleState;
  207. }
  208. //检查所有晶圆是否完成传送
  209. public bool CheckDone()
  210. {
  211. if (m_Robot.IsReady())
  212. {
  213. WaferInfo[] wafers = Singleton<WaferManager>.Instance.GetWafers(_source);
  214. WaferInfo[] array = wafers;
  215. WaferInfo[] _wafers = Singleton<WaferManager>.Instance.GetWafers(_destination);
  216. WaferInfo[] _destinations = _wafers;
  217. if (_destinations.ToList().FindAll(wafer => !wafer.IsEmpty && wafer.SubstE90Status == EnumE90Status.Processed).Count() == cyclewafernum)
  218. {
  219. ++CycleIndex;
  220. //DATA.Subscribe("Process.CycleIndex", () => CycleIndex);
  221. if (CycleIndex >= cyclenumber)
  222. return true;
  223. else
  224. {
  225. ModuleName swapmd = _destination;
  226. _destination = _source;
  227. _source = swapmd;
  228. PrepareTask();
  229. }
  230. }
  231. }
  232. return false;
  233. }
  234. /// <summary>
  235. /// 用于检查source和dest LP是否已经load且map
  236. /// </summary>
  237. /// <returns></returns>
  238. public bool LPTaskDone()
  239. {
  240. if (!m_soucelp.IsMapped || !m_soucelp.IsLoaded)
  241. {
  242. if (m_sourceLoadRoutine.Monitor() == RState.Failed ||
  243. m_sourceLoadRoutine.Monitor() == RState.Timeout)
  244. {
  245. LogObject.Error(_name, $"{_source} Load Failed or Timeout");
  246. _cycleState = RState.Failed;
  247. return false;
  248. }
  249. if (m_sourceLoadRoutine.Monitor() == RState.Running)
  250. return false;
  251. }
  252. if (_source != _destination && (!m_destlp.IsMapped || !m_destlp.IsLoaded))
  253. {
  254. if (m_destLoadRoutine.Monitor() == RState.Failed ||
  255. m_destLoadRoutine.Monitor() == RState.Timeout)
  256. {
  257. LogObject.Error(_name, $"{_destination} Load Failed or Timeout");
  258. _cycleState = RState.Failed;
  259. return false;
  260. }
  261. if (m_destLoadRoutine.Monitor() == RState.Running)
  262. return false;
  263. }
  264. //LogObject.Info(_name, "所有LP Load就绪 准备传送");
  265. return true;
  266. }
  267. /// <summary>
  268. /// 用于判定任务
  269. /// </summary>
  270. public void PrepareTask()
  271. {
  272. //检索所有source LP中的wafer信息
  273. LogObject.Info(_name,"建立传送任务 确认需要传送的晶圆信息");
  274. cyclewafernum = 0;
  275. _hasFlipper.Clear();
  276. _flippertimes.Clear();
  277. for (int i = 0; i < 25; i++)
  278. {
  279. _hasFlipper.Add(false);
  280. _flippertimes.Add(0);
  281. if (Singleton<WaferManager>.Instance.CheckHasWafer(_source, i))
  282. {
  283. cyclewafernum++;
  284. WaferInfo wafer= Singleton<WaferManager>.Instance.GetWafer(_source, i);
  285. wafer.SubstE90Status = EnumE90Status.InProcess;
  286. wafer.DestinationStation = (int)_destination;
  287. wafer.DestinationSlot = i;
  288. wafer.IsChecked = false;
  289. Singleton<WaferManager>.Instance.UpdateWaferProcessStatus(_source, i, EnumWaferProcessStatus.Wait);
  290. _movingStatus.Add(MovingStatus.Waiting);
  291. }
  292. else
  293. {
  294. _movingStatus.Add(MovingStatus.None);
  295. }
  296. }
  297. cyclecreated = true;
  298. }
  299. public RState EFEMRobotTask()
  300. {
  301. if (m_Robot.IsReady())
  302. {
  303. LogObject.Info("cycle", "robot is Idle,prepare to have the Robot's Task");
  304. //手臂全空取片
  305. if (IsRobotEmpty())
  306. {
  307. LogObject.Info("cycle","手臂全空");
  308. WaferInfo firstwafer = GetFirstWafer(new List<ModuleName>() { _source }, EnumE90Status.InProcess);
  309. //LP可以有片取cycle
  310. if (firstwafer != null)
  311. {
  312. LogObject.Info("cycle", "开始Pick from LP");
  313. m_pickRoutine.Source = _source;
  314. m_pickRoutine.Slot = firstwafer.Slot;
  315. m_pickRoutine.Blade = Hand.Blade1;
  316. return m_pickRoutine.Start();
  317. }
  318. //
  319. firstwafer = GetFirstWafer(_lstPass,EnumE90Status.InProcess);
  320. if (firstwafer != null)
  321. {
  322. LogObject.Info("cycle", "开始Pick from Pass");
  323. m_pickRoutine.Blade = Hand.Blade1;
  324. LogObject.Info("cycle", $"确定station => {firstwafer.Station}");
  325. m_pickRoutine.Source = (ModuleName)firstwafer.Station;
  326. LogObject.Info("cycle", $"确定slot => {firstwafer.Slot}");
  327. m_pickRoutine.Slot = firstwafer.Slot;
  328. //如果是loadport
  329. if (ModuleHelper.IsLoadPort(m_pickRoutine.Source))
  330. {
  331. return m_pickRoutine.Start();
  332. }
  333. //如果是cooling
  334. if (ModuleHelper.IsCoolingBuffer(m_pickRoutine.Source))
  335. {
  336. return m_pickRoutine.Start();
  337. }
  338. if (ModuleHelper.IsLoadLock(m_pickRoutine.Source))
  339. {
  340. return m_pickRoutine.Start();
  341. }
  342. if (ModuleHelper.IsTurnOverStation(m_pickRoutine.Source) && _hasFlipper[firstwafer.OriginSlot] && _flippertimes[firstwafer.OriginSlot] == 1
  343. && Singleton<RouteManager1>.Instance.GetFlipper().IsIdle)
  344. {
  345. return m_pickRoutine.Start();
  346. }
  347. if (ModuleHelper.IsAligner(m_pickRoutine.Source))
  348. {
  349. return m_pickRoutine.Start();
  350. }
  351. if (ModuleHelper.IsBuffer(m_pickRoutine.Source))
  352. {
  353. return m_pickRoutine.Start();
  354. }
  355. }
  356. }
  357. //手臂全满放片
  358. else if (IsRobotFull())
  359. {
  360. LogObject.Info("cycle", "手臂全满");
  361. WaferInfo Robotwafer = Singleton<WaferManager>.Instance.GetWafer(ModuleName.Robot,0);
  362. if (Singleton<WaferManager>.Instance.CheckHasWafer((ModuleName)Robotwafer.NextStation, Robotwafer.NextStationSlot))
  363. {
  364. LogObject.Error("System","下一步有wafer 而手臂全满");
  365. return RState.Failed;
  366. }
  367. m_placeRoutine.Blade = Hand.Blade1;
  368. m_placeRoutine.Station = (ModuleName)Robotwafer.NextStation;
  369. m_placeRoutine.Slot = Robotwafer.NextStationSlot;
  370. if (ModuleHelper.IsLoadPort(m_placeRoutine.Station))
  371. {
  372. LoadPortBaseDevice LP = DEVICE.GetDevice<LoadPortBaseDevice>(m_placeRoutine.Station.ToString());
  373. if (LP.IsEnableTransferWafer(out _))
  374. {
  375. return m_placeRoutine.Start();
  376. }
  377. }
  378. if (ModuleHelper.IsCoolingBuffer(m_placeRoutine.Station))
  379. {
  380. return m_placeRoutine.Start(null);
  381. }
  382. if (ModuleHelper.IsAligner(m_placeRoutine.Station))
  383. {
  384. return m_placeRoutine.Start(null);
  385. }
  386. if (ModuleHelper.IsLoadLock(m_placeRoutine.Station))
  387. {
  388. LoadLockDevice LL = DEVICE.GetDevice<LoadLockDevice>(m_placeRoutine.Station.ToString());
  389. if (LL.IsEnableTransferWafer(out _))
  390. {
  391. return m_placeRoutine.Start();
  392. }
  393. }
  394. if (ModuleHelper.IsTurnOverStation(m_placeRoutine.Station))
  395. {
  396. return m_placeRoutine.Start();
  397. }
  398. }
  399. //手臂有空 swap或place
  400. else
  401. {
  402. LogObject.Info("cycle", "手臂一只手wafer 一只手空");
  403. WaferInfo RobotWafer = GetFirstWafer(new List<ModuleName>() { ModuleName.Robot }, EnumE90Status.InProcess);
  404. if (RobotWafer == null)
  405. {
  406. LogObject.Error(_name,"未能获取手臂wafer信息");
  407. return RState.Failed;
  408. }
  409. //目标地没有wafer 直接place
  410. if (Singleton<WaferManager>.Instance.CheckNoWafer((ModuleName)RobotWafer.NextStation, RobotWafer.NextStationSlot))
  411. {
  412. m_placeRoutine.Blade = (Hand)RobotWafer.Slot;
  413. m_placeRoutine.Station = (ModuleName)RobotWafer.NextStation;
  414. m_placeRoutine.Slot = RobotWafer.NextStationSlot;
  415. if (ModuleHelper.IsLoadPort(m_placeRoutine.Station))
  416. {
  417. LoadPortBaseDevice LP = DEVICE.GetDevice<LoadPortBaseDevice>(m_placeRoutine.Station.ToString());
  418. if (LP.IsEnableTransferWafer(out _))
  419. {
  420. return m_placeRoutine.Start();
  421. }
  422. }
  423. if (ModuleHelper.IsCoolingBuffer(m_placeRoutine.Station))
  424. {
  425. return m_placeRoutine.Start();
  426. }
  427. if (ModuleHelper.IsAligner(m_placeRoutine.Station))
  428. {
  429. m_placeRoutine.Start();
  430. }
  431. if (ModuleHelper.IsLoadLock(m_placeRoutine.Station))
  432. {
  433. LoadLockDevice LL = DEVICE.GetDevice<LoadLockDevice>(m_placeRoutine.Station.ToString());
  434. if (LL.IsEnableTransferWafer(out _))
  435. {
  436. return m_placeRoutine.Start();
  437. }
  438. }
  439. if (ModuleHelper.IsBuffer(m_placeRoutine.Station))
  440. {
  441. SimpleBuffer buffer = DEVICE.GetDevice<SimpleBuffer>(m_placeRoutine.Station.ToString());
  442. return m_placeRoutine.Start();
  443. }
  444. if (ModuleHelper.IsTurnOverStation(m_placeRoutine.Station))
  445. {
  446. return m_placeRoutine.Start();
  447. }
  448. }
  449. //目标地有wafer 需要swap
  450. else
  451. {
  452. if (ModuleHelper.IsLoadPort((ModuleName)RobotWafer.NextStation))
  453. {
  454. LogObject.Error(_name, "目标loadport 不可能swap");
  455. return RState.Failed;
  456. }
  457. m_swapRoutine.Source = (ModuleName)RobotWafer.NextStation;
  458. m_swapRoutine.Slot = RobotWafer.NextStationSlot;
  459. if (RobotWafer.Slot == 0)
  460. {
  461. m_swapRoutine.PlaceBlade = Hand.Blade1;
  462. }
  463. else
  464. {
  465. m_swapRoutine.PlaceBlade = Hand.Blade2;
  466. }
  467. //if (ModuleHelper.IsLoadPort(m_swapRoutine.Source))
  468. //{
  469. // LoadPortBaseDevice LP = DEVICE.GetDevice<LoadPortBaseDevice>(m_swapRoutine.Source.ToString());
  470. // if (LP.IsEnableTransferWafer(out _))
  471. // {
  472. // return m_swapRoutine.Start();
  473. // }
  474. //}
  475. if (ModuleHelper.IsCoolingBuffer(m_swapRoutine.Source))
  476. {
  477. return m_swapRoutine.Start();
  478. }
  479. if (ModuleHelper.IsAligner(m_swapRoutine.Source))
  480. {
  481. return m_swapRoutine.Start();
  482. }
  483. if (ModuleHelper.IsBuffer(m_swapRoutine.Source))
  484. {
  485. //BufferStation buffer = DEVICE.GetDevice<BufferStation>(m_swapRoutine.Source.ToString());
  486. //if (buffer.IsEnableTransferWafer(out _))
  487. //{
  488. // return m_swapRoutine.Start();
  489. //}
  490. return m_swapRoutine.Start();
  491. }
  492. if (ModuleHelper.IsLoadLock(m_swapRoutine.Source))
  493. {
  494. LoadLockDevice LL = DEVICE.GetDevice<LoadLockDevice>(m_swapRoutine.Source.ToString());
  495. if (LL.IsEnableTransferWafer(out _))
  496. {
  497. return m_swapRoutine.Start();
  498. }
  499. }
  500. if (ModuleHelper.IsTurnOverStation(m_swapRoutine.Source))
  501. {
  502. return m_swapRoutine.Start();
  503. }
  504. }
  505. }
  506. }
  507. return RState.Running;
  508. }
  509. private bool IsRobotEmpty() => WaferManager.Instance.CheckNoWafer(ModuleName.Robot,0) && WaferManager.Instance.CheckNoWafer(ModuleName.Robot, 1);
  510. private bool IsRobotFull() => WaferManager.Instance.CheckHasWafer(ModuleName.Robot,0) && WaferManager.Instance.CheckHasWafer(ModuleName.Robot, 1);
  511. private WaferInfo GetFirstWafer(List<ModuleName> modules, EnumE90Status estatus)
  512. {
  513. foreach (ModuleName md in modules)
  514. {
  515. WaferInfo[] wafers = Singleton<WaferManager>.Instance.GetWafers(md);
  516. WaferInfo[] copywafers = wafers;
  517. foreach (WaferInfo wafer in copywafers)
  518. {
  519. if (!wafer.IsEmpty && wafer.SubstE90Status == estatus)
  520. {
  521. wafer.Station = (int)md;
  522. return wafer;
  523. }
  524. }
  525. }
  526. return null;
  527. }
  528. //从lp中取出wafer
  529. public void GetWaferFromLP()
  530. {
  531. if (m_Robot.IsIdle)
  532. {
  533. //如果都没有wafer 可以pick
  534. if (WaferManager.Instance.CheckNoWafer(m_Robot.Module, (int)Hand.Blade1))
  535. {
  536. if (_movingStatus.Exists(x => x == MovingStatus.Waiting))
  537. {
  538. int slot = _movingStatus.FindIndex(x => x == MovingStatus.Waiting);
  539. m_pickRoutine.Source = _source;
  540. m_pickRoutine.Slot = slot;
  541. m_pickRoutine.Blade = Hand.Blade1;
  542. m_pickRoutine.Start();
  543. }
  544. }
  545. else if (WaferManager.Instance.CheckNoWafer(m_Robot.Module, (int)Hand.Blade2))
  546. {
  547. if (_movingStatus.Exists(x => x == MovingStatus.Waiting))
  548. {
  549. int slot = _movingStatus.FindIndex(x => x == MovingStatus.Waiting);
  550. m_pickRoutine.Source = _source;
  551. m_pickRoutine.Slot = slot;
  552. m_pickRoutine.Blade = Hand.Blade1;
  553. if (m_pickRoutine.Start() == RState.Running)
  554. {
  555. _movingStatus[slot] = NextStation(MovingStatus.Waiting);
  556. }
  557. }
  558. }
  559. }
  560. }
  561. public Hand GetFreeHand()
  562. {
  563. if (WaferManager.Instance.CheckHasWafer(m_Robot.Module, 0))
  564. {
  565. return Hand.Blade1;
  566. }
  567. if (WaferManager.Instance.CheckHasWafer(m_Robot.Module, 1))
  568. {
  569. return Hand.Blade2;
  570. }
  571. return Hand.Both;
  572. }
  573. public MovingStatus NextStation(MovingStatus currentStation)
  574. {
  575. if (_taskQueue.Exists(x => x == currentStation))
  576. {
  577. return _taskQueue[_taskQueue.FindIndex(x => x == currentStation)+1];
  578. }
  579. else
  580. {
  581. LogObject.Error(_name, $"meet unknown Status:{currentStation}");
  582. _cycleState = RState.Failed;
  583. return MovingStatus.None;
  584. }
  585. }
  586. public void RunEFEMRobotTask()
  587. {
  588. try
  589. {
  590. switch (m_pickRoutine.Monitor())
  591. {
  592. case RState.Running:
  593. _cycleState = RState.Running;
  594. return;
  595. //break;
  596. case RState.Timeout:
  597. case RState.Failed:
  598. LogObject.Error(_name, "pick失败");
  599. _cycleState = RState.Failed;
  600. return;
  601. //break;
  602. default:
  603. switch (m_placeRoutine.Monitor())
  604. {
  605. case RState.Running:
  606. _cycleState = RState.Running;
  607. return;
  608. //break;
  609. case RState.Timeout:
  610. case RState.Failed:
  611. LogObject.Error(_name, "place失败");
  612. _cycleState = RState.Failed;
  613. return;
  614. //break;
  615. default:
  616. switch (m_swapRoutine.Monitor())
  617. {
  618. case RState.Running:
  619. _cycleState = RState.Running;
  620. return;
  621. //break;
  622. case RState.Timeout:
  623. case RState.Failed:
  624. LogObject.Error(_name, "swap失败");
  625. _cycleState = RState.Failed;
  626. return;
  627. //break;
  628. default:
  629. if (CheckDone())
  630. {
  631. _cycleState = RState.End;
  632. return;
  633. }
  634. if (m_Robot.IsReady())
  635. {
  636. UpdataWaferNextStation();
  637. RState ret = EFEMRobotTask();
  638. switch (ret)
  639. {
  640. case RState.Failed:
  641. case RState.Timeout:
  642. _cycleState = RState.Failed;
  643. break;
  644. default:
  645. break;
  646. }
  647. }
  648. //策略开始
  649. break;
  650. }
  651. break;
  652. }
  653. break;
  654. }
  655. }
  656. catch (Exception ex)
  657. {
  658. LogObject.Info("cycle", $"Cycle Exception: {ex.Message},Site:{ex.TargetSite}|Source:{ex.Source}");
  659. }
  660. }
  661. public void RunOtherTask()
  662. {
  663. if (_lstPass.Contains(ModuleName.TurnOverStation)
  664. &&Singleton<RouteManager1>.Instance.GetFlipper().State == Devices.FLP.FlipperState.Idle
  665. &&WaferManager.Instance.CheckHasWafer(ModuleName.TurnOverStation,0) )
  666. {
  667. WaferInfo flipperwafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0);
  668. //LogObject.Info("Cycle",$"Wafer on Flipperstatus:{flipwafer.IsChecked}|Empty:{flipwafer.IsEmpty}");
  669. if (_flippertimes[flipperwafer.OriginSlot] < 1 && !_hasFlipper[flipperwafer.OriginSlot])
  670. {
  671. LogObject.Info("Cycle",$"Flipper上有wafer且未翻面 可以旋转 Slot:{flipperwafer.OriginSlot}|hasFlip:{_hasFlipper[flipperwafer.OriginSlot]}");
  672. Singleton<RouteManager1>.Instance.GetFlipper().PostMsg(FlipperMSG.TurnOver);
  673. //flipwafer.IsChecked = true;
  674. }
  675. }
  676. if ((Singleton<RouteManager1>.Instance.GetFlipper().State == Devices.FLP.FlipperState.Turning)
  677. && WaferManager.Instance.CheckHasWafer(ModuleName.TurnOverStation, 0))
  678. {
  679. WaferInfo flipperwafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0);
  680. _hasFlipper[flipperwafer.OriginSlot] = true;
  681. }
  682. if ((Singleton<RouteManager1>.Instance.GetFlipper().State == Devices.FLP.FlipperState.Idle)
  683. && WaferManager.Instance.CheckHasWafer(ModuleName.TurnOverStation, 0))
  684. {
  685. WaferInfo flipperwafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0);
  686. if (_hasFlipper[flipperwafer.OriginSlot] && _flippertimes[flipperwafer.OriginSlot] == 0)
  687. {
  688. _flippertimes[flipperwafer.OriginSlot] = 1;
  689. }
  690. if (!_hasFlipper[flipperwafer.OriginSlot] && _flippertimes[flipperwafer.OriginSlot] == 1)
  691. {
  692. _flippertimes[flipperwafer.OriginSlot] = 2;
  693. }
  694. }
  695. }
  696. //更新晶圆下一刻要去的位置
  697. private void UpdataWaferNextStation()
  698. {
  699. //获取起始点的所有晶圆
  700. WaferInfo[] wafers = Singleton<WaferManager>.Instance.GetWafers(_source);
  701. WaferInfo[] array = wafers;
  702. LogObject.Info("cycle", "更新LP wafer下一刻状态");
  703. foreach (WaferInfo waferInfo in array)
  704. {
  705. //有晶圆且状态为inprocess
  706. if (!waferInfo.IsEmpty && waferInfo.SubstE90Status == EnumE90Status.InProcess)
  707. {
  708. LogObject.Info("cycle", $"LP waferInfo:{waferInfo.OriginStation}|{waferInfo.OriginSlot}");
  709. if (_lstPass.Count != 0)
  710. {
  711. waferInfo.NextStation = (int)_lstPass[0];
  712. int slot = 0;
  713. if (ModuleHelper.IsBuffer((ModuleName)waferInfo.NextStation))
  714. slot = CycleIndex % 10;
  715. waferInfo.NextStationSlot = slot;
  716. LogObject.Info("cycle", $"buffer cycle waferInfo:{waferInfo.NextStation}|{waferInfo.NextStationSlot}");
  717. Singleton<WaferManager>.Instance.UpdateWaferProcessStatus((ModuleName)waferInfo.Station, waferInfo.Slot, EnumWaferProcessStatus.InProcess);
  718. }
  719. else
  720. {
  721. //没有任务直接传送回目标
  722. waferInfo.NextStation = waferInfo.DestinationStation;
  723. waferInfo.NextStationSlot = waferInfo.DestinationSlot;
  724. Singleton<WaferManager>.Instance.UpdateWaferProcessStatus((ModuleName)waferInfo.Station, waferInfo.Slot, EnumWaferProcessStatus.InProcess);
  725. }
  726. }
  727. else
  728. {
  729. if (waferInfo.IsEmpty)
  730. {
  731. //LogObject.Info("Cycle",$"晶圆为空{waferInfo.Slot}");
  732. }
  733. if (waferInfo.SubstE90Status != EnumE90Status.InProcess)
  734. {
  735. //LogObject.Info("Cycle", $"晶圆为非InProcess {waferInfo.Slot}");
  736. }
  737. }
  738. }
  739. LogObject.Info("cycle", "更新Pass station wafer下一刻状态");
  740. //_lstPass.ForEach(x => LogObject.Info("cycle", $"Module=>{x}"));
  741. for (int idx = 0; idx < _lstPass.Count(); idx++)
  742. {
  743. LogObject.Info("cycle", $"Pass waferInfo => Pass index:{idx} & Pass Module:{_lstPass[idx]}");
  744. int slot = 0;
  745. if (ModuleHelper.IsBuffer(_lstPass[idx]))
  746. slot = CycleIndex % 10;
  747. WaferInfo wafer = Singleton<WaferManager>.Instance.GetWafer(_lstPass[idx], slot);
  748. LogObject.Info("cycle", $"Pass waferInfo => Empty:{wafer.IsEmpty}");
  749. if (!wafer.IsEmpty && wafer.SubstE90Status == EnumE90Status.InProcess)
  750. {
  751. LogObject.Info("cycle", $"Pass waferInfo:{_lstPass[idx]}|0");
  752. if (idx == _lstPass.Count - 1)
  753. {
  754. wafer.NextStation = wafer.DestinationStation;
  755. wafer.NextStationSlot = wafer.DestinationSlot;
  756. }
  757. else
  758. {
  759. wafer.NextStation = (int)_lstPass[idx + 1];
  760. wafer.NextStationSlot = 0;
  761. if (ModuleHelper.IsBuffer((ModuleName)wafer.NextStation))
  762. wafer.NextStationSlot = CycleIndex % 10;
  763. //LogObject.Info("cycle", $"buff cycle:{wafer.NextStation}|{wafer.NextStationSlot}");
  764. }
  765. }
  766. }
  767. }
  768. /// <summary>
  769. /// 当前的状态
  770. /// 用于对一些子设备的模拟计时
  771. /// </summary>
  772. /// <param name="currentStatus"></param>
  773. /// <returns></returns>
  774. private MovingStatus throughPath(MovingStatus currentStatus)
  775. {
  776. switch (currentStatus)
  777. {
  778. case MovingStatus.WaitAlign:
  779. return MovingStatus.Aligning;
  780. case MovingStatus.Aligning:
  781. return MovingStatus.AlignDone;
  782. case MovingStatus.WaitCool:
  783. return MovingStatus.Cooling;
  784. case MovingStatus.Cooling:
  785. return MovingStatus.CoolDone;
  786. case MovingStatus.WaitFlip:
  787. return MovingStatus.Flipping;
  788. case MovingStatus.Flipping:
  789. return MovingStatus.FlipDone;
  790. case MovingStatus.WaitProcess:
  791. return MovingStatus.Processing;
  792. case MovingStatus.Processing:
  793. return MovingStatus.ProcessDone;
  794. default:
  795. return MovingStatus.Idle;
  796. }
  797. }
  798. private bool IsModulesEmpty(List<ModuleName> lstPassThrough)
  799. {
  800. foreach (ModuleName item in lstPassThrough)
  801. {
  802. if (Singleton<WaferManager>.Instance.CheckHasWafer(item, 0))
  803. {
  804. return false;
  805. }
  806. }
  807. return true;
  808. }
  809. public void Abort()
  810. {
  811. _cycleState = RState.End;
  812. }
  813. }
  814. public class TransferModule
  815. {
  816. protected SchedulerEfemRobot _efemRobot = new SchedulerEfemRobot();
  817. //protected SchedulerTMRobot _tmRobot = new SchedulerTMRobot();
  818. //protected SchedulerSETMRobot _setm;
  819. //
  820. //protected SchedulerLoadPort _lp1 = new SchedulerLoadPort(ModuleName.LP1);
  821. //protected SchedulerLoadPort _lp2 = new SchedulerLoadPort(ModuleName.LP2);
  822. //protected SchedulerLoadPort _lp3 = new SchedulerLoadPort(ModuleName.LP3);
  823. //
  824. //protected SchedulerLoadLock _lla = new SchedulerLoadLock(ModuleName.LLA);
  825. //protected SchedulerLoadLock _llb = new SchedulerLoadLock(ModuleName.LLB);
  826. //
  827. //protected SchedulerAligner _aligner1 = new SchedulerAligner(ModuleName.Aligner1);
  828. //protected SchedulerAligner _aligner2 = new SchedulerAligner(ModuleName.Aligner2);
  829. //protected SchedulerAligner _cooling1 = new SchedulerAligner(ModuleName.Cooling1);
  830. //protected SchedulerAligner _cooling2 = new SchedulerAligner(ModuleName.Cooling2);
  831. //
  832. //protected SchedulerPM _pma = new SchedulerPM(ModuleName.PMA);
  833. //protected SchedulerPM _pmb = new SchedulerPM(ModuleName.PMB);
  834. //
  835. //protected SchedulerPM _pmc = new SchedulerPM(ModuleName.PMC);
  836. //protected SchedulerPM _pmd = new SchedulerPM(ModuleName.PMD);
  837. public TransferModule()
  838. {
  839. }
  840. public SchedulerModule GetScheduler(ModuleName module)
  841. {
  842. switch (module)
  843. {
  844. case ModuleName.EfemRobot:
  845. return _efemRobot;
  846. }
  847. return null;
  848. }
  849. }
  850. }