Base_Rgv.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using WCS.Data;
  5. using System.Linq;
  6. using WCS.Data.Models;
  7. using SqlSugar;
  8. using System.Threading;
  9. using WCS.PLC.Model.Equipment;
  10. namespace WCS.PLC
  11. {
  12. public enum RgvPosEnum
  13. {
  14. 一号工位 = 1,
  15. 二号工位 = 2,
  16. }
  17. public class WaitExecInfo
  18. {
  19. /// <summary>
  20. /// 预执行任务号
  21. /// </summary>
  22. public int WaitExecTaskNo { get; set; }
  23. /// <summary>
  24. /// 预执行上料点
  25. /// </summary>
  26. public string WaitExecOnMatPosNo { get; set; }
  27. /// <summary>
  28. /// 预执行下料点
  29. /// </summary>
  30. public string WaitExecUpMatPosNo { get; set; }
  31. public bool IsNotEmpty()
  32. {
  33. if (WaitExecTaskNo > 0 &&
  34. (string.IsNullOrWhiteSpace(WaitExecOnMatPosNo) == false) &&
  35. (string.IsNullOrWhiteSpace(WaitExecUpMatPosNo) == false))
  36. {
  37. return true;
  38. }
  39. else
  40. {
  41. return false;
  42. }
  43. }
  44. public void SetInfo(int waiteExecTaskNo, string waitExecOnMatPosNo, string waitExecUpMatPosNo)
  45. {
  46. WaitExecTaskNo = waiteExecTaskNo;
  47. WaitExecOnMatPosNo = waitExecOnMatPosNo;
  48. WaitExecUpMatPosNo = waitExecUpMatPosNo;
  49. }
  50. public void Clear()
  51. {
  52. WaitExecTaskNo = 0;
  53. WaitExecOnMatPosNo = string.Empty;
  54. WaitExecUpMatPosNo = string.Empty;
  55. }
  56. }
  57. public abstract class Base_Rgv : Base_EquPlc
  58. {
  59. /// <summary>
  60. /// 预执行信息
  61. /// </summary>
  62. protected WaitExecInfo WaitExecTask = new WaitExecInfo();
  63. #region Constructor
  64. public Base_Rgv() : base() { }
  65. #endregion;
  66. #region 属性
  67. /// <summary>
  68. /// RGV当前位置
  69. /// </summary>
  70. protected string RgvCurrentSition
  71. {
  72. get
  73. {
  74. //RGV当前地址
  75. string curPosNo = string.Empty;
  76. if (Rgv.DB521_ToSition_1) curPosNo = Rgv.DB521_DestPosition_1.ToString();
  77. else if (Rgv.DB521_ToSition_2) curPosNo = Rgv.DB521_DestPosition_2.ToString();
  78. if (string.IsNullOrWhiteSpace(curPosNo))
  79. {
  80. var tempList = Current.WCS_RGVOutInInfoSet.Where(v => v.RGVOUTIN_RGVNO == PlcName).ToList();
  81. curPosNo = tempList[0].RGVOUTIN_CONVNO;
  82. }
  83. return curPosNo;
  84. }
  85. }
  86. protected PLC RgvPlc
  87. {
  88. get
  89. {
  90. return WCS_PLCItem.Plc;
  91. }
  92. }
  93. protected WCS_EQUIPMENTINFO RgvData
  94. {
  95. get
  96. {
  97. return WCS_PLCItem.WCS_EquipmentInfoSet[0];
  98. }
  99. }
  100. public RGVSignal Rgv
  101. {
  102. get
  103. {
  104. return WCS_PLCItem.WCS_EquipmentInfoSet[0].EquSignal_Rgv;
  105. }
  106. }
  107. /// <summary>
  108. /// RGV上下料列表
  109. /// </summary>
  110. protected List<WCS_RGVOutInInfo> RGVOnUpPosList
  111. {
  112. get
  113. {
  114. var tempList = Current.WCS_RGVOutInInfoSet.Where(v => v.RGVOUTIN_RGVNO == PlcName).ToList();
  115. var curItem = tempList.FirstOrDefault(v => v.RGVOUTIN_CONVNO == RgvCurrentSition);
  116. if (curItem != null)
  117. {
  118. foreach (var item in tempList)
  119. {
  120. int difference = item.RGVOUTIN_SEQUENCE - curItem.RGVOUTIN_SEQUENCE;
  121. item.RGVCURRENT_SEQUENCE = Math.Abs(difference);
  122. }
  123. }
  124. return tempList.OrderBy(v => v.RGVCURRENT_SEQUENCE).ToList();
  125. }
  126. }
  127. /// <summary>
  128. /// RGV上料点列表
  129. /// </summary>
  130. protected virtual List<WCS_RGVOutInInfo> RGVOnPosList
  131. {
  132. get
  133. {
  134. var _onPosList = RGVOnUpPosList.Where(v => v.RGVOUTIN_ISSTOP == false && (v.RGVOUTIN_OUTINTYPE == "OnMat" || v.RGVOUTIN_OUTINTYPE == "OnUpMat")).ToList();
  135. return _onPosList;
  136. }
  137. }
  138. /// <summary>
  139. /// RGV下料点列表
  140. /// </summary>
  141. protected virtual List<WCS_RGVOutInInfo> RGVUpPosList
  142. {
  143. get
  144. {
  145. var _upPosList = RGVOnUpPosList.Where(v => v.RGVOUTIN_ISSTOP == false && (v.RGVOUTIN_OUTINTYPE == "UpMat" || v.RGVOUTIN_OUTINTYPE == "OnUpMat")).ToList();
  146. return _upPosList;
  147. }
  148. }
  149. #endregion;
  150. #region 方法
  151. /// <summary>
  152. /// 写入任务到穿梭车
  153. /// </summary>
  154. /// <param name="rgvwrite">Rgv写入信号</param>
  155. protected virtual void WriteTaskToRgv(WCSWriteToRgvSignal rgvwrite)
  156. {
  157. if (CheckTaskInfo(Rgv, rgvwrite))
  158. {
  159. WaitExecTask.Clear();
  160. string result = TryCachHelper.TryTranExecute((db) =>
  161. {
  162. UpdateRgvTaskStatus(db, rgvwrite);
  163. WriteTrigger(Rgv, rgvwrite);
  164. });
  165. if (!string.IsNullOrWhiteSpace(result))
  166. throw new Exception(string.Format("任务[{0}]RGV执行失败,原因:[{1}]", rgvwrite.Tasknum, result));
  167. }
  168. else
  169. {
  170. WriteTaskToBuffer(rgvwrite);
  171. }
  172. }
  173. protected void WriteTask(WCSWriteToRgvSignal rgvwrite)
  174. {
  175. string cacheAreaName = rgvwrite.Tasknum.ToString();
  176. var cacheInfo = SugarBase.DB.Queryable<WCS_CacheInfo>().First(v => v.Cache_ConvNo == rgvwrite.DestPosition.ToString());
  177. if (cacheInfo != null)
  178. {
  179. cacheAreaName = cacheInfo.Cache_AreaName;
  180. }
  181. string errorMsg = WriteTaskToRgv(rgvwrite, cacheAreaName);
  182. if (!string.IsNullOrWhiteSpace(errorMsg)) throw new Exception(errorMsg);
  183. }
  184. protected string WriteTaskToRgv(WCSWriteToRgvSignal rgvwrite, string cacheAreaName)
  185. {
  186. using (var mutex = new Mutex(false, cacheAreaName))
  187. {
  188. string resultMsg = string.Empty;
  189. try
  190. {
  191. if (mutex.WaitOne(-1, false))
  192. {
  193. WriteTaskToRgv(rgvwrite);
  194. }
  195. }
  196. catch (Exception ex)
  197. {
  198. resultMsg = ex.Message;
  199. }
  200. finally
  201. {
  202. mutex.ReleaseMutex();
  203. }
  204. return resultMsg;
  205. }
  206. }
  207. private bool CheckTaskInfo(RGVSignal rgvSignal, WCSWriteToRgvSignal rgvwrite)
  208. {
  209. bool result = false;
  210. if (rgvwrite.RgvPos == RgvPosEnum.一号工位)
  211. {
  212. if (rgvSignal.DB520_TaskID_1 == rgvwrite.Tasknum &&
  213. rgvSignal.DB520_TaskType_1 == rgvwrite.TaskType &&
  214. rgvSignal.DB520_StartPosition_1 == rgvwrite.StartPosition &&
  215. rgvSignal.DB520_DestPosition_1 == rgvwrite.DestPosition &&
  216. rgvSignal.DB520_Priority_1 == rgvwrite.Priority &&
  217. rgvSignal.DB520_Res1_1 == rgvwrite.RES1 &&
  218. rgvSignal.DB520_Res2_1 == rgvwrite.RES2)
  219. {
  220. result = true;
  221. }
  222. else
  223. {
  224. result = false;
  225. }
  226. }
  227. else if (rgvwrite.RgvPos == RgvPosEnum.二号工位)
  228. {
  229. if (rgvSignal.DB520_TaskID_2 == rgvwrite.Tasknum &&
  230. rgvSignal.DB520_TaskType_2 == rgvwrite.TaskType &&
  231. rgvSignal.DB520_StartPosition_2 == rgvwrite.StartPosition &&
  232. rgvSignal.DB520_DestPosition_2 == rgvwrite.DestPosition &&
  233. rgvSignal.DB520_Priority_2 == rgvwrite.Priority &&
  234. rgvSignal.DB520_Res1_2 == rgvwrite.RES1 &&
  235. rgvSignal.DB520_Res2_2 == rgvwrite.RES2)
  236. {
  237. result = true;
  238. }
  239. else
  240. {
  241. result = false;
  242. }
  243. }
  244. return result;
  245. }
  246. private void WriteTrigger(RGVSignal rgvSignal, WCSWriteToRgvSignal rgvwrite)
  247. {
  248. if (rgvwrite.RgvPos == RgvPosEnum.一号工位)
  249. {
  250. if (rgvSignal.DB520_Trigger_1 != 1)
  251. {
  252. if (rgvwrite.Plc.WriteSignal((ushort)rgvwrite.DBName, 16, 2, 1))
  253. {
  254. WaitExecTask.Clear();
  255. Log4netHelper.Logger_Info.InfoFormat(string.Format("任务[{0}]穿梭车[{1}]写入触发信号成功!", rgvwrite.Tasknum, PlcName));
  256. }
  257. else
  258. {
  259. throw new Exception(string.Format("任务[{0}]穿梭车[{1}]写入触发信号失败!", rgvwrite.Tasknum, PlcName));
  260. }
  261. }
  262. }
  263. else if (rgvwrite.RgvPos == RgvPosEnum.二号工位)
  264. {
  265. if (rgvSignal.DB520_Trigger_2 != 1)
  266. {
  267. if (rgvwrite.Plc.WriteSignal((ushort)rgvwrite.DBName, 34, 2, 1))
  268. {
  269. Log4netHelper.Logger_Info.InfoFormat(string.Format("任务[{0}]穿梭车[{1}]写入触发信号成功!", rgvwrite.Tasknum, PlcName));
  270. }
  271. else
  272. {
  273. throw new Exception(string.Format("任务[{0}]穿梭车[{1}]写入触发信号失败!", rgvwrite.Tasknum, PlcName));
  274. }
  275. }
  276. }
  277. }
  278. /// <summary>
  279. /// 写入任务信息
  280. /// </summary>
  281. /// <param name="rgvwrite">写入的信息</param>
  282. protected void WriteTaskToBuffer(WCSWriteToRgvSignal rgvwrite)
  283. {
  284. List<byte> list = new List<byte>();
  285. //写入任务号
  286. list.AddRange(ExtendsUtil.UintToByte((uint)rgvwrite.Tasknum).ToList());
  287. //类型
  288. list.AddRange(ExtendsUtil.UshortToByte((ushort)rgvwrite.TaskType).ToList());
  289. //写入起点地址
  290. list.AddRange(ExtendsUtil.UshortToByte((ushort)rgvwrite.StartPosition).ToList());
  291. //写入目标地址
  292. list.AddRange(ExtendsUtil.UshortToByte((ushort)rgvwrite.DestPosition).ToList());
  293. //优先级
  294. list.AddRange(ExtendsUtil.UshortToByte((ushort)rgvwrite.Priority).ToList());
  295. list.AddRange(ExtendsUtil.UshortToByte((ushort)rgvwrite.RES1).ToList());
  296. list.AddRange(ExtendsUtil.UshortToByte((ushort)rgvwrite.RES2).ToList());
  297. bool result = rgvwrite.Plc.Write((ushort)rgvwrite.DBName, (ushort)(rgvwrite.WriteStartAddress), list.ToArray());
  298. if (result)
  299. {
  300. WaitExecTask.SetInfo(rgvwrite.Tasknum, rgvwrite.StartPosition.ToString(), rgvwrite.DestPosition.ToString());
  301. Log4netHelper.Logger_Info.InfoFormat(string.Format("RGV[{0}]写入任务[{1}]起点地址[{2}]目标地址[{3}]是否托盘异常退回[{4}]成功。", rgvwrite.RgvNo, rgvwrite.Tasknum, rgvwrite.StartPosition, rgvwrite.DestPosition, rgvwrite.RES1));
  302. }
  303. else
  304. {
  305. throw new Exception(string.Format("RGV[{0}]写入任务[{1}]起点地址[{2}]目标地址[{3}]失败。", rgvwrite.RgvNo, rgvwrite.Tasknum, rgvwrite.StartPosition, rgvwrite.DestPosition));
  306. }
  307. }
  308. /// <summary>
  309. /// 修改任务信息
  310. /// </summary>
  311. protected virtual void UpdateRgvTaskStatus(SqlSugarClient db, WCSWriteToRgvSignal rgvwrite) { }
  312. #endregion;
  313. }
  314. public struct WCSWriteToRgvSignal
  315. {
  316. /// <summary>
  317. /// 工位
  318. /// </summary>
  319. public RgvPosEnum RgvPos;
  320. public PLC Plc;
  321. /// <summary>
  322. /// DB名称
  323. /// </summary>
  324. public int DBName;
  325. /// <summary>
  326. /// RGV编号
  327. /// </summary>
  328. public string RgvNo;
  329. /// <summary>
  330. /// 写入信号起始地址
  331. /// </summary>
  332. public int WriteStartAddress;
  333. /// <summary>
  334. /// 任务号
  335. /// </summary>
  336. public int Tasknum;
  337. /// <summary>
  338. /// 1取货、2放货、3移动、4码盘、5拆盘 、6、变更放货站台、7变更取货站台(环穿、双工位使用)
  339. /// </summary>
  340. public int TaskType;
  341. /// <summary>
  342. /// 起始地址
  343. /// </summary>
  344. public int StartPosition;
  345. /// <summary>
  346. /// 目标地址
  347. /// </summary>
  348. public int DestPosition;
  349. /// <summary>
  350. /// 优先级
  351. /// </summary>
  352. public int Priority;
  353. public int RES1;
  354. public int RES2;
  355. /// <summary>
  356. /// WCS写入1,plc清零
  357. /// </summary>
  358. public int Trigger;
  359. }
  360. //public class RGVList
  361. //{
  362. // /// <summary>
  363. // /// Rgv运行
  364. // /// </summary>
  365. // public static void RgvRun()
  366. // {
  367. // try
  368. // {
  369. // foreach (var rgv in Current.RgvSet)
  370. // {
  371. // ThreadHelper.TaskThread(rgv.RgvRun);
  372. // }
  373. // }
  374. // catch (Exception ex)
  375. // {
  376. // Log4netHelper.Logger_Error.ErrorFormat(ex.ToString());
  377. // }
  378. // }
  379. //}
  380. }