123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- using Aitex.Core.RT.IOCore;
- using Aitex.Core.Util;
- namespace MECF.Framework.Simulator.Core.IoProviders
- {
- public enum E84Stage
- {
- WaitForStation,
- IDLE,
- TD0, //when CS_0 wait for VALID
- TA1, //CS_0 and VALID wait for L_REQ(U_REQ)
- TP1, //when TA1 and TR_REQ is set
- TA2, //
- TP2,
- TP3,
- TP4,
- TA3,
- TP5
- }
-
- public class SimulatorE84
- {
- #region sequence
- /*
- * for loading sequence:
- * (1) Active set CS_0 *ON* then set VALID *ON* for valid confirm
- * A:CS_0 *ON* VALID *ON*
- * (2) Passive equipment set L_REQ *ON* if the load port is ready for loading operation / U_REQ for unload
- * A:CS_0 *ON* VALID *ON*
- * P:L_REQ *ON \\ U_REQ *ON*
- * (3) After active equipment receive the L_REQ/U_REQ *ON* set TR_REQ *ON*
- * A:TR_TRQ *ON* CS_0 *ON* VALID *ON*
- * P:L_REQ *ON \\ U_REQ *ON*
- * (4) After passive equipment turn the READY *ON*, active equipment BUSY set to *ON* and proceed handoff operation
- * A:BUSY *ON* TR_TRQ *ON* CS_0 *ON* VALID *ON*
- * P:READY *ON* L_REQ *ON \\ U_REQ *ON*
- * (5) When passive equipment turns the L_REQ(U_REQ) signal *OFF* when carrier is done processing
- * A:BUSY *ON* TR_TRQ *ON* CS_0 *ON* VALID *ON*
- * P:READY *ON*
- * (6) After finish the operation and the active equipment is out of conflict area,
- * active equipment turns the BUSY signal *OFF*(make sure after the L_REQ(R_REQ) was *OFF*)
- * A:TR_TRQ *ON* CS_0 *ON* VALID *ON*
- * P:READY *ON*
- * (7) After the BUSY *OFF*, active equipment set the TR_REQ signal *OFF*
- * A:CS_0 *ON* VALID *ON*
- * P:READY *ON*
- * (8) When finish those above, active equipment set the COMPT *ON*
- * A:COMPT *ON* CS_0 *ON* VALID *ON*
- * P:READY *ON*
- * (9) After COMPT *ON*, passive equipment should set the READY *OFF*
- * A:COMPT *ON* CS_0 *ON* VALID *ON*
- * P:
- * (10) After READY *OFF*, active set the signal all off
- * A:
- * P:
- */
-
- #endregion
- private readonly string _loadPortName;
- private PeriodicJob _thread;
- public readonly bool IsFloor;
- public bool IsLoading => Stage == E84Stage.TP2 && lReq;
- public bool IsUnLoading => Stage == E84Stage.TP2 && uReq;
- public string LoadPortName => _loadPortName;
- public bool LReq => lReq;
- public bool UReq => uReq;
- public bool Ready => ready;
- public bool HoAvbl => hoAvbl;
- public bool ES => es;
- public bool VA => va;
- public bool VS0 => vs0;
- public bool VS1 => vs1;
-
- //inputs
- private bool lReq;
- private bool uReq;
- private bool ready;
- private bool hoAvbl;
- private bool es;
- private bool va;
- private bool vs0;
- private bool vs1;
-
- private RD_TRIG _lReq = new RD_TRIG();
- private RD_TRIG _uReq = new RD_TRIG();
- private RD_TRIG _ready = new RD_TRIG();
- private RD_TRIG _hoAvbl = new RD_TRIG();
- private RD_TRIG _es = new RD_TRIG();
- private RD_TRIG _va = new RD_TRIG();
- private RD_TRIG _vs0 = new RD_TRIG();
- private RD_TRIG _vs1 = new RD_TRIG();
-
- //outputs
- public bool ON => IO.DI[$"DI_{_loadPortName}_ON"].Value;
- public bool VALID => IO.DI[$"DI_{_loadPortName}_VALID"].Value;
- public bool CS_0 => IO.DI[$"DI_{_loadPortName}_CS_0"].Value;
- public bool TR_REQ => IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value;
- public bool BUSY => IO.DI[$"DI_{_loadPortName}_BUSY"].Value;
- public bool COMPT => IO.DI[$"DI_{_loadPortName}_COMPT"].Value;
- public bool CONT => IO.DI[$"DI_{_loadPortName}_CONT"].Value;
- public bool AM_AVBL => IO.DI[$"DI_{_loadPortName}_AM_AVBL"].Value;
-
- public E84Stage Stage;
- private readonly DeviceTimer _timerDelay = new DeviceTimer();
- public SimulatorE84(string loadPortName, bool isFloor)
- {
- _loadPortName = loadPortName;
- IsFloor = isFloor;
- _thread = new PeriodicJob(50, OnMonitor, _loadPortName, true);
- Stage = E84Stage.IDLE;
- if (isFloor)
- IO.DI[$"DI_{_loadPortName}_AM_AVBL"].Value = true;
- _thread.Start();
- }
-
- //DO_LP1_L_REQ Load Request
- //DO_LP1_U_REQ Unload Request
- //DO_LP1_READY Ready Signal
- //DO_LP1_HO_AVBL HandOff Available Always on
- //DO_LP1_ES Emergency Stop Always on
- //DO_LP1_VA Vehicle Arrive
- //DO_LP1_VS_O Carrier Stage 0
- //DO_LP1_VS_1 Carrier Stage 1
- private bool OnMonitor()
- {
- //inputs
- lReq = IO.DO[$"DO_{_loadPortName}_L_REQ"].Value;
- uReq = IO.DO[$"DO_{_loadPortName}_U_REQ"].Value;
- ready = IO.DO[$"DO_{_loadPortName}_READY"].Value;
- hoAvbl = IO.DO[$"DO_{_loadPortName}_HO_AVBL"].Value;
- es = IO.DO[$"DO_{_loadPortName}_ES"].Value;
- va = IO.DO[$"DO_{_loadPortName}_VA"].Value;
- vs0 = IO.DO[$"DO_{_loadPortName}_VS_O"].Value;
- vs1 = IO.DO[$"DO_{_loadPortName}_VS_1"].Value;
- _lReq.CLK = lReq;
- _uReq.CLK = uReq;
- _ready.CLK = ready;
- _hoAvbl.CLK = hoAvbl;
- _es.CLK = es;
- _va.CLK = va;
- _vs0.CLK = vs0;
- _vs1.CLK = vs1;
-
- //outputs
- if (IsFloor)
- {
- if (_es.T || _hoAvbl.T)
- {
- Stage = E84Stage.WaitForStation;
- IO.DI[$"DI_{_loadPortName}_CS_0"].Value = false;
- IO.DI[$"DI_{_loadPortName}_VALID"].Value = false;
- IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value = false;
- IO.DI[$"DI_{_loadPortName}_BUSY"].Value = false;
- IO.DI[$"DI_{_loadPortName}_COMPT"].Value = false;
- }
- else if (_es.R || _hoAvbl.R)
- {
- Stage = E84Stage.IDLE;
- }
-
- switch(Stage)
- {
- case E84Stage.IDLE:
- {
- if ((lReq || uReq) && (vs0 || vs1))
- Stage = E84Stage.TD0;
- break;
- }
- case E84Stage.TD0:
- {
- if (va)
- Stage = E84Stage.TA1;
- break;
- }
- case E84Stage.TA1:
- {
- IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value = true;
- Stage = E84Stage.TA2;
- break;
- }
- case E84Stage.TA2:
- {
- if (ready)
- Stage = E84Stage.TP2;
- break;
- }
- case E84Stage.TP2:
- IO.DI[$"DI_{_loadPortName}_BUSY"].Value = true;
- Stage = E84Stage.TP3;
- break;
- case E84Stage.TP3:
- {
- if (!uReq || !lReq)
- Stage = E84Stage.TP4;
- break;
- }
- case E84Stage.TP4:
- IO.DI[$"DI_{_loadPortName}_BUSY"].Value = false;
- IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value = false;
- IO.DI[$"DI_{_loadPortName}_COMPT"].Value = true;
- Stage = E84Stage.TA3;
- break;
- case E84Stage.TA3:
- {
- if (!ready)
- Stage = E84Stage.TP5;
- break;
- }
- case E84Stage.TP5:
- IO.DI[$"DI_{_loadPortName}_CS_0"].Value = false;
- IO.DI[$"DI_{_loadPortName}_VALID"].Value = false;
- IO.DI[$"DI_{_loadPortName}_COMPT"].Value = false;
- Stage = E84Stage.IDLE;
- break;
- }
- }
- else
- {
- if (_es.T || _hoAvbl.T)
- {
- Stage = E84Stage.WaitForStation;
- IO.DI[$"DI_{_loadPortName}_CS_0"].Value = false;
- IO.DI[$"DI_{_loadPortName}_VALID"].Value = false;
- IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value = false;
- IO.DI[$"DI_{_loadPortName}_BUSY"].Value = false;
- IO.DI[$"DI_{_loadPortName}_COMPT"].Value = false;
- }
- else if (_es.R || _hoAvbl.R)
- {
- Stage = E84Stage.IDLE;
- }
- switch(Stage)
- {
- case E84Stage.IDLE:
- {
- IO.DI[$"DI_{_loadPortName}_CS_0"].Value = true;
- Stage = E84Stage.TD0;
- break;
- }
- case E84Stage.TD0:
- {
- IO.DI[$"DI_{_loadPortName}_VALID"].Value = true;
- Stage = E84Stage.TA1;
- break;
- }
- case E84Stage.TA1:
- {
- if (lReq || uReq)
- Stage = E84Stage.TP1;
- break;
- }
- case E84Stage.TP1:
- IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value = true;
- Stage = E84Stage.TA2;
- break;
- case E84Stage.TA2:
- {
- if (ready)
- Stage = E84Stage.TP2;
- break;
- }
- case E84Stage.TP2:
- IO.DI[$"DI_{_loadPortName}_BUSY"].Value = true;
- Stage = E84Stage.TP3;
- break;
- case E84Stage.TP3:
- {
- if (!uReq || !lReq)
- Stage = E84Stage.TP4;
- break;
- }
- case E84Stage.TP4:
- IO.DI[$"DI_{_loadPortName}_BUSY"].Value = false;
- IO.DI[$"DI_{_loadPortName}_TR_REQ"].Value = false;
- IO.DI[$"DI_{_loadPortName}_COMPT"].Value = true;
- Stage = E84Stage.TA3;
- break;
- case E84Stage.TA3:
- {
- if (!ready)
- Stage = E84Stage.TP5;
- break;
- }
- case E84Stage.TP5:
- IO.DI[$"DI_{_loadPortName}_CS_0"].Value = false;
- IO.DI[$"DI_{_loadPortName}_VALID"].Value = false;
- IO.DI[$"DI_{_loadPortName}_COMPT"].Value = false;
- Stage = E84Stage.IDLE;
- break;
- }
- }
-
- return true;
- }
- }
- }
|