You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

386 lines
15 KiB

  1. using System;
  2. using HBLConsole.Interface;
  3. using HBLConsole.Service;
  4. using HBLConsole.Communication;
  5. using BPA.Message;
  6. using HBLConsole.Model;
  7. using System.Linq;
  8. using System.Threading;
  9. using HBLConsole.Factory;
  10. using BPA.Message.Enum;
  11. namespace HBLConsole.MORKD
  12. {
  13. public class Control_MORKD : IControl
  14. {
  15. #region 单例模式
  16. private static Control_MORKD _instance;
  17. public static Control_MORKD Instance
  18. {
  19. get
  20. {
  21. if (_instance == null)
  22. _instance = new Control_MORKD();
  23. return _instance;
  24. }
  25. }
  26. public Control_MORKD()
  27. {
  28. }
  29. #endregion
  30. GVL_MORKD mORKD = new GVL_MORKD();
  31. public void ConnectOk()
  32. {
  33. Main();
  34. ReadData();
  35. }
  36. public object GetT()
  37. {
  38. return mORKD;
  39. }
  40. public void DataParse<T>(T order)
  41. {
  42. if (order is MorkOrderPush morkOrderPush)
  43. {
  44. foreach (var item in morkOrderPush.GoodBatchings)
  45. {
  46. var res = Json<BatchingInfoPar>.Data.orderMaterialDelivery.BatchingInfo.FirstOrDefault(p => p.BatchingId == item.BatchingId);
  47. if (res != null)
  48. {
  49. if (ushort.TryParse(res.BatchingLoc, out ushort loc))
  50. {
  51. if (loc >= 1 && loc <= 5)
  52. {
  53. mORKD.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId, BatchingId = res.BatchingId });
  54. }
  55. else if (loc >= 6 && loc <= 10)
  56. {
  57. mORKD.TakeSoupTask.Enqueue(new OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId });
  58. }
  59. else if (loc >= 11 && loc <= 12)
  60. {
  61. mORKD.TakeBowlTask.Enqueue(new OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId });
  62. }
  63. }
  64. }
  65. }
  66. }
  67. }
  68. public void Init()
  69. {
  70. ActionOperate.GetInstance.Register(new Action(() => { mORKD.InitControl(); }), "InitCommand");
  71. }
  72. public void Main()
  73. {
  74. ThreadOperate.GetInstance.StartLong(new Action(() =>
  75. {
  76. mORKD.AllowRun = mORKD.InitComplete && !mORKD.TemperatureReached;
  77. TakeBowlTask();
  78. TakeNoodleTask();
  79. OutNoodleTask();
  80. SingleDetect();
  81. TurntableControl();
  82. OutSoupTask();
  83. TakeSoupTask();
  84. Thread.Sleep(100);
  85. }), "MainTask");
  86. }
  87. public void ReadData()
  88. {
  89. ModbusTcpHelper.GetInstance.Readbool(1120, 29, new Action<bool[]>((bools) =>
  90. {
  91. mORKD.InitComplete = bools[0];
  92. mORKD.TurntableInPlace = bools[1];
  93. mORKD.RBTakeNoodleComplete = bools[2];
  94. for (int i = 0; i < 2; i++)
  95. {
  96. mORKD.AxisIdle[i] = bools[3 + i];
  97. mORKD.AxisAllowInvertedNoodle[i] = bools[5 + i];
  98. mORKD.AxisAllowInvertedSoup[i] = bools[7 + i];
  99. mORKD.SoupHeatComplete[i] = bools[9 + i];
  100. mORKD.BreakMechanismIdle[i] = bools[25 + i];
  101. }
  102. for (int i = 0; i < 6; i++)
  103. {
  104. mORKD.CookNoodleBasketIdle[i] = bools[11 + i];
  105. mORKD.CookNoodleComplete[i] = bools[17 + i];
  106. }
  107. mORKD.TakeNoodleRobotIdle = bools[23];
  108. mORKD.TakeSoupRobotIdle = bools[24];
  109. mORKD.TakeSoupComplete = bools[27];
  110. mORKD.PutNoodleTakeMealComplete = bools[28];
  111. }));
  112. ModbusTcpHelper.GetInstance.Readbool(1200, 11, new Action<bool[]>((bools) =>
  113. {
  114. mORKD.TurntableLowerLimit = bools[0];
  115. mORKD.TurntableUpLimit = bools[1];
  116. for (int i = 0; i < 5; i++)
  117. {
  118. mORKD.SoupMaterialShortage[i] = bools[2 + i];
  119. }
  120. for (int i = 0; i < 3; i++)
  121. {
  122. mORKD.OutMealDetect[i] = bools[7 + i];
  123. }
  124. mORKD.TemperatureReached = bools[10];
  125. }));
  126. }
  127. public void SimOrder<T>(T simOrder)
  128. {
  129. if (simOrder != null)
  130. {
  131. if (simOrder is SimOrderData simOrderData)
  132. {
  133. string subId = Guid.NewGuid().ToString();
  134. mORKD.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = simOrderData.NoodleLoc, SuborderId = subId });
  135. mORKD.TakeBowlTask.Enqueue(new OrderLocInfo() { Loc = simOrderData.BowlLoc, SuborderId = subId });
  136. mORKD.TakeSoupTask.Enqueue(new OrderLocInfo() { Loc = simOrderData.SoupLoc, SuborderId = subId });
  137. MessageLog.GetInstance.Show($"添加订单:面条位置【{simOrderData.NoodleLoc}】,浇头位置【{simOrderData.SoupLoc}】,碗位置【{simOrderData.BowlLoc}】");
  138. }
  139. }
  140. }
  141. /// <summary>
  142. /// 取碗控制
  143. /// </summary>
  144. private void TakeBowlTask()
  145. {
  146. mORKD.AxisIdleIndex = mORKD.AxisIdle.GetIndex(true);
  147. mORKD.AxisIdleLockIndex = mORKD.AxisIdleLock.GetIndex(false);
  148. if (mORKD.AxisIdleLockIndex == mORKD.AxisIdleIndex)
  149. {
  150. if (mORKD.AxisIdleIndex >= 0 && mORKD.AxisIdleIndex <= 1)
  151. {
  152. if (mORKD.AllowRun && mORKD.TakeBowlTask.Count > 0)
  153. {
  154. if (mORKD.TakeBowlTask.TryDequeue(out OrderLocInfo orderLocInfo))
  155. {
  156. mORKD.AxisAllowInvertedNoodleID[mORKD.AxisIdleIndex] = orderLocInfo.SuborderId;
  157. mORKD.DropBowlStart((ushort)mORKD.AxisIdleIndex, orderLocInfo.Loc);
  158. mORKD.AxisIdleLock[mORKD.AxisIdleLockIndex] = true;
  159. MessageLog.GetInstance.Show($"执行取碗控制,位置:[{orderLocInfo.Loc}]");
  160. }
  161. }
  162. }
  163. }
  164. }
  165. /// <summary>
  166. /// 转台控制
  167. /// </summary>
  168. private void TurntableControl()
  169. {
  170. if (mORKD.InitComplete && !mORKD.TurntableInterlock && !mORKD.AllowTakeNoodle && mORKD.RBTakeNoodleTask.Count > 0)
  171. {
  172. var result = Json<BatchingInfoPar>.Data.orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == mORKD.RBTakeNoodleTask.ElementAt(0).BatchingId).ToList();
  173. if (result != null)
  174. {
  175. foreach (var item in result)
  176. {
  177. if (ushort.TryParse(item.BatchingLoc, out ushort loc))
  178. {
  179. if (!mORKD.TurntableLocLists.Contains(loc))
  180. {
  181. mORKD.TurntableStart(loc);
  182. return;
  183. }
  184. }
  185. }
  186. }
  187. }
  188. //转台到位检测
  189. if (RTrig.GetInstance("TurntableInPlace").Start(mORKD.TurntableInPlace))
  190. {
  191. if (mORKD.TurntableInterlock)
  192. {
  193. if (mORKD.TurntableLowerLimit)
  194. {
  195. mORKD.TurntableLocLists.Clear();
  196. mORKD.AllowTakeNoodle = true;
  197. }
  198. else
  199. {
  200. mORKD.TurntableInterlock = false;
  201. mORKD.AllowTakeNoodle = false;
  202. }
  203. }
  204. }
  205. }
  206. /// <summary>
  207. /// 取面任务
  208. /// </summary>
  209. private void TakeNoodleTask()
  210. {
  211. //取面控制
  212. if (mORKD.AllowRun && mORKD.TakeNoodleRobotIdle && !mORKD.RobotTaskInterlock && mORKD.AllowTakeNoodle)
  213. {
  214. if (mORKD.TurntableInPlace && !mORKD.OutNoodleing && mORKD.RBTakeNoodleTask.Count > 0)
  215. {
  216. int loc = mORKD.CookNoodleBasketIdle.GetIndex(false);//查找煮面炉空闲位置
  217. if (loc >= 0 && loc <= 5)
  218. {
  219. if (mORKD.RBTakeNoodleTask.TryDequeue(out OrderLocInfo orderLocInfo))
  220. {
  221. mORKD.RBTakeNoodleStart((ushort)(loc + 1), orderLocInfo.Loc);
  222. mORKD.CookNodelId[loc] = orderLocInfo.SuborderId;
  223. SimpleFactory.GetInstance.OrderChanged(orderLocInfo.SuborderId, ORDER_STATUS.COOKING);
  224. MessageLog.GetInstance.Show($"订单【{orderLocInfo.SuborderId}】,煮面栏:[{loc + 1}]");
  225. mORKD.TakeNoodleInterlock = true;
  226. }
  227. }
  228. }
  229. }
  230. //机器人取面完成信号检测
  231. if (RTrig.GetInstance("TakeNoodleComplete").Start(mORKD.RBTakeNoodleComplete))
  232. {
  233. mORKD.TakeNoodleInterlock = false;
  234. mORKD.AllowTakeNoodle = false;
  235. MessageLog.GetInstance.Show("转台取面完成");
  236. mORKD.TakeNoodleCompleteReset();
  237. }
  238. }
  239. /// <summary>
  240. /// 出餐控制
  241. /// </summary>
  242. private void OutNoodleTask()
  243. {
  244. for (ushort i = 0; i < 6; i++)
  245. {
  246. if (RTrig.GetInstance($"CookNoodleCompleteTask{i}").Start(mORKD.CookNoodleComplete[i]))
  247. {
  248. mORKD.CookNoodleCompleteTask.Enqueue(i);
  249. }
  250. }
  251. if (mORKD.RobotTaskInterlock && !mORKD.TakeNoodleInterlock && mORKD.TakeNoodleRobotIdle)
  252. {
  253. if (mORKD.CookNoodleCompleteTask.Count > 0)
  254. {
  255. string id = mORKD.CookNodelId[mORKD.CookNoodleCompleteTask.ElementAt(0)];
  256. int index = mORKD.AxisAllowInvertedNoodleID.GetIndex(id);
  257. if (index >= 0 && index <= 1)
  258. {
  259. if (mORKD.AxisAllowInvertedNoodle[index])
  260. {
  261. if (mORKD.CookNoodleCompleteTask.TryDequeue(out ushort loc))
  262. {
  263. mORKD.OutNoodleing = true;
  264. mORKD.RBOutNoodleStart((ushort)(loc + 1), (ushort)(index + 1));
  265. mORKD.AxisIdleLock[index] = false;
  266. mORKD.AxisAllowInvertedSoupID[index] = mORKD.AxisAllowInvertedNoodleID[index];
  267. mORKD.AxisAllowInvertedNoodleID[index] = string.Empty;
  268. MessageLog.GetInstance.Show($"从{loc + 1}号位置取面");
  269. MessageLog.GetInstance.Show($"倒入{index + 1}号碗位置");
  270. }
  271. }
  272. }
  273. }
  274. }
  275. int mlCount = mORKD.CookNoodleBasketIdle.Where(p => p == true).ToList().Count;
  276. mORKD.RobotTaskInterlock = mORKD.CookNoodleCompleteTask.Count > 0 && (mlCount >= 2 || mORKD.RBTakeNoodleTask.Count == 0);
  277. }
  278. /// <summary>
  279. /// 取浇头控制
  280. /// </summary>
  281. private void TakeSoupTask()
  282. {
  283. int index = mORKD.BreakMechanismIdle.GetIndex(true);
  284. if (index >= 0 && index <= 1)
  285. {
  286. if (mORKD.TakeSoupTask.Count > 0 && !mORKD.AllowTakeSoup && mORKD.TakeSoupRobotIdle && mORKD.AllowRun)
  287. {
  288. if (mORKD.TakeSoupTask.TryDequeue(out OrderLocInfo orderLocInfo))
  289. {
  290. mORKD.SoupHeatCompleteID[index] = orderLocInfo.SuborderId;
  291. mORKD.RBTakeSoupStart(orderLocInfo.Loc, (ushort)(index + 1));
  292. SimpleFactory.GetInstance.OrderChanged(orderLocInfo.SuborderId, ORDER_STATUS.COOKING);
  293. }
  294. }
  295. }
  296. if (RTrig.GetInstance("TakeSoupComplete").Start(mORKD.TakeSoupComplete))
  297. {
  298. mORKD.AllowTakeSoup = false;
  299. MessageLog.GetInstance.Show("取浇头完成");
  300. mORKD.TakeSoupCompleteReset();
  301. }
  302. }
  303. /// <summary>
  304. /// 浇头加热完成出浇头控制
  305. /// </summary>
  306. private void OutSoupTask()
  307. {
  308. if (!mORKD.AllowTakeSoup && !mORKD.AllowPutSoup && mORKD.TakeSoupRobotIdle)
  309. {
  310. mORKD.PutNoodleLoc = mORKD.OutMealDetect.GetIndex(false);
  311. if (mORKD.PutNoodleLoc >= 0 && mORKD.PutNoodleLoc <= 2)
  312. {
  313. for (int i = 0; i < 2; i++)
  314. {
  315. if (mORKD.SoupHeatComplete[i] && mORKD.SoupHeatCompleteID[i].Length > 0)
  316. {
  317. for (int m = 0; m < 2; m++)
  318. {
  319. if (mORKD.AxisAllowInvertedSoup[m] && mORKD.AxisAllowInvertedSoupID[m].Length > 0)
  320. {
  321. if (mORKD.SoupHeatCompleteID[i] == mORKD.AxisAllowInvertedSoupID[m])
  322. {
  323. mORKD.HeatCompleteTakeSoupStart((ushort)(i + 1), (ushort)(m + 1), (ushort)(mORKD.PutNoodleLoc + 1));
  324. mORKD.OutMealId[mORKD.PutNoodleLoc] = mORKD.AxisAllowInvertedSoupID[m];
  325. mORKD.AxisAllowInvertedSoupID[m] = string.Empty;
  326. mORKD.SoupHeatCompleteID[i] = string.Empty;
  327. }
  328. }
  329. }
  330. }
  331. }
  332. }
  333. }
  334. if (RTrig.GetInstance("PutNoodleTakeMealComplete").Start(mORKD.PutNoodleTakeMealComplete))
  335. {
  336. mORKD.AllowPutSoup = false;
  337. SimpleFactory.GetInstance.OrderChanged(mORKD.OutMealId[mORKD.PutNoodleLoc], ORDER_STATUS.COMPLETED_COOK);
  338. mORKD.PutNoodleTakeMealCompleteReset();
  339. }
  340. }
  341. /// <summary>
  342. /// 信号检测
  343. /// </summary>
  344. private void SingleDetect()
  345. {
  346. }
  347. }
  348. }