TransporterCommon.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. using Aitex.Core.RT.DataCenter;
  2. using Aitex.Core.RT.Device;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.Log;
  5. using Aitex.Core.RT.OperationCenter;
  6. using Aitex.Core.RT.Routine;
  7. using Aitex.Core.RT.SCCore;
  8. using Aitex.Core.Util;
  9. using MECF.Framework.Common.Beckhoff.ModuleIO;
  10. using MECF.Framework.Common.CommonData.Transporter;
  11. using MECF.Framework.Common.Equipment;
  12. using MECF.Framework.Common.ToolLayout;
  13. using MECF.Framework.Common.TwinCat;
  14. using CyberX8_Core;
  15. using CyberX8_RT.Devices.AXIS;
  16. using CyberX8_RT.Devices.AXIS.CANOpen;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Linq;
  20. using System.Net.NetworkInformation;
  21. using System.Reflection;
  22. using System.Text;
  23. using System.Threading.Tasks;
  24. using CyberX8_RT.Devices.BarcodeReader;
  25. using MECF.Framework.Common.IOCore;
  26. namespace CyberX8_RT.Devices.TransPorter
  27. {
  28. public class TransporterCommon : BaseDevice, IDevice
  29. {
  30. private enum TransporterCommonOperation
  31. {
  32. None=0,
  33. Lock=1,
  34. Unlock=2,
  35. Retract=3,
  36. Extend=4
  37. }
  38. #region 常量
  39. private const string UNLOCK = "Unlock";
  40. private const string LOCKED1 = "Locked1";
  41. private const string LOCKED2 = "Locked2";
  42. private const string UNLOCKED1 = "Unlocked1";
  43. private const string UNLOCKED2 = "Unlocked2";
  44. private const string IMMOBILIZE_ACTIVE = "ImmobilizeActive";
  45. private const string IMMOBILIZE_ACTIVE2 = "ImmobilizeActive2";
  46. private const string IMMOBILIZE_RETRACTED1 = "ImmobilizeRetracted1";
  47. private const string IMMOBILIZE_RETRACTED2 = "ImmobilizeRetracted2";
  48. private const string IMMOBILIZE_EXTEND1 = "ImmobilizeExtended1";
  49. private const string IMMOBILIZE_EXTEND2= "ImmobilizeExtended2";
  50. private const string READY_TO_LOCK1 = "ReadyToLock1";
  51. private const string READY_TO_LOCK2 = "ReadyToLock2";
  52. private const string WH_PRESENT1 = "WhPresent1";
  53. private const string WH_PRESENT2 = "WhPresent2";
  54. private const string TRANSPORTER_DATA = "TransporterData";
  55. private const string LOCK = "Lock";
  56. private const string WSHOLDPRESENT = "WSHoldPresent";
  57. #endregion
  58. #region 内部变量
  59. private TransporterData _transporterData = new TransporterData();
  60. /// <summary>
  61. /// 状态
  62. /// </summary>
  63. private RState _status;
  64. /// <summary>
  65. /// 当前操作
  66. /// </summary>
  67. private TransporterCommonOperation _currentOperation;
  68. /// <summary>
  69. /// unlock后自动lock时长
  70. /// </summary>
  71. private int _unlockTimerLockInterval = 20;
  72. /// <summary>
  73. /// unlock时间
  74. /// </summary>
  75. private DateTime _unlockDateTime = DateTime.Now;
  76. #region Routine
  77. /// <summary>
  78. /// Retract Routine
  79. /// </summary>
  80. private TransporterRetractRoutine _retractRoutine;
  81. /// <summary>
  82. /// Extend Routine
  83. /// </summary>
  84. private TransporterExtendRoutine _extendRoutine;
  85. /// <summary>
  86. /// barcodeReaderName
  87. /// </summary>
  88. private string _barcodeReaderName;
  89. /// <summary>
  90. /// 条码读取器
  91. /// </summary>
  92. private BarcodeReaderController _barcodeReader;
  93. #endregion
  94. #endregion
  95. #region 属性
  96. /// <summary>
  97. /// 数据
  98. /// </summary>
  99. public TransporterData TransporterData { get { return _transporterData; } }
  100. #endregion
  101. /// <summary>
  102. /// 构造函数
  103. /// </summary>
  104. /// <param name="moduleName"></param>
  105. public TransporterCommon(string moduleName) : base(moduleName, "Common", "Common", "Common")
  106. {
  107. TransporterItem transporterItem = TransporterItemManager.Instance.GetTransporterItem(moduleName);
  108. if(transporterItem != null)
  109. {
  110. _barcodeReaderName =transporterItem.BarcodeReader;
  111. }
  112. }
  113. /// <summary>
  114. /// 初始化
  115. /// </summary>
  116. /// <returns></returns>
  117. public bool Initialize()
  118. {
  119. InitializeData();
  120. SubscribeValueAction();
  121. InitializeRoutine();
  122. InitializeOperation();
  123. return true;
  124. }
  125. /// <summary>
  126. /// 初始化数据
  127. /// </summary>
  128. private void InitializeData()
  129. {
  130. DATA.Subscribe($"{Module}.{TRANSPORTER_DATA}", () => _transporterData, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  131. DATA.Subscribe($"{Module}.BarcodeReader", () => _barcodeReaderName, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  132. DATA.Subscribe($"{Module}.WSPresent1", ()=>_transporterData.WhPresent1, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  133. DATA.Subscribe($"{Module}.WSPresent2", () => _transporterData.WhPresent2, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  134. DATA.Subscribe($"{Module}.ImmobilizeActive1", () => _transporterData.ImmobilizeActive, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  135. DATA.Subscribe($"{Module}.ImmobilizeActive2", () => _transporterData.ImmobilizeActive2, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  136. DATA.Subscribe($"{Module}.ImmobilizeRetracted1", () => _transporterData.ImmobilizeRetracted1, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  137. DATA.Subscribe($"{Module}.ImmobilizeRetracted2", () => _transporterData.ImmobilizeRetracted2, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  138. DATA.Subscribe($"{Module}.ImmobilizeExtended1", () => _transporterData.ImmobilizeExtended1, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  139. DATA.Subscribe($"{Module}.ImmobilizeExtended2", () => _transporterData.ImmobilizeExtended2, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  140. DATA.Subscribe($"{Module}.Locked1", () => _transporterData.Locked1, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  141. DATA.Subscribe($"{Module}.Locked2", () => _transporterData.Locked2, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  142. DATA.Subscribe($"{Module}.ReadyToLock1", () => _transporterData.ReadyToLock1, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  143. DATA.Subscribe($"{Module}.ReadyToLock2", () => _transporterData.ReadyToLock2, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  144. DATA.Subscribe($"{Module}.Unlocked1", () => _transporterData.Unlocked1, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  145. DATA.Subscribe($"{Module}.Unlocked2", () => _transporterData.Unlocked2, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  146. DATA.Subscribe($"{Module}.Locked", () => _transporterData.Lock, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  147. DATA.Subscribe($"{Module}.WSHoldPresent", () => _transporterData.WSHoldPresent, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  148. }
  149. /// <summary>
  150. /// 订阅变量数值发生变化
  151. /// </summary>
  152. private void SubscribeValueAction()
  153. {
  154. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", UNLOCK, UpdateVariableValue);
  155. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", LOCKED1, UpdateVariableValue);
  156. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", LOCKED2, UpdateVariableValue);
  157. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", UNLOCKED1, UpdateVariableValue);
  158. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", UNLOCKED2, UpdateVariableValue);
  159. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", IMMOBILIZE_ACTIVE, UpdateVariableValue);
  160. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", IMMOBILIZE_ACTIVE2, UpdateVariableValue);
  161. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", IMMOBILIZE_RETRACTED1, UpdateVariableValue);
  162. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", IMMOBILIZE_RETRACTED2, UpdateVariableValue);
  163. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", IMMOBILIZE_EXTEND1, UpdateVariableValue);
  164. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", IMMOBILIZE_EXTEND2, UpdateVariableValue);
  165. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", READY_TO_LOCK1, UpdateVariableValue);
  166. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", READY_TO_LOCK2, UpdateVariableValue);
  167. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", WH_PRESENT1, UpdateVariableValue);
  168. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", WH_PRESENT2, UpdateVariableValue);
  169. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", LOCK, UpdateVariableValue);
  170. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", WSHOLDPRESENT, UpdateVariableValue);
  171. }
  172. /// <summary>
  173. /// 初始化操作
  174. /// </summary>
  175. private void InitializeOperation()
  176. {
  177. OP.Subscribe($"{Module}.Lock", LockOperation);
  178. OP.Subscribe($"{Module}.Unlock", UnlockOperation);
  179. OP.Subscribe($"{Module}.Retract", RetractOperation);
  180. OP.Subscribe($"{Module}.Extend", ExtendOperation);
  181. }
  182. /// <summary>
  183. /// 更新变量数值
  184. /// </summary>
  185. /// <param name="variable"></param>
  186. /// <param name="value"></param>
  187. private void UpdateVariableValue(string variable, object value)
  188. {
  189. PropertyInfo property = TransporterData.GetType().GetProperty(variable);
  190. if (property != null)
  191. {
  192. property.SetValue(TransporterData, value);
  193. }
  194. if(TransporterData.Unlock)
  195. {
  196. _unlockDateTime = DateTime.Now;
  197. }
  198. }
  199. /// <summary>
  200. /// 初始化Routine
  201. /// </summary>
  202. private void InitializeRoutine()
  203. {
  204. _retractRoutine= new TransporterRetractRoutine(Module);
  205. _extendRoutine=new TransporterExtendRoutine(Module);
  206. }
  207. #region 指令
  208. /// <summary>
  209. /// Lock 操作
  210. /// </summary>
  211. /// <param name="cmd"></param>
  212. /// <param name="args"></param>
  213. /// <returns></returns>
  214. public bool LockOperation(string cmd, object[] args)
  215. {
  216. string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{LOCK}");
  217. if (!string.IsNullOrEmpty(ioName))
  218. {
  219. return IOModuleManager.Instance.WriteIoValue(ioName, true);
  220. }
  221. else
  222. {
  223. return false;
  224. }
  225. }
  226. /// <summary>
  227. /// Unlock 操作
  228. /// </summary>
  229. /// <param name="cmd"></param>
  230. /// <param name="args"></param>
  231. /// <returns></returns>
  232. public bool UnlockOperation(string cmd, object[] args)
  233. {
  234. string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{LOCK}");
  235. if (!string.IsNullOrEmpty(ioName))
  236. {
  237. return IOModuleManager.Instance.WriteIoValue(ioName, false);
  238. }
  239. else
  240. {
  241. return false;
  242. }
  243. }
  244. /// <summary>
  245. /// Retract 操作
  246. /// </summary>
  247. /// <param name="cmd"></param>
  248. /// <param name="args"></param>
  249. /// <returns></returns>
  250. private bool RetractOperation(string cmd , object[] args)
  251. {
  252. JetAxisBase elevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Elevator");
  253. if (elevatorAxis!=null && !elevatorAxis.CurrentStation.Contains("UP"))
  254. {
  255. LOG.WriteLog(eEvent.ERR_TRANSPORTER, Module, $"{Module}.Elevator is not in 'UP' Postion,Can not do Retract Action");
  256. return false;
  257. }
  258. return StartRoutine(TransporterCommonOperation.Retract, _retractRoutine, null);
  259. }
  260. /// <summary>
  261. /// Extend 操作
  262. /// </summary>
  263. /// <param name="cmd"></param>
  264. /// <param name="args"></param>
  265. /// <returns></returns>
  266. private bool ExtendOperation(string cmd , object[] args)
  267. {
  268. JetAxisBase elevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Elevator");
  269. if (elevatorAxis != null && !elevatorAxis.CurrentStation.Contains("UP"))
  270. {
  271. LOG.WriteLog(eEvent.ERR_TRANSPORTER, Module, $"{Module}.Elevator is not in 'UP' Postion,Can not do Extend Action");
  272. return false;
  273. }
  274. return StartRoutine(TransporterCommonOperation.Extend, _extendRoutine, null);
  275. }
  276. /// <summary>
  277. /// 启动Routine
  278. /// </summary>
  279. /// <param name="operation"></param>
  280. /// <param name="obj"></param>
  281. /// <returns></returns>
  282. private bool StartRoutine(TransporterCommonOperation operation,IRoutine routine,object obj)
  283. {
  284. if (!JudgeRunningState(operation))
  285. {
  286. _currentOperation = operation;
  287. _status = routine.Start(obj);
  288. return true;
  289. }
  290. else
  291. {
  292. return false;
  293. }
  294. }
  295. /// <summary>
  296. /// 判定运行状态
  297. /// </summary>
  298. /// <returns></returns>
  299. private bool JudgeRunningState(TransporterCommonOperation operation)
  300. {
  301. if (_status == RState.Running)
  302. {
  303. LOG.WriteLog(eEvent.ERR_TRANSPORTER,Module, $"{Module} current execute {_currentOperation},cannot {operation}");
  304. return true;
  305. }
  306. return false;
  307. }
  308. #endregion
  309. /// <summary>
  310. /// 读取条码
  311. /// </summary>
  312. /// <returns></returns>
  313. public string ReaderBarcode()
  314. {
  315. _barcodeReader = DEVICE.GetDevice<BarcodeReaderController>(_barcodeReaderName);
  316. if (_barcodeReader != null)
  317. {
  318. return _barcodeReader.ReadBarcode();
  319. }
  320. return "";
  321. }
  322. /// <summary>
  323. /// 定时器
  324. /// </summary>
  325. /// <returns></returns>
  326. public bool OnTimer()
  327. {
  328. if (_status == RState.Running)
  329. {
  330. if (_currentOperation != TransporterCommonOperation.None)
  331. {
  332. IRoutine routine = GetCurrentRoutine(_currentOperation);
  333. if (routine != null)
  334. {
  335. CheckRoutineState(routine, _currentOperation);
  336. }
  337. else
  338. {
  339. EndOperation();
  340. }
  341. }
  342. }
  343. if (SC.ContainsItem($"Transporter.{Module}.UnlockTimerLock"))
  344. {
  345. _unlockTimerLockInterval = SC.GetValue<int>($"Transporter.{Module}.UnlockTimerLock") * 1000;
  346. }
  347. if(TransporterData.Unlock)
  348. {
  349. if(DateTime.Now.Subtract(_unlockDateTime).TotalMilliseconds>=_unlockTimerLockInterval)
  350. {
  351. string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{UNLOCK}");
  352. if (!string.IsNullOrEmpty(ioName))
  353. {
  354. IOModuleManager.Instance.WriteIoValue(ioName, false);
  355. }
  356. }
  357. }
  358. return true;
  359. }
  360. /// <summary>
  361. /// 获取当前操作对应的Routine
  362. /// </summary>
  363. /// <param name="currentOperation"></param>
  364. /// <returns></returns>
  365. private IRoutine GetCurrentRoutine(TransporterCommonOperation currentOperation)
  366. {
  367. switch (currentOperation)
  368. {
  369. case TransporterCommonOperation.Retract:
  370. return _retractRoutine;
  371. case TransporterCommonOperation.Extend:
  372. return _extendRoutine;
  373. default:
  374. return null;
  375. }
  376. }
  377. /// <summary>
  378. /// 检验Routine状态
  379. /// </summary>
  380. /// <param name="routine"></param>
  381. /// <param name="currentOperation"></param>
  382. private void CheckRoutineState(IRoutine routine, TransporterCommonOperation currentOperation)
  383. {
  384. RState state = routine.Monitor();
  385. if (state == RState.End)
  386. {
  387. EndOperation();
  388. }
  389. else if (state == RState.Failed || state == RState.Timeout)
  390. {
  391. LOG.WriteLog(eEvent.ERR_TRANSPORTER, $"{Module}.{Name}", $"{currentOperation} error");
  392. EndOperation();
  393. }
  394. }
  395. /// <summary>
  396. /// 结束操作
  397. /// </summary>
  398. private void EndOperation()
  399. {
  400. _status = RState.End;
  401. _currentOperation = TransporterCommonOperation.None;
  402. }
  403. #region 设备接口
  404. public void Monitor()
  405. {
  406. }
  407. public void Reset()
  408. {
  409. }
  410. public void Terminate()
  411. {
  412. }
  413. #endregion
  414. }
  415. }