123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908 |
- using Aitex.Core.Common;
- using Aitex.Core.RT.Device.Unit;
- using Aitex.Core.RT.Event;
- using Aitex.Core.RT.Log;
- using Aitex.Core.RT.Routine;
- using Aitex.Core.RT.SCCore;
- using Aitex.Core.Util;
- using Aitex.Sorter.Common;
- using Brooks.WinSECS;
- using MECF.Framework.Common.Communications;
- using MECF.Framework.Common.Equipment;
- using MECF.Framework.Common.SubstrateTrackings;
- using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
- using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase;
- using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.SMIFs.Brooks;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.SMIF
- {
- public class BrooksSmifPort : LoadPortBaseDevice, IConnection
- {
- public WinSECS wshost { get; set; }
- public BrooksSMIFHostAgent ha { get; set; }
- protected bool _isLoaded;
- protected bool _isUnloaded;
- public bool IsActionComplete { get; set; }
- public override bool IsLoaded => _isLoaded;
- public bool IsAutoMode { get; set; }
- public bool IsPioInterlockOn { get; set; }
- public bool IsPodPresent { get; set; }
- public bool IsOpStatusReady { get; set; }
- public LastFunctionEnum LastFunctionDone { get; set; }
- public PortStateEnum CurrentPortStatus { get; set; }
- public bool IsLiftAtOverTravelLimit { get; set; }
- public bool IsLiftAtUpLimit { get; set; }
- public bool IsLiftAtStagePosition { get; set; }
- public WaferSeaterStateEnum CurrentWaferSeaterStatus { get; set; }
- public bool IsNormalModeNotServiceMode { get; set; }
- public int PortLifterSlotPosition { get; set; }
- public bool IsArmRetract { get; set; }
- public bool IsAlarm { get; set; }
- public bool IsDisableEvenSlot
- {
- get
- {
- if (SC.ContainsItem($"CarrierInfo.Carrier{InfoPadCarrierIndex}.DisableEvenSlot"))
- return SC.GetValue<bool>($"CarrierInfo.Carrier{InfoPadCarrierIndex}.DisableEvenSlot");
- return false;
- }
- }
- public bool IsDisableOddSlot
- {
- get
- {
- if (SC.ContainsItem($"CarrierInfo.Carrier{InfoPadCarrierIndex}.DisableOddSlot"))
- return SC.GetValue<bool>($"CarrierInfo.Carrier{InfoPadCarrierIndex}.DisableOddSlot");
- return false;
- }
- }
- public bool IsConnected { get; set; }
- // public override bool IsLoad { get; set; }
- private R_TRIG _trigError = new R_TRIG();
- private R_TRIG _trigCommunicationError = new R_TRIG();
- private R_TRIG _trigRetryConnect = new R_TRIG();
- private DeviceTimer _reConnectdTimer = new DeviceTimer();
- private PeriodicJob _thread;
- protected object _locker = new object();
- private bool _enableLog;
- private string _errorCode = "";
- private DeviceTimer _setStatusTimer = new DeviceTimer();
- private int SetStatusTime = 800;
- private DateTime _dtStartAction;
- private string _scRoot;
- public WaferSize DefaultWaferSize = WaferSize.WS8;
- public override WaferSize GetCurrentWaferSize()
- {
- return DefaultWaferSize;
- }
- public override LoadportCassetteState CassetteState
- {
- get
- {
- if (IsPodPresent)
- return LoadportCassetteState.Normal;
- return LoadportCassetteState.Absent;
- }
- }
- public string Address { get; private set; }
- public BrooksSmifPort(string module, string name, string scRoot, RobotBaseDevice robot, bool mapbyLp = true,int slotsCount = 25) : base(module, name, robot,null,slotsCount)
- {
- Module = module;
- Name = name;
- _scRoot = scRoot;
- string commPort = SC.GetStringValue($"LoadPort.{Name}.PortName");
- if (!Enum.TryParse(name, out ModuleName m))
- Enum.TryParse(module, out m);
- //Instantiate the WinSecs objects for the Host
- wshost = new WinSECS();
- //Set the PortType for RS232 communication
- wshost.PortType = SECS_PORT_TYPE.SECS1_SERIAL;
- //Properties that apply to all port types
- wshost.AutoDevice = true;
- wshost.DefaultDeviceID = 0;
- wshost.Secs1.IgnoreSytemBytes = false;
- wshost.MultipleOpen = true;
- wshost.MonitorEnabled = true;
- //Properties that apply to all SECS1 port types, which includes RS232
- wshost.Secs1.AcceptDupBlock = false;
- wshost.Secs1.Interleave = true;
- wshost.Secs1.RetryCount = 10;
- wshost.Secs1.SecsHost = true;
- wshost.Secs1.T1 = 1;
- wshost.Secs1.T2 = 10;
- wshost.Secs1.T3 = 30;
- wshost.Secs1.T4 = 45;
- wshost.Secs1.AutoBaud = false;
- wshost.Secs1.PortName = commPort;
- wshost.Secs1.BaudRate = 9600;
- //Set up the agents that deals with the SECS messages
- ha = new BrooksSMIFHostAgent(wshost, this);
- wshost.OpenPort(ha);
- if (wshost.PortIsOpen)
- {
- IsConnected = true;
- }
- ConnectionManager.Instance.Subscribe($"{Name}", this);
- IsMapWaferByLoadPort = mapbyLp;
- }
- public void OnErrorArrived(string alarmcode, string alarmdecri, string alarmtext)
- {
- if (alarmcode == "5")
- {
- if (_ErrorDict.ContainsKey(alarmdecri))
- EV.PostWarningLog(Name, $"AlarmID:({alarmdecri}){_ErrorDict[alarmdecri]},AlarmText{alarmtext}");
- OnError();
- }
- if (alarmcode == "6")
- {
- if (_ErrorDict.ContainsKey(alarmdecri))
- EV.PostAlarmLog(Name, $"AlarmID:({alarmdecri}){_ErrorDict[alarmdecri]},AlarmText{alarmtext}");
- OnError();
- }
- }
- public void OnStausArrived(object[] datas)
- {
- try
- {
- string templog = "";
- foreach (var data in datas)
- templog += data.ToString() + " ";
- LOG.Write($"{LPModuleName} received data message:{templog}");
- IsPioInterlockOn = datas[0].ToString() == "1";
- IsPodPresent = datas[1].ToString() == "1";
- if (IsPodPresent)
- {
- OnCarrierPresent();
- OnCarrierPlaced();
- }
- else
- {
- OnCarrierNotPresent();
- OnCarrierNotPlaced();
- }
- IsOpStatusReady = datas[2].ToString() == "1";
- IsHomed = datas[3].ToString() == "1";
- LastFunctionDone = (LastFunctionEnum)Convert.ToInt32(datas[4]);
- CurrentPortStatus = (PortStateEnum)Convert.ToInt32(datas[5]);
- IsLiftAtOverTravelLimit = datas[6].ToString() == "1";
- IsLiftAtUpLimit = datas[7].ToString() == "1";
- IsLiftAtStagePosition = datas[8].ToString() == "1";
- CurrentWaferSeaterStatus = (WaferSeaterStateEnum)Convert.ToInt32(datas[9]);
- IsNormalModeNotServiceMode = datas[10].ToString() == "1";
- PortLifterSlotPosition = Convert.ToInt32(datas[11]);
- }
- catch (Exception ex)
- {
- LOG.Write(ex);
- }
- }
- internal void OnEventArrived(string eventID)
- {
- EV.PostInfoLog("LoadPort", $"{LPModuleName} received event,CEID:{eventID}");
- if (int.TryParse(eventID, out int index))
- {
- BrooksSMIFEventEnum eventname = (BrooksSMIFEventEnum)index;
- switch (eventname)
- {
- case BrooksSMIFEventEnum.AutoMode:
- IsAutoMode = true;
- break;
- case BrooksSMIFEventEnum.ManualMode:
- IsAutoMode = false;
- break;
- case BrooksSMIFEventEnum.PodArrived:
- IsPodPresent = true;
- OnCarrierPresent();
- OnCarrierPlaced();
- _isLoaded = false;
- break;
- case BrooksSMIFEventEnum.PodRemoved:
- IsPodPresent = false;
- OnCarrierNotPresent();
- OnCarrierNotPlaced();
- break;
- case BrooksSMIFEventEnum.ReachStage:
- DockState = FoupDockState.Docked;
- _isLoaded = true;
- DoorState = FoupDoorState.Open;
- EV.PostInfoLog("LoadPort", $"{LPModuleName} complete load");
- break;
- case BrooksSMIFEventEnum.BeginLoad:
- EV.PostInfoLog("LoadPort", $"{LPModuleName} start to load");
- break;
- case BrooksSMIFEventEnum.CompleteLoad:
- DockState = FoupDockState.Docked;
- _isLoaded = true;
- DoorState = FoupDoorState.Open;
- EV.PostInfoLog("LoadPort", $"{LPModuleName} complete load");
- break;
- case BrooksSMIFEventEnum.AbortLoad:
- OnError("LoadAborted");
- break;
- case BrooksSMIFEventEnum.BeginUnload:
- EV.PostInfoLog("LoadPort", $"{LPModuleName} start to unload");
- break;
- case BrooksSMIFEventEnum.CompleteUnload:
- DockState = FoupDockState.Undocked;
- _isUnloaded = true;
- DoorState = FoupDoorState.Close;
- _isLoaded = false;
- break;
- case BrooksSMIFEventEnum.AbortUnload:
- OnError("UnloadAborted");
- break;
- case BrooksSMIFEventEnum.BeginHome:
- EV.PostInfoLog("LoadPort", $"{LPModuleName} start to home");
- break;
- case BrooksSMIFEventEnum.ReachHome:
- _isLoaded = false;
- _isUnloaded = true;
- DoorState = FoupDoorState.Close;
- DockState = FoupDockState.Undocked;
- IsHomed = true;
- break;
- case BrooksSMIFEventEnum.AbortHome:
- OnError("HomeAborted");
- break;
- }
- }
- lock (_locker)
- {
- SECSTransactionBuilder.BuildS1F5(0).Send(wshost);
- }
- }
- internal void OnTagFileWriteComplete()
- {
- IsWriteSmartTagComplete = true;
- }
- public void OnTagFileRead(string strTag)
- {
- CurrentReadSmartTagFileText = strTag;
- IsReadSmartTagFileBack = true;
- }
- private static Dictionary<string, string> _ErrorDict = new Dictionary<string, string>()
- {
- {"1","Move to Stage" },
- {"2","Return Home" },
- {"8","Wafer Map" },
- {"32","Port lock or unlock" },
- {"34","Move to a specified position" },
- {"37","Others" },
- {"38","X Move (shuttle failure)" },
- };
- private static Dictionary<string, string> _RealyMessageDict = new Dictionary<string, string>()
- {
- {"OK","Comment accepted" },
- {"BUSY","Command rejected, LPI is busy" },
- {"ALARM","Command rejected, LPI in alarm state" },
- {"NO_POD","Command rejected, Pod not on LPI" },
- {"NOT_READY","Command rejected, Host interlock not enabled" },
- {"INVALID_ARG","Command rejected, at least one invalid parameter" },
- {"CANNOT_PERFORM","LPI not in the proper state to perform the Host command" },
- {"DENIED","Command rejected for other reason" },
- };
- private static Dictionary<string, string> _AlarmTimeCodeDict = new Dictionary<string, string>()
- {
- {"00","No alarm" },
- {"41","Alarm occurred during a fetch or open operation" },
- {"42","Alarm occurred during a cassette placement on the process tool" },
- {"43","Alarm occurred during a returning of the minienvironment to Home" },
- {"44","Alarm occurred during a retrieval of the cassette from the Tool" },
- {"45","Alarm occurred during a placement of the cassette on the Pod door" },
- {"46","Non-recoverable fatal error" }
- };
- private static Dictionary<string, string> _ErrorCodeDict = new Dictionary<string, string>()
- {
- {"00","No error" },
- {"01","Position following error" },
- {"02","LPI not Home" },
- {"03","LPI busy" },
- {"04","Pod removed/missing elevator door" },
- {"05","Aborted by user" },
- {"07","Protrusion sensor failure" },
- {"08","Slot sensor failure" },
- {"09","Wafer presence sensor failure" },
- {"10","Flash sensor failure" },
- {"11","Elevator over-travel limit trip" },
- {"13","Excessive wafer protrusion" },
- {"14","System internal time-out" },
- {"15","Servo command error" },
- {"16","Pod door open time-out" },
- {"17","Pod door close time-out" },
- {"18","Pod hold-down open time-out" },
- {"19","Pod hold-down close time-out" },
- {"20","Wafer seater failed to move toward wafer" },
- {"21","Wafer seater failed to return to Home" },
- {"22","Elevator failed to reach target position" },
- {"24","System error" },
- {"27","Loss of configuration data" },
- {"28","Cassette not present" },
- {"29","Loss of air flow" },
- {"31","Gripper open time out" },
- {"32","Gripper close time out" },
- {"33","Interprocessor communication error" },
- {"34","Gripper overtravel" },
- {"35","Cassette found during unload" },
- };
- internal void OnAlarmArrived(string alarmData)
- {
- EV.PostAlarmLog(Name, $"alarmdata:{alarmData}");
- if (alarmData.Length != 4)
- return;
- string alarmTimeCode = alarmData.Substring(0, 2);
- string alarmInfoCode = alarmData.Substring(2, 2);
- AlarmOccurTime = alarmTimeCode + "=" + _AlarmTimeCodeDict[alarmTimeCode];
- AlarmInfo = alarmInfoCode + "=" + _ErrorCodeDict[alarmInfoCode];
- EV.PostAlarmLog(Module, $"{Module} {AlarmOccurTime}, for {AlarmInfo}");
- OnError();
- IsAlarm = true;
- }
- public override void Reset()
- {
- _trigError.RST = true;
- _trigCommunicationError.RST = true;
- _trigRetryConnect.RST = true;
- }
- protected override bool fStartReset(object[] param)
- {
- lock (_locker)
- {
- SECSTransactionBuilder.BuildS2F41((int)BrooksSMIFRCMDEnum.Reset).Send(wshost);
- SECSTransactionBuilder.BuildS1F5(0).Send(wshost);
- }
- return true;
- }
- protected override bool fMonitorReset(object[] param)
- {
- IsBusy = false;
- return true;
- }
- #region Command Functions
- protected override bool fStartInit(object[] param)
- {
- IsHomed = false;
- lock (_locker)
- {
- SECSTransactionBuilder.BuildS1F5(0).Send(wshost);
- SECSTransactionBuilder.BuildS2F41((int)BrooksSMIFRCMDEnum.GoHome).Send(wshost);
- }
- _dtStartAction = DateTime.Now;
- return true;
- }
- protected override bool fMonitorInit(object[] param)
- {
- IsBusy = false;
- if (DateTime.Now - _dtStartAction > TimeSpan.FromSeconds(TimelimitHome))
- {
- OnError("InitTimeout");
- return true;
- }
- return IsHomed;
- }
- protected override bool fStartLoad(object[] objs)
- {
- ResetRoutine();
- return true;
- }
- protected override bool fMonitorLoad(object[] param)
- {
- IsBusy = false;
- LoadCassette((int)LpStepEnum.Step1, TimelimitAction, OnError);
- if (ExecuteResult.Item1)
- {
- return false;
- }
- if (IsMapWaferByLoadPort)
- {
- QueryMap((int)LpStepEnum.Step2, TimelimitAction, OnError);
- if (ExecuteResult.Item1)
- {
- return false;
- }
- }
- IsBusy = false;
- return true;
- }
- protected override bool fStartExecute(object[] param)
- {
- try
- {
- IsActionComplete = false;
- switch (param[0].ToString())
- {
- case "Unclamp":
- lock (_locker)
- {
- SECSTransactionBuilder.BuildS2F41((int)BrooksSMIFRCMDEnum.HostToUnlockPort).Send(wshost);
- }
- break;
- case "Clamp":
- lock (_locker)
- {
- SECSTransactionBuilder.BuildS2F41((int)BrooksSMIFRCMDEnum.HostToLockPort).Send(wshost);
- }
- break;
- case "MapWafer":
- lock (_locker)
- {
- if (!IsMapWaferByLoadPort)
- {
- if (MapRobot != null)
- return MapRobot.WaferMapping(LPModuleName, out _);
- return false;
- }
- }
- break;
- }
- _dtStartAction = DateTime.Now;
- return true;
- }
- catch (Exception ex)
- {
- LOG.Write(ex);
- EV.PostAlarmLog(Name, $"Parameter invalid");
- return false;
- }
- }
- protected override bool fMonitorExecuting(object[] param)
- {
- IsBusy = false;
- if (DateTime.Now - _dtStartAction > TimeSpan.FromSeconds(TimelimitHome))
- {
- OnError("InitTimeout");
- return true;
- }
- switch (CurrentParamter[0].ToString())
- {
- case "Unclamp":
- return CurrentPortStatus == PortStateEnum.Unlock;
- case "Clamp":
- return CurrentPortStatus == PortStateEnum.Lock;
- case "MapWafer":
- break;
- default:
- return true;
- }
- return false;
- }
- public override bool Stop(out string reason)
- {
- lock (_locker)
- {
- SECSTransactionBuilder.BuildS2F41((int)BrooksSMIFRCMDEnum.EmergencyStop).Send(wshost);
- }
- return base.Stop(out reason);
- }
- public bool QueryMapStatus(out string reason)
- {
- //IsBusy = true;
- reason = string.Empty;
- lock (_locker)
- {
- SECSTransactionBuilder.BuildS1F5(2).Send(wshost);
- }
- if (!_setStatusTimer.IsIdle())
- _setStatusTimer.Stop();
- _setStatusTimer.Start(0);
- return true;
- }
- public bool QueryPortStatus(out string reason)
- {
- reason = string.Empty;
- lock (_locker)
- {
- SECSTransactionBuilder.BuildS1F5(0).Send(wshost);
- }
- //IsIdle = false;
- if (!_setStatusTimer.IsIdle())
- _setStatusTimer.Stop();
- _setStatusTimer.Start(0);
- return true;
- }
- protected override bool fStartUnload(object[] param)
- {
- lock (_locker)
- {
- _isUnloaded = false;
- //SECSTransactionBuilder.BuildS2F41((int)BrooksSMIFRCMDEnum.EnableUnload).Send(wshost);
- //Thread.Sleep(500);
- SECSTransactionBuilder.BuildS2F41((int)BrooksSMIFRCMDEnum.GoHome).Send(wshost);
- }
- _isUnloaded = false;
- _dtStartAction = DateTime.Now;
- return true;
- }
- protected override bool fMonitorUnload(object[] param)
- {
- IsBusy = false;
- if (DateTime.Now - _dtStartAction > TimeSpan.FromSeconds(TimelimitAction))
- {
- OnError("UnloadTimeout");
- EV.Notify(AlarmLoadPortUnloadTimeOut);
- return true;
- }
- if (_isUnloaded)
- {
- OnUnloaded();
- return true;
- }
- return false;
- }
- public void OnCarrierNotPlaced()
- {
- _isPlaced = false;
- ConfirmRemoveCarrier();
- }
- public void OnCarrierNotPresent()
- {
- _isPresent = false;
- //ConfirmRemoveCarrier();
- }
- public void OnCarrierPlaced()
- {
- _isPlaced = true;
- ConfirmAddCarrier();
- }
- public void OnCarrierPresent()
- {
- _isPresent = true;
- //ConfirmAddCarrier();
- }
- public override void OnSlotMapRead(string slotMap)
- {
- MapError = false;
- CurrentSlotMapResult = slotMap;
- for (int i = 0; i < slotMap.Length; i++)
- {
- // No wafer: "0", Wafer: "1", Crossed:"2", Undefined: "?", Overlapping wafers: "W"
- WaferInfo wafer = null;
- if (i >= SlotsCount)
- continue;
- if (IsMapWaferByLoadPort)
- {
-
- CurrentSlotMapResult = slotMap.Replace("0", "?").Replace("1", "0").Replace("2", "1");
- switch (slotMap[i])
- {
- case '2':
- WaferManager.Instance.DeleteWafer(LPModuleName, i);
- CarrierManager.Instance.UnregisterCarrierWafer(Name, i);
- break;
- case '1':
- wafer = WaferManager.Instance.CreateWafer(LPModuleName, i, WaferStatus.Normal, GetCurrentWaferSize());
- CarrierManager.Instance.RegisterCarrierWafer(Name, i, wafer);
- break;
- case '4':
- wafer = WaferManager.Instance.CreateWafer(LPModuleName, i, WaferStatus.Crossed, GetCurrentWaferSize());
- WaferManager.Instance.CheckWaferSize(LPModuleName, i, GetCurrentWaferSize());
- CarrierManager.Instance.RegisterCarrierWafer(Name, i, wafer);
- OnError($"MappingError:Slot:{i + 1} crossedwafer");
- //NotifyWaferError(Name, i, WaferStatus.Crossed);
- break;
- default:
- wafer = WaferManager.Instance.CreateWafer(LPModuleName, i, WaferStatus.Unknown, GetCurrentWaferSize());
- CarrierManager.Instance.RegisterCarrierWafer(Name, i, wafer);
- //NotifyWaferError(Name, i, WaferStatus.Unknown);
- OnError($"MappingError:Slot:{i + 1} unknowwafer");
- break;
- }
- }
- else
- {
- switch (slotMap[i])
- {
- case '0':
- WaferManager.Instance.DeleteWafer(LPModuleName, i);
- CarrierManager.Instance.UnregisterCarrierWafer(Name, i);
- break;
- case '1':
- if ((IsDisableEvenSlot && i % 2 == 1) || (IsDisableOddSlot && i % 2 == 0))
- {
- OnMapError($"Slot{i + 1}WaferOn");
- wafer = WaferManager.Instance.CreateWafer(LPModuleName, i, WaferStatus.Unknown, GetCurrentWaferSize());
- }
- else
- wafer = WaferManager.Instance.CreateWafer(LPModuleName, i, WaferStatus.Normal, GetCurrentWaferSize());
- WaferManager.Instance.CheckWaferSize(LPModuleName, i, GetCurrentWaferSize());
- CarrierManager.Instance.RegisterCarrierWafer(Name, i, wafer);
- break;
- case '?':
- if ((IsDisableEvenSlot && i % 2 == 1) || (IsDisableOddSlot && i % 2 == 0))
- {
- OnMapError($"Slot{i + 1}WaferOn");
- }
- wafer = WaferManager.Instance.CreateWafer(LPModuleName, i, WaferStatus.Crossed, GetCurrentWaferSize());
- WaferManager.Instance.CheckWaferSize(LPModuleName, i, GetCurrentWaferSize());
- CarrierManager.Instance.RegisterCarrierWafer(Name, i, wafer);
- OnMapError($"MappingError:Slot:{i + 1} crossedwafer");
- //NotifyWaferError(Name, i, WaferStatus.Crossed);
- break;
- case 'W':
- if ((IsDisableEvenSlot && i % 2 == 1) || (IsDisableOddSlot && i % 2 == 0))
- {
- OnMapError($"Slot{i + 1}WaferOn");
- }
- wafer = WaferManager.Instance.CreateWafer(LPModuleName, i, WaferStatus.Double, GetCurrentWaferSize());
- WaferManager.Instance.CheckWaferSize(LPModuleName, i, GetCurrentWaferSize());
- CarrierManager.Instance.RegisterCarrierWafer(Name, i, wafer);
- OnMapError($"MappingError:Slot:{i + 1} doublewafer");
- //NotifyWaferError(Name, i, WaferStatus.Double);
- break;
- default:
- if ((IsDisableEvenSlot && i % 2 == 1) || (IsDisableOddSlot && i % 2 == 0))
- {
- OnMapError($"Slot{i + 1}WaferOn");
- }
- wafer = WaferManager.Instance.CreateWafer(LPModuleName, i, WaferStatus.Unknown, GetCurrentWaferSize());
- WaferManager.Instance.CheckWaferSize(LPModuleName, i, GetCurrentWaferSize());
- CarrierManager.Instance.RegisterCarrierWafer(Name, i, wafer);
- OnMapError($"MappingError:Slot:{i + 1} unknowwafer");
- //NotifyWaferError(Name, i, WaferStatus.Unknown);
- break;
- }
- }
- }
- if (CurrentSlotMapResult.Contains("2"))
- {
- MapError = true;
- EV.Notify(AlarmLoadPortMapCrossedWafer);
- EV.Notify(AlarmLoadPortMappingError);
- }
- if (CurrentSlotMapResult.Contains("4"))
- {
- MapError = true;
- EV.Notify(AlarmLoadPortMapCrossedWafer);
- EV.Notify(AlarmLoadPortMappingError);
- }
- if (CurrentSlotMapResult.Contains("W"))
- {
- MapError = true;
- EV.Notify(AlarmLoadPortMapDoubleWafer);
- EV.Notify(AlarmLoadPortMappingError);
- }
- if (CurrentSlotMapResult.Contains("?"))
- {
- MapError = true;
- EV.Notify(AlarmLoadPortMapUnknownWafer);
- EV.Notify(AlarmLoadPortMappingError);
- }
- if (MapError)
- {
- Unload(out _);
- }
- SerializableDictionary<string, object> dvid = new SerializableDictionary<string, object>();
- dvid["SlotMap"] = CurrentSlotMapResult;
- dvid["PortID"] = PortID;
- dvid["PORT_CTGRY"] = SpecPortName;
- dvid["CarrierType"] = SpecCarrierType;
- dvid["CarrierIndex"] = InfoPadCarrierIndex;
- dvid["InfoPadSensorIndex"] = InfoPadSensorIndex;
- dvid["CarrierID"] = CarrierId;
- EV.Notify(EventSlotMapAvailable, dvid);
- EV.Notify(EventMapComplete, dvid);
- if (LPCallBack != null)
- LPCallBack.MappingComplete(_carrierId, CurrentSlotMapResult);
- _isMapped = true;
- }
- private void OnMapError(string errText)
- {
- EV.Notify(AlarmLoadPortError);
- EV.PostAlarmLog("LoadPort", $"{LPModuleName} occurried error:{errText} with carrier:{CarrierId ?? ""}.");
- }
- #endregion
- #region Properties
- public string AlarmOccurTime { get; private set; }
- public string AlarmInfo { get; private set; }
- #endregion
- public override void Terminate()
- {
- }
- public override void Monitor()
- {
- if (!IsConnected && ha != null && (_reConnectdTimer.IsIdle() || _reConnectdTimer.GetElapseTime() > 10000))
- {
- wshost.ClosePort();
- wshost.OpenPort(ha);
- _reConnectdTimer.Start(0);
- }
- if (IsConnected)
- {
- _reConnectdTimer.Stop();
- }
- if (!IsPlacement)
- {
- _isLoaded = false;
- }
- }
- public override bool IsEnableMapWafer(out string reason)
- {
- reason = "";
- if (!_isLoaded)
- {
- reason = "Not loaded";
- return false;
- }
- if (!IsReady())
- {
- reason = "Not Ready";
- return false;
- }
- if (_isPresent && _isPlaced && CassetteState == LoadportCassetteState.Normal)
- return true;
- reason = "No cassette";
- return false;
- }
- public override bool IsEnableTransferWafer(out string reason)
- {
- reason = "";
- if (!IsReady())
- {
- reason = "Not ready";
- return false;
- }
- if (!_isLoaded)
- {
- reason = "Not loaded";
- return false;
- }
- if (!_isMapped)
- {
- reason = "Not Mapped";
- return false;
- }
- if (CurrentSlotMapResult.Contains("2"))
- {
- reason = "Cross wafer";
- return false;
- }
- if (CurrentSlotMapResult.Contains("3"))
- {
- reason = "Double wafer";
- return false;
- }
- if (CurrentSlotMapResult.Contains("4"))
- {
- reason = "Double wafer";
- return false;
- }
- if (_isPresent && _isPlaced && CassetteState == LoadportCassetteState.Normal)
- return true;
- reason = "No cassette";
- return false;
- }
- public override bool IsEnableUnload(out string reason)
- {
- reason = "";
- return true;
- }
- public override bool IsEnableLoad(out string reason)
- {
- reason = "";
- return true;
- }
- public override bool Connect()
- {
- return true;
- }
- public bool Disconnect()
- {
- return true;
- }
- protected override bool fStartWrite(object[] param)
- {
- return true;
- }
- protected override bool fStartRead(object[] param)
- {
- return true;
- }
- public override bool ReadCarrierID()
- {
- return ReadCarrierIDByIndex(0, 16);
- }
- public override bool ReadCarrierIDByIndex(int offset = 0, int length = 16, int index = 0)
- {
- if (CIDReaders != null && CIDReaders.Length > 0 && CIDReaders[0] != null)
- {
- return base.ReadCarrierIDByIndex(offset, length, index);
- }
- ReadSmifSmartTag();
- return true;
- }
- public virtual void ReadSmifSmartTag()
- {
- SECSTransaction secsTransaction = new SECSTransaction(100, 121);
- secsTransaction.Primary.Root.Name = "S100F121";
- secsTransaction.Primary.Root.AddNew("L2a", "");
- secsTransaction.Primary.Root.Item("L2a").Format = SECS_FORMAT.U4;
- secsTransaction.Primary.Root.Item("L2a").Value = 7;
- //secsTransaction.Primary.Root.Item("L2a").Format = SECS_FORMAT.LIST;
- //secsTransaction.Primary.Root.Item("L2a").AddNew("Param1", "");
- //secsTransaction.Primary.Root.Item("L2a").Item("Param1").Format = SECS_FORMAT.U4;
- //secsTransaction.Primary.Root.Item("L2a").Item("Param1").Value = 7;
- secsTransaction.ReplyExpected = true;
- secsTransaction.Send(wshost);
- }
- public override bool GetCarrierID(int offset, int length, string tagid, out string carrierId)
- {
- carrierId = "";
- ReadSmifSmartTagFile(tagid);
- int waitCount = 0;
- while (!IsReadSmartTagFileBack)
- {
- Thread.Sleep(100);
- waitCount++;
- if (waitCount > 200)
- {
- return false;
- }
- }
- carrierId = CurrentReadSmartTagFileText;
- return true;
- }
- public bool IsReadSmartTagFileBack;
- public bool IsWriteSmartTagComplete;
- public string CurrentReadSmartTagFileText;
- public virtual void ReadSmifSmartTagFile(string file)
- {
- SECSTransaction secsTransaction = new SECSTransaction(100, 109);
- secsTransaction.Primary.Root.Name = "S100F109";
- secsTransaction.Primary.Root.AddNew("L2a", "");
- secsTransaction.Primary.Root.Item("L2a").Format = SECS_FORMAT.LIST;
- secsTransaction.Primary.Root.Item("L2a").AddNew("FileIndex");
- secsTransaction.Primary.Root.Item("L2a").Item("FileIndex").Format = SECS_FORMAT.U4;
- secsTransaction.Primary.Root.Item("L2a").Item("FileIndex").Value = 0;
- secsTransaction.Primary.Root.Item("L2a").AddNew("FileName");
- secsTransaction.Primary.Root.Item("L2a").Item("FileName").Format = SECS_FORMAT.ASCII;
- secsTransaction.Primary.Root.Item("L2a").Item("FileName").Value = file;
- secsTransaction.ReplyExpected = true;
- IsReadSmartTagFileBack = false;
- secsTransaction.Send(wshost);
- }
- public override bool WriteCarrierID(string cid, int offset, int length, string tagid, out string reason)
- {
- reason = "";
- WriteTagfile(tagid, cid);
- int waitCount = 0;
- while (true)
- {
- if (IsWriteSmartTagComplete)
- return true;
- Thread.Sleep(100);
- waitCount++;
- if (waitCount > 150)
- break;
- }
- reason = "TimeOut";
- return false;
- }
- public void WriteTagfile(string filename, string tag)
- {
- SECSTransaction secsTransaction = new SECSTransaction(100, 107);
- secsTransaction.Primary.Root.Name = "S100F107";
- secsTransaction.Primary.Root.AddNew("L2a", "");
- secsTransaction.Primary.Root.Item("L2a").Format = SECS_FORMAT.LIST;
- secsTransaction.Primary.Root.Item("L2a").AddNew("FileIndex");
- secsTransaction.Primary.Root.Item("L2a").Item("FileIndex").Format = SECS_FORMAT.U4;
- secsTransaction.Primary.Root.Item("L2a").Item("FileIndex").Value = 0;
- secsTransaction.Primary.Root.Item("L2a").AddNew("FileIndex1");
- secsTransaction.Primary.Root.Item("L2a").Item("FileIndex1").Format = SECS_FORMAT.U1;
- secsTransaction.Primary.Root.Item("L2a").Item("FileIndex1").Value = 1;
- secsTransaction.Primary.Root.Item("L2a").AddNew("FileName");
- secsTransaction.Primary.Root.Item("L2a").Item("FileName").Format = SECS_FORMAT.ASCII;
- secsTransaction.Primary.Root.Item("L2a").Item("FileName").Value = filename;
- secsTransaction.Primary.Root.Item("L2a").AddNew("Parameter1");
- secsTransaction.Primary.Root.Item("L2a").Item("Parameter1").Format = SECS_FORMAT.ASCII;
- secsTransaction.Primary.Root.Item("L2a").Item("Parameter1").Value = "";
- secsTransaction.Primary.Root.Item("L2a").AddNew("Tagcontent");
- secsTransaction.Primary.Root.Item("L2a").Item("Tagcontent").Format = SECS_FORMAT.ASCII;
- secsTransaction.Primary.Root.Item("L2a").Item("Tagcontent").Value = tag;
- secsTransaction.ReplyExpected = true;
- IsWriteSmartTagComplete = false;
- secsTransaction.Send(wshost);
- }
- public void LoadCassette(int id, int time, Action<string> error)
- {
- var ret = ExecuteAndWait(id, () =>
- {
- EV.PostInfoLog("System", $"{MapRobot.RobotModuleName} start loading");
- var reason = string.Empty;
- lock (_locker)
- {
- SECSTransactionBuilder.BuildS2F41((int)BrooksSMIFRCMDEnum.EnableLoad).Send(wshost);
- Thread.Sleep(500);
- SECSTransactionBuilder.BuildS2F41((int)BrooksSMIFRCMDEnum.GotoStagePosition).Send(wshost);
- SECSTransactionBuilder.BuildS1F5(0).Send(wshost);
- }
- _isLoaded = false;
- _isMapped = false;
- return true;
- }, () =>
- {
- if (_isLoaded)
- return Result.DONE;
- return Result.RUN;
- }, time * 1000);
- if (ret.Item1)
- {
- if (ret.Item2 == Result.FAIL)
- {
- error("load failed");
- EV.Notify(AlarmLoadPortLoadTimeOut);
- }
- if (ret.Item2 == Result.TIMEOUT) //timeout
- {
- error("load timeout");
- EV.Notify(AlarmLoadPortLoadTimeOut);
- }
- }
- }
- protected void QueryMap(int id, int time, Action<string> error)
- {
- var ret = ExecuteAndWait(id, () =>
- {
- EV.PostInfoLog("System", $"{MapRobot.RobotModuleName} start to query map");
- var reason = string.Empty;
- _isMapped = false;
- lock (_locker)
- {
- SECSTransactionBuilder.BuildS1F5(2).Send(wshost);
- }
- return true;
- }, () =>
- {
- if (_isMapped)
- return Result.DONE;
- return Result.RUN;
- }, time * 1000);
- if (ret.Item1)
- {
- if (ret.Item2 == Result.FAIL)
- error("map failed");
- if (ret.Item2 == Result.TIMEOUT) //timeout
- {
- error("map timeout");
- }
- }
- }
- protected void SetDoValue(int id, IoTrigger dotrig, bool bValue)
- {
- var ret = Execute(id, () =>
- {
- EV.PostInfoLog("LoadPort", $"{LPModuleName} start to set {dotrig.Name} start to {bValue}");
- dotrig.SetTrigger(bValue, out _);
- return true;
- });
- }
- public void WaitDiValue(int id, int time, IoSensor disensor, bool bvalue, Action<string> error)
- {
- var ret = ExecuteAndWait(id, () =>
- {
- EV.PostInfoLog("System", $"Wait {disensor.Name} to be {bvalue}");
- return true;
- }, () =>
- {
- if (disensor.Value == bvalue)
- return Result.DONE;
- return Result.RUN;
- }, time * 1000);
- if (ret.Item1)
- {
- if (ret.Item2 == Result.FAIL)
- {
- error($"Wait {disensor.Name} to be {bvalue} failed");
- }
- if (ret.Item2 == Result.TIMEOUT) //timeout
- {
- error($"Wait {disensor.Name} to be {bvalue} timeout");
- }
- }
- }
- public enum LpStepEnum
- {
- Step1,
- Step2,
- Step3,
- Step4,
- Step5,
- Step6,
- Step7,
- Step8,
- Step9,
- Step10,
- Step11,
- Step12,
- }
- protected DeviceTimer counter = new DeviceTimer();
- protected DeviceTimer delayTimer = new DeviceTimer();
- private enum STATE
- {
- IDLE,
- WAIT,
- }
- public int TokenId
- {
- get { return _id; }
- }
- private int _id; //step index
- private int _currentTokenId = -1;
- /// <summary>
- /// already done steps
- /// </summary>
- private Stack<int> _steps = new Stack<int>();
- private STATE state; //step state //idel,wait,
- //loop control
- private int loop = 0;
- private int loopCount = 0;
- private int loopID = 0;
- private DeviceTimer timer = new DeviceTimer();
- public int LoopCounter { get { return loop; } }
- public int LoopTotalTime { get { return loopCount; } }
- // public int Timeout { get { return (int)(timer.GetTotalTime() / 1000); } }
- //状态持续时间,单位为秒
- public int Elapsed { get { return (int)(timer.GetElapseTime() / 1000); } }
- protected RoutineResult RoutineToken = new RoutineResult() { Result = RoutineState.Running };
- protected Tuple<bool, Result> ExecuteResult;
- public void ResetRoutine()
- {
- _id = 0;
- _steps.Clear();
- loop = 0;
- loopCount = 0;
- state = STATE.IDLE;
- counter.Start(60 * 60 * 100); //默认1小时
- RoutineToken.Result = RoutineState.Running;
- _currentTokenId = -1;
- ExecuteResult = Tuple.Create(false, Result.DONE);
- }
- protected void PerformRoutineStep(int id, Func<RoutineState> execution, RoutineResult result)
- {
- if (!Acitve(id))
- return;
- result.Result = execution();
- }
- #region interface
- public void StopLoop()
- {
- loop = loopCount;
- }
- public Tuple<bool, Result> Loop<T>(T id, Func<bool> func, int count)
- {
- int idx = Convert.ToInt32(id);
- bool bActive = Acitve(idx);
- if (bActive)
- {
- if (!func())
- {
- return Tuple.Create(bActive, Result.FAIL); //执行错误
- }
- loopID = idx;
- loopCount = count;
- next();
- return Tuple.Create(true, Result.RUN);
- }
- return Tuple.Create(false, Result.RUN);
- }
- public Tuple<bool, Result> EndLoop<T>(T id, Func<bool> func)
- {
- int idx = Convert.ToInt32(id);
- bool bActive = Acitve(idx);
- if (bActive)
- {
- if (++loop >= loopCount) //Loop 结束
- {
- if (!func())
- {
- return Tuple.Create(bActive, Result.FAIL); //执行错误
- }
- loop = 0;
- loopCount = 0; // Loop 结束时,当前loop和loop总数都清零
- next();
- return Tuple.Create(true, Result.RUN);
- }
- //继续下一LOOP
- next(loopID);
- return Tuple.Create(true, Result.RUN);
- }
- return Tuple.Create(false, Result.RUN);
- }
- public Tuple<bool, Result> ExecuteAndWait<T>(T id, IRoutine routine)
- {
- int idx = Convert.ToInt32(id);
- bool bActive = Acitve(idx);
- if (bActive)
- {
- if (state == STATE.IDLE)
- {
- Result startRet = routine.Start();
- if (startRet == Result.FAIL)
- {
- return Tuple.Create(true, Result.FAIL); //执行错误
- }
- else if (startRet == Result.DONE)
- {
- next();
- return Tuple.Create(true, Result.DONE);
- }
- state = STATE.WAIT;
- }
- Result ret = routine.Monitor();
- if (ret == Result.DONE)
- {
- next();
- return Tuple.Create(true, Result.DONE);
- }
- else if (ret == Result.FAIL || ret == Result.TIMEOUT)
- {
- return Tuple.Create(true, Result.FAIL);
- }
- else
- {
- return Tuple.Create(true, Result.RUN);
- }
- }
- return Tuple.Create(false, Result.RUN);
- }
- public Tuple<bool, Result> ExecuteAndWait<T>(T id, List<IRoutine> routines)
- {
- int idx = Convert.ToInt32(id);
- bool bActive = Acitve(idx);
- if (bActive)
- {
- if (state == STATE.IDLE)
- {
- foreach (var item in routines)
- {
- if (item.Start() == Result.FAIL)
- return Tuple.Create(true, Result.FAIL);
- }
- state = STATE.WAIT;
- }
- //wait all sub failed or completedboo
- bool bFail = false;
- bool bDone = true;
- foreach (var item in routines)
- {
- Result ret = item.Monitor();
- bDone &= (ret == Result.FAIL || ret == Result.DONE);
- bFail |= ret == Result.FAIL;
- }
- if (bDone)
- {
- next();
- if (bFail)
- return Tuple.Create(true, Result.FAIL);
- return Tuple.Create(true, Result.DONE);
- }
- return Tuple.Create(true, Result.RUN);
- }
- return Tuple.Create(false, Result.RUN);
- }
- public Tuple<bool, Result> Check<T>(T id, Func<bool> func) //顺序执行
- {
- return Check(Check(Convert.ToInt32(id), func));
- }
- public Tuple<bool, Result> Execute<T>(T id, Func<bool> func) //顺序执行
- {
- return Check(execute(Convert.ToInt32(id), func));
- }
- public Tuple<bool, Result> Wait<T>(T id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
- {
- return Check(wait(Convert.ToInt32(id), func, timeout));
- }
- public Tuple<bool, Result> Wait<T>(T id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition
- {
- return Check(wait(Convert.ToInt32(id), func, timeout));
- }
- public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<Result?> check, double timeout = int.MaxValue)
- {
- int idx = Convert.ToInt32(id);
- bool bActive = Acitve(idx);
- Result? bExecute = Result.RUN;
- if (bActive)
- {
- //if (idx != _currentTokenId && ExecuteResult.Item1) return ExecuteResult;
- if (state == STATE.IDLE)
- {
- if (!execute())
- {
- ExecuteResult = Tuple.Create(bActive, Result.FAIL);
- return Tuple.Create(bActive, Result.FAIL); //执行错误
- }
- timer.Start(timeout);
- state = STATE.WAIT;
- _currentTokenId = idx;
- }
- bExecute = check();
- if (bExecute == null)
- {
- ExecuteResult = Tuple.Create(bActive, Result.FAIL);
- return Tuple.Create(bActive, Result.FAIL); //Termianate
- }
- else
- {
- if (bExecute == Result.DONE) //检查Success, next
- {
- next();
- ExecuteResult = Tuple.Create(true, Result.RUN);
- return Tuple.Create(true, Result.RUN);
- }
- if (bExecute == Result.Succeed) //检查Success, next
- {
- next();
- ExecuteResult = Tuple.Create(true, Result.RUN);
- return Tuple.Create(true, Result.RUN);
- }
- if (bExecute == Result.FAIL) //检查 Fail 直接返回Fail
- {
- ExecuteResult = Tuple.Create(true, Result.FAIL);
- return Tuple.Create(true, Result.FAIL);
- }
- }
- if (timer.IsTimeout())
- {
- ExecuteResult = Tuple.Create(true, Result.TIMEOUT);
- return Tuple.Create(true, Result.TIMEOUT);
- }
- ExecuteResult = Tuple.Create(true, Result.RUN);
- return Tuple.Create(true, Result.RUN);
- }
- ExecuteResult = Tuple.Create(false, Result.RUN);
- return Tuple.Create(false, Result.RUN);
- }
- public Tuple<bool, Result> Wait<T>(T id, IRoutine rt)
- {
- int idx = Convert.ToInt32(id);
- bool bActive = Acitve(idx);
- if (bActive)
- {
- if (state == STATE.IDLE)
- {
- rt.Start();
- state = STATE.WAIT;
- }
- Result ret = rt.Monitor();
- return Tuple.Create(true, ret);
- }
- return Tuple.Create(false, Result.RUN);
- }
- //Monitor
- public Tuple<bool, Result> Monitor<T>(T id, Func<bool> func, Func<bool> check, double time)
- {
- int idx = Convert.ToInt32(id);
- bool bActive = Acitve(idx);
- bool bCheck = false;
- if (bActive)
- {
- if (state == STATE.IDLE)
- {
- if ((func != null) && !func())
- {
- return Tuple.Create(true, Result.FAIL);
- }
- timer.Start(time);
- state = STATE.WAIT;
- }
- bCheck = check();
- if (!bCheck)
- {
- return Tuple.Create(true, Result.FAIL); //Termianate
- }
- if (timer.IsTimeout())
- {
- next();
- }
- return Tuple.Create(true, Result.RUN);
- }
- return Tuple.Create(false, Result.RUN);
- }
- //Delay
- public Tuple<bool, Result> Delay<T>(T id, Func<bool> func, double time)
- {
- int idx = Convert.ToInt32(id);
- bool bActive = Acitve(idx);
- if (bActive)
- {
- //if (_currentTokenId != idx && !ExecuteResult.Item1) return ExecuteResult;
- if (state == STATE.IDLE)
- {
- if ((func != null) && !func())
- {
- ExecuteResult = Tuple.Create(true, Result.FAIL);
- return Tuple.Create(true, Result.FAIL);
- }
- _currentTokenId = idx;
- timer.Start(time);
- state = STATE.WAIT;
- }
- if (timer.IsTimeout())
- {
- next();
- }
- ExecuteResult = Tuple.Create(true, Result.RUN);
- return Tuple.Create(true, Result.RUN);
- }
- ExecuteResult = Tuple.Create(false, Result.RUN);
- return Tuple.Create(false, Result.RUN);
- }
- //先delay 再运行
- public Tuple<bool, Result> DelayCheck<T>(T id, Func<bool> func, double time)
- {
- int idx = Convert.ToInt32(id);
- bool bActive = Acitve(idx);
- if (bActive)
- {
- if (state == STATE.IDLE)
- {
- timer.Start(time);
- state = STATE.WAIT;
- }
- if (timer.IsTimeout())
- {
- if (func != null && !func())
- {
- return Tuple.Create(true, Result.FAIL);
- }
- next();
- }
- return Tuple.Create(true, Result.RUN);
- }
- return Tuple.Create(false, Result.RUN);
- }
- #endregion
- private Tuple<bool, bool> execute(int id, Func<bool> func) //顺序执行
- {
- bool bActive = Acitve(id);
- bool bExecute = false;
- if (bActive)
- {
- //if (ExecuteResult.Item1) return Tuple.Create(true, true);
- bExecute = func();
- if (bExecute)
- {
- next();
- }
- }
- return Tuple.Create(bActive, bExecute);
- }
- private Tuple<bool, bool> Check(int id, Func<bool> func) //check
- {
- bool bActive = Acitve(id);
- bool bExecute = false;
- if (bActive)
- {
- if (ExecuteResult.Item1) return Tuple.Create(true, true);
- bExecute = func();
- next();
- }
- return Tuple.Create(bActive, bExecute);
- }
- /// <summary>
- /// </summary>
- /// <param name="id"></param>
- /// <param name="func"></param>
- /// <param name="timeout"></param>
- /// <returns>
- /// item1 Active
- /// item2 execute
- /// item3 Timeout
- ///</returns>
- private Tuple<bool, bool, bool> wait(int id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
- {
- bool bActive = Acitve(id);
- bool bExecute = false;
- bool bTimeout = false;
- if (bActive)
- {
- if (state == STATE.IDLE)
- {
- timer.Start(timeout);
- state = STATE.WAIT;
- }
- bExecute = func();
- if (bExecute)
- {
- next();
- }
- bTimeout = timer.IsTimeout();
- }
- return Tuple.Create(bActive, bExecute, bTimeout);
- }
- private Tuple<bool, bool?, bool> wait(int id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition && Check error
- {
- bool bActive = Acitve(id);
- bool? bExecute = false;
- bool bTimeout = false;
- if (bActive)
- {
- if (state == STATE.IDLE)
- {
- timer.Start(timeout);
- state = STATE.WAIT;
- }
- bExecute = func();
- if (bExecute.HasValue && bExecute.Value)
- {
- next();
- }
- bTimeout = timer.IsTimeout();
- }
- return Tuple.Create(bActive, bExecute, bTimeout);
- }
- /// <summary>
- /// </summary>
- /// <param name="value"></param>
- /// <returns>
- /// item1 true, return item2
- /// </returns>
- private Tuple<bool, Result> Check(Tuple<bool, bool> value)
- {
- if (value.Item1)
- {
- if (!value.Item2)
- {
- ExecuteResult = Tuple.Create(true, Result.FAIL);
- return Tuple.Create(true, Result.FAIL);
- }
- ExecuteResult = Tuple.Create(true, Result.RUN);
- return Tuple.Create(true, Result.RUN);
- }
- ExecuteResult = Tuple.Create(false, Result.RUN);
- return Tuple.Create(false, Result.RUN);
- }
- private Tuple<bool, Result> Check(Tuple<bool, bool, bool> value)
- {
- if (value.Item1) // 当前执行
- {
- if (CheckTimeout(value)) //timeout
- {
- return Tuple.Create(true, Result.TIMEOUT);
- }
- return Tuple.Create(true, Result.RUN);
- }
- return Tuple.Create(false, Result.RUN);
- }
- private Tuple<bool, Result> Check(Tuple<bool, bool?, bool> value)
- {
- if (value.Item1) // 当前执行
- {
- if (value.Item2 == null)
- {
- return Tuple.Create(true, Result.FAIL);
- }
- else
- {
- if (value.Item2 == false && value.Item3 == true) //timeout
- {
- return Tuple.Create(true, Result.TIMEOUT);
- }
- return Tuple.Create(true, Result.RUN);
- }
- }
- return Tuple.Create(false, Result.RUN);
- }
- private bool CheckTimeout(Tuple<bool, bool, bool> value)
- {
- return value.Item1 == true && value.Item2 == false && value.Item3 == true;
- }
- private bool Acitve(int id) //
- {
- if (_steps.Contains(id))
- return false;
- this._id = id;
- return true;
- }
- private void next()
- {
- _steps.Push(this._id);
- state = STATE.IDLE;
- }
- private void next(int step) //loop
- {
- while (_steps.Pop() != step) ;
- state = STATE.IDLE;
- }
- public void Delay(int id, double delaySeconds)
- {
- Tuple<bool, Result> ret = Delay(id, () =>
- {
- return true;
- }, delaySeconds * 1000);
- if (ret.Item1)
- {
- if (ret.Item2 == Result.RUN)
- {
- }
- }
- }
- public bool IsActived(int id)
- {
- return _steps.Contains(id);
- }
- }
- public enum LastFunctionEnum
- {
- PowerUp,
- OpenOrReachStage,
- CloseOrAutoHome,
- Map = 8,
- HomingCalibration = 16,
- MoveCommand = 34,
- }
- public enum PortStateEnum
- {
- Unlock,
- Lock,
- Other,
- }
- public enum WaferSeaterStateEnum
- {
- SeaterAtHome,
- SeaterOut,
- None,
- }
- }
|