using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; 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 MECF.Framework.Common.CommonData; 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.Robot; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using EventType = Aitex.Core.RT.Event.EventType; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.HRC100Robots.GM201LVPRobot { public class YaskawaRobotMessage : AsciiMessage { public int UNo { get; set; } public int SeqNo { get; set; } public string Status { get; set; } public string Ackcd { get; set; } public string Command { get; set; } public string[] Data { get; set; } public string ErrorCode { get; set; } public string EvNo { get; set; } public string EvDate { get; set; } public string EvData { get; set; } } public class GM201LVPRobot : RobotBaseDevice, IConnection { //public int UnitNumber //{ // get; private set; //} private bool isSimulatorMode; private string _scRoot; private bool _isError; public GM201LVPTokenGenerator SeqnoGenerator { get; private set; } public bool IsEnableSeqNo { get; private set; } public bool IsEnableCheckSum { get; private set; } public int CurrentSeqNo { get; set; } public string PortName; private string _address; private bool _enableLog; private GM201LVPRobotConnection _connection; private R_TRIG _trigError = new R_TRIG(); private R_TRIG _trigCommunicationError = new R_TRIG(); private R_TRIG _trigRetryConnect = new R_TRIG(); public string Address => _address; private PeriodicJob _thread; private object _locker = new object(); private LinkedList _lstHandlers = new LinkedList(); private LinkedList _lstMonitorHandler = new LinkedList(); private IoSensor _diRobotReady = null; //Normal ON private IoSensor _diRobotBlade1WaferOn = null; //Off when wafer present private IoSensor _diRobotBlade2WaferOn = null; private IoSensor _diRobotError = null; //Normal ON private IoSensor _diTPinUse = null; private IoTrigger _doRobotHold = null; // Normal ON public ModuleName CurrentInteractiveModule { get; private set; } public bool IsConnected => throw new NotImplementedException(); public float CurrentThetaPosition { get; private set; } public float CurrentExtensionPosition { get; private set; } public float CurrentArm1Position { get; private set; } public float CurrentArm2Position { get; private set; } public float CurrentZPosition { get; private set; } public float CommandThetaPosition { get; private set; } public float CommandExtensionPosition { get; private set; } public float CommandArm1Position { get; private set; } public float CommandArm2Position { get; private set; } public float CommandZPosition { get; private set; } public int SpeedLevel { get; private set; } public int SpeedLevelSetting => SC.GetValue($"{Name}.RobotSpeed"); public string ReadMemorySpec { get; private set; } public string ReadTransferStation { get; private set; } public int ReadSlotNumber { get; private set; } public string ReadArmPosture { get; private set; } public RobotArmEnum ReadBladeNo { get; private set; } public GM201LVPPositonEnum ReadPositionType { get; private set; } public float ReadThetaPosition { get; private set; } public float ReadExtensionPosition { get; private set; } public float ReadArm1Position { get; private set; } public float ReadArm2Position { get; private set; } public float ReadZPosition { get; private set; } public Dictionary ReadStationItemValues { get; private set; } = new Dictionary(); public Dictionary ReadStationItemContents { get; private set; } = new Dictionary(); public string ReadParameterType { get; private set; } public string ReadParameterNo { get; private set; } public string ReadParameterValue { get; private set; } public bool IsManipulatorBatteryLow { get; private set; } public bool IsCommandExecutionReady { get; private set; } public bool IsServoON { get; private set; } public bool IsErrorOccurred { get; private set; } public bool IsControllerBatteryLow { get; private set; } public bool IsCheckInterlockWaferPresenceOnBlade1 { get; private set; } public bool IsCheckInterlockWaferPresenceOnBlade2 { get; private set; } public bool IsCheckInterlockWaferPresenceOnBlade3 { get; private set; } public bool IsCheckInterlockWaferPresenceOnBlade4 { get; private set; } public bool IsCheckInterlockWaferPresenceOnBlade5 { get; private set; } public string RobotSoftwareVersion { get; private set; } public string ReadMappingTransferStation { get; private set; } public int ReadMappingSlotNumbers { get; private set; } public string ReadSlotMap { get; private set; } public MaterialType _MaterialType { get; set; } private int _timeLimitPick => SC.GetValue($"{Name}.PickTimeout"); private int _timeLimitPlace => SC.GetValue($"{Name}.PlaceTimeout"); private int _timeLimitHome => SC.GetValue($"{Name}.HomeTimeout"); private int _timeLimitMotion => SC.GetValue($"{Name}.MotionTimeout"); public Dictionary ReadMappingCalibrationResult { get; private set; } public Dictionary ReadRobotParameterResult { get; private set; } = new Dictionary(); public enum MaterialType { Carrier, Wafer } private Dictionary _moduleAssociateStationDic; public override Dictionary ModuleAssociateStationDic { get { return _moduleAssociateStationDic; } set { _moduleAssociateStationDic = value; } } private Dictionary _moduleAssociateHandDic; public Dictionary ModuleAssociateHandDic { get { return _moduleAssociateHandDic; } set { _moduleAssociateHandDic = value; } } private IoAlarmSignal _tpStatus = null; public GM201LVPRobot(string module, string name, string scRoot, MaterialType material, IoSensor[] dis, IoTrigger[] dos) : base(module, name) { Module = module; Name = name; _MaterialType = material; isSimulatorMode = SC.ContainsItem("System.IsSimulatorMode") ? SC.GetValue("System.IsSimulatorMode") : false; _scRoot = scRoot; _address = SC.GetStringValue($"{Name}.Address"); _enableLog = SC.GetValue($"{Name}.EnableLogMessage"); //UnitNumber = SC.GetValue($"{_scRoot}.{Name}.UnitNumber"); //IsEnableCheckSum = SC.GetValue($"{_scRoot}.{Name}.EnableCheckSum"); //IsEnableSeqNo = SC.GetValue($"{_scRoot}.{Name}.EnableSeqNo"); //SpeedLevelSetting = SC.GetValue($"{Name}.SpeedLevel"); _connection = new GM201LVPRobotConnection(this, _address); _connection.EnableLog(_enableLog); //SeqnoGenerator = new GM201LVPTokenGenerator($"{_scRoot}.{Name}.CommunicationToken"); if (dis != null && dis.Length >= 5) { _diRobotReady = dis[0]; _diRobotBlade1WaferOn = dis[1]; _diRobotBlade2WaferOn = dis[2]; _diRobotError = dis[3]; _diTPinUse = dis[4]; _diRobotError.OnSignalChanged += _diRobotError_OnSignalChanged; _diTPinUse.OnSignalChanged += _diTPinUse_OnSignalChanged; } if (dos != null && dos.Length >= 1) { _doRobotHold = dos[0]; } ConnectionManager.Instance.Subscribe($"{Name}", _connection); _thread = new PeriodicJob(10, OnTimer, $"{Module}.{Name} MonitorHandler", true); ReadStationItemContents.Add("00", "Upward offset"); ReadStationItemContents.Add("01", "Downward offset"); ReadStationItemContents.Add("02", "Grip position offset"); ReadStationItemContents.Add("06", "G2/P3 offset in the extending direction"); ReadStationItemContents.Add("08", "Put downward offset"); ReadStationItemContents.Add("70", "Get operation Movet_grip function yes/no"); ReadStationItemContents.Add("71", "Get operation rising pattern"); ReadStationItemContents.Add("80", "Put operation Move_grip function yes/no"); ReadStationItemContents.Add("81", "Put operation dropping pattern"); ReadStationItemContents.Add("50", "Slot Numbers"); ReadStationItemContents.Add("30", "Slot pitch(Left elbow,Blade1)"); ReadStationItemContents.Add("31", "Slot pitch(Left elbow,Blade2)"); ReadStationItemContents.Add("32", "Slot pitch(Right elbow,Blade1)"); ReadStationItemContents.Add("33", "Slot pitch(Right elbow,Blade2)"); if (Name == "CarrierRobot") { _tpStatus = DEVICE.GetDevice($"PM1.AlarmSignaFOUPRobotTPStatusWarning"); } else { _tpStatus = DEVICE.GetDevice($"PM1.AlarmSignaWaferRobotTPStatusWarning"); } ResetPropertiesAndResponses(); RegisterSpecialData(); RegisterAlarm(); } protected override void SubscribeWaferLocation() { } private void RegisterAlarm() { EV.Subscribe(new EventItem("Alarm", $"{Name}Error040", $"{Name} Robot Occurred Error:机械手在 TP 模式中,命令被拒绝。", "机械手在 TP 模式中,命令被拒绝。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error041", $"{Name} Robot Occurred Error:机械手在空模式中,命令被拒绝。", "机械手在空模式中,命令被拒绝。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error055", $"{Name} Robot Occurred Error:设定无法访问的工位。", "指定了不可访问的工位类型。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error057", $"{Name} Robot Occurred Error:运动失败。", "伺服电机执行运动程序失败。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error070", $"{Name} Robot Occurred Error:位置未记录完整。", "命令被拒绝,因为此工位没有示教,未记录位置信息。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error072", $"{Name} Robot Occurred Error:层数超限。", "机械手运行位置已超出工位层数上限。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error073", $"{Name} Robot Occurred Error:禁止轴动作。", "当前轴动作可能会导致碰撞。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*00", $"{Name} Robot Occurred Error:伺服报警。", "控制器判断驱动器有报警。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*01", $"{Name} Robot Occurred Error:伺服警告。", "控制器判断驱动器警告。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*02", $"{Name} Robot Occurred Error:伺服驱动器参数错误1", "伺服单元的参数有误差。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*03", $"{Name} Robot Occurred Error:主回路错误。", "主电路的检测数据有错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*04", $"{Name} Robot Occurred Error:伺服驱动器参数错误2。", "伺服参数异常。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*05", $"{Name} Robot Occurred Error:结合误差1。", "连接不支持的设备。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*07", $"{Name} Robot Occurred Error:结合误差2。", "编码器类型不匹配。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*08", $"{Name} Robot Occurred Error:伺服驱动器参数错误3。", "伺服参数异常。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*10", $"{Name} Robot Occurred Error:溢出电流。", "过电流。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*30", $"{Name} Robot Occurred Error:检测到再生错误。", "检测再生电路错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*32", $"{Name} Robot Occurred Error:再生过载。", "发生再生过载。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*33", $"{Name} Robot Occurred Error:主电路电源接线错误。", "电源接线不正确。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*40", $"{Name} Robot Occurred Error:过电压。", "驱动器电压过高。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*41", $"{Name} Robot Occurred Error:欠电压。", "驱动器电压过底。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*50", $"{Name} Robot Occurred Error:碰撞检出警报。", "检测到了碰撞发生。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*51", $"{Name} Robot Occurred Error:电机超速。", "电机转速过高。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*52", $"{Name} Robot Occurred Error:振动报警。", "电机转速出现异常振荡。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*55", $"{Name} Robot Occurred Error:伺服驱动器参数错误4。", "伺服参数异常。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*71", $"{Name} Robot Occurred Error:瞬时过载(电机)。", "电机被施加了很大程度上超过额定值的转矩。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*72", $"{Name} Robot Occurred Error:连续过载(电机)。", "一个大大超过额定值的转矩被连续施加。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*73", $"{Name} Robot Occurred Error:动态制动过载。", "超过动态制动电阻容量。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*74", $"{Name} Robot Occurred Error:浪涌限流电阻过载。", "主电路电源经常被打开和关闭。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*7A", $"{Name} Robot Occurred Error:控制器风机停止。", "控制器风扇停止运行。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*7B", $"{Name} Robot Occurred Error:温度传感器电路错误。", "温度传感器电路错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*81", $"{Name} Robot Occurred Error:绝对编码器备份错误。", "绝对编码器电池被移除过,位置数据被清除。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*82", $"{Name} Robot Occurred Error:绝对编码器校验错误", "编码器内存的校验和结果有错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*83", $"{Name} Robot Occurred Error:绝对编码器的电池电压低。", "绝对值编码器备用电池电压低。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*84", $"{Name} Robot Occurred Error:编码器数据误差。", "编码器内部数据错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*85", $"{Name} Robot Occurred Error:编码器速度过快。", "通电时编码器高速旋转。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*86", $"{Name} Robot Occurred Error:编码器过热。", "编码器过热。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*B3", $"{Name} Robot Occurred Error:电流检测错误。", "电流检测电路错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*B6", $"{Name} Robot Occurred Error:伺服 M-III 通信错误。", "MECHATROLINK 通信出现错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*BF", $"{Name} Robot Occurred Error:系统报警。", "伺服单元内部程序错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*C1", $"{Name} Robot Occurred Error:电机失控。", "伺服电机失控。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*C2", $"{Name} Robot Occurred Error:相位信息不匹配。", "相位信息不匹配。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*C5", $"{Name} Robot Occurred Error:极性检测失败。", "极性检测错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*C8", $"{Name} Robot Occurred Error:编码器复位错误。", "多回合数据未正确清除或设置。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*C9", $"{Name} Robot Occurred Error:编码器通信错误。", "编码器与伺服单元通信错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*CA", $"{Name} Robot Occurred Error:编码器参数错误1。", "编码器中的参数已损坏。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*CB", $"{Name} Robot Occurred Error:编码器参数错误2。", "与编码器通信的内容不正确。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*CC", $"{Name} Robot Occurred Error:编码器参数错误3。", "编码器与驱动器数据不一致。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*D0", $"{Name} Robot Occurred Error:位置偏差错误。", "位置偏差脉冲超过设定值。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*D3", $"{Name} Robot Occurred Error:位置数据溢出。", "反馈数据超过+1,879,048,192。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*D8", $"{Name} Robot Occurred Error:转矩检测异常。", "检测到异常转矩。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*E0", $"{Name} Robot Occurred Error:伺服 M-III 通信错误 2。", "MECHATROLINK 与伺服单元通信时发生同步错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*E4", $"{Name} Robot Occurred Error:伺服 M-III 通信错误 3。", "MECHATROLINK 通信设置不正确。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*E5", $"{Name} Robot Occurred Error:伺服 M-III 通信错误 4。", "MECHATROLINK 与伺服单元通信时发生同步错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*E6", $"{Name} Robot Occurred Error:伺服 M-III 通信错误 5。", "MECHATROLINK 通信出现错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*ED", $"{Name} Robot Occurred Error:伺服 M-III 通信错误 6。", "MECHATROLINK 通信出现错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error*F1", $"{Name} Robot Occurred Error:相位损失。", "电源缺相。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorE*E", $"{Name} Robot Occurred Error:通信错误(内部控制器)。", "控制器内部通信故障。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error930", $"{Name} Robot Occurred Error:未定义的命令收到。", "从主机接收到未定义的命令。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error940", $"{Name} Robot Occurred Error:消息参数错误。", "从主机接收的命令附加的参数无效。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error950", $"{Name} Robot Occurred Error:机械手在运动中,命令被拒绝。", "命令被拒绝,控制器正在执行一个运动命令。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error970", $"{Name} Robot Occurred Error:分隔符错误。", "没有分隔符。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error971", $"{Name} Robot Occurred Error:结束符错误。", "结束符不正确。")); EV.Subscribe(new EventItem("Alarm", $"{Name}Error972", $"{Name} Robot Occurred Error:指令长度错误。", "指令长度不正确。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorA10", $"{Name} Robot Occurred Error:外部急停。", "I/O 启用外部紧急停止(EXESP)功能。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorA20", $"{Name} Robot Occurred Error:T.P 紧急停。", "教学挂件上的急停按钮被按下。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorA30", $"{Name} Robot Occurred Error:急停。", "主机发出紧急停止命令。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorA31", $"{Name} Robot Occurred Error:碰撞检出。", "机械手发生碰撞。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorA45", $"{Name} Robot Occurred Error:单元风扇1错误。", "主机风扇1故障。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorA47", $"{Name} Robot Occurred Error:机械手风扇1错误。", "机械手风扇故障。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorA4F", $"{Name} Robot Occurred Error:控制器电池报警。", "控制器内存备用电池电量不足。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorA60", $"{Name} Robot Occurred Error:F47 连续错误。", "重新检测到供电电压下降。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAE0", $"{Name} Robot Occurred Error:主机模式切换错误。", "模式切换到“HOST”,同时从示教器控制。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAE1", $"{Name} Robot Occurred Error:教模式切换错误。", "在主机控制下切换为“TEACH”模式。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAE8", $"{Name} Robot Occurred Error:伺服使能开关错误。", "示教器操作时松开使能开关。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAF0", $"{Name} Robot Occurred Error:互锁故障1。", "检测到安全模块错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAF1", $"{Name} Robot Occurred Error:互锁故障2。", "检测到安全模块错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAF2", $"{Name} Robot Occurred Error:互锁故障3。", "检测到安全模块错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAF3", $"{Name} Robot Occurred Error:互锁故障4。", "检测到安全模块错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAF4", $"{Name} Robot Occurred Error:互锁故障5。", "检测到安全模块错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAF5", $"{Name} Robot Occurred Error:互锁故障6。", "检测到安全模块错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAF6", $"{Name} Robot Occurred Error:互锁故障7。", "检测到安全模块错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAF8", $"{Name} Robot Occurred Error:互锁故障8。", "检测到安全模块错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAF9", $"{Name} Robot Occurred Error:互锁故障9。", "检测到安全模块错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAFA", $"{Name} Robot Occurred Error:互锁故障10。", "检测到安全模块错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAFB", $"{Name} Robot Occurred Error:互锁故障11。", "检测到安全模块错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorAFC", $"{Name} Robot Occurred Error:互锁故障12。", "检测到安全模块错误。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB20", $"{Name} Robot Occurred Error:轴1正(+)方向软件限位检测1。", "正方向超过Axis-1运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB21", $"{Name} Robot Occurred Error:轴2正(+)方向软件限位检测1。", "正方向超过Axis-3运动范围。.")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB22", $"{Name} Robot Occurred Error:轴3正(+)方向软件限位检测1。", "正方向超过Axis-3运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB23", $"{Name} Robot Occurred Error:轴4正(+)方向软件限位检测1。", "正方向超过Axis-4运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB24", $"{Name} Robot Occurred Error:轴5正(+)方向软件限位检测1。", "正方向超过Axis-5运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB25", $"{Name} Robot Occurred Error:轴6正(+)方向软件限位检测1。", "正方向超过Axis-6运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB28", $"{Name} Robot Occurred Error:轴1正(+)方向限位检测。", "正方向超过Axis-1运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB29", $"{Name} Robot Occurred Error:轴2正(+)方向限位检测。", "正方向超过Axis-2运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB2A", $"{Name} Robot Occurred Error:轴3正(+)方向限位检测。", "正方向超过Axis-3运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB2B", $"{Name} Robot Occurred Error:轴4正(+)方向限位检测。", "正方向超过Axis-4运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB2C", $"{Name} Robot Occurred Error:轴5正(+)方向限位检测。", "正方向超过Axis-5运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB2D", $"{Name} Robot Occurred Error:轴6正(+)方向限位检测。", "正方向超过Axis-6运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB30", $"{Name} Robot Occurred Error:轴1负(-)方向软件限位检测1。", "负方向超过Axis-1运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB31", $"{Name} Robot Occurred Error:轴2负(-)方向软件限位检测1。", "负方向超过Axis-2运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB32", $"{Name} Robot Occurred Error:轴3负(-)方向软件限位检测1。", "负方向超过Axis-3运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB33", $"{Name} Robot Occurred Error:轴4负(-)方向软件限位检测1。", "负方向超过Axis-4运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB34", $"{Name} Robot Occurred Error:轴5负(-)方向软件限位检测1。", "负方向超过Axis-5运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB35", $"{Name} Robot Occurred Error:轴6负(-)方向软件限位检测1。", "负方向超过Axis-6运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB38", $"{Name} Robot Occurred Error:轴1负(-)方向限位检测。", "负方向超过Axis-1运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB39", $"{Name} Robot Occurred Error:轴2负(-)方向限位检测。", "负方向超过Axis-2运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB3A", $"{Name} Robot Occurred Error:轴3负(-)方向限位检测。", "负方向超过Axis-3运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB3B", $"{Name} Robot Occurred Error:轴4负(-)方向限位检测。", "负方向超过Axis-4运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB3C", $"{Name} Robot Occurred Error:轴5负(-)方向限位检测。", "负方向超过Axis-5运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB3D", $"{Name} Robot Occurred Error:轴6负(-)方向限位检测。", "负方向超过Axis-6运动范围。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB88", $"{Name} Robot Occurred Error:手爪传感器ON超时错误1。", "取片时手爪传感器1没有在规定时间内ON。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB89", $"{Name} Robot Occurred Error:手爪传感器ON超时错误2。", "取片时手爪传感器2没有在规定时间内ON。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB8A", $"{Name} Robot Occurred Error:手爪传感器OFF超时错误1。", "放片时手爪传感器1没有在规定时间内OFF。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorB8B", $"{Name} Robot Occurred Error:手爪传感器OFF超时错误2。", "放片时手爪传感器2没有在规定时间内OFF。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorBA8", $"{Name} Robot Occurred Error:手爪传感器OFF状态错误1。", "取片时手爪传感器1状态应该为OFF但当前状态未符合。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorBA9", $"{Name} Robot Occurred Error:手爪传感器OFF状态错误2。", "取片时手爪传感器2状态应该为OFF但当前状态未符合。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorBAA", $"{Name} Robot Occurred Error:手爪传感器ON状态错误1。", "放片时手爪传感器1状态应该为ON但当前状态未符合。")); EV.Subscribe(new EventItem("Alarm", $"{Name}ErrorBAB", $"{Name} Robot Occurred Error:手爪传感器ON状态错误2。", "放片时手爪传感器 2 状态应该为 ON 但当前状态未符合。")); } public void NotifyAlarmByErrorCode(string errorcode) { EV.Notify($"{Name}Error{errorcode}"); } private void _diTPinUse_OnSignalChanged(IoSensor arg1, bool arg2) { SetMaintenanceMode(!arg1.Value); } private void _diRobotError_OnSignalChanged(IoSensor arg1, bool arg2) { if (arg1.Value == false) { lock (_locker) { _lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RSTS")); } OnError("RobotError"); } } private void ResetPropertiesAndResponses() { } private void RegisterSpecialData() { if (Name != "CarrierRobot") { DATA.Subscribe($"{Name}.CurrentArm1Position", () => CurrentArm1Position); DATA.Subscribe($"{Name}.CurrentArm2Position", () => CurrentArm2Position); DATA.Subscribe($"{Name}.CurrentZPosition", () => CurrentZPosition); DATA.Subscribe($"{Name}.IsWaferPresenceOnBlade2", () => IsWaferPresenceOnBlade2); DATA.Subscribe($"{Name}.IsWaferPresenceOnBlade3", () => IsWaferPresenceOnBlade3); DATA.Subscribe($"{Name}.IsWaferPresenceOnBlade4", () => IsWaferPresenceOnBlade4); DATA.Subscribe($"{Name}.IsWaferPresenceOnBlade5", () => IsWaferPresenceOnBlade5); } DATA.Subscribe($"{Name}.TPStatus", () => _tpStatus != null && _tpStatus.Value); DATA.Subscribe($"{Name}.CurrentExtensionPosition", () => CurrentExtensionPosition); DATA.Subscribe($"{Name}.CurrentThetaPosition", () => CurrentThetaPosition); DATA.Subscribe($"{Name}.IsManipulatorBatteryLow", () => IsManipulatorBatteryLow); DATA.Subscribe($"{Name}.IsCommandExecutionReady", () => IsCommandExecutionReady); DATA.Subscribe($"{Name}.IsServoON", () => IsServoON); DATA.Subscribe($"{Name}.IsErrorOccurred", () => IsErrorOccurred); DATA.Subscribe($"{Name}.IsControllerBatteryLow", () => IsControllerBatteryLow); DATA.Subscribe($"{Name}.IsWaferPresenceOnBlade1", () => IsWaferPresenceOnBlade1); DATA.Subscribe($"{Name}.MappingResult", () => ReadSlotMap); DATA.Subscribe($"{Name}.ReadRobotParameterResultDict", () => ReadRobotParameterResult); DATA.Subscribe($"{Name}.ErrorCode", () => ErrorCode); DATA.Subscribe($"{Name}.RobotSpeed", () => SpeedLevelSetting.ToString()); OP.Subscribe($"{Name}.SetSpeed", InvokeSetSpeed); } private bool OnTimer() { try { _connection.MonitorTimeout(); if (!_connection.IsConnected || _connection.IsCommunicationError) { lock (_locker) { _lstHandlers.Clear(); _lstMonitorHandler.Clear(); } _trigRetryConnect.CLK = !_connection.IsConnected; if (_trigRetryConnect.Q) { if (!_connection.Connect()) { EV.PostAlarmLog(RobotModuleName.ToString(), $"Can not connect with {_connection.Address}, {Name}"); } else { //_lstHandler.AddLast(new RobotHirataR4QueryPinHandler(this, _deviceAddress)); //_lstHandler.AddLast(new RobotHirataR4SetCommModeHandler(this, _deviceAddress, EnumRfPowerCommunicationMode.Host)); } } return true; } HandlerBase handler = null; lock (_locker) { if (!_connection.IsBusy) { if (_lstHandlers.Count > 0) { handler = _lstHandlers.First.Value; _connection.Execute(handler); _lstHandlers.RemoveFirst(); } else { if (_lstMonitorHandler.Count > 0) { handler = _lstMonitorHandler.First.Value; _connection.Execute(handler); _lstMonitorHandler.RemoveFirst(); } } } else { _connection.MonitorTimeout(); _trigCommunicationError.CLK = _connection.IsCommunicationError; if (_trigCommunicationError.Q) { _lstHandlers.Clear(); _lstMonitorHandler.Clear(); //EV.PostAlarmLog(RobotModuleName.ToString(), $"{Module}.{Name} communication error, {_connection.LastCommunicationError}"); OnError($"{Name} communication error, {_connection.LastCommunicationError}"); //_trigActionDone.CLK = true; } } } } catch (Exception ex) { LOG.Write(ex); } return true; } public bool Connect() { return _connection.Connect(); } public bool Disconnect() { return _connection.Disconnect(); } public override bool IsReady() { //if (_diRobotReady!=null && !_diRobotReady.Value) // return false; if (_diRobotError != null && !_diRobotError.Value) return false; if (_diTPinUse != null && !_diTPinUse.Value) return false; return RobotState == RobotStateEnum.Idle && !IsBusy && !_connection.IsBusy && _lstHandlers.Count == 0 && !_connection.IsCommunicationError && _connection.IsConnected; } public override bool IsReady(out string reason) { reason = ""; //if (_diRobotReady!=null && !_diRobotReady.Value) // return false; if (_diRobotError != null && !_diRobotError.Value) return false; if (_diTPinUse != null && !_diTPinUse.Value) return false; var ret = RobotState == RobotStateEnum.Idle && !IsBusy && !_connection.IsBusy && _lstHandlers.Count == 0 && !_connection.IsCommunicationError && _connection.IsConnected; if (!ret) { if (RobotState != RobotStateEnum.Idle) reason = "RobotState != RobotStateEnum.Idle"; if (IsBusy) reason = "IsBusy"; if (_lstHandlers.Count != 0) reason = "_lstHandlers.Count != 0"; if (_connection.IsCommunicationError) reason = "_connection.IsCommunicationError"; if (!_connection.IsConnected) reason = "!_connection.IsConnected"; } return ret; } public bool ParseReadData(string _command, string[] rdata) { try { if (_command == "RSTS") { return ((rdata.Length == 3 || rdata.Length == 2) && ParseRSTSStatus(rdata)); } if (_command == "RSLV") //Read the speed level { return (rdata.Length == 3 && ParseSpeedLevel(rdata[2])); } if (_command == "RPOS") //Reference current postion { return (rdata.Length > 1 && ParsePositionData(rdata)); } if (_command == "RSTP") //Reference registered position, read the save postion for station { if (rdata.Length == 5) { return ParsePositionAxisDataV2(rdata); } if (rdata.Length == 7) { return ParsePositionAxisData(rdata); } // return (rdata.Length > 6 && ParseRegisteredPositionData(rdata)); } if (_command == "RSTR") //Reference station item value { return (rdata.Length == 4 && ParseStationData(rdata)); } if (_command == "RPRM") //Reference the parameter values of the specified unit { return (rdata.Length == 3 && ParseParameterData(rdata)); } if (_command == "RMSK") //Reference the interlock information { return (rdata.Length == 1 && ParseInterlockInfo(rdata)); } if (_command == "RVER") //Reference the software version { return (rdata.Length == 2 && ParseSoftwareVersion(rdata)); } if (_command == "RMAP") //Reference the slot map { return (rdata.Length > 2 && ParseSlotMap(rdata)); } if (_command == "RMPD") //reference the mapping data { return (rdata.Length > 1 && ParseMappingData(rdata)); } if (_command == "RMCA") // Reference the mapping calibration result { return (rdata.Length > 1 && ParseMappingCalibrationResult(rdata)); } if (_command == "RERR") // Request ERR { return (rdata.Length > 2 && ParseERR(rdata)); } return true; } catch (Exception ex) { LOG.Write(ex); return true; } } public bool ParseRSTSStatus(string[] status) { try { if (status.Length > 2) { //wafer robot int intstatus = Convert.ToInt16(status[2].Substring(5, 2), 16); IsWaferPresenceOnBlade5 = (((intstatus >> 4) & 0x1) == 0x1); IsWaferPresenceOnBlade4 = (((intstatus >> 3) & 0x1) == 0x1); IsWaferPresenceOnBlade3 = (((intstatus >> 2) & 0x1) == 0x1); IsWaferPresenceOnBlade2 = (((intstatus >> 1) & 0x1) == 0x1); IsWaferPresenceOnBlade1 = (((intstatus >> 0) & 0x1) == 0x1); } else { //foup robot int intstatus = Convert.ToInt16(status[1].Substring(5, 2), 16); IsWaferPresenceOnBlade5 = (((intstatus >> 4) & 0x1) == 0x1); IsWaferPresenceOnBlade4 = (((intstatus >> 3) & 0x1) == 0x1); IsWaferPresenceOnBlade3 = (((intstatus >> 2) & 0x1) == 0x1); IsWaferPresenceOnBlade2 = (((intstatus >> 1) & 0x1) == 0x1); IsWaferPresenceOnBlade1 = (((intstatus >> 0) & 0x1) == 0x1); } return true; } catch (Exception ex) { LOG.Write(ex); return true; } } public bool ParseSpeedLevel(string speedlevel) { try { int level = Convert.ToInt32(speedlevel); if (level < 1 || level > 100) return false; SpeedLevel = level; return true; } catch (Exception ex) { LOG.Write(ex); return false; } } public bool ParsePositionData(string[] pdata) { try { if (pdata[1] == "R" || pdata[1] == "F") { CommandZPosition = Convert.ToSingle(pdata[1]) / 1000; CommandThetaPosition = Convert.ToSingle(pdata[2]) / 1000; CommandExtensionPosition = Convert.ToSingle(pdata[3]) / 1000; return true; } return false; } catch (Exception ex) { LOG.Write(ex); return false; } } public bool ParsePositionAxisData(string[] pdata) { try { ReadMemorySpec = pdata[0]; ReadTransferStation = pdata[1]; if (ReadStationItemValues.ContainsKey(pdata[2])) ReadStationItemValues.Remove(pdata[2]); ReadStationItemValues.Add(pdata[2], pdata[3]); if (ReadRobotParameterResult.ContainsKey(ReadTransferStation)) { ReadRobotParameterResult[ReadTransferStation] = $"{pdata[2]},{pdata[3]},{pdata[4]},{pdata[5]},{pdata[6]}"; } else { ReadRobotParameterResult.Add(ReadTransferStation, $"{pdata[2]},{pdata[3]},{pdata[4]},{pdata[5]},{pdata[6]}"); } return true; } catch (Exception ex) { LOG.Write(ex); return false; } } public bool ParsePositionAxisDataV2(string[] pdata) { try { ReadMemorySpec = pdata[0]; ReadTransferStation = pdata[1]; if (ReadStationItemValues.ContainsKey(pdata[2])) ReadStationItemValues.Remove(pdata[2]); ReadStationItemValues.Add(pdata[2], pdata[3]); if (ReadRobotParameterResult.ContainsKey(ReadTransferStation)) { ReadRobotParameterResult[ReadTransferStation] = $"{pdata[2]},{pdata[3]},{pdata[4]}"; } else { ReadRobotParameterResult.Add(ReadTransferStation, $"{pdata[2]},{pdata[3]},{pdata[4]}"); } return true; } catch (Exception ex) { LOG.Write(ex); return false; } } public bool ParseRegisteredPositionData(string[] pdata) { try { ReadMemorySpec = pdata[0]; ReadTransferStation = pdata[1]; ReadSlotNumber = Convert.ToInt16(pdata[2]); ReadArmPosture = pdata[3]; ReadBladeNo = (RobotArmEnum)(Convert.ToInt16(pdata[4]) - 1); if (pdata[5] == "S") ReadPositionType = GM201LVPPositonEnum.RegisteredPosition; if (pdata[5] == "R") ReadPositionType = GM201LVPPositonEnum.ReadyPosition; if (pdata[5] == "M") ReadPositionType = GM201LVPPositonEnum.IntermediatePosition; if (pdata[5] == "B") ReadPositionType = GM201LVPPositonEnum.MappingStartPosition; if (pdata[5] == "E") ReadPositionType = GM201LVPPositonEnum.MappingFinishPosition; return true; } catch (Exception ex) { LOG.Write(ex); return false; } } public bool ParseStationData(string[] pdata) { try { ReadMemorySpec = pdata[0]; ReadTransferStation = pdata[1]; if (ReadStationItemValues.ContainsKey(pdata[2])) ReadStationItemValues.Remove(pdata[2]); ReadStationItemValues.Add(pdata[2], pdata[3]); if (ReadRobotParameterResult.ContainsKey(ReadTransferStation)) { ReadRobotParameterResult[ReadTransferStation] = $"{pdata[2]},{pdata[3]}"; } else { ReadRobotParameterResult.Add(ReadTransferStation, $"{pdata[2]},{pdata[3]}"); } return true; } catch (Exception ex) { LOG.Write(ex); return false; } } public bool ParseParameterData(string[] pdata) { try { ReadParameterType = pdata[0]; ReadParameterNo = pdata[1]; ReadParameterValue = pdata[2]; if (ReadRobotParameterResult.ContainsKey(ReadParameterNo)) { ReadRobotParameterResult[ReadParameterNo] = ReadParameterValue; } else { ReadRobotParameterResult.Add(ReadParameterNo, ReadParameterValue); } return true; } catch (Exception ex) { LOG.Write(ex); return false; } } public bool ParseInterlockInfo(string[] pdata) { try { int intdata = Convert.ToInt16(pdata[1]); IsCheckInterlockWaferPresenceOnBlade1 = (intdata & 0x1) == 0; IsCheckInterlockWaferPresenceOnBlade2 = (intdata & 0x2) == 0; IsCheckInterlockWaferPresenceOnBlade3 = (intdata & 0x4) == 0; IsCheckInterlockWaferPresenceOnBlade4 = (intdata & 0x8) == 0; IsCheckInterlockWaferPresenceOnBlade5 = (intdata & 0x16) == 0; return true; } catch (Exception ex) { LOG.Write(ex); return false; } } public bool ParseSoftwareVersion(string[] pdata) { try { //RobotSystemVersion = pdata[0]; RobotSoftwareVersion = pdata[1]; return true; } catch (Exception ex) { LOG.Write(ex); return false; } } public bool ParseERR(string[] pdata) { try { var index = pdata[1]; var code = pdata[2]; if (code != "000") { EV.Notify($"{Name}Error{code}"); LOG.Write($"{Name} Error {index} {code}"); _isError = true; } else { _isError = false; } return true; } catch (Exception ex) { LOG.Write(ex); return false; } } public bool ParseSlotMap(string[] pdata) { try { ReadMappingTransferStation = pdata[1]; ReadMappingSlotNumbers = pdata[2].Length - 1; StringBuilder sb = new StringBuilder(); for (int i = 1; i < pdata[2].Length; i++) { string value = pdata[2][i].ToString(); switch (value) { case "0": sb.Append("0"); break; case "1": sb.Append("1"); break; case "C": sb.Append("C"); break; case "D": sb.Append("D"); break; } } SlotMap = ReadSlotMap = sb.ToString(); NotifySlotMapResult(CurrentInteractiveModule, ReadSlotMap); return true; } catch (Exception ex) { LOG.Write(ex); return false; } } public bool ParseMappingData(string[] pdata) { try { ReadMappingTransferStation = pdata[0]; List lstupdata = new List(); List lstdowndata = new List(); for (int i = 0; i < (pdata.Length - 1) / 2; i++) { lstupdata.Add(pdata[2 * i + 1].Remove(0, 3)); lstdowndata.Add(pdata[2 * i + 2]); } ReadMappingDownData = lstdowndata.ToArray(); ReadMappingUpData = lstupdata.ToArray(); return true; } catch (Exception ex) { LOG.Write(ex); return false; } } public bool ParseMappingCalibrationResult(string[] pdata) { try { ReadMappingTransferStation = pdata[0]; ReadMappingCalibrationResult.Clear(); ReadMappingCalibrationResult.Add("LowestLaySlotPosition", Convert.ToInt32(pdata[1]) / 1000); ReadMappingCalibrationResult.Add("HighestLaySlotPosition", Convert.ToInt32(pdata[2]) / 1000); ReadMappingCalibrationResult.Add("WaferWidth", Convert.ToInt32(pdata[3]) / 1000); ReadMappingCalibrationResult.Add("ThreshhholdValueofDoubleInsertion", Convert.ToInt32(pdata[4]) / 1000); ReadMappingCalibrationResult.Add("ThreshhholdValueofSlantingInsertion1", Convert.ToInt32(pdata[5]) / 1000); ReadMappingCalibrationResult.Add("ThreshhholdValueofSlantingInsertion2", Convert.ToInt32(pdata[6]) / 1000); return true; } catch (Exception ex) { LOG.Write(ex); return false; } } protected override bool fClear(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} clear failed for not connect with {_connection.Address}"); return false; } lock (_locker) { _lstHandlers.Clear(); _connection.ForceClear(); //_lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "CCLR", "E")); string strpara = "1,1,N"; _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "INIT", strpara)); _lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RSTS")); } return true; } protected override bool fStartReadData(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} read data failed for not connect with {_connection.Address}"); return false; } if (param.Length < 1) return false; string readcommand = param[0].ToString(); switch (readcommand) { case "CurrentStatus": lock (_locker) { _lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RSTS")); //_lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RPOS", "F")); //_lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RPOS", "R")); } break; case "CurrentRobotParameters": lock (_locker) { var parameters = param[1].ToString().Split(';').ToList(); foreach (var item in parameters) { _lstMonitorHandler.AddLast(new GM201LVPRobotReadHandler(this, "RPRM", item)); } } break; case "CurrentRobotPositionConfig": lock (_locker) { var parameters = param[1].ToString().Split(';').ToList(); foreach (var item in parameters) { _lstMonitorHandler.AddLast(new GM201LVPRobotReadHandler(this, "RSTR", item)); } } break; case "CurrentRobotPositionAxis": lock (_locker) { var parameters = param[1].ToString().Split(';').ToList(); foreach (var item in parameters) { _lstMonitorHandler.AddLast(new GM201LVPRobotReadHandler(this, "RSTP", item)); } } break; default: break; } return true; } protected override bool fMonitorReadData(object[] param) { IsBusy = false; return _lstHandlers.Count == 0 && !_connection.IsBusy; } private void ExecuteHandler(HandlerBase handler) { _connection.Execute(handler); } private string Checksum(byte[] bytes) { int sum = 0; foreach (byte code in bytes) { sum += code; } string hex = String.Format("{0:X2}", sum % 256); return hex; } private Stopwatch _timerActionMonitor = new Stopwatch(); protected override bool fStartSetParameters(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} set parameter failed for not connect with {_connection.Address}"); return false; } try { string strParameter; string setcommand = param[0].ToString(); switch (setcommand) { case "SetSpeed": // SSPD Set the motion speed int speedLevel = Convert.ToInt32(param[1]); if (speedLevel > 100) speedLevel = 100; if (speedLevel < 1) speedLevel = 1; lock (_locker) { _lstHandlers.AddLast(new GM201LVPRobotSetHandler(this, "SSLV", $"1,{SpeedLevelSetting.ToString("D3")}")); } break; case "SetParameter": // SPRM lock (_locker) { var data = param[1].ToString().Split(';').ToList(); foreach (var item in data) { if (!string.IsNullOrEmpty(item)) { _lstMonitorHandler.AddLast(new GM201LVPRobotSetHandler(this, "SPRM", item)); } } } break; case "SetPositionConfig": //SSTR,C01,000,00000000025 lock (_locker) { var data = param[1].ToString().Split(';').ToList(); foreach (var item in data) { if (!string.IsNullOrEmpty(item)) { _lstMonitorHandler.AddLast(new GM201LVPRobotSetHandler(this, "SSTR", item)); } } } break; case "SetPositionAxis": //SABS,C01,00000100000,00000090000,00000000000,00000450000,00000010000 lock (_locker) { var data = param[1].ToString().Split(';').ToList(); foreach (var item in data) { if (!string.IsNullOrEmpty(item)) { _lstMonitorHandler.AddLast(new GM201LVPRobotSetHandler(this, "SABS", item)); } } } break; case "EnableInterLock": //SMSK int smskValid = Convert.ToInt16(param[1].ToString()); lock (_locker) { _lstHandlers.AddLast(new GM201LVPRobotSetHandler(this, "SPRM", smskValid.ToString("D4"))); } break; } _timerActionMonitor.Restart(); } catch (Exception) { string reason = ""; if (param != null) { foreach (var para in param) { reason += para.ToString() + ","; } } EV.PostAlarmLog(Name, "Set command parameter invalid:" + reason); return false; } return true; } protected override bool fMonitorSetParamter(object[] param) { IsBusy = false; if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(_timeLimitMotion)) { _timerActionMonitor.Stop(); OnError("SetParameterTimeOut"); return true; } if (_lstHandlers.Count == 0 && !_connection.IsBusy) { //EV.PostInfoLog(Name, "SetParameter complete"); return true; } return false; } protected override bool fStartTransferWafer(object[] param) { return false; } protected override bool fStartUnGrip(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} ungrip failed for not connect with {_connection.Address}"); return false; } lock (_locker) { RobotArmEnum arm = (RobotArmEnum)param[0]; string strpara = (arm == RobotArmEnum.Both ? "F" : ((int)arm + 1).ToString()) + ",0,0"; _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "CSOL", strpara)); } _timerActionMonitor.Restart(); return true; } protected override bool fMonitorUnGrip(object[] param) { IsBusy = false; if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(_timeLimitMotion)) { _timerActionMonitor.Stop(); OnError("UngripTimeOut"); return true; } if (_lstHandlers.Count == 0 && !_connection.IsBusy) { //EV.PostInfoLog(Name, "Ungrip complete"); return true; } return false; } protected override bool fStartGrip(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} grip failed for not connect with {_connection.Address}"); return false; } lock (_locker) { RobotArmEnum arm = (RobotArmEnum)param[0]; string strpara = (arm == RobotArmEnum.Both ? "F" : ((int)arm + 1).ToString()) + ",1,0"; _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "CSOL", strpara)); } return true; } protected override bool fMonitorGrip(object[] param) { IsBusy = false; if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(_timeLimitMotion)) { _timerActionMonitor.Stop(); OnError("GripTimeOut"); return true; } if (_lstHandlers.Count == 0 && !_connection.IsBusy) { //EV.PostInfoLog(Name, "Grip complete"); return true; } return false; } protected override bool fStartInit(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} init failed for not connect with {_connection.Address}"); return false; } lock (_locker) { if (_doRobotHold != null) { _doRobotHold.SetTrigger(true, out _); Thread.Sleep(100); } //ExecuteHandler(new GM201LVPRobotReadHandler(this, "RERR", "001")); if (_isError) { string strparaReset = "1,1,N"; _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "INIT", strparaReset)); _isError = false; } string strpara = "1,1,G"; if (RobotModuleName == ModuleName.CarrierRobot) { strpara = "1,1,S"; } _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "INIT", strpara)); if (SpeedLevelSetting >= 1 && SpeedLevelSetting <= 100) _lstHandlers.AddLast(new GM201LVPRobotSetHandler(this, "SSLV", $"1,{SpeedLevelSetting.ToString("D3")}")); _lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RSTS")); } _timerActionMonitor.Restart(); return true; } protected override bool fMonitorInit(object[] param) { IsBusy = false; if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(_timeLimitHome)) { _timerActionMonitor.Stop(); OnError("InitTimeOut"); return true; } if (_lstHandlers.Count == 0 && !_connection.IsBusy) { BladeTarget = ModuleName.System; Blade1Target = ModuleName.System; Blade2Target = ModuleName.System; CmdTarget = ModuleName.System; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; //EV.PostInfoLog(Name, "Init complete"); return true; } return false; } protected override bool fStartHome(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} init failed for not connect with {_connection.Address}"); return false; } lock (_locker) { if (_doRobotHold != null) { _doRobotHold.SetTrigger(true, out _); Thread.Sleep(100); } //ExecuteHandler(new GM201LVPRobotReadHandler(this, "RERR", "001")); if (_isError) { string strparaReset = "1,1,N"; _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "INIT", strparaReset)); _isError = false; } string strpara = "1,1,G"; if (RobotModuleName == ModuleName.CarrierRobot) { strpara = "1,1,S"; } _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "INIT", strpara, _timeLimitHome)); if (SpeedLevelSetting >= 1 && SpeedLevelSetting <= 100) _lstHandlers.AddLast(new GM201LVPRobotSetHandler(this, "SSLV", $"1,{SpeedLevelSetting.ToString("D3")}")); _lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RSTS")); } _timerActionMonitor.Restart(); return true; } protected override bool fMonitorHome(object[] param) { IsBusy = false; if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(_timeLimitHome)) { _timerActionMonitor.Stop(); OnError("HomeTimeOut"); return true; } if (_lstHandlers.Count == 0 && !_connection.IsBusy) { BladeTarget = ModuleName.System; Blade1Target = ModuleName.System; Blade2Target = ModuleName.System; CmdTarget = ModuleName.System; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; //EV.PostInfoLog(Name, "Home complete"); return true; } return false; } protected override bool fStartGoTo(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} move failed for not connect with {_connection.Address}"); return false; } try { RobotArmEnum arm = (RobotArmEnum)param[0]; ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString()); BladeTarget = module; Blade1Target = module; Blade2Target = module; int slot = (int)param[2] + 1; //RobotPostionEnum postype = (RobotPostionEnum)param[3]; RobotPostionEnum postype = (RobotPostionEnum)Enum.Parse(typeof(RobotPostionEnum), param[3].ToString()); string strpara = string.Empty; //bool isFromOriginal = (bool)param[8]; //bool isJumpToNextMotion = (bool)param[9]; //if ((int)postype >= 0 && (int)postype < 10) //{ // strpara = "G"; //} //if ((int)postype >= 10 && (int)postype < 20) //{ // strpara = "P"; //} //if ((int)postype >= 20 && (int)postype < 30) //{ // strpara = "E"; //} string trsSt = GetStationsName(module); if (string.IsNullOrEmpty(trsSt)) { LOG.Write("invalid transfer paramter"); return false; } string TrsPnt = string.Empty; if (postype == RobotPostionEnum.PickReady) { TrsPnt = "G"; } if (postype == RobotPostionEnum.PlaceReady) { TrsPnt = "P"; } //strCmd = "MTCH"; if (_MaterialType == MaterialType.Wafer) { int bladeNo = (arm == RobotArmEnum.Blade1 || arm == RobotArmEnum.Lower) ? 4 : 31; strpara += $"{TrsPnt},{trsSt},{slot:D3},{bladeNo:D3}"; } else if (_MaterialType == MaterialType.Carrier) { //strpara = $"{TrsPnt},{trsSt},001,000"; string strHand = GetHandsName(module); if (string.IsNullOrEmpty(strHand)) { LOG.Write("Invalid Paramter."); return false; } strpara = $"{TrsPnt},{trsSt},001,{strHand},001"; } lock (_locker) { { _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "MTCH", strpara)); _lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RSTS")); } } _timerActionMonitor.Restart(); return true; } catch (Exception ex) { LOG.Write(ex); return false; } } protected override bool fMonitorGoTo(object[] param) { if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(_timeLimitMotion)) { _timerActionMonitor.Stop(); OnError("GotoTimeOut"); return true; } if (_lstHandlers.Count != 0 || _connection.IsBusy) return false; IsBusy = false; return true; } protected override bool fGoToComplete(object[] param) { try { if (_lstHandlers.Count > 0) return false; RobotArmEnum arm = (RobotArmEnum)CurrentParamter[0]; ModuleName sourcemodule = (ModuleName)Enum.Parse(typeof(ModuleName), CurrentParamter[1].ToString()); int SourceslotIndex = (int)CurrentParamter[2]; RobotPostionEnum postype = (RobotPostionEnum)CurrentParamter[3]; //bool isFromOriginal = (bool)CurrentParamter[8]; //bool isJumpToNextMotion = (bool)CurrentParamter[9]; } catch (Exception ex) { LOG.Write(ex); } return base.fGoToComplete(param); } protected override bool fStop(object[] param) { lock (_locker) { if (_doRobotHold != null) _doRobotHold.SetTrigger(false, out _); _lstHandlers.Clear(); _connection.ForceClear(); //ExecuteHandler(new GM201LVPRobotMotionHandler(this, "CSTP", "E")); } return true; ; } protected override bool fMonitorStop(object[] param) { return true; } protected override bool fStartMove(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} move failed for not connect with {_connection.Address}"); return false; } try { string strCmd = param[0].ToString(); string strpara = string.Empty; for (int i = 1; i < param.Length; i++) { if (i == 1) strpara += param[i].ToString(); else strpara += "," + param[i].ToString(); } lock (_locker) { _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, strCmd, strpara)); _lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RPOS", "F")); } _timerActionMonitor.Restart(); return true; } catch (Exception ex) { LOG.Write(ex); return false; } } private string GetStationsName(ModuleName chamber) { if (!_moduleAssociateStationDic.ContainsKey(chamber.ToString())) { LOG.Error($"not define teach position {chamber}"); return ""; } var moduleIndex = _moduleAssociateStationDic[chamber.ToString()]; return moduleIndex.ToString(); } private string GetHandsName(ModuleName chamber) { if (!_moduleAssociateHandDic.ContainsKey(chamber.ToString())) { LOG.Error($"not define teach position {chamber}"); return ""; } var moduleIndex = _moduleAssociateHandDic[chamber.ToString()]; return moduleIndex.ToString(); } private int GetSlotsNumber(ModuleName module) { try { if (ModuleHelper.IsLoadPort(module)) { return DEVICE.GetDevice(module.ToString()).ValidSlotsNumber; } return SC.GetValue($"CarrierInfo.{module}SlotsNumber"); } catch (Exception ex) { LOG.Write(ex); return -1; } } private bool _isNeedMappignData { get { if (SC.ContainsItem($"Robot.{RobotModuleName}.NeedReadMapData")) return SC.GetValue($"Robot.{RobotModuleName}.NeedReadMapData"); return true; } } protected override bool fStartMapWafer(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} map failed for not connect with {_connection.Address}"); return false; } try { ReadSlotMap = ""; //RobotArmEnum pickarm = (RobotArmEnum)param[0]; ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[0].ToString()); BladeTarget = module; Blade1Target = module; Blade2Target = module; //int slotsNumber = GetSlotsNumber(module); //if (slotsNumber == -1) //{ // LOG.Write("Invalid mapping paramter slots number"); // return false; //} string TrsSt = GetStationsName(module); if (string.IsNullOrEmpty(TrsSt)) { LOG.Write("Invalid Paramter."); return false; } string strpara = $"{TrsSt},1"; lock (_locker) { CurrentInteractiveModule = module; _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "MMAP", strpara, _timeLimitMotion)); //if (_isNeedMappignData) // _lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RMPD", $"{GetStationsName(module)},025")); _lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RMAP", $"{GetStationsName(module)}")); } _timerActionMonitor.Restart(); return true; } catch (Exception ex) { LOG.Write(ex); return false; } } protected override bool fMonitorMap(object[] param) { if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(_timeLimitMotion)) { _timerActionMonitor.Stop(); OnError("PlaceTimeOut"); return true; } if (_lstHandlers.Count != 0 || _connection.IsBusy) return false; IsBusy = false; BladeTarget = ModuleName.System; Blade1Target = ModuleName.System; Blade2Target = ModuleName.System; CmdTarget = ModuleName.System; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return true; } protected override bool fStartSwapWafer(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} move failed for not connect with {_connection.Address}"); return false; } try { RobotArmEnum arm = (RobotArmEnum)param[0]; ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString()); BladeTarget = module; Blade1Target = module; Blade2Target = module; if (ModuleHelper.IsLoadPort(module)) { var lp = DEVICE.GetDevice(module.ToString()); if (lp != null) lp.NoteTransferStart(); } int slot = (int)param[2] + 1; float x = 0, y = 0, z = 0, w = 0; if (param.Length > 3) { x = (float)param[3]; y = (float)param[4]; z = (float)param[5]; w = (float)param[6]; } int intXvalue = (int)(x * 1000); int intYvalue = (int)(y * 1000); int intZvalue = (int)(z * 1000); int intWvalue = (int)(w * 1000); string TrsSt = GetStationsName(module); if (string.IsNullOrEmpty(TrsSt)) { LOG.Write("Invalid Paramter."); return false; } string strpara = $"E,{TrsSt},{slot:D2},A,{(arm == RobotArmEnum.Both ? "F" : ((int)arm + 1).ToString())},P4"; if (x != 0 || y != 0 || z != 0) { strpara += $",{intXvalue:D8},{intYvalue:D8},{intZvalue:D8}"; } if (w != 0) { strpara += $",{intWvalue:D8}"; } lock (_locker) { if (_lstHandlers.Count == 0 && !_connection.IsBusy) { ExecuteHandler(new GM201LVPRobotMotionHandler(this, "MTRS", strpara, _timeLimitMotion)); } else { _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "MTRS", strpara)); } } return true; } catch (Exception ex) { LOG.Write(ex); return false; } } protected override bool fSwapComplete(object[] param) { RobotArmEnum arm = (RobotArmEnum)CurrentParamter[0]; ModuleName sourcemodule; if (!Enum.TryParse(CurrentParamter[1].ToString(), out sourcemodule)) return false; int Sourceslotindex; if (!int.TryParse(CurrentParamter[2].ToString(), out Sourceslotindex)) return false; int delayCount = 0; if (arm == RobotArmEnum.Lower) { //WaferManager.Instance.WaferMoved(sourcemodule, Sourceslotindex, RobotModuleName, 0); //WaferManager.Instance.WaferMoved(RobotModuleName, 1, sourcemodule, Sourceslotindex); while (!isSimulatorMode && !(GetWaferState(RobotArmEnum.Lower) == RobotArmWaferStateEnum.Present && GetWaferState(RobotArmEnum.Upper) == RobotArmWaferStateEnum.Absent)) { delayCount++; Thread.Sleep(50); LOG.Write($"{RobotModuleName} delay {delayCount} time to detect wafer"); if (delayCount > 100) { OnError("Wafer detect error"); return true; } } WaferManager.Instance.WaferMoved(sourcemodule, Sourceslotindex, RobotModuleName, 0); WaferManager.Instance.WaferMoved(RobotModuleName, 1, sourcemodule, Sourceslotindex); } if (arm == RobotArmEnum.Upper) { //WaferManager.Instance.WaferMoved(sourcemodule, Sourceslotindex, RobotModuleName, 1); //WaferManager.Instance.WaferMoved(RobotModuleName, 0, sourcemodule, Sourceslotindex); delayCount = 0; while (!isSimulatorMode && !(GetWaferState(RobotArmEnum.Upper) == RobotArmWaferStateEnum.Present && GetWaferState(RobotArmEnum.Lower) == RobotArmWaferStateEnum.Absent)) { delayCount++; Thread.Sleep(50); LOG.Write($"{RobotModuleName} delay {delayCount} time to detect wafer"); if (delayCount > 100) { OnError("Wafer detect error"); return true; } } WaferManager.Instance.WaferMoved(sourcemodule, Sourceslotindex, RobotModuleName, 1); WaferManager.Instance.WaferMoved(RobotModuleName, 0, sourcemodule, Sourceslotindex); } return base.fSwapComplete(param); } protected override bool fStartPlaceWafer(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} place failed for not connect with {_connection.Address}"); return false; } try { RobotArmEnum arm = (RobotArmEnum)param[0]; ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString()); if (ModuleHelper.IsLoadPort(module)) { var lp = DEVICE.GetDevice(module.ToString()); if (lp != null) lp.NoteTransferStart(); } BladeTarget = module; Blade1Target = module; Blade2Target = module; int slot = (int)param[2] + 1; string TrsSt = GetStationsName(module); if (string.IsNullOrEmpty(TrsSt)) { LOG.Write("Invalid Parameter."); return false; } string strpara = ""; if (_MaterialType == MaterialType.Wafer) { int bladeNo = (arm == RobotArmEnum.Blade1 || arm == RobotArmEnum.Lower) ? 4 : 31; strpara = $"P,{TrsSt},{slot:D3},{bladeNo:D3}"; } else if (_MaterialType == MaterialType.Carrier) { string strHand = GetHandsName(module); if (string.IsNullOrEmpty(strHand)) { LOG.Write("Invalid Paramter."); return false; } strpara = $"P,{TrsSt},001,{strHand}"; } lock (_locker) { { _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "MTRS", strpara, _timeLimitPlace)); _lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RSTS")); } } CmdTarget = module; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; _timerActionMonitor.Restart(); return true; } catch (Exception ex) { LOG.Write(ex); return false; } } protected override bool fMonitorPlace(object[] param) { IsBusy = false; if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(_timeLimitPlace)) { _timerActionMonitor.Stop(); OnError("PlaceTimeOut"); return true; } if (_lstHandlers.Count == 0 && !_connection.IsBusy) { _timerActionMonitor.Stop(); //EV.PostInfoLog(Name, "Place complete"); fPlaceComplete(param); BladeTarget = ModuleName.System; Blade1Target = ModuleName.System; Blade2Target = ModuleName.System; CmdTarget = ModuleName.System; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return true; } return false; } protected override bool fPlaceComplete(object[] param) { if (_isError) { OnError("RobotError"); return true; } if (_lstHandlers.Count > 0) return false; RobotArmEnum arm = (RobotArmEnum)CurrentParamter[0]; ModuleName sourcemodule; if (!Enum.TryParse(CurrentParamter[1].ToString(), out sourcemodule)) return false; int Sourceslotindex; if (!int.TryParse(CurrentParamter[2].ToString(), out Sourceslotindex)) return false; int delayCount = 0; if (arm == RobotArmEnum.Lower || arm == RobotArmEnum.Blade1) { //WaferManager.Instance.WaferMoved(RobotModuleName, 0, sourcemodule, Sourceslotindex); while (!isSimulatorMode && GetWaferState(arm) != RobotArmWaferStateEnum.Absent) { delayCount++; Thread.Sleep(50); LOG.Write($"{RobotModuleName} delay {delayCount} time to detect wafer"); if (delayCount > 100) { OnError("Wafer detect error"); return true; } } if (_MaterialType == MaterialType.Wafer) { WaferManager.Instance.WaferMoved(RobotModuleName, 2, sourcemodule, Sourceslotindex); } else if (_MaterialType == MaterialType.Carrier) { if (CarrierManager.Instance.CheckHasCarrier(RobotModuleName.ToString(), 0)) { CarrierManager.Instance.CarrierMoved(RobotModuleName.ToString(), sourcemodule.ToString(), true); for (int i = 0; i < WaferManager.Instance.GetWafers(RobotModuleName).Length; i++) { if (WaferManager.Instance.CheckHasWafer(RobotModuleName, i)) WaferManager.Instance.WaferMoved(RobotModuleName, i, sourcemodule, i, false); } } } } if (arm == RobotArmEnum.Upper || arm == RobotArmEnum.Blade2) { //WaferManager.Instance.WaferMoved(RobotModuleName, 1, sourcemodule, Sourceslotindex); delayCount = 0; while (!isSimulatorMode && GetWaferState(arm) != RobotArmWaferStateEnum.Absent) { delayCount++; Thread.Sleep(50); LOG.Write($"{RobotModuleName} delay {delayCount} time to detect wafer"); if (delayCount > 100) { OnError("Wafer detect error"); return true; } } WaferManager.Instance.WaferMoved(RobotModuleName, 1, sourcemodule, Sourceslotindex); } if (arm == RobotArmEnum.Both) { //WaferManager.Instance.WaferMoved(RobotModuleName, 0, sourcemodule, Sourceslotindex); //WaferManager.Instance.WaferMoved(RobotModuleName, 1, sourcemodule, Sourceslotindex); while (!isSimulatorMode && GetWaferState(arm) != RobotArmWaferStateEnum.Absent) { delayCount++; Thread.Sleep(50); LOG.Write($"{RobotModuleName} delay {delayCount} time to detect wafer"); if (delayCount > 100) { OnError("Wafer detect error"); return true; } } WaferManager.Instance.WaferMoved(RobotModuleName, 0, sourcemodule, Sourceslotindex); WaferManager.Instance.WaferMoved(RobotModuleName, 1, sourcemodule, Sourceslotindex + 1); WaferManager.Instance.WaferMoved(RobotModuleName, 2, sourcemodule, Sourceslotindex + 2); WaferManager.Instance.WaferMoved(RobotModuleName, 3, sourcemodule, Sourceslotindex + 3); WaferManager.Instance.WaferMoved(RobotModuleName, 4, sourcemodule, Sourceslotindex + 4); } return base.fPlaceComplete(param); } protected override bool fStartPickWafer(object[] param) { if (!_connection.IsConnected) { EV.PostAlarmLog(RobotModuleName.ToString(), $"{RobotModuleName} move failed for not connect with {_connection.Address}"); return false; } try { RobotArmEnum arm = (RobotArmEnum)param[0]; ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString()); if (ModuleHelper.IsLoadPort(module)) { var lp = DEVICE.GetDevice(module.ToString()); if (lp != null) lp.NoteTransferStart(); } BladeTarget = module; Blade1Target = module; Blade2Target = module; int slot = (int)param[2] + 1; string TrsSt = GetStationsName(module); if (string.IsNullOrEmpty(TrsSt)) { LOG.Write("Invalid Paramter."); return false; } string strpara = ""; if (_MaterialType == MaterialType.Wafer) { int bladeNo = (arm == RobotArmEnum.Blade1 || arm == RobotArmEnum.Lower) ? 4 : 31; strpara = $"G,{TrsSt},{slot:D3},{bladeNo:D3}"; } else if (_MaterialType == MaterialType.Carrier) { string strHand = GetHandsName(module); if (string.IsNullOrEmpty(strHand)) { LOG.Write("Invalid Paramter."); return false; } strpara = $"G,{TrsSt},001,{strHand}"; } lock (_locker) { _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "MTRS", strpara, _timeLimitPick)); _lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RSTS")); } CmdTarget = module; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; _timerActionMonitor.Restart(); return true; } catch (Exception ex) { LOG.Write(ex); return false; } } protected override bool fMonitorPick(object[] param) { IsBusy = false; if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(_timeLimitPick)) { _timerActionMonitor.Stop(); OnError("PickTimeOut"); return true; } if (_lstHandlers.Count == 0 && !_connection.IsBusy) { _timerActionMonitor.Stop(); //EV.PostInfoLog(Name, "Pick complete"); fPickComplete(param); BladeTarget = ModuleName.System; Blade1Target = ModuleName.System; Blade2Target = ModuleName.System; CmdTarget = ModuleName.System; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return true; } return false; } protected override bool fPickComplete(object[] param) { if (_isError) { OnError("RobotError"); return true; } RobotArmEnum arm = (RobotArmEnum)CurrentParamter[0]; ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), CurrentParamter[1].ToString()); ModuleName sourcemodule; if (!Enum.TryParse(CurrentParamter[1].ToString(), out sourcemodule)) return false; int SourceslotIndex; if (!int.TryParse(CurrentParamter[2].ToString(), out SourceslotIndex)) return false; int delayCount = 0; if (arm == RobotArmEnum.Lower || arm == RobotArmEnum.Blade1) { //WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 0); while (!isSimulatorMode && GetWaferState(arm) != RobotArmWaferStateEnum.Present) { delayCount++; LOG.Write($"{RobotModuleName} delay {delayCount} time to detect wafer"); Thread.Sleep(50); if (delayCount > 100) { OnError("Wafer detect error"); return true; } } if (_MaterialType == MaterialType.Wafer) { WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 2); } else if (_MaterialType == MaterialType.Carrier) { if (CarrierManager.Instance.CheckHasCarrier(sourcemodule.ToString(), 0)) { CarrierManager.Instance.CarrierMoved(sourcemodule.ToString(), RobotModuleName.ToString(), true); for (int i = 0; i < WaferManager.Instance.GetWafers(sourcemodule).Length; i++) { if (WaferManager.Instance.CheckHasWafer(sourcemodule, i)) WaferManager.Instance.WaferMoved(sourcemodule, i, RobotModuleName, i, false); } } } } if (arm == RobotArmEnum.Upper || arm == RobotArmEnum.Blade2) { //WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 1); while (!isSimulatorMode && GetWaferState(arm) != RobotArmWaferStateEnum.Present) { delayCount++; LOG.Write($"{RobotModuleName} delay {delayCount} time to detect wafer"); Thread.Sleep(50); if (delayCount > 100) { OnError("Wafer detect error"); return true; } } WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 1); } if (arm == RobotArmEnum.Both) { //WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 0); //WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 1); while (!isSimulatorMode && GetWaferState(arm) != RobotArmWaferStateEnum.Present) { delayCount++; LOG.Write($"{RobotModuleName} delay {delayCount} time to detect wafer"); Thread.Sleep(50); if (delayCount > 100) { OnError("Wafer detect error"); return true; } } WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 0); WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex + 1, RobotModuleName, 1); WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex + 2, RobotModuleName, 2); WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex + 3, RobotModuleName, 3); WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex + 4, RobotModuleName, 4); } return base.fPickComplete(param); } protected override bool fResetToReady(object[] param) { if (_doRobotHold != null) _doRobotHold.SetTrigger(true, out _); return true; } protected override bool fReset(object[] param) { if (!_connection.IsConnected) { _address = SC.GetStringValue($"{Name}.Address"); _enableLog = SC.GetValue($"{Name}.EnableLogMessage"); _connection = new GM201LVPRobotConnection(this, _address); _connection.EnableLog(_enableLog); _connection.Connect(); } var alarmSignaRobotAlarm = DEVICE.GetDevice($"PM1.AlarmSignaFOUPRobotAlarm"); if (Name == "WaferRobot") alarmSignaRobotAlarm = DEVICE.GetDevice($"PM1.AlarmSignaWaferRobotAlarm"); if (_isError || (alarmSignaRobotAlarm != null && alarmSignaRobotAlarm.Value)) { lock (_locker) { string strpara = "1,1,N"; _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "INIT", strpara)); } _isError = false; return true; } lock (_locker) { if (_doRobotHold != null) _doRobotHold.SetTrigger(true, out _); _lstHandlers.Clear(); _connection.ForceClear(); //_lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "CCLR", "E", _timeLimitMotion)); //string strpara = "1,1,N"; //_lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "INIT", strpara)); //string strpara = "1,0,N"; //_lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "INIT", strpara, _timeLimitMotion)); //_lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RSTS")); _timerActionMonitor.Restart(); } return true; } protected override bool fMonitorReset(object[] param) { IsBusy = false; if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(_timeLimitMotion)) { _timerActionMonitor.Stop(); OnError("ResetTimeOut"); return true; } if (_lstHandlers.Count == 0 && !_connection.IsBusy) { return true; } return false; } protected override bool fError(object[] param) { return true; } protected override bool fStartExtendForPick(object[] param) { return false; } protected override bool fStartExtendForPlace(object[] param) { return false; } protected override bool fStartRetractFromPick(object[] param) { return false; } protected override bool fStartRetractFromPlace(object[] param) { return false; } public void CheckWaferPresentAndGrip() { if (GetWaferState(RobotArmEnum.Lower) == RobotArmWaferStateEnum.Present) { if (WaferManager.Instance.CheckNoWafer(RobotModuleName, 0)) { EV.PostWarningLog($"{RobotModuleName}", $"System detec wafer on lower arm, will create wafer automatically."); WaferManager.Instance.CreateWafer(RobotModuleName, 0, WaferStatus.Normal); } } if (GetWaferState(RobotArmEnum.Lower) == RobotArmWaferStateEnum.Absent) { _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "CSOL", "1,0,0")); if (WaferManager.Instance.CheckHasWafer(RobotModuleName, 0)) { EV.PostWarningLog($"{RobotModuleName}", $"System didn't detect wafer on lower arm, but it has record."); } } if (GetWaferState(RobotArmEnum.Upper) == RobotArmWaferStateEnum.Present) { if (WaferManager.Instance.CheckNoWafer(RobotModuleName, 1)) { EV.PostWarningLog($"{RobotModuleName}", $"System detect wafer on upper arm, will create wafer automatically."); WaferManager.Instance.CreateWafer(RobotModuleName, 1, WaferStatus.Normal); } } if (GetWaferState(RobotArmEnum.Upper) == RobotArmWaferStateEnum.Absent) { _lstHandlers.AddLast(new GM201LVPRobotMotionHandler(this, "CSOL", "2,0,0")); if (WaferManager.Instance.CheckHasWafer(RobotModuleName, 1)) { EV.PostWarningLog($"{RobotModuleName}", $"System didn't detect wafer on upper arm, but it has record."); } } } public override RobotArmWaferStateEnum GetWaferState(RobotArmEnum arm) { if (arm == RobotArmEnum.Lower || arm == RobotArmEnum.Blade1) { if (_diRobotBlade1WaferOn != null) { if (_diRobotBlade1WaferOn.Value) return RobotArmWaferStateEnum.Absent; else return RobotArmWaferStateEnum.Present; } var waferPresenceOnBlade1 = _MaterialType == MaterialType.Wafer ? IsWaferPresenceOnBlade3 : IsWaferPresenceOnBlade1; return waferPresenceOnBlade1 ? RobotArmWaferStateEnum.Present : RobotArmWaferStateEnum.Absent; } if (arm == RobotArmEnum.Upper || arm == RobotArmEnum.Blade2) { if (_diRobotBlade2WaferOn != null) { if (_diRobotBlade2WaferOn.Value) return RobotArmWaferStateEnum.Absent; else return RobotArmWaferStateEnum.Present; } return IsWaferPresenceOnBlade2 ? RobotArmWaferStateEnum.Present : RobotArmWaferStateEnum.Absent; } if (arm == RobotArmEnum.Both) { if (_diRobotBlade1WaferOn != null && _diRobotBlade2WaferOn != null) { if (_diRobotBlade2WaferOn.Value && _diRobotBlade1WaferOn.Value) return RobotArmWaferStateEnum.Absent; else if (!_diRobotBlade2WaferOn.Value && !_diRobotBlade1WaferOn.Value) return RobotArmWaferStateEnum.Present; else return RobotArmWaferStateEnum.Unknown; } if (IsWaferPresenceOnBlade1 && IsWaferPresenceOnBlade2 && IsWaferPresenceOnBlade3 && IsWaferPresenceOnBlade4 && IsWaferPresenceOnBlade5) { return RobotArmWaferStateEnum.Present; } if ((!IsWaferPresenceOnBlade1) && !IsWaferPresenceOnBlade2 && !IsWaferPresenceOnBlade3 && !IsWaferPresenceOnBlade4 && !IsWaferPresenceOnBlade5) { return RobotArmWaferStateEnum.Absent; } } return RobotArmWaferStateEnum.Unknown; } public override void NoteError(string errortext) { _isError = true; if (!string.IsNullOrEmpty(errortext)) OnError(errortext); //lock (_locker) { _lstHandlers.Clear(); _connection.ForceClear(); if (_tpStatus != null && _tpStatus.Value) { //true是TP状态 //TP状态,不需要发 } else { _lstHandlers.AddLast(new GM201LVPRobotReadHandler(this, "RERR", "001")); } } } //public void SenACK() //{ // _connection.SendAck(); //} public override bool OnActionDone(object[] param) { return true; } public override void Terminate() { _thread.Stop(); if (!SC.ContainsItem($"{Name}.CloseConnectionOnShutDown") || SC.GetValue($"{Name}.CloseConnectionOnShutDown")) { LOG.Write("Close connection for" + RobotModuleName.ToString()); _connection.Disconnect(); } base.Terminate(); } private string BuildBladeTarget() { return (CmdRobotArm == RobotArmEnum.Upper ? "ArmB" : "ArmA") + "." + CmdTarget; } public override void SetPauseResume(bool isPause) { _connection.SendMessage($"{(isPause ? "CSTP,H" : "CRSM")}\r"); if (_connection.ActiveHandler != null) { if (isPause) { _connection.ActiveHandler.TimerAck?.Stop(); _connection.ActiveHandler.TimerComplete?.Stop(); } else { _connection.ActiveHandler.TimerAck?.Start(); _connection.ActiveHandler.TimerComplete?.Start(); } } } public void NotePause(bool isPause) { IsPause = isPause; } } public class GM201LVPTokenGenerator { private int _last = 0; List _pool = new List(); SCConfigItem scToken = null; public int CurrentToken => _last; public GM201LVPTokenGenerator(string scName) { scToken = SC.GetConfigItem(scName); if (scToken == null) _last = scToken.IntValue; Random r = new Random(); _last = r.Next() % 20; } public int create() { int first = _last; int token = first; do { token = (token + 1) % 100; if (_pool.Contains(token)) continue; _pool.Add(token); _last = token; scToken.IntValue = _last; return _last; } while (token != first); throw (new ExcuteFailedException("Get token failed,pool is full")); } public void release(int token) { _pool.Remove(token); } public void release() { _last = 0; _pool.Clear(); } } public enum GM201LVPPositonEnum { RegisteredPosition, ReadyPosition, IntermediatePosition, MappingStartPosition, MappingFinishPosition, } }