SchedulerModuleTimeManager.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. using Aitex.Core.RT.Fsm;
  2. using Aitex.Core.RT.IOCore;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.RT.SCCore;
  5. using Aitex.Core.Util;
  6. using PunkHPX8_RT.Modules;
  7. using MECF.Framework.Common.CommonData;
  8. using MECF.Framework.Common.Equipment;
  9. using MECF.Framework.Common.RecipeCenter;
  10. using SecsGem.Core.ItemModel;
  11. using System;
  12. using System.Collections.Generic;
  13. using System.Linq;
  14. using System.Reflection;
  15. using System.Text;
  16. using System.Threading.Tasks;
  17. namespace PunkHPX8_RT.Schedulers
  18. {
  19. public class SchedulerModuleTimeManager : Singleton<SchedulerModuleTimeManager>
  20. {
  21. /// <summary>
  22. /// 确定后面所有Metal、Qdr和Dryer资源
  23. /// </summary>
  24. /// <param name="schedulerSequences"></param>
  25. /// <param name="waferHolderId"></param>
  26. /// <param name="waferHolderMoveItem"></param>
  27. /// <param name="sequenceIndex"></param>
  28. /// <param name="materialId"></param>
  29. /// <param name="existEnableCell"></param>
  30. public bool ConfirmAllMetalQdrAndDryer(List<SchedulerSequence> schedulerSequences, string waferHolderId, int sequenceIndex,bool checkConflict,DateTime startTime)
  31. {
  32. int transporterTransferSeconds = SC.GetValue<int>("Transporter.TransporterTransferSeconds");
  33. var avaibleResults = AnalyseAfterAvaibleCell(schedulerSequences, startTime, waferHolderId, sequenceIndex,checkConflict);
  34. if (!avaibleResults.success)
  35. {
  36. return false;
  37. }
  38. if (avaibleResults.results.Count == 0 && avaibleResults.rinseResults.Item2 == ModuleName.Unknown && avaibleResults.dryerResults.Item2 == ModuleName.Unknown)
  39. {
  40. return false;
  41. }
  42. SchedulerModulePartTime metalPartTime = new SchedulerModulePartTime();
  43. SchedulerModulePartTime qdrPartTime = new SchedulerModulePartTime();
  44. SchedulerModulePartTime dryerPartTime = new SchedulerModulePartTime();
  45. //处理metal和Rinse
  46. for (int i = 0; i < avaibleResults.results.Count; i++)
  47. {
  48. var item = avaibleResults.results[i];
  49. int index = item.Item1;
  50. SchedulerSequence sequence = schedulerSequences[index];
  51. if (sequence.State == PunkHPX8_Core.RState.End)
  52. {
  53. continue;
  54. }
  55. if (sequence.ModuleName != ModuleName.Transporter1)
  56. {
  57. continue;
  58. }
  59. SchedulerSequence metalSequence = schedulerSequences[index + 1];
  60. if (metalSequence.ModuleType != ModuleType.Metal)
  61. {
  62. continue;
  63. }
  64. DepRecipe depRecipe = (DepRecipe)metalSequence.Recipe;
  65. QdrRecipe qdrRecipe = (QdrRecipe)metalSequence.NextRecipe;
  66. int depRecipeTimeLength = depRecipe.CalculateRecipeTotalTime();
  67. int qdrRecipeTimeLength = qdrRecipe.CalculateRunRecipeTime();
  68. DateTime metalStartTime = item.Item4.AddSeconds(transporterTransferSeconds);
  69. if (metalSequence.SchedulerModule == null)
  70. {
  71. metalSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(item.Item2);
  72. metalSequence.ModuleName = item.Item2;
  73. }
  74. if (!checkConflict)
  75. {
  76. SchedulerTime lastSchedulerTime = SchedulerMetalTimeManager.Instance.GetLastSchedulerTime(item.Item2.ToString());
  77. DateTime lastSchedulerEndTime = GetModuleLastSchedulerEndTime(lastSchedulerTime, metalPartTime, item.Item2.ToString(), depRecipeTimeLength, transporterTransferSeconds);
  78. if (lastSchedulerEndTime > metalStartTime)
  79. {
  80. metalStartTime = lastSchedulerEndTime;
  81. }
  82. }
  83. SchedulerMetalTimeManager.Instance.AddMetalScheduler(item.Item2.ToString(), waferHolderId, index + 1, metalStartTime,
  84. depRecipeTimeLength, false);
  85. SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, item.Item2.ToString(), ModuleType.Metal, index + 1,
  86. metalStartTime, depRecipeTimeLength);
  87. metalPartTime.AddScheduler(item.Item2.ToString(), waferHolderId, index + 1, metalStartTime, depRecipeTimeLength);
  88. if (index + 3 >= schedulerSequences.Count)
  89. {
  90. continue;
  91. }
  92. //增加了transporter时间轴
  93. SchedulerTransporterTimeManager.Instance.AddTransporterScheduler(ModuleName.Transporter1.ToString(), waferHolderId, index + 2, metalStartTime.AddSeconds(depRecipeTimeLength),
  94. false);
  95. SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, ModuleName.Transporter1.ToString(), ModuleType.Transporter, index + 2,
  96. metalStartTime.AddSeconds(depRecipeTimeLength), transporterTransferSeconds);
  97. SchedulerSequence qdrSequence = schedulerSequences[index + 3];
  98. if (qdrSequence.ModuleType != ModuleType.Rinse)
  99. {
  100. continue;
  101. }
  102. if (qdrSequence.SchedulerModule == null)
  103. {
  104. qdrSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(item.Item3);
  105. qdrSequence.ModuleName = item.Item3;
  106. }
  107. DateTime schedulerQdrStartTime = SchedulerQdrTimeManager.Instance.CalculateQdrSchedulerStartTime(metalStartTime, depRecipeTimeLength);
  108. if (!checkConflict)
  109. {
  110. SchedulerTime lastSchedulerTime = SchedulerQdrTimeManager.Instance.GetLastSchedulerTime(item.Item3.ToString());
  111. DateTime lastSchedulerEndTime = GetModuleLastSchedulerEndTime(lastSchedulerTime, qdrPartTime, item.Item3.ToString(), qdrRecipeTimeLength, transporterTransferSeconds);
  112. if (lastSchedulerEndTime > schedulerQdrStartTime)
  113. {
  114. schedulerQdrStartTime = lastSchedulerEndTime;
  115. }
  116. }
  117. SchedulerQdrTimeManager.Instance.AddQdrScheduler(item.Item3.ToString(), waferHolderId, index + 3, schedulerQdrStartTime, qdrRecipeTimeLength, false);
  118. SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, item.Item3.ToString(),ModuleType.Rinse, index + 3,
  119. schedulerQdrStartTime, qdrRecipeTimeLength);
  120. qdrPartTime.AddScheduler(item.Item3.ToString(), waferHolderId, index + 3, schedulerQdrStartTime, qdrRecipeTimeLength);
  121. //增加了transporter时间轴
  122. SchedulerTransporterTimeManager.Instance.AddTransporterScheduler(ModuleName.Transporter1.ToString(), waferHolderId, index + 4, schedulerQdrStartTime.AddSeconds(qdrRecipeTimeLength),
  123. false);
  124. SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, ModuleName.Transporter1.ToString(), ModuleType.Transporter, index + 4,
  125. schedulerQdrStartTime.AddSeconds(qdrRecipeTimeLength), transporterTransferSeconds);
  126. }
  127. //处理单独Rinse
  128. if (avaibleResults.rinseResults.Item2 != ModuleName.Unknown)
  129. {
  130. int transporterIndex = avaibleResults.rinseResults.Item1;
  131. SchedulerSequence transporterSequence = schedulerSequences[transporterIndex];
  132. if (transporterSequence.State != PunkHPX8_Core.RState.End)
  133. {
  134. //增加了transporter时间轴
  135. SchedulerTransporterTimeManager.Instance.AddTransporterScheduler(ModuleName.Transporter1.ToString(), waferHolderId, transporterIndex, avaibleResults.rinseResults.Item3,
  136. false);
  137. SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, ModuleName.Transporter1.ToString(), ModuleType.Transporter, transporterIndex,
  138. avaibleResults.rinseResults.Item3, transporterTransferSeconds);
  139. }
  140. }
  141. //处理Dryer
  142. if (avaibleResults.dryerResults.Item2 != ModuleName.Unknown)
  143. {
  144. int transporterIndex = avaibleResults.dryerResults.Item1;
  145. SchedulerSequence transporterSequence = schedulerSequences[transporterIndex];
  146. }
  147. SchedulerMetalTimeManager.Instance.WriteMetalSchedulerTimeLog();
  148. SchedulerQdrTimeManager.Instance.WriteQdrSchedulerTimeLog();
  149. SchedulerDryerTimeManager.Instance.WriteDryerSchedulerTimeLog();
  150. SchedulerTransporterTimeManager.Instance.WriteTransporterSchedulerTimeLog();
  151. SchedulerWaferHolderTimeManager.Instance.WriteSchedulerTimeLog(waferHolderId);
  152. qdrPartTime.Dispose();
  153. metalPartTime.Dispose();
  154. dryerPartTime.Dispose();
  155. return true;
  156. }
  157. /// <summary>
  158. /// 获取最新调度时间
  159. /// </summary>
  160. /// <param name="schedulerTime"></param>
  161. /// <param name="partTime"></param>
  162. /// <param name="module"></param>
  163. /// <param name="recipeLength"></param>
  164. /// <param name="transporterTransferSeconds"></param>
  165. /// <returns></returns>
  166. private DateTime GetModuleLastSchedulerEndTime(SchedulerTime schedulerTime,SchedulerModulePartTime partTime,string module,int recipeLength,int transporterTransferSeconds)
  167. {
  168. DateTime lastSchedulerEndTime = DateTime.MinValue;
  169. if (schedulerTime != null)
  170. {
  171. lastSchedulerEndTime = schedulerTime.ScheduleStartTime.AddSeconds(recipeLength).AddSeconds(transporterTransferSeconds);
  172. }
  173. DateTime lastPartTime = partTime.GetLastSchedulerTime(module);
  174. if (lastPartTime.AddSeconds(transporterTransferSeconds) > lastSchedulerEndTime)
  175. {
  176. lastSchedulerEndTime = lastPartTime.AddSeconds(transporterTransferSeconds);
  177. }
  178. return lastSchedulerEndTime;
  179. }
  180. /// <summary>
  181. /// 分析后面所有Cell可用资源
  182. /// sequenceIndex为transporter对应的索引
  183. /// </summary>
  184. /// <param name="schedulerSequences"></param>
  185. /// <param name="waferHolderId"></param>
  186. /// <param name="sequenceIndex"></param>
  187. /// <returns></returns>
  188. public (bool success,List<(int, ModuleName, ModuleName, DateTime)> results, (int, ModuleName, DateTime) rinseResults,(int, ModuleName, DateTime) dryerResults) AnalyseAfterAvaibleCell(List<SchedulerSequence> schedulerSequences,
  189. DateTime startTime, string waferHolderId, int sequenceIndex,bool checkConflict)
  190. {
  191. int transporterTransferSeconds = SC.GetValue<int>("Transporter.TransporterTransferSeconds");
  192. List<(int, ModuleName, ModuleName, DateTime)> results = new List<(int, ModuleName, ModuleName, DateTime)>();
  193. var dryerResults = new ValueTuple<int, ModuleName, DateTime>();
  194. dryerResults.Item2 = ModuleName.Unknown;
  195. var rinseResults = new ValueTuple<int, ModuleName, DateTime>();
  196. rinseResults.Item2 = ModuleName.Unknown;
  197. SchedulerModulePartTime metalPartTime = new SchedulerModulePartTime();
  198. SchedulerModulePartTime qdrPartTime = new SchedulerModulePartTime();
  199. for (int i = sequenceIndex; i < schedulerSequences.Count; i++)
  200. {
  201. SchedulerSequence sequence = schedulerSequences[i];
  202. if (sequence.State == PunkHPX8_Core.RState.End)
  203. {
  204. continue;
  205. }
  206. if (sequence.ModuleName != ModuleName.Transporter1)
  207. {
  208. continue;
  209. }
  210. SchedulerSequence metalSequence = schedulerSequences[i + 1];
  211. if (metalSequence.Recipe == null || !(metalSequence.Recipe is DepRecipe))
  212. {
  213. continue;
  214. }
  215. DepRecipe depRecipe = (DepRecipe)metalSequence.Recipe;
  216. QdrRecipe qdrRecipe = (QdrRecipe)metalSequence.NextRecipe;
  217. int depRecipeTimeLength = depRecipe.CalculateRecipeTotalTime();
  218. int qdrRecipeTimeLength = qdrRecipe.CalculateRunRecipeTime();
  219. startTime = startTime.AddSeconds(transporterTransferSeconds).AddSeconds(depRecipeTimeLength)
  220. .AddSeconds(transporterTransferSeconds).AddSeconds(qdrRecipeTimeLength);
  221. i += 3;
  222. }
  223. metalPartTime.Dispose();
  224. qdrPartTime.Dispose();
  225. return (true, results,rinseResults, dryerResults);
  226. }
  227. }
  228. }