SimulatorE84.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. using Aitex.Core.RT.IOCore;
  2. using Aitex.Core.Util;
  3. namespace MECF.Framework.Simulator.Core.IoProviders
  4. {
  5. public enum E84Stage
  6. {
  7. WaitForStation,
  8. IDLE,
  9. TD0, //when CS_0 wait for VALID
  10. TA1, //CS_0 and VALID wait for L_REQ(U_REQ)
  11. TP1, //when TA1 and TR_REQ is set
  12. TA2, //
  13. TP2,
  14. TP3,
  15. TP4,
  16. TA3,
  17. TP5
  18. }
  19. public class SimulatorE84
  20. {
  21. #region sequence
  22. /*
  23. * for loading sequence:
  24. * (1) Active set CS_0 *ON* then set VALID *ON* for valid confirm
  25. * A:CS_0 *ON* VALID *ON*
  26. * (2) Passive equipment set L_REQ *ON* if the load port is ready for loading operation / U_REQ for unload
  27. * A:CS_0 *ON* VALID *ON*
  28. * P:L_REQ *ON \\ U_REQ *ON*
  29. * (3) After active equipment receive the L_REQ/U_REQ *ON* set TR_REQ *ON*
  30. * A:TR_TRQ *ON* CS_0 *ON* VALID *ON*
  31. * P:L_REQ *ON \\ U_REQ *ON*
  32. * (4) After passive equipment turn the READY *ON*, active equipment BUSY set to *ON* and proceed handoff operation
  33. * A:BUSY *ON* TR_TRQ *ON* CS_0 *ON* VALID *ON*
  34. * P:READY *ON* L_REQ *ON \\ U_REQ *ON*
  35. * (5) When passive equipment turns the L_REQ(U_REQ) signal *OFF* when carrier is done processing
  36. * A:BUSY *ON* TR_TRQ *ON* CS_0 *ON* VALID *ON*
  37. * P:READY *ON*
  38. * (6) After finish the operation and the active equipment is out of conflict area,
  39. * active equipment turns the BUSY signal *OFF*(make sure after the L_REQ(R_REQ) was *OFF*)
  40. * A:TR_TRQ *ON* CS_0 *ON* VALID *ON*
  41. * P:READY *ON*
  42. * (7) After the BUSY *OFF*, active equipment set the TR_REQ signal *OFF*
  43. * A:CS_0 *ON* VALID *ON*
  44. * P:READY *ON*
  45. * (8) When finish those above, active equipment set the COMPT *ON*
  46. * A:COMPT *ON* CS_0 *ON* VALID *ON*
  47. * P:READY *ON*
  48. * (9) After COMPT *ON*, passive equipment should set the READY *OFF*
  49. * A:COMPT *ON* CS_0 *ON* VALID *ON*
  50. * P:
  51. * (10) After READY *OFF*, active set the signal all off
  52. * A:
  53. * P:
  54. */
  55. #endregion
  56. private readonly string _loadPortName;
  57. private PeriodicJob _thread;
  58. public readonly bool IsFloor;
  59. public bool IsLoading => Stage == E84Stage.TP2 && lReq;
  60. public bool IsUnLoading => Stage == E84Stage.TP2 && uReq;
  61. public string LoadPortName => _loadPortName;
  62. public bool LReq => lReq;
  63. public bool UReq => uReq;
  64. public bool Ready => ready;
  65. public bool HoAvbl => hoAvbl;
  66. public bool ES => es;
  67. public bool VA => va;
  68. public bool VS0 => vs0;
  69. public bool VS1 => vs1;
  70. //inputs
  71. private bool lReq;
  72. private bool uReq;
  73. private bool ready;
  74. private bool hoAvbl;
  75. private bool es;
  76. private bool va;
  77. private bool vs0;
  78. private bool vs1;
  79. private RD_TRIG _lReq = new RD_TRIG();
  80. private RD_TRIG _uReq = new RD_TRIG();
  81. private RD_TRIG _ready = new RD_TRIG();
  82. private RD_TRIG _hoAvbl = new RD_TRIG();
  83. private RD_TRIG _es = new RD_TRIG();
  84. private RD_TRIG _va = new RD_TRIG();
  85. private RD_TRIG _vs0 = new RD_TRIG();
  86. private RD_TRIG _vs1 = new RD_TRIG();
  87. //outputs
  88. public bool ON => IO.DI[$"DI_{_loadPortName}_ON"].Value;
  89. public bool VALID => IO.DI[$"DI_{_loadPortName}_VALID"].Value;
  90. public bool CS_0 => IO.DI[$"DI_{_loadPortName}_CS_0"].Value;
  91. public bool TR_REQ => IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value;
  92. public bool BUSY => IO.DI[$"DI_{_loadPortName}_BUSY"].Value;
  93. public bool COMPT => IO.DI[$"DI_{_loadPortName}_COMPT"].Value;
  94. public bool CONT => IO.DI[$"DI_{_loadPortName}_CONT"].Value;
  95. public bool AM_AVBL => IO.DI[$"DI_{_loadPortName}_AM_AVBL"].Value;
  96. public E84Stage Stage;
  97. private readonly DeviceTimer _timerDelay = new DeviceTimer();
  98. public SimulatorE84(string loadPortName, bool isFloor)
  99. {
  100. _loadPortName = loadPortName;
  101. IsFloor = isFloor;
  102. _thread = new PeriodicJob(50, OnMonitor, _loadPortName, true);
  103. Stage = E84Stage.IDLE;
  104. if (isFloor)
  105. IO.DI[$"DI_{_loadPortName}_AM_AVBL"].Value = true;
  106. _thread.Start();
  107. }
  108. //DO_LP1_L_REQ Load Request
  109. //DO_LP1_U_REQ Unload Request
  110. //DO_LP1_READY Ready Signal
  111. //DO_LP1_HO_AVBL HandOff Available Always on
  112. //DO_LP1_ES Emergency Stop Always on
  113. //DO_LP1_VA Vehicle Arrive
  114. //DO_LP1_VS_O Carrier Stage 0
  115. //DO_LP1_VS_1 Carrier Stage 1
  116. private bool OnMonitor()
  117. {
  118. //inputs
  119. lReq = IO.DO[$"DO_{_loadPortName}_L_REQ"].Value;
  120. uReq = IO.DO[$"DO_{_loadPortName}_U_REQ"].Value;
  121. ready = IO.DO[$"DO_{_loadPortName}_READY"].Value;
  122. hoAvbl = IO.DO[$"DO_{_loadPortName}_HO_AVBL"].Value;
  123. es = IO.DO[$"DO_{_loadPortName}_ES"].Value;
  124. va = IO.DO[$"DO_{_loadPortName}_VA"].Value;
  125. vs0 = IO.DO[$"DO_{_loadPortName}_VS_O"].Value;
  126. vs1 = IO.DO[$"DO_{_loadPortName}_VS_1"].Value;
  127. _lReq.CLK = lReq;
  128. _uReq.CLK = uReq;
  129. _ready.CLK = ready;
  130. _hoAvbl.CLK = hoAvbl;
  131. _es.CLK = es;
  132. _va.CLK = va;
  133. _vs0.CLK = vs0;
  134. _vs1.CLK = vs1;
  135. //outputs
  136. if (IsFloor)
  137. {
  138. if (_es.T || _hoAvbl.T)
  139. {
  140. Stage = E84Stage.WaitForStation;
  141. IO.DI[$"DI_{_loadPortName}_CS_0"].Value = false;
  142. IO.DI[$"DI_{_loadPortName}_VALID"].Value = false;
  143. IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value = false;
  144. IO.DI[$"DI_{_loadPortName}_BUSY"].Value = false;
  145. IO.DI[$"DI_{_loadPortName}_COMPT"].Value = false;
  146. }
  147. else if (_es.R || _hoAvbl.R)
  148. {
  149. Stage = E84Stage.IDLE;
  150. }
  151. switch(Stage)
  152. {
  153. case E84Stage.IDLE:
  154. {
  155. if ((lReq || uReq) && (vs0 || vs1))
  156. Stage = E84Stage.TD0;
  157. break;
  158. }
  159. case E84Stage.TD0:
  160. {
  161. if (va)
  162. Stage = E84Stage.TA1;
  163. break;
  164. }
  165. case E84Stage.TA1:
  166. {
  167. IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value = true;
  168. Stage = E84Stage.TA2;
  169. break;
  170. }
  171. case E84Stage.TA2:
  172. {
  173. if (ready)
  174. Stage = E84Stage.TP2;
  175. break;
  176. }
  177. case E84Stage.TP2:
  178. IO.DI[$"DI_{_loadPortName}_BUSY"].Value = true;
  179. Stage = E84Stage.TP3;
  180. break;
  181. case E84Stage.TP3:
  182. {
  183. if (!uReq || !lReq)
  184. Stage = E84Stage.TP4;
  185. break;
  186. }
  187. case E84Stage.TP4:
  188. IO.DI[$"DI_{_loadPortName}_BUSY"].Value = false;
  189. IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value = false;
  190. IO.DI[$"DI_{_loadPortName}_COMPT"].Value = true;
  191. Stage = E84Stage.TA3;
  192. break;
  193. case E84Stage.TA3:
  194. {
  195. if (!ready)
  196. Stage = E84Stage.TP5;
  197. break;
  198. }
  199. case E84Stage.TP5:
  200. IO.DI[$"DI_{_loadPortName}_CS_0"].Value = false;
  201. IO.DI[$"DI_{_loadPortName}_VALID"].Value = false;
  202. IO.DI[$"DI_{_loadPortName}_COMPT"].Value = false;
  203. Stage = E84Stage.IDLE;
  204. break;
  205. }
  206. }
  207. else
  208. {
  209. if (_es.T || _hoAvbl.T)
  210. {
  211. Stage = E84Stage.WaitForStation;
  212. IO.DI[$"DI_{_loadPortName}_CS_0"].Value = false;
  213. IO.DI[$"DI_{_loadPortName}_VALID"].Value = false;
  214. IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value = false;
  215. IO.DI[$"DI_{_loadPortName}_BUSY"].Value = false;
  216. IO.DI[$"DI_{_loadPortName}_COMPT"].Value = false;
  217. }
  218. else if (_es.R || _hoAvbl.R)
  219. {
  220. Stage = E84Stage.IDLE;
  221. }
  222. switch(Stage)
  223. {
  224. case E84Stage.IDLE:
  225. {
  226. IO.DI[$"DI_{_loadPortName}_CS_0"].Value = true;
  227. Stage = E84Stage.TD0;
  228. break;
  229. }
  230. case E84Stage.TD0:
  231. {
  232. IO.DI[$"DI_{_loadPortName}_VALID"].Value = true;
  233. Stage = E84Stage.TA1;
  234. break;
  235. }
  236. case E84Stage.TA1:
  237. {
  238. if (lReq || uReq)
  239. Stage = E84Stage.TP1;
  240. break;
  241. }
  242. case E84Stage.TP1:
  243. IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value = true;
  244. Stage = E84Stage.TA2;
  245. break;
  246. case E84Stage.TA2:
  247. {
  248. if (ready)
  249. Stage = E84Stage.TP2;
  250. break;
  251. }
  252. case E84Stage.TP2:
  253. IO.DI[$"DI_{_loadPortName}_BUSY"].Value = true;
  254. Stage = E84Stage.TP3;
  255. break;
  256. case E84Stage.TP3:
  257. {
  258. if (!uReq || !lReq)
  259. Stage = E84Stage.TP4;
  260. break;
  261. }
  262. case E84Stage.TP4:
  263. IO.DI[$"DI_{_loadPortName}_BUSY"].Value = false;
  264. IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value = false;
  265. IO.DI[$"DI_{_loadPortName}_COMPT"].Value = true;
  266. Stage = E84Stage.TA3;
  267. break;
  268. case E84Stage.TA3:
  269. {
  270. if (!ready)
  271. Stage = E84Stage.TP5;
  272. break;
  273. }
  274. case E84Stage.TP5:
  275. IO.DI[$"DI_{_loadPortName}_CS_0"].Value = false;
  276. IO.DI[$"DI_{_loadPortName}_VALID"].Value = false;
  277. IO.DI[$"DI_{_loadPortName}_COMPT"].Value = false;
  278. Stage = E84Stage.IDLE;
  279. break;
  280. }
  281. }
  282. return true;
  283. }
  284. }
  285. }