| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698 | using Aitex.Core.RT.Routine;using Aitex.Core.RT.SCCore;using Aitex.Core.Util;using Aitex.Sorter.Common;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.Schedulers;using MECF.Framework.Common.SubstrateTrackings;using MECF.Framework.RT.EquipmentLibrary.LogicUnits;using System;using System.Collections.Generic;using FurnaceRT.Equipments.FIMSs;using FurnaceRT.Equipments.LPs;using FurnaceRT.Equipments.Stockers;using FurnaceRT.Equipments.Systems;using static FurnaceRT.Equipments.FIMSs.FIMSModule;namespace FurnaceRT.Equipments.CarrierRobots{    public class CarrierUnload : ModuleRoutine, IRoutine    {        enum RoutineStep        {            SetLPLoad,            SetLPUnload,            Place,            DoorOpen,            DoorClose,            RobotRequestCassettePresent,            CheckCassetteInfoByRobotSensor,            SetStageLock,            SetStageUnlock,            CheckBeforePlace,            SetRobotActionCommand,            Goto,            CheckGotoFinish,        }        private CarrierRobotModule _cassetteRobotModule;        private ModuleName _destination;        private int _destinationSlot;        private Hand _blade;        private int _timeout = 0;        private RD_TRIG _holdTrig = new RD_TRIG();        private R_TRIG _emergencyStopTrig = new R_TRIG();        private R_TRIG _pauseTrig = new R_TRIG();        private R_TRIG _resumeTrig = new R_TRIG();        private RoutineStep _routineStep;        private double _durationTime = 0;        private bool _isHasAlarm = false;        private bool _needStartCheck = true;        public CarrierUnload(CarrierRobotModule cassetteModule)        {            _cassetteRobotModule = cassetteModule;            Module = cassetteModule.Module;            Name = "Unload";        }        public void Init(ModuleName destination, int destinationSlot, Hand blade, bool isHasAlarm)        {            _destination = destination;            _destinationSlot = destinationSlot;            _blade = blade;            var para = new List<object> { _destination, _destinationSlot, _blade, true };            _cassetteRobotModule.PlaceCassetteFailAlarm.RetryMessage = (int)CarrierRobotModule.MSG.UnloadRetry;            _cassetteRobotModule.PlaceCassetteFailAlarm.RetryMessageParas = para.ToArray();            _cassetteRobotModule.PlaceCassetteTimeoutAlarm.RetryMessage = (int)CarrierRobotModule.MSG.UnloadRetry;            _cassetteRobotModule.PlaceCassetteTimeoutAlarm.RetryMessageParas = para.ToArray();            _cassetteRobotModule.RequestCassettePresentFailAlarm.RetryMessage = (int)CarrierRobotModule.MSG.UnloadRetry;            _cassetteRobotModule.RequestCassettePresentFailAlarm.RetryMessageParas = para.ToArray();            _cassetteRobotModule.RequestCassettePresentTimeoutAlarm.RetryMessage = (int)CarrierRobotModule.MSG.UnloadRetry;            _cassetteRobotModule.RequestCassettePresentTimeoutAlarm.RetryMessageParas = para.ToArray();            _cassetteRobotModule.RobotHasError.RetryMessage = (int)CarrierRobotModule.MSG.UnloadRetry;            _cassetteRobotModule.RobotHasError.RetryMessageParas = para.ToArray();            _cassetteRobotModule.ShutterOpenTimeoutAlarm.RetryMessage = (int)CarrierRobotModule.MSG.UnloadRetry;            _cassetteRobotModule.ShutterOpenTimeoutAlarm.RetryMessageParas = para.ToArray();            _cassetteRobotModule.ShutterCloseTimeoutAlarm.RetryMessage = (int)CarrierRobotModule.MSG.UnloadRetry;            _cassetteRobotModule.ShutterCloseTimeoutAlarm.RetryMessageParas = para.ToArray();            _isHasAlarm = isHasAlarm;            if (!_isHasAlarm)                _needStartCheck = true;        }        public Result Start(params object[] objs)        {            // 抛出过alarm就不reset            if (!_isHasAlarm)            {                Reset();            }            else            {                _historySteps.Remove((int)_routineStep);                _isHasAlarm = false;                ResetState();            }            _holdTrig.RST = true;            _emergencyStopTrig.RST = true;            _pauseTrig.RST = true;            _resumeTrig.RST = true;            _timeout = SC.GetValue<int>($"{Module}.MotionTimeout");            if (_needStartCheck)            {                if (!Singleton<EquipmentManager>.Instance.Modules.ContainsKey(_destination))                {                    _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {_destination} failed for not install");                    return Result.FAIL;                }                if (ModuleHelper.IsLoadPort(_destination))                {                    var lpModule = Singleton<EquipmentManager>.Instance.Modules[_destination] as LoadPortModule;                    if (lpModule == null)                    {                        _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {_destination} failed for not install");                        return Result.FAIL;                    }                    if (lpModule != null && !lpModule.CheckReadyForTransfer(ModuleHelper.Converter(Module), _blade, _destinationSlot, EnumTransferType.Place, out string reason))                    {                        _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {_destination} failed for {reason}");                        return Result.FAIL;                    }                }                else if (_destination == ModuleName.FIMS1 || _destination == ModuleName.FIMS2)                {                    var fims = Singleton<EquipmentManager>.Instance.Modules[_destination] as FIMSModule;                    if (fims == null)                    {                        _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {_destination} failed for not install");                        return Result.FAIL;                    }                    if (fims != null && !fims.CheckReadyForTransfer(ModuleHelper.Converter(Module), _blade, _destinationSlot, EnumTransferType.Place, out string reason))                    {                        _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {_destination} failed for {reason}");                        return Result.FAIL;                    }                    if (!SC.GetValue<bool>("System.IsSimulatorMode"))                    {                        if (fims != null && fims.IsFoupExist)                        {                            _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {_destination} failed for carrier is present");                            return Result.FAIL;                        }                    }                }                else                {                    var stockerModule = Singleton<EquipmentManager>.Instance.Modules[_destination] as StockerModule;                    if (stockerModule == null)                    {                        _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {_destination} failed for not install");                        return Result.FAIL;                    }                    if (!SC.GetValue<bool>("System.IsSimulatorMode"))                    {                        if (stockerModule != null && stockerModule.IsFoupPresent)                        {                            _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {_destination} failed for carrier is present");                            return Result.FAIL;                        }                    }                }                if (SC.GetValue<bool>("System.IsSimulatorMode"))                {                    if (!CarrierManager.Instance.CheckHasCarrier(ModuleName.CarrierRobot, 0))                    {                        _cassetteRobotModule.BladeCassetteNotPresentWarning.Set($"{ModuleName.CarrierRobot} cassette not present");                        return Result.FAIL;                    }                }                else                {                    if (!_cassetteRobotModule.CarrierRobotDevice.IsWaferPresenceOnBlade1 || !CarrierManager.Instance.CheckHasCarrier(ModuleName.CarrierRobot, 0))                    {                        _cassetteRobotModule.BladeCassetteNotPresentWarning.Set($"{ModuleName.CarrierRobot} cassette not present");                        return Result.FAIL;                    }                }                if (!CarrierManager.Instance.CheckNoCarrier(_destination, 0))                {                    _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {_destination} failed for carrier is present");                    return Result.FAIL;                }            }            Notify($"Start");            return Result.RUN;        }        public void Abort()        {            _cassetteRobotModule.ResetRobotActionCommand();            _cassetteRobotModule.Stop();            (Singleton<EquipmentManager>.Instance.Modules[_destination] as ITransferTarget)?.NoteTransferStop(ModuleHelper.Converter(_cassetteRobotModule.Module), _blade, _destinationSlot, EnumTransferType.Place);        }        public override Result Monitor()        {            try            {                PauseRountine(_cassetteRobotModule.CarrierRobotDevice.IsPause);                if (_cassetteRobotModule.CarrierRobotDevice.IsPause)                    return Result.RUN;                CheckBeforePlace((int)RoutineStep.CheckBeforePlace, _destination, _destinationSlot, _blade);                Goto((int)RoutineStep.Goto, _destination, _destinationSlot, _blade, true, _timeout);                if (_destination == ModuleName.LP1 || _destination == ModuleName.LP2)                {                    SaferDoorOpen((int)RoutineStep.DoorOpen, true, _timeout);                    SetLPLoad((int)RoutineStep.SetLPLoad, _destination, _timeout);                }                else if (_destination == ModuleName.LP3 || _destination == ModuleName.LP4)                {                    SetLPLoad((int)RoutineStep.SetLPLoad, _destination, _timeout);                }                CheckGotoFinish((int)RoutineStep.CheckGotoFinish, _destination, _timeout);                if (_cassetteRobotModule.TrigActionCommand != null)                    SetRobotActionCommand((int)RoutineStep.SetRobotActionCommand, _destination, _timeout);                Place((int)RoutineStep.Place, _destination, _destinationSlot, _blade, _timeout);                if (_destination == ModuleName.LP1 || _destination == ModuleName.LP2)                {                    SetLPUnload((int)RoutineStep.SetLPUnload, _destination, _timeout);                    SaferDoorOpen((int)RoutineStep.DoorClose, false, _timeout);                }                else if (_destination == ModuleName.LP3 || _destination == ModuleName.LP4)                {                    SetLPUnload((int)RoutineStep.SetLPUnload, _destination, _timeout);                }                                   RobotRequestCassettePresent((int)RoutineStep.RobotRequestCassettePresent, _blade, _timeout);                CheckCassetteInfoByRobotSensor((int)RoutineStep.CheckCassetteInfoByRobotSensor, _blade, false);            }            catch (RoutineBreakException)            {                return Result.RUN;            }            catch (RoutineFaildException ex)            {                _cassetteRobotModule.ResetRobotActionCommand();                (Singleton<EquipmentManager>.Instance.Modules[_destination] as ITransferTarget)?.NoteTransferStop(ModuleHelper.Converter(_cassetteRobotModule.Module), _blade, _destinationSlot, EnumTransferType.Place);                return Result.FAIL;            }            //if (SC.GetValue<bool>("System.IsSimulatorMode"))            //    CarrierManager.Instance.DeleteCarrier(_destination.ToString());            _cassetteRobotModule.ResetRobotActionCommand();            (Singleton<EquipmentManager>.Instance.Modules[_destination] as ITransferTarget)?.NoteTransferStop(ModuleHelper.Converter(_cassetteRobotModule.Module), _blade, _destinationSlot, EnumTransferType.Place);            Notify("Finished");            return Result.DONE;        }        private void SetRobotActionCommand(int id, ModuleName source, int timeout)        {            _routineStep = (RoutineStep)Enum.Parse(typeof(RoutineStep), id.ToString());            Tuple<bool, Result> ret = ExecuteAndWait(id, () =>            {                Notify($"Set robot action command target position {source}");                _cassetteRobotModule.SetRobotActionCommand(source, EnumTransferType.Place);                return true;            }, () =>            {                return _cassetteRobotModule.CheckRobotActionCommand(source, EnumTransferType.Place);            }, timeout * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    _cassetteRobotModule.PlaceCassetteTimeoutAlarm.Set($"place to {source} failed for robot action command interlock");                    throw (new RoutineFaildException());                }                else if (ret.Item2 == Result.TIMEOUT) //timeout                {                    _cassetteRobotModule.PlaceCassetteTimeoutAlarm.Set($"timeout over {timeout} seconds");                    throw (new RoutineFaildException());                }                else                    throw (new RoutineBreakException());            }        }        private void SetLPLoad(int id, ModuleName source, int timeout)        {            Tuple<bool, Result> ret = ExecuteAndWait(id, () =>            {                Notify($"Set {source} load");                var lp = Singleton<EquipmentManager>.Instance.Modules[source] as LoadPortModule;                if (lp != null)                    lp.LPDevice.Load(out string reason);                return true;            }, () =>            {                return true;            }, timeout * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw (new RoutineFaildException());                }                else if (ret.Item2 == Result.TIMEOUT) //timeout                {                    throw (new RoutineFaildException());                }                else                    throw (new RoutineBreakException());            }        }        private void SetLPUnload(int id, ModuleName source, int timeout)        {            Tuple<bool, Result> ret = ExecuteAndWait(id, () =>            {                Notify($"Set {source} unload");                var lp = Singleton<EquipmentManager>.Instance.Modules[source] as LoadPortModule;                if (lp != null)                    lp.LPDevice.Unload(out string reason);                return true;            }, () =>            {                return true;            }, timeout * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw (new RoutineFaildException());                }                else if (ret.Item2 == Result.TIMEOUT) //timeout                {                    throw (new RoutineFaildException());                }                else                    throw (new RoutineBreakException());            }        }        private void Place(int id, ModuleName target, int slot, Hand hand, int timeout)        {            _routineStep = (RoutineStep)Enum.Parse(typeof(RoutineStep), id.ToString());            Tuple<bool, Result> ret = ExecuteAndWait(id, () =>            {                Notify($"Send place to {target} command to robot device");                string reason;                (Singleton<EquipmentManager>.Instance.Modules[target] as ITransferTarget)?.NoteTransferStart(ModuleHelper.Converter(_cassetteRobotModule.Module), hand, slot, EnumTransferType.Place);                if (!_cassetteRobotModule.RobotPlace(target, slot, hand, out reason))                {                    //_cassetteRobotModule.PlaceCassetteFailAlarm.Description = reason;                    _cassetteRobotModule.PlaceCassetteFailAlarm.Set(reason);                    return false;                }                return true;            }, () =>            {                if (_cassetteRobotModule.CarrierRobotDevice.IsReady() && !_cassetteRobotModule.CarrierRobotDevice.IsError)                {                    return true;                }                return false;            }, timeout * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    //_cassetteRobotModule.PlaceCassetteFailAlarm.Description = $"{_cassetteRobotModule.CassetteRobotDevice.ErrorCode}";                    _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {target} failed for robot error, error code={_cassetteRobotModule.CarrierRobotDevice.ErrorCode}");                    throw (new RoutineFaildException());                }                else if (ret.Item2 == Result.TIMEOUT) //timeout                {                    //_cassetteRobotModule.PlaceCassetteTimeoutAlarm.Description = $"timeout over {timeout} seconds";                    _cassetteRobotModule.PlaceCassetteTimeoutAlarm.Set($"timeout over {timeout} seconds");                    throw (new RoutineFaildException());                }                else                    throw (new RoutineBreakException());            }        }        private void RobotRequestCassettePresent(int id, Hand hand, int timeout)        {            Tuple<bool, Result> ret = ExecuteAndWait(id, () =>            {                Notify("Request cassette present");                if (!_cassetteRobotModule.RequestCassettePresent(hand, out string reason))                {                    //_cassetteRobotModule.RequestCassettePresentFailAlarm.Description = reason;                    _cassetteRobotModule.RequestCassettePresentFailAlarm.Set(reason);                    return false;                }                return true;            }, () =>            {                if (_cassetteRobotModule.CarrierRobotDevice.IsReady() && !_cassetteRobotModule.CarrierRobotDevice.IsError)                {                    return true;                }                return false;            }, timeout * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw (new RoutineFaildException());                }                else if (ret.Item2 == Result.TIMEOUT) //timeout                {                    //_cassetteRobotModule.RequestCassettePresentTimeoutAlarm.Description = $"timeout over {timeout} seconds";                    _cassetteRobotModule.RequestCassettePresentTimeoutAlarm.Set($"timeout over {timeout} seconds");                    throw (new RoutineFaildException());                }                else                    throw (new RoutineBreakException());            }        }        private void CheckCassetteInfoByRobotSensor(int id, Hand hand, bool isAfterPick)        {            Tuple<bool, Result> ret = Execute(id, () =>            {                Notify($"Check cassette info by robot RQ present");                if (SC.GetValue<bool>("System.IsSimulatorMode"))                    return true;                if (hand == Hand.Blade1 || hand == Hand.Both)                {                    if (!isAfterPick && _cassetteRobotModule.CarrierRobotDevice.IsWaferPresenceOnBlade1)                    {                        //_cassetteRobotModule.RobotSensorFoundCassetteOnBladeAfterPlaceAlarm.Description = "Cassette Robot sensor found cassette on blade 1";                        _cassetteRobotModule.RobotSensorFoundCassetteOnBladeAfterPlaceAlarm.Set("Cassette Robot sensor found cassette on blade 1");                        return false;                    }                    if (isAfterPick && !_cassetteRobotModule.CarrierRobotDevice.IsWaferPresenceOnBlade1)                    {                        //_cassetteRobotModule.RobotSensorNotFoundCassetteOnBladeAfterPickAlarm.Description = "Cassette Robot sensor no cassette on blade 1";                        _cassetteRobotModule.RobotSensorNotFoundCassetteOnBladeAfterPickAlarm.Set("Cassette Robot sensor no cassette on blade 1");                        return false;                    }                }                if (hand == Hand.Blade2 || hand == Hand.Both)                {                    if (!isAfterPick && _cassetteRobotModule.CarrierRobotDevice.IsWaferPresenceOnBlade2)                    {                        //_cassetteRobotModule.RobotSensorFoundCassetteOnBladeAfterPlaceAlarm.Description = "Cassette Robot sensor found cassette on blade 2";                        _cassetteRobotModule.RobotSensorFoundCassetteOnBladeAfterPlaceAlarm.Set("Cassette Robot sensor found cassette on blade 2");                        return false;                    }                    if (isAfterPick && !_cassetteRobotModule.CarrierRobotDevice.IsWaferPresenceOnBlade2)                    {                        //_cassetteRobotModule.RobotSensorNotFoundCassetteOnBladeAfterPickAlarm.Description = "Cassette Robot sensor no cassette on blade 2";                        _cassetteRobotModule.RobotSensorNotFoundCassetteOnBladeAfterPickAlarm.Set("Cassette Robot sensor no cassette on blade 2");                        return false;                    }                }                return true;            });            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    //_cassetteRobotModule.CheckCassetteInformationFailAlarm.Description = $"check cassette info failed.";                    _cassetteRobotModule.CheckCassetteInformationFailAlarm.Set($"check cassette info failed.");                    throw (new RoutineFaildException());                }                else                    throw (new RoutineBreakException());            }        }        private void CheckBeforePlace(int id, ModuleName target, int slot, Hand blade)        {            Tuple<bool, Result> ret = Execute(id, () =>            {                Notify($"Check place to {target} condition");                string reason = string.Empty;                if (_cassetteRobotModule.CarrierRobotDevice.IsError)                {                    _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {target} failed for robot error, error code={_cassetteRobotModule.CarrierRobotDevice.ErrorCode}");                    return false;                }                if (!_cassetteRobotModule.CarrierRobotDevice.IsReady())                {                    _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {target} failed for robot isn't Ready");                    return false;                }                if (!CarrierManager.Instance.CheckNoCarrier(_destination, 0))                {                    _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {_destination} failed for pod is present");                    return false;                }                if (blade == Hand.Blade1)                {                    if (!CarrierManager.Instance.CheckNoCarrier(target, 0))                    {                        _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {target} failed for {target} has carrier");                        return false;                    }                    if (!CarrierManager.Instance.CheckHasCarrier(Module, 0))                    {                        _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {target} failed for blade no carrier");                        return false;                    }                }                else if (blade == Hand.Blade2)                {                    if (!CarrierManager.Instance.CheckNoCarrier(target, 0))                    {                        _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {target} failed for {target} has carrier");                        return false;                    }                    if (!CarrierManager.Instance.CheckHasCarrier(Module, 0))                    {                        _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {target} failed for blade no carrier");                        return false;                    }                }                else                {                    if (!CarrierManager.Instance.CheckNoCarrier(target, 0))                    {                        _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {target} failed for {target} has carrier");                        return false;                    }                    if (!CarrierManager.Instance.CheckHasCarrier(Module, 0))                    {                        _cassetteRobotModule.PlaceCassetteFailAlarm.Set($"place to {target} failed for blade no carrier");                        return false;                    }                }                return true;            });            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw (new RoutineFaildException());                }            }            _needStartCheck = false;        }        private void Goto(int id, ModuleName target, int slot, Hand hand, bool isPickReady, int timeout)        {            _routineStep = (RoutineStep)Enum.Parse(typeof(RoutineStep), id.ToString());            Tuple<bool, Result> ret = ExecuteAndWait(id, () =>            {                Notify($"Send goto to {target} command to robot device");                string reason;                _cassetteRobotModule.RobotGoto(target, slot, hand, isPickReady, out reason);                return true;            }, () =>            {                return true;            }, timeout * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    _cassetteRobotModule.GotoFailAlarm.Set($"goto to {target} failed for robot error, error code={_cassetteRobotModule.CarrierRobotDevice.ErrorCode}");                    throw (new RoutineFaildException());                }                else if (ret.Item2 == Result.TIMEOUT) //timeout                {                    _cassetteRobotModule.GotoTimeoutAlarm.Set($"timeout over {timeout} seconds");                    throw (new RoutineFaildException());                }                else                    throw (new RoutineBreakException());            }        }        private void CheckGotoFinish(int id, ModuleName target, int timeout)        {            Tuple<bool, Result> ret = ExecuteAndWait(id, () =>            {                Notify($"Check goto to {target} command finish");                return true;            }, () =>            {                if (_cassetteRobotModule.CarrierRobotDevice.IsError)                    return null;                if (_cassetteRobotModule.CarrierRobotDevice.IsReady() && !_cassetteRobotModule.CarrierRobotDevice.IsError)                {                    return true;                }                return false;            }, timeout * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    _cassetteRobotModule.GotoFailAlarm.Set($"goto to {target} failed for robot error, error code={_cassetteRobotModule.CarrierRobotDevice.ErrorCode}");                    throw (new RoutineFaildException());                }                else if (ret.Item2 == Result.TIMEOUT) //timeout                {                    _cassetteRobotModule.GotoTimeoutAlarm.Set($"timeout over {timeout} seconds");                    throw (new RoutineFaildException());                }                else                    throw (new RoutineBreakException());            }        }        private void SaferDoorOpen(int id, bool isOpen, int timeout)        {            Tuple<bool, Result> ret = ExecuteAndWait(id, () =>            {                Notify($"Shutter Door {(isOpen ? "Open" : "Close")}");                if (isOpen)                    _cassetteRobotModule.DoorDevice.Open();                else                    _cassetteRobotModule.DoorDevice.Close();                if (isOpen)                    (Singleton<EquipmentManager>.Instance.Modules[_destination] as LoadPortModule)?.LPDevice.Unclamp(out _);                return true;            }, () =>            {                return isOpen ? _cassetteRobotModule.DoorDevice.OpenCloseStatus == Devices.DeviceStatus.Open && (Singleton<EquipmentManager>.Instance.Modules[_destination] as LoadPortModule).IsReleased : _cassetteRobotModule.DoorDevice.OpenCloseStatus == Devices.DeviceStatus.Close;            }, timeout * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw new RoutineFaildException();                }                else if (ret.Item2 == Result.TIMEOUT) //timeout                {                    if (isOpen)                        _cassetteRobotModule.ShutterOpenTimeoutAlarm.Set($"timeout over {timeout} seconds");                    else                        _cassetteRobotModule.ShutterCloseTimeoutAlarm.Set($"timeout over {timeout} seconds");                    throw (new RoutineFaildException());                }                else                    throw new RoutineBreakException();            }        }    }}
 |