Sic.Framework-Nanjing-Baishi/MECF.Framework.RT.Equipment.../HardwareUnits/Robots/HineAutomation/HAtmRobot.cs

817 lines
28 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using Aitex.Sorter.Common;
using MECF.Framework.Common.Communications;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot.HineAutomation
{
public class HAtmRobot : Robot
{
#region properties
public override bool Error
{
get
{
return _exceuteErr;
}
}
public bool IsThetaBusy { get; set; }
public bool IsZBusy { get; set; }
public bool IsRadialBusy { get; set; }
public override bool Busy
{
get
{
return IsBusy || IsThetaBusy || IsZBusy || IsRadialBusy || (!_motionTimer.IsIdle() && _motionTimer.GetElapseTime() < _motionTime) /*|| ThetaAxisAddressPosition != _targetThetaAxisAddressPosition || ZAxisAddressPosition != _targetZAxisAddressPosition*/;
}
}
public override bool Moving
{
get
{
return IsBusy || IsThetaBusy || IsZBusy || IsRadialBusy || (!_motionTimer.IsIdle() && _motionTimer.GetElapseTime() < _motionTime) /*|| ThetaAxisAddressPosition != _targetThetaAxisAddressPosition || ZAxisAddressPosition != _targetZAxisAddressPosition*/;
}
}
public override bool WaferOnBlade1 => WaferPresentOnBlade1;
public bool IsBusy { private get; set; }
public bool IsRetract { get; set; }
public bool IsUp { get; set; }
public int ThetaAxisAddressPosition { get; set; }
public int ZAxisAddressPosition { get; set; }
public int RetractReqPos { get; set; }
public int RotateReqPos { get; set; }
public int ZReqPos { get; set; }
public int ZActPos { get; set; }
public string SlotMap { get; set; }
public Dictionary<string, string> ErrorCodeReference;
public R_TRIG IsRotationAxisUnreferencedTrig { get; set; }
public R_TRIG IsExtensionAxisUnreferencedTrig { get; set; }
public R_TRIG IsZAxisUnreferencedTrig { get; set; }
public bool IsHomed => _isHomed;
#endregion
#region fields
private HAtmConnection _connection;
private string _address;
private PeriodicJob _thread;
private LinkedList<HandlerBase> _lstHandler = new LinkedList<HandlerBase>();
private object _lockerHandlerList = new object();
private R_TRIG _trigError = new R_TRIG();
private R_TRIG _trigWarningMessage = new R_TRIG();
private string _lastError = string.Empty;
private int _errorCode;
private int _targetThetaAxisAddressPosition;
private int _targetZAxisAddressPosition;
private HandlerBase _waferMoveHandler;
private HandlerBase _homeHandler;
private bool _isHomed;
private bool _isSimulator;
//private bool _isFirstHome = true;
private bool _enableLog;
private bool _isPowerUp = true;
private DeviceTimer _motionTimer = new DeviceTimer();
private int _motionTime = 1000;
private Dictionary<string, int> _motionTimeDic;
private ModuleName _lastTarget;
private R_TRIG _zAxisHomeTrig = new R_TRIG();
#endregion
public HAtmRobot(string module)
: base(module, module, module, module, "", RobotType.HAtm)
{
IsRetract = true;
}
static bool CheckAddressPort(string s)
{
bool isLegal;
Regex regex = new Regex(@"^((2[0-4]\d|25[0-5]|[1]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[1]?\d\d?)\:([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-6][0-5][0-5][0-3][0-5])$");//CheckAddressPort
Match match = regex.Match(s);
if (match.Success)
{
isLegal = true;
}
else
{
isLegal = false;
}
return isLegal;
}
public override bool Initialize()
{
_address = SC.GetStringValue($"{Module}.Address");
_isSimulator = SC.GetValue<bool>("System.IsSimulatorMode");
_enableLog = SC.GetValue<bool>($"{Module}.EnableLogMessage");
_connection = new HAtmConnection(_address);
if (CheckAddressPort(_address))
{
if (_connection.Connect())
{
EV.PostInfoLog(Module, $"{Module} connected");
}
}
else EV.PostWarningLog(Module, $"{Module} Adress is illegal");
_thread = new PeriodicJob(50, OnTimer, $"{Module} MonitorHandler", true);
DATA.Subscribe($"{Name}.IsHomed", () => _isHomed);
DATA.Subscribe($"{Name}.IsConnected", () => _connection.IsConnected);
OP.Subscribe("Robot.QueryOperationalStatus", (string cmd, object[] args) =>
{
QueryOperationalStatus();
return true;
});
_motionTimeDic = new Dictionary<string, int>()
{
{ $"{ModuleName.Cassette}.{ModuleName.PM}.Picking",4000},
{ $"{ModuleName.PM}.{ModuleName.PM}.Picking",1500},
{ $"{ModuleName.PM}.{ModuleName.Cooling}.Picking",2400},
{ $"{ModuleName.Cooling}.{ModuleName.Cooling}.Picking",1500},
{ $"{ModuleName.Cooling}.{ModuleName.PM}.Picking",2400},
{ $"{ModuleName.Cassette}.{ModuleName.Cooling}.Picking",2200},
{ $"{ModuleName.Cooling}.{ModuleName.Cassette}.Picking",2200},
{ $"{ModuleName.Cassette}.{ModuleName.Cassette}.Picking",1500},
{ $"{ModuleName.PM}.{ModuleName.Cassette}.Picking",4000},
{ $"{ModuleName.TMRobot}.{ModuleName.Cassette}.Picking",5000},
{ $"{ModuleName.TMRobot}.{ModuleName.Cooling}.Picking",3700},
{ $"{ModuleName.TMRobot}.{ModuleName.PM}.Picking",2200},
{ $"System.{ModuleName.Cassette}.Picking",5000},
{ $"System.{ModuleName.Cooling}.Picking",3700},
{ $"System.{ModuleName.PM}.Picking",2200},
};
ErrorCodeReference = new Dictionary<string, string>()
{
{ "S0","Serial response timeout"},
{ "S1","Illegal sc interrupt"},
{ "S2","Parity Error"},
{ "S3","Input Buffer overflow"},
{ "C0","Command not recognized"},
{ "C1","Illegal Z-Axis Command Address"},
{ "C2","Illegal Radial Axis Command Address"},
{ "C3","Illegal Theta Axis Command Address"},
{ "C4","Illegal Pick wafer on pan"},
{ "C5","Illegal Place wafer not on pan"},
{ "C6","Illegal action command error present"},
{ "C7","Command overrun Hatm5.0 Busy"},
{ "C8","Illegal command not in learn mode"},
{ "C9","Illegal Search hardware not present"},
{ "CA","Illegal Fetch hardware not present"},
{ "CB","Illegal Action data not valid"},
{ "CC","Illegal Action Request Queue overrun"},
{ "CD","Illegal Action Overcurrent Latch Set"},
{ "CE","Illegal Action Interlock Open"},
{ "CF","Loss of Vacuum Detect"},
{ "D0","Illegal Pitch"},
{ "D1","Illegal Offset"},
{ "D2","Illegal number of slots"},
{ "D3","Illegal rotate position"},
{ "D4","Illegal difference value"},
{ "D5","Parameter missing"},
{ "D6","Illegal Set Command"},
{ "D7","Illegal Option"},
{ "D8","Illegal Category"},
{ "D9","Illegal Bias"},
{ "DA","Illegal Bias Set, Z not valid"},
{ "DB","Invalid rotational speed data(exceeded the legal percent range)"},
{ "DC","Invalid z-axis speed data (exceeded the legal percent range)"},
{ "I0","Z requested position is out of range"},
{ "I1","Theta requested position is out of range"},
{ "I2","Radial requested position is out of range"},
{ "I3","Illegal Z Position"},
{ "I4","Illegal Theta Position"},
{ "I5","Illegal Data"},
{ "A0","Theta Axis action timeout"},
{ "A1","Z-Axis action timeout"},
{ "A2","Radial Axis action timeout"},
{ "A3","Theta overtravel"},
{ "A4","Theta Axis reference detect"},
{ "A5","Z-Axis reference detect"},
{ "A6","Function timeout"},
{ "A7","Loss of Retrace on Rotate"},
{ "A8","Cassette Interlock error"},
{ "A9","Overcurrent shutdown"},
{ "P0","Bad Checksum Theta Parameters"},
{ "P1","Bad Checksum Z Parameters"},
{ "P2","Bad Checksum Radial Parameters"},
{ "F0","Flipper current limit activated"},
{ "F1","Flipper device error"},
{ "F2","Flipper over voltage"},
{ "F3","Flipper over temperature"},
{ "F4","Flipper continuous current limit"},
{ "F5","No Flipper is installed"},
};
IsRotationAxisUnreferencedTrig = new R_TRIG();
IsExtensionAxisUnreferencedTrig = new R_TRIG();
IsZAxisUnreferencedTrig = new R_TRIG();
return base.Initialize();
}
private bool OnTimer()
{
try
{
_connection.MonitorTimeout();
_connection.MonitorConnection(SC.GetValue<int>("TMRobot.ReconnectCount"), out bool retried);
if (retried)
{
lock (_lockerHandlerList)
{
_lstHandler.Clear();
}
}
if (!_connection.IsConnected || _connection.IsCommunicationError)
{
return true;
}
if (_connection.IsBusy)
return true;
HandlerBase handler = null;
lock (_lockerHandlerList)
{
if (_isPowerUp)
{
if(SC.GetValue<bool>("TMRobot.AllCommandsHaveResponse"))
_lstHandler.AddFirst(new SetCommandResponseHandler(this));
_isPowerUp = false;
}
if (_lstHandler.Count == 0)
{
_lstHandler.AddLast(new QueryOperationalStatusHandler(this));
_lstHandler.AddLast(new QueryAllAxisStatusHandler(this));
_lstHandler.AddLast(new QueryThetaAxisStatusHandler(this));
_lstHandler.AddLast(new QueryZAxisStatusHandler(this));
_lstHandler.AddLast(new QueryRadialAxisStatusHandler(this));
_lstHandler.AddLast(new QueryPositionHandler(this));
}
if (_lstHandler.Count > 0)
{
handler = _lstHandler.First.Value;
_lstHandler.RemoveFirst();
}
}
if (handler != null)
{
handler.SendText = ((HAtmHandler)handler).Package();
_connection.Execute(handler);
}
if (_waferMoveHandler != null)
{
var pick = _waferMoveHandler as PickHandler;
if (pick != null && WaferOnBlade1 && WaferManager.Instance.CheckHasWafer(pick.Target, pick.Slot))
{
WaferManager.Instance.WaferMoved(pick.Target, pick.Slot, ModuleHelper.Converter(Name), (int)Hand.Blade1);
CmdBladeTarget = $"{pick.Target}.Retract";
}
var place = _waferMoveHandler as PlaceHandler;
if (place != null && !WaferOnBlade1 && WaferManager.Instance.CheckHasWafer(ModuleHelper.Converter(Name), (int)Hand.Blade1))
{
WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Name), (int)Hand.Blade1, place.Target, place.Slot);
CmdBladeTarget = $"{place.Target}.Retract";
}
}
if (_waferMoveHandler != null && !Moving)
{
_lastTarget = ((HAtmHandler)_waferMoveHandler).Target;
((HAtmHandler)_waferMoveHandler).Update();
_waferMoveHandler = null;
_motionTimer.Stop();
}
if (_homeHandler != null)
{
_zAxisHomeTrig.CLK = ZReqPos == 0;
if(_zAxisHomeTrig.Q)//means ZAXis is homed
{
ChangeRobotBladeTarget();
}
if (!Moving)
{
_lastTarget = ((HAtmHandler)_homeHandler).Target;
_isHomed = true;
_homeHandler = null;
_motionTimer.Stop();
}
}
}
catch (Exception ex)
{
LOG.Write(ex);
}
return true;
}
private void ChangeRobotBladeTarget()
{
//CmdBladeTarget = $"{ModuleHelper.Converter(RobotDevice.Name)}.Retract";
int cassette = 180;
int cooling = 110;
int pm = 55;
if(Math.Abs(RotateReqPos - cassette) < 10)
{
CmdBladeTarget = $"{ModuleName.Cassette}.{ModuleHelper.Converter(Name)}.Retract";
return;
}
if (Math.Abs(RotateReqPos - cooling) < 10)
{
CmdBladeTarget = $"{ModuleName.Cooling}.{ModuleHelper.Converter(Name)}.Retract";
return;
}
if (Math.Abs(RotateReqPos - pm) < 10)
{
CmdBladeTarget = $"{ModuleName.PM}.{ModuleHelper.Converter(Name)}.Retract";
return;
}
if (Math.Abs(RotateReqPos) < 10)
{
CmdBladeTarget = $"{ModuleHelper.Converter(Name)}.{ModuleHelper.Converter(Name)}.Retract";
return;
}
CmdBladeTarget = $"{ModuleHelper.Converter(Name)}.Retract";
}
public override void Monitor()
{
}
public override void Reset()
{
_trigError.RST = true;
_trigWarningMessage.RST = true;
IsRotationAxisUnreferencedTrig.RST = true;
IsExtensionAxisUnreferencedTrig.RST = true;
IsZAxisUnreferencedTrig.RST = true;
_connection.Reset();
_exceuteErr = false;
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(new ResetHandler(this));
}
_motionTimer.Stop();
_zAxisHomeTrig.RST = true;
_isHomed = false;
base.Reset();
}
public void SetErrorCode(int errorCode)
{
_errorCode = errorCode;
}
public void SetError(string reason)
{
_trigWarningMessage.CLK = true;
if (_trigWarningMessage.Q)
{
EV.PostWarningLog(Module, $"{Module} error, {reason}");
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(new QueryErrorHandler(this));
}
}
_exceuteErr = true;
}
public override void OnDataChanged(string package)
{
}
public override bool Home(out string reason)
{
reason = string.Empty;
var handler = new HomeHandler(this);
//if (_lstHandler.Count > 0 && Moving && !_isFirstHome)
//{
// reason = "Robot busy, please wait or abort.";
// EV.PostMessage(Name, EventEnum.DefaultWarning, string.Format("{0} {1} {2}", this.Name, handler.Name.ToString(), reason));
// return false;
//}
SetBusy();
_exceuteErr = false;
_targetThetaAxisAddressPosition = 0;
_targetZAxisAddressPosition = 0;
ThetaAxisAddressPosition = -1;
ZAxisAddressPosition = -1;
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(handler);
if(SC.GetValue<bool>("TMRobot.AllCommandsHaveResponse"))
_lstHandler.AddFirst(new SetCommandResponseHandler(this));
}
_homeHandler = handler;
_isHomed = false;
//_isFirstHome = false;
_enableLog = SC.GetValue<bool>($"{Module}.EnableLogMessage");
IsThetaBusy = true;
IsZBusy = true;
IsRadialBusy = true;
_motionTimer.Start(0);
_zAxisHomeTrig.RST = true;
return true;
}
public bool Pick(ModuleName target, int slot, out string reason)
{
reason = string.Empty;
var handler = new PickHandler(this, target, slot);
if (_lstHandler.Count > 0 && Moving)
{
reason = "Robot busy, please wait or abort.";
EV.PostMessage(Name, EventEnum.DefaultWarning, string.Format("{0} {1} {2}", this.Name, handler.Name.ToString(), reason));
return false;
}
SetBusy();
_targetThetaAxisAddressPosition = RobotConvertor.Chamber2ThetaAxisPosition(target);
_targetZAxisAddressPosition = RobotConvertor.ChamberSlot2ZAxisPosition(target, slot);
ThetaAxisAddressPosition = -1;
ZAxisAddressPosition = -1;
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(handler);
}
_waferMoveHandler = handler;
IsThetaBusy = true;
IsZBusy = true;
IsRadialBusy = true;
_motionTimer.Start(0);
if(_isSimulator)
WaferPresentOnBlade1 = false;
return true;
}
public bool Place(ModuleName target, int slot, out string reason)
{
reason = string.Empty;
var handler = new PlaceHandler(this, target, slot);
if (_lstHandler.Count > 0 && Moving)
{
reason = "Robot busy, please wait or abort.";
EV.PostMessage(Name, EventEnum.DefaultWarning, string.Format("{0} {1} {2}", this.Name, handler.Name.ToString(), reason));
return false;
}
SetBusy();
_targetThetaAxisAddressPosition = RobotConvertor.Chamber2ThetaAxisPosition(target);
_targetZAxisAddressPosition = RobotConvertor.ChamberSlot2ZAxisPosition(target, slot);
ThetaAxisAddressPosition = -1;
ZAxisAddressPosition = -1;
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(handler);
}
_waferMoveHandler = handler;
IsThetaBusy = true;
IsZBusy = true;
IsRadialBusy = true;
_motionTimer.Start(0);
if (_isSimulator)
WaferPresentOnBlade1 = true;
return true;
}
public bool GotoExtend(ModuleName target, int slot, bool isPick, bool isUp, out string reason)
{
reason = string.Empty;
var handler = new GotoHandler(this, target, slot, isPick, isUp);
if (_lstHandler.Count > 0 && Moving)
{
reason = "Robot busy, please wait or abort.";
EV.PostMessage(Name, EventEnum.DefaultWarning, string.Format("{0} {1} {2}", this.Name, handler.Name.ToString(), reason));
return false;
}
SetBusy();
_targetThetaAxisAddressPosition = RobotConvertor.Chamber2ThetaAxisPosition(target);
_targetZAxisAddressPosition = RobotConvertor.ChamberSlot2ZAxisPosition(target, slot);
ThetaAxisAddressPosition = -1;
ZAxisAddressPosition = -1;
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(handler);
}
_waferMoveHandler = handler;
IsThetaBusy = true;
IsZBusy = true;
IsRadialBusy = true;
_motionTimer.Start(0);
return true;
}
public bool ZAxisMove(ModuleName target, int slot, bool isUp, out string reason)
{
reason = string.Empty;
var handler = new ZAxisMoveHandler(this, target, slot, isUp);
if (_lstHandler.Count > 0 && Moving)
{
reason = "Robot busy, please wait or abort.";
EV.PostMessage(Name, EventEnum.DefaultWarning, string.Format("{0} {1} {2}", this.Name, handler.Name.ToString(), reason));
return false;
}
_targetZAxisAddressPosition = RobotConvertor.ChamberSlot2ZAxisPosition(target, slot);
ZAxisAddressPosition = -1;
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(handler);
}
IsZBusy = true;
_motionTimer.Start(0);
return true;
}
public bool PlaceRetract(ModuleName target, int slot, out string reason)
{
reason = string.Empty;
var handler = new PlaceRetractHandler(this, target, slot);
if (_lstHandler.Count > 0 && Moving)
{
reason = "Robot busy, please wait or abort.";
EV.PostMessage(Name, EventEnum.DefaultWarning, string.Format("{0} {1} {2}", this.Name, handler.Name.ToString(), reason));
return false;
}
SetBusy();
_targetThetaAxisAddressPosition = RobotConvertor.Chamber2ThetaAxisPosition(target);
_targetZAxisAddressPosition = RobotConvertor.ChamberSlot2ZAxisPosition(target, slot);
ThetaAxisAddressPosition = -1;
ZAxisAddressPosition = -1;
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(handler);
}
_waferMoveHandler = handler;
IsThetaBusy = true;
IsZBusy = true;
IsRadialBusy = true;
_motionTimer.Start(0);
return true;
}
public bool PickRetract(ModuleName target, int slot, bool isNeedWaferMove, out string reason)
{
reason = string.Empty;
var handler = new PickRetractHandler(this, target, slot, isNeedWaferMove);
if (_lstHandler.Count > 0 && Moving)
{
reason = "Robot busy, please wait or abort.";
EV.PostMessage(Name, EventEnum.DefaultWarning, string.Format("{0} {1} {2}", this.Name, handler.Name.ToString(), reason));
return false;
}
SetBusy();
_targetThetaAxisAddressPosition = RobotConvertor.Chamber2ThetaAxisPosition(target);
_targetZAxisAddressPosition = RobotConvertor.ChamberSlot2ZAxisPosition(target, slot);
ThetaAxisAddressPosition = -1;
ZAxisAddressPosition = -1;
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(handler);
}
_waferMoveHandler = handler;
IsThetaBusy = true;
IsZBusy = true;
IsRadialBusy = true;
_motionTimer.Start(0);
return true;
}
public void Abort()
{
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(new AbortHandler(this));
}
_waferMoveHandler = null;
_homeHandler = null;
_motionTimer.Stop();
_zAxisHomeTrig.RST = true;
}
public void QueryAllAxisStatus()
{
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(new QueryAllAxisStatusHandler(this));
}
}
public void QueryError()
{
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(new QueryErrorHandler(this));
}
}
public void SetSpeed()
{
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(new SetThetaSpeedHandler(this, SC.GetValue<int>("TMRobot.Speed"), SC.GetValue<int>("TMRobot.Speed")));
_lstHandler.AddFirst(new SetReachSpeedHandler(this, SC.GetValue<int>("TMRobot.Speed"), SC.GetValue<int>("TMRobot.Speed")));
}
}
public void QueryOperationalStatus()
{
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(new QueryOperationalStatusHandler(this));
}
}
public bool VacuumOn(out string reason)
{
reason = string.Empty;
var handler = new VacuumOnHandler(this);
//if (_lstHandler.Count > 0)
//{
// reason = "Robot busy, please wait or abort.";
// EV.PostMessage(Name, EventEnum.DefaultWarning, string.Format("{0} {1} {2}", this.Name, handler.Name.ToString(), reason));
// return false;
//}
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(handler);
}
return true;
}
public bool VacuumOff(out string reason)
{
reason = string.Empty;
var handler = new VacuumOffHandler(this);
//if (_lstHandler.Count > 0)
//{
// reason = "Robot busy, please wait or abort.";
// EV.PostMessage(Name, EventEnum.DefaultWarning, string.Format("{0} {1} {2}", this.Name, handler.Name.ToString(), reason));
// return false;
//}
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(handler);
}
return true;
}
public bool WaferMap(ModuleName target, out string reason)
{
reason = string.Empty;
var handler = new WaferMapHandler(this, target);
if (_lstHandler.Count > 0 && Moving)
{
reason = "Robot busy, please wait or abort.";
EV.PostMessage(Name, EventEnum.DefaultWarning, string.Format("{0} {1} {2}", this.Name, handler.Name.ToString(), reason));
return false;
}
SetBusy();
_targetThetaAxisAddressPosition = RobotConvertor.Chamber2ThetaAxisPosition(target);
ThetaAxisAddressPosition = -1;
ZAxisAddressPosition = -1;
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(handler);
}
IsThetaBusy = true;
IsZBusy = true;
IsRadialBusy = true;
_motionTimer.Start(0);
return true;
}
public bool GetWaferMap(ModuleName target, out string reason)
{
reason = string.Empty;
var handler = new QueryWaferMapHandler(this, target);
SlotMap = string.Empty;
lock (_lockerHandlerList)
{
_lstHandler.AddFirst(handler);
}
return true;
}
private void SetBusy()
{
//IsBusy || IsThetaBusy || IsZBusy || IsRadialBusy
IsBusy = true;
IsThetaBusy = true;
IsZBusy = true;
IsRadialBusy = true;
}
}
}