Sic.Framework-Nanjing-Baishi/MECF.Framework.RT.Equipment.../HardwareUnits/Robots/GuanAng/GAPlcRobot.cs

1884 lines
66 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 System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using Aitex.Core.Common.DeviceData;
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.Communications;
using MECF.Framework.Common.Device.Bases;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Common;
using Newtonsoft.Json;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using System.Threading;
using Aitex.Core.Common;
using Aitex.Core.RT.DataCenter;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
using System.Xml;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Routine;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
using MECF.Framework.Common.CommonData;
using EventType = Aitex.Core.RT.Event.EventType;
namespace Aitex.Core.RT.Device.Unit
{
public class GAPlcRobot:RobotBaseDevice
{
public GAPlcRobot(string module,XmlElement node,string ioModule =""): base(node.GetAttribute("module"), node.GetAttribute("id"))
{
base.Module = node.GetAttribute("module");//string.IsNullOrEmpty(node.GetAttribute("module")) ? module : node.GetAttribute("module");
base.Name = node.GetAttribute("id");
ioModule = node.GetAttribute("ioModule");
_aiCurrentXPos_L = ParseAiNode("AI_CurrentXPos_L", node, ioModule);
_aiCurrentXPos_H = ParseAiNode("AI_CurrentXPos_H", node, ioModule);
_aiCurrentYPos_L = ParseAiNode("AI_CurrentYPos_L", node, ioModule);
_aiCurrentYPos_H = ParseAiNode("AI_CurrentYPos_H", node, ioModule);
_aiCurrentZPos_L = ParseAiNode("AI_CurrentZPos_L", node, ioModule);
_aiCurrentZPos_H = ParseAiNode("AI_CurrentZPos_H", node, ioModule);
_aiZAxisPitch_L = ParseAiNode("AI_ZAxisPitch_L", node, ioModule);
_aiZAxisPitch_H = ParseAiNode("AI_ZAxisPitch_H", node, ioModule);
_aiZAxisFirstPos_L = ParseAiNode("AI_ZAxisFirstPos_L", node, ioModule);
_aiZAxisFirstPos_H = ParseAiNode("AI_ZAxisFirstPos_H", node, ioModule);
_aiZAxisPlacePos_L = ParseAiNode("AI_ZAxisPlacePos_L", node, ioModule);
_aiZAxisPlacePos_H = ParseAiNode("AI_ZAxisPlacePos_H", node, ioModule);
_aiXAxisMoveDistance_L = ParseAiNode("AI_XAxisMoveDistance_L", node, ioModule);
_aiXAxisMoveDistance_H = ParseAiNode("AI_XAxisMoveDistance_H", node, ioModule);
_aiYAxisMoveDistance_L = ParseAiNode("AI_YAxisMoveDistance_L", node, ioModule);
_aiYAxisMoveDistance_H = ParseAiNode("AI_YAxisMoveDistance_H", node, ioModule);
_aiZAxisMoveSpeed_L = ParseAiNode("AI_ZAxisMoveSpeed_L", node, ioModule);
_aiZAxisMoveSpeed_H = ParseAiNode("AI_ZAxisMoveSpeed_H", node, ioModule);
_aiXAxisMoveSpeed_L = ParseAiNode("AI_XAxisMoveSpeed_L", node, ioModule);
_aiXAxisMoveSpeed_H = ParseAiNode("AI_XAxisMoveSpeed_H", node, ioModule);
_aiYAxisMoveSpeed_L = ParseAiNode("AI_YAxisMoveSpeed_L", node, ioModule);
_aiYAxisMoveSpeed_H = ParseAiNode("AI_YAxisMoveSpeed_H", node, ioModule);
_aiTargetPos = ParseAiNode("AI_TargetPos", node, ioModule);
_aoZAxisPitch_L = ParseAoNode("AO_ZAxisPitch_L", node, ioModule);
_aoZAxisPitch_H = ParseAoNode("AO_ZAxisPitch_H", node, ioModule);
_aoZAxisFirstPos_L = ParseAoNode("AO_ZAxisFirstPos_L", node, ioModule);
_aoZAxisFirstPos_H = ParseAoNode("AO_ZAxisFirstPos_H", node, ioModule);
_aoZAxisPlacePos_L = ParseAoNode("AO_ZAxisPlacePos_L", node, ioModule);
_aoZAxisPlacePos_H = ParseAoNode("AO_ZAxisPlacePos_H", node, ioModule);
_aoXAxisMoveDistance_L = ParseAoNode("AO_XAxisMoveDistance_L", node, ioModule);
_aoXAxisMoveDistance_H = ParseAoNode("AO_XAxisMoveDistance_H", node, ioModule);
_aoYAxisMoveDistance_L = ParseAoNode("AO_YAxisMoveDistance_L", node, ioModule);
_aoYAxisMoveDistance_H = ParseAoNode("AO_YAxisMoveDistance_H", node, ioModule);
_aoZAxisMoveSpeed_L = ParseAoNode("AO_ZAxisMoveSpeed_L", node, ioModule);
_aoZAxisMoveSpeed_H = ParseAoNode("AO_ZAxisMoveSpeed_H", node, ioModule);
_aoXAxisMoveSpeed_L = ParseAoNode("AO_XAxisMoveSpeed_L", node, ioModule);
_aoXAxisMoveSpeed_H = ParseAoNode("AO_XAxisMoveSpeed_H", node, ioModule);
_aoYAxisMoveSpeed_L = ParseAoNode("AO_YAxisMoveSpeed_L", node, ioModule);
_aoYAxisMoveSpeed_H = ParseAoNode("AO_YAxisMoveSpeed_H", node, ioModule);
_aoTargetPos = ParseAoNode("AO_TargetPos", node, ioModule);
_aoXMoveFwdDistance_L = ParseAoNode("AO_XMoveFwdDistance_L", node, ioModule);
_aoXMoveFwdDistance_H = ParseAoNode("AO_XMoveFwdDistance_H", node, ioModule);
_aoYMoveFwdDistance_L = ParseAoNode("AO_YMoveFwdDistance_L", node, ioModule);
_aoYMoveFwdDistance_H = ParseAoNode("AO_YMoveFwdDistance_H", node, ioModule);
_aoZMoveFwdDistance_L = ParseAoNode("AO_ZMoveFwdDistance_L", node, ioModule);
_aoZMoveFwdDistance_H = ParseAoNode("AO_ZMoveFwdDistance_H", node, ioModule);
_aoXMoveRevDistance_L = ParseAoNode("AO_XMoveRevDistance_L", node, ioModule);
_aoXMoveRevDistance_H = ParseAoNode("AO_XMoveRevDistance_H", node, ioModule);
_aoYMoveRevDistance_L = ParseAoNode("AO_YMoveRevDistance_L", node, ioModule);
_aoYMoveRevDistance_H = ParseAoNode("AO_YMoveRevDistance_H", node, ioModule);
_aoZMoveRevDistance_L = ParseAoNode("AO_ZMoveRevDistance_L", node, ioModule);
_aoZMoveRevDistance_H = ParseAoNode("AO_ZMoveRevDistance_H", node, ioModule);
_diReset_Ack = ParseDiNode("DI_Reset_Ack", node, ioModule);
_diHome_Ack = ParseDiNode("DI_Home_Ack", node, ioModule);
_diSave_Ack = ParseDiNode("DI_Save_Ack", node, ioModule);
_diPick_Ack = ParseDiNode("DI_Pick_Ack", node, ioModule);
_diPlace_Ack = ParseDiNode("DI_Place_Ack", node, ioModule);
_diX_Fwd_Ack = ParseDiNode("DI_X_Fwd_Ack", node, ioModule);
_diX_Rev_Ack = ParseDiNode("DI_X_Rev_Ack", node, ioModule);
_diY_Fwd_Ack = ParseDiNode("DI_Y_Fwd_Ack", node, ioModule);
_diY_Rev_Ack = ParseDiNode("DI_Y_Rev_Ack", node, ioModule);
_diZ_Fwd_Ack = ParseDiNode("DI_Z_Fwd_Ack", node, ioModule);
_diZ_Rev_Ack = ParseDiNode("DI_Z_Rev_Ack", node, ioModule);
_diPlugError = ParseDiNode("DI_PlugError", node, ioModule);
_diZMotionError = ParseDiNode("DI_ZMotionError", node, ioModule);
_diXMotionError = ParseDiNode("DI_XMotionError", node, ioModule);
_diYMotionError = ParseDiNode("DI_YMotionError", node, ioModule);
_diZMotionOutLimit = ParseDiNode("DI_ZMotionOutLimit", node, ioModule);
_diXMotionOutLimit = ParseDiNode("DI_XMotionOutLimit", node, ioModule);
_diYMotionOutLimit = ParseDiNode("DI_YMotionOutLimit", node, ioModule);
_diPLCReady = ParseDiNode("DI_PLCReady", node, ioModule);
_diMotionIdle = ParseDiNode("DI_MotionIdle", node, ioModule);
_doResetCmd = ParseDoNode("DO_ResetCmd", node, ioModule);
_doHomeCmd = ParseDoNode("DO_HomeCmd", node, ioModule);
_doSaveCmd = ParseDoNode("DO_SaveCmd", node, ioModule);
_doPickCmd = ParseDoNode("DO_PickCmd", node, ioModule);
_doPlaceCmd = ParseDoNode("DO_PlaceCmd", node, ioModule);
_doX_FwdCmd = ParseDoNode("DO_X_FwdCmd", node, ioModule);
_doX_RevCmd = ParseDoNode("DO_X_RevCmd", node, ioModule);
_doY_FwdCmd = ParseDoNode("DO_Y_FwdCmd", node, ioModule);
_doY_RevCmd = ParseDoNode("DO_Y_RevCmd", node, ioModule);
_doZ_FwdCmd = ParseDoNode("DO_Z_FwdCmd", node, ioModule);
_doZ_RevCmd = ParseDoNode("DO_Z_RevCmd", node, ioModule);
EV.Subscribe(new EventItem("Alarm", AlarmRobotError, $"Robot occurred error.", EventLevel.Alarm, EventType.EventUI_Notify));
DATA.Subscribe($"{Name}.PLCReady", () => _diPLCReady.Value);
DATA.Subscribe($"{Name}.MotionIdle", () => _diMotionIdle.Value);
DATA.Subscribe($"{Name}.SlotPitch", () => _slotPitch);
DATA.Subscribe($"{Name}.FirstZPosition", () => _zFirstPosition);
DATA.Subscribe($"{Name}.PlaceWaferZPosition", () => _zPutWaferPosition);
DATA.Subscribe($"{Name}.XMoveDistance", () => _xMoveDistance);
DATA.Subscribe($"{Name}.YMoveDistance", () => _yMoveDistance);
DATA.Subscribe($"{Name}.ZMoveSpeed", () => _zMoveSpeed);
DATA.Subscribe($"{Name}.YMoveSpeed", () => _yMoveSpeed);
DATA.Subscribe($"{Name}.XMoveSpeed", () => _xMoveSpeed);
DATA.Subscribe($"{Name}.CurrentXPosition", () => _currentXPosition);
DATA.Subscribe($"{Name}.CurrentYPosition", () => _currentYPosition);
DATA.Subscribe($"{Name}.CurrentZPosition", () => _currentZPosition);
_trigErrorOccurred = new R_TRIG();
_thread = new PeriodicJob(10, OnTimer, $"{Module}.{Name} MonitorHandler", true);
}
private string AlarmRobotError = "RobotOccurredError";
private AIAccessor _aiZAxisPitch_L;
private AIAccessor _aiZAxisPitch_H;
private AIAccessor _aiZAxisFirstPos_L;
private AIAccessor _aiZAxisFirstPos_H;
private AIAccessor _aiZAxisPlacePos_L;
private AIAccessor _aiZAxisPlacePos_H;
private AIAccessor _aiXAxisMoveDistance_L;
private AIAccessor _aiXAxisMoveDistance_H;
private AIAccessor _aiYAxisMoveDistance_L;
private AIAccessor _aiYAxisMoveDistance_H;
private AIAccessor _aiZAxisMoveSpeed_L;
private AIAccessor _aiZAxisMoveSpeed_H;
private AIAccessor _aiXAxisMoveSpeed_L;
private AIAccessor _aiXAxisMoveSpeed_H;
private AIAccessor _aiYAxisMoveSpeed_L;
private AIAccessor _aiYAxisMoveSpeed_H;
private AIAccessor _aiTargetPos;
private AIAccessor _aiCurrentXPos_L;
private AIAccessor _aiCurrentXPos_H;
private AIAccessor _aiCurrentYPos_L;
private AIAccessor _aiCurrentYPos_H;
private AIAccessor _aiCurrentZPos_L;
private AIAccessor _aiCurrentZPos_H;
private AOAccessor _aoZAxisPitch_L;
private AOAccessor _aoZAxisPitch_H;
private AOAccessor _aoZAxisFirstPos_L;
private AOAccessor _aoZAxisFirstPos_H;
private AOAccessor _aoZAxisPlacePos_L;
private AOAccessor _aoZAxisPlacePos_H;
private AOAccessor _aoXAxisMoveDistance_L;
private AOAccessor _aoXAxisMoveDistance_H;
private AOAccessor _aoYAxisMoveDistance_L;
private AOAccessor _aoYAxisMoveDistance_H;
private AOAccessor _aoZAxisMoveSpeed_L;
private AOAccessor _aoZAxisMoveSpeed_H;
private AOAccessor _aoXAxisMoveSpeed_L;
private AOAccessor _aoXAxisMoveSpeed_H;
private AOAccessor _aoYAxisMoveSpeed_L;
private AOAccessor _aoYAxisMoveSpeed_H;
private AOAccessor _aoTargetPos;
private AOAccessor _aoXMoveFwdDistance_L;
private AOAccessor _aoXMoveFwdDistance_H;
private AOAccessor _aoYMoveFwdDistance_L;
private AOAccessor _aoYMoveFwdDistance_H;
private AOAccessor _aoZMoveFwdDistance_L;
private AOAccessor _aoZMoveFwdDistance_H;
private AOAccessor _aoXMoveRevDistance_L;
private AOAccessor _aoXMoveRevDistance_H;
private AOAccessor _aoYMoveRevDistance_L;
private AOAccessor _aoYMoveRevDistance_H;
private AOAccessor _aoZMoveRevDistance_L;
private AOAccessor _aoZMoveRevDistance_H;
private DIAccessor _diReset_Ack;
private DIAccessor _diHome_Ack;
private DIAccessor _diSave_Ack;
private DIAccessor _diPick_Ack;
private DIAccessor _diPlace_Ack;
private DIAccessor _diX_Fwd_Ack;
private DIAccessor _diX_Rev_Ack;
private DIAccessor _diY_Fwd_Ack;
private DIAccessor _diY_Rev_Ack;
private DIAccessor _diZ_Fwd_Ack;
private DIAccessor _diZ_Rev_Ack;
private DIAccessor _diPlugError;
private DIAccessor _diZMotionError;
private DIAccessor _diXMotionError;
private DIAccessor _diYMotionError;
private DIAccessor _diZMotionOutLimit;
private DIAccessor _diXMotionOutLimit;
private DIAccessor _diYMotionOutLimit;
private DIAccessor _diPLCReady;
private DIAccessor _diMotionIdle;
private DOAccessor _doResetCmd;
private DOAccessor _doHomeCmd;
private DOAccessor _doSaveCmd;
private DOAccessor _doPickCmd;
private DOAccessor _doPlaceCmd;
private DOAccessor _doX_FwdCmd;
private DOAccessor _doX_RevCmd;
private DOAccessor _doY_FwdCmd;
private DOAccessor _doY_RevCmd;
private DOAccessor _doZ_FwdCmd;
private DOAccessor _doZ_RevCmd;
private PeriodicJob _thread;
private R_TRIG _trigErrorOccurred;
private int _currentXPosition
{
get
{
return TwoShortConvInt(_aiCurrentXPos_L.Value, _aiCurrentXPos_H.Value);
}
}
private int _currentYPosition
{
get
{
return TwoShortConvInt(_aiCurrentYPos_L.Value, _aiCurrentYPos_H.Value);
}
}
private int _currentZPosition
{
get
{
return TwoShortConvInt(_aiCurrentZPos_L.Value, _aiCurrentZPos_H.Value);
}
}
private int _slotPitch
{
get
{
return TwoShortConvInt(_aiZAxisPitch_L.Value, _aiZAxisPitch_H.Value);
}
}
private int _zFirstPosition
{
get
{
return TwoShortConvInt(_aiZAxisFirstPos_L .Value, _aiZAxisFirstPos_H.Value);
}
}
private int _zPutWaferPosition
{
get
{
return TwoShortConvInt(_aiZAxisPlacePos_L.Value, _aiZAxisPlacePos_H.Value);
}
}
private int _xMoveDistance
{
get
{
return TwoShortConvInt(_aiXAxisMoveDistance_L.Value, _aiXAxisMoveDistance_H.Value);
}
}
private int _yMoveDistance
{
get
{
return TwoShortConvInt(_aiYAxisMoveDistance_L.Value, _aiYAxisMoveDistance_H.Value);
}
}
private int _zMoveSpeed
{
get
{
return TwoShortConvInt(_aiZAxisMoveSpeed_L.Value, _aiZAxisMoveSpeed_H.Value);
}
}
private int _yMoveSpeed
{
get
{
return TwoShortConvInt(_aiYAxisMoveSpeed_L.Value, _aiYAxisMoveSpeed_H.Value);
}
}
private int _xMoveSpeed
{
get
{
return TwoShortConvInt(_aiXAxisMoveSpeed_L.Value, _aiXAxisMoveSpeed_H.Value);
}
}
private bool OnTimer()
{
_trigErrorOccurred.CLK =
_diPlugError.Value || _diZMotionError.Value
|| _diXMotionError.Value || _diYMotionError.Value || _diZMotionOutLimit.Value
|| _diXMotionOutLimit.Value || _diYMotionOutLimit.Value;
if(_trigErrorOccurred.Q)
{
EV.Notify(AlarmRobotError);
if (_diPlugError.Value)
{
EV.PostAlarmLog("Robot", $"Robot occurred error: _diPlugError.");
}
if (_diZMotionError.Value)
{
EV.PostAlarmLog("Robot", $"Robot occurred error: _diZMotionError.");
}
if (_diXMotionError.Value)
{
EV.PostAlarmLog("Robot", $"Robot occurred error: _diXMotionError.");
}
if (_diYMotionError.Value)
{
EV.PostAlarmLog("Robot", $"Robot occurred error: _diYMotionError.");
}
if (_diZMotionOutLimit.Value)
{
EV.PostAlarmLog("Robot", $"Robot occurred error: _diZMotionOutLimit.");
}
if (_diYMotionOutLimit.Value)
{
EV.PostAlarmLog("Robot", $"Robot occurred error: _diYMotionOutLimit.");
}
if (_diXMotionOutLimit.Value)
{
EV.PostAlarmLog("Robot", $"Robot occurred error: _diXMotionOutLimit.");
}
OnError("Robot Error");
}
return true;
}
#region Override Robot base function
private enum RobotStepEnum
{
ActionStep1,
ActionStep2,
ActionStep3,
ActionStep4,
ActionStep5,
ActionStep6,
ActionStep7,
ActionStep8,
ActionStep9,
ActionStep10,
ActionStep11,
ActionStep12,
ActionStep13,
ActionStep14,
ActionStep15,
ActionStep16,
}
private DateTime _dtActionStart;
protected override bool fClear(object[] param)
{
return true;
}
protected override bool fStartReadData(object[] param)
{
return true;
}
protected override bool fStartSetParameters(object[] param)
{
try
{
_aoZAxisPitch_L.Value = _aiZAxisPitch_L.Value;
_aoZAxisPitch_H.Value = _aiZAxisPitch_H.Value;
_aoZAxisFirstPos_L.Value = _aiZAxisFirstPos_L.Value;
_aoZAxisFirstPos_H.Value = _aiZAxisFirstPos_H.Value;
_aoZAxisPlacePos_L.Value = _aiZAxisPlacePos_L.Value;
_aoZAxisPlacePos_H.Value = _aiZAxisPlacePos_H.Value;
_aoXAxisMoveDistance_L.Value = _aiXAxisMoveDistance_L.Value;
_aoXAxisMoveDistance_H.Value = _aiXAxisMoveDistance_H.Value;
_aoYAxisMoveDistance_L.Value = _aiYAxisMoveDistance_L.Value;
_aoYAxisMoveDistance_H.Value = _aiYAxisMoveDistance_H.Value;
_aoZAxisMoveSpeed_L.Value = _aiZAxisMoveSpeed_L.Value;
_aoZAxisMoveSpeed_H.Value = _aiZAxisMoveSpeed_H.Value;
_aoXAxisMoveSpeed_L.Value = _aiXAxisMoveSpeed_L.Value;
_aoXAxisMoveSpeed_H.Value = _aiXAxisMoveSpeed_H.Value;
_aoYAxisMoveSpeed_L.Value = _aiYAxisMoveSpeed_L.Value;
_aoYAxisMoveSpeed_H.Value = _aiYAxisMoveSpeed_H.Value;
string setcommand = param[0].ToString();
int setvalue = Convert.ToInt32(param[1].ToString());
short lowbit=0, highbit=0;
IntConvTwoShort(setvalue, ref lowbit, ref highbit);
_dtActionStart = DateTime.Now;
ResetRoutine();
switch (setcommand)
{
case "SlotPitch":
_aoZAxisPitch_L.Value = lowbit;
_aoZAxisPitch_H.Value = highbit;
break;
case "FirstZPosition":
_aoZAxisFirstPos_L.Value = lowbit;
_aoZAxisFirstPos_H.Value = highbit;
break;
case "PlaceWaferZPosition":
_aoZAxisPlacePos_L.Value = lowbit;
_aoZAxisPlacePos_H.Value = highbit;
break;
case "XMoveDistance":
_aoXAxisMoveDistance_L.Value = lowbit;
_aoXAxisMoveDistance_H.Value = highbit;
break;
case "YMoveDistance":
_aoYAxisMoveDistance_L.Value = lowbit;
_aoYAxisMoveDistance_H.Value = highbit;
break;
case "ZMoveSpeed":
_aoZAxisMoveSpeed_L.Value = lowbit;
_aoZAxisMoveSpeed_H.Value = highbit;
break;
case "XMoveSpeed":
_aoXAxisMoveSpeed_L.Value = lowbit;
_aoXAxisMoveSpeed_H.Value = highbit;
break;
case "YMoveSpeed":
_aoYAxisMoveSpeed_L.Value = lowbit;
_aoYAxisMoveSpeed_H.Value = highbit;
break;
default:
return false;
}
}
catch(Exception ex)
{
LOG.Write(ex);
}
return true;
}
protected override bool fMonitorSetParamter(object[] param)
{
IsBusy = false;
if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))
{
OnError("Command execution timeout");
return true;
}
try
{
SetDoState((int)RobotStepEnum.ActionStep2, _doSaveCmd, true, Notify);
WaitDiState((int)RobotStepEnum.ActionStep3, RobotCommandTimeout, _diSave_Ack, true, Notify, Stop);
SetDoState((int)RobotStepEnum.ActionStep4, _doSaveCmd, false, Notify);
WaitDiState((int)RobotStepEnum.ActionStep5, RobotCommandTimeout, _diSave_Ack, false, Notify, Stop);
}
catch (RoutineBreakException)
{
return false;
}
catch (RoutineFaildException)
{
EV.PostAlarmLog("Alarm", "Pick wafer failed.");
OnError("PickFailed");
}
return true;
}
protected override bool fStartTransferWafer(object[] param)
{
return true;
}
protected override bool fStartUnGrip(object[] param)
{
return false;
}
protected override bool fStartGrip(object[] param)
{
return false;
}
protected override bool fStartGoTo(object[] param)
{
return false;
}
protected override bool fStartMapWafer(object[] param)
{
return false;
}
protected override bool fStartSwapWafer(object[] param)
{
return false;
}
protected override bool fStartPlaceWafer(object[] param)
{
if(!_diPLCReady.Value)
{
EV.PostAlarmLog("Robot", "PLC ready signal is OFF.");
return false;
}
if(!_diMotionIdle.Value)
{
EV.PostAlarmLog("Robot", "Motion idle signal is OFF.");
return false;
}
_dtActionStart = DateTime.Now;
ResetRoutine();
try
{
//RobotArmEnum arm = (RobotArmEnum)param[0];
ModuleName tempmodule = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString());
int slotindex = int.Parse(param[2].ToString());
if (ModuleHelper.IsLoadPort(tempmodule))
{
_aoTargetPos.Value = (short)(slotindex + 1);
}
else
_aoTargetPos.Value = 26;
Blade1Target = tempmodule;
Blade2Target = tempmodule;
CmdTarget = tempmodule;
MoveInfo = new RobotMoveInfo()
{
Action = RobotAction.Picking,
ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
BladeTarget = BuildBladeTarget(),
};
}
catch (Exception ex)
{
LOG.Write(ex);
return false;
}
return true;
}
protected override bool fMonitorPlace(object[] param)
{
IsBusy = false;
if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))
{
OnError("Command execution timeout");
return true;
}
try
{
WaitAiValue((int)RobotStepEnum.ActionStep1, RobotCommandTimeout, _aiTargetPos, _aoTargetPos.Value, Notify, Stop);
SetDoState((int)RobotStepEnum.ActionStep2, _doPlaceCmd, true, Notify);
WaitDiState((int)RobotStepEnum.ActionStep3, RobotCommandTimeout, _diPlace_Ack, true, Notify, Stop);
SetDoState((int)RobotStepEnum.ActionStep4, _doPlaceCmd, false, Notify);
WaitDiState((int)RobotStepEnum.ActionStep5, RobotCommandTimeout, _diPlace_Ack, false, Notify, Stop);
}
catch (RoutineBreakException)
{
return false;
}
catch (RoutineFaildException)
{
EV.PostAlarmLog("Alarm", "Pick wafer failed.");
OnError("PickFailed");
return true;
}
Blade1Target = ModuleName.System;
Blade2Target = ModuleName.System;
CmdTarget = ModuleName.System;
MoveInfo = new RobotMoveInfo()
{
Action = RobotAction.Picking,
ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
BladeTarget = BuildBladeTarget(),
};
ModuleName sourcemodule;
if (!Enum.TryParse(CurrentParamter[1].ToString(), out sourcemodule)) return false;
int SourceslotIndex;
if (!int.TryParse(CurrentParamter[2].ToString(), out SourceslotIndex)) return false;
WaferManager.Instance.WaferMoved(RobotModuleName, 0,sourcemodule, SourceslotIndex);
return true;
}
protected override bool fMonitorPick(object[] param)
{
IsBusy = false;
if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))
{
OnError("Command execution timeout");
return true;
}
try
{
WaitAiValue((int)RobotStepEnum.ActionStep1, RobotCommandTimeout, _aiTargetPos, _aoTargetPos.Value, Notify, Stop);
SetDoState((int)RobotStepEnum.ActionStep2, _doPickCmd, true, Notify);
WaitDiState((int)RobotStepEnum.ActionStep3, RobotCommandTimeout, _diPick_Ack, true, Notify, Stop);
SetDoState((int)RobotStepEnum.ActionStep4, _doPickCmd, false, Notify);
WaitDiState((int)RobotStepEnum.ActionStep5, RobotCommandTimeout, _diPick_Ack, false, Notify, Stop);
}
catch (RoutineBreakException)
{
return false;
}
catch (RoutineFaildException)
{
EV.PostAlarmLog("Alarm","Pick wafer failed.");
OnError("PickFailed");
return true;
}
Blade1Target = ModuleName.System;
Blade2Target = ModuleName.System;
CmdTarget = ModuleName.System;
MoveInfo = new RobotMoveInfo()
{
Action = RobotAction.Picking,
ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
BladeTarget = BuildBladeTarget(),
};
ModuleName sourcemodule;
if (!Enum.TryParse(CurrentParamter[1].ToString(), out sourcemodule)) return false;
int SourceslotIndex;
if (!int.TryParse(CurrentParamter[2].ToString(), out SourceslotIndex)) return false;
WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 0);
return true;
}
protected override bool fStartPickWafer(object[] param)
{
if (!_diPLCReady.Value)
{
EV.PostAlarmLog("Robot", "PLC ready signal is OFF.");
return false;
}
if (!_diMotionIdle.Value)
{
EV.PostAlarmLog("Robot", "Motion idle signal is OFF.");
return false;
}
_dtActionStart = DateTime.Now;
ResetRoutine();
try
{
ModuleName tempmodule = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString());
int slotindex = int.Parse(param[2].ToString());
if (ModuleHelper.IsLoadPort(tempmodule))
{
_aoTargetPos.Value = (short)(slotindex + 1);
}
else
_aoTargetPos.Value = 26;
Blade1Target = tempmodule;
Blade2Target = tempmodule;
CmdTarget = tempmodule;
MoveInfo = new RobotMoveInfo()
{
Action = RobotAction.Picking,
ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
BladeTarget = BuildBladeTarget(),
};
}
catch (Exception ex)
{
LOG.Write(ex);
return false;
}
return true;
}
protected override bool fResetToReady(object[] param)
{
return true;
}
protected override bool fReset(object[] param)
{
_dtActionStart = DateTime.Now;
ResetRoutine();
return true;
}
protected override bool fMonitorReset(object[] param)
{
IsBusy = false;
if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))
{
OnError("Command execution timeout");
return true;
}
try
{
SetDoState((int)RobotStepEnum.ActionStep1, _doPickCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep2, _doPlaceCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep3, _doHomeCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep4, _doSaveCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep5, _doX_FwdCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep6, _doX_RevCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep7, _doY_FwdCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep8, _doY_RevCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep9, _doZ_FwdCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep10, _doZ_RevCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep11, _doResetCmd, true, Notify);
WaitDiState((int)RobotStepEnum.ActionStep12, RobotCommandTimeout, _diReset_Ack, true, Notify, Stop);
SetDoState((int)RobotStepEnum.ActionStep13, _doResetCmd, false, Notify);
WaitDiState((int)RobotStepEnum.ActionStep14, RobotCommandTimeout, _diReset_Ack, false, Notify, Stop);
}
catch (RoutineBreakException)
{
return false;
}
catch (RoutineFaildException)
{
EV.PostAlarmLog("Alarm", "Pick wafer failed.");
OnError("PickFailed");
return true;
}
return true;
}
protected override bool fStartInit(object[] param)
{
_dtActionStart = DateTime.Now;
ResetRoutine();
return true;
}
protected override bool fMonitorInit(object[] param)
{
IsBusy = false;
if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))
{
OnError("Command execution timeout");
return true;
}
try
{
SetDoState((int)RobotStepEnum.ActionStep1, _doPickCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep2, _doPlaceCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep3, _doResetCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep4, _doSaveCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep5, _doX_FwdCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep6, _doX_RevCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep7, _doY_FwdCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep8, _doY_RevCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep9, _doZ_FwdCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep10, _doZ_RevCmd, false, Notify);
SetDoState((int)RobotStepEnum.ActionStep11, _doHomeCmd, true, Notify);
WaitDiState((int)RobotStepEnum.ActionStep12, RobotCommandTimeout, _diHome_Ack, true, Notify, Stop);
SetDoState((int)RobotStepEnum.ActionStep13, _doHomeCmd, false, Notify);
WaitDiState((int)RobotStepEnum.ActionStep14, RobotCommandTimeout, _diHome_Ack, false, Notify, Stop);
}
catch (RoutineBreakException)
{
return false;
}
catch (RoutineFaildException)
{
EV.PostAlarmLog("Alarm", "Pick wafer failed.");
OnError("PickFailed");
return true;
}
Blade1Target = ModuleName.System;
Blade2Target = ModuleName.System;
CmdTarget = ModuleName.System;
MoveInfo = new RobotMoveInfo()
{
Action = RobotAction.Picking,
ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
BladeTarget = BuildBladeTarget(),
};
return true;
}
protected override bool fStartExecuteCommand(object[] param)
{
CurrentExecuteCmd = param[0].ToString();
if (string.IsNullOrEmpty(CurrentExecuteCmd))
return false;
_dtActionStart = DateTime.Now;
ResetRoutine();
return true;
}
public string CurrentExecuteCmd { get; private set; }
protected override bool fMonitorExecuting(object[] param)
{
string command = CurrentParamter[0].ToString();
Int32 pnum = Convert.ToInt32(CurrentParamter[1]);
short high16bit = (short)(pnum >> 16);
short low16bit = (short)(pnum & ushort.MaxValue);
try
{
switch (command)
{
case "XMoveFwd":
SetAoValue((int)RobotStepEnum.ActionStep1, _aoXMoveFwdDistance_H, high16bit, Notify);
SetAoValue((int)RobotStepEnum.ActionStep2, _aoXMoveFwdDistance_L, low16bit, Notify);
SetDoState((int)RobotStepEnum.ActionStep3, _doX_FwdCmd, true, Notify);
WaitDiState((int)RobotStepEnum.ActionStep4, RobotCommandTimeout, _diX_Fwd_Ack, true, Notify,Stop);
SetDoState((int)RobotStepEnum.ActionStep5, _doX_FwdCmd, false, Notify);
WaitDiState((int)RobotStepEnum.ActionStep6, RobotCommandTimeout, _diX_Fwd_Ack, false, Notify, Stop);
SetAoValue((int)RobotStepEnum.ActionStep7, _aoXMoveFwdDistance_H, 0, Notify);
SetAoValue((int)RobotStepEnum.ActionStep8, _aoXMoveFwdDistance_L, 0, Notify);
break;
case "XMoveRev":
high16bit = (short)((-1*pnum) >> 16);
low16bit = (short)((-1 * pnum) & ushort.MaxValue);
SetAoValue((int)RobotStepEnum.ActionStep1, _aoXMoveRevDistance_H, high16bit, Notify);
SetAoValue((int)RobotStepEnum.ActionStep2, _aoXMoveRevDistance_L, low16bit, Notify);
SetDoState((int)RobotStepEnum.ActionStep3, _doX_RevCmd, true, Notify);
WaitDiState((int)RobotStepEnum.ActionStep4, RobotCommandTimeout, _diX_Rev_Ack, true, Notify, Stop);
SetDoState((int)RobotStepEnum.ActionStep5, _doX_RevCmd, false, Notify);
WaitDiState((int)RobotStepEnum.ActionStep6, RobotCommandTimeout, _diX_Rev_Ack, false, Notify, Stop);
SetAoValue((int)RobotStepEnum.ActionStep7, _aoXMoveRevDistance_H, 0, Notify);
SetAoValue((int)RobotStepEnum.ActionStep8, _aoXMoveRevDistance_L, 0, Notify);
break;
case "YMoveFwd":
SetAoValue((int)RobotStepEnum.ActionStep1, _aoYMoveFwdDistance_H, high16bit, Notify);
SetAoValue((int)RobotStepEnum.ActionStep2, _aoYMoveFwdDistance_L, low16bit, Notify);
SetDoState((int)RobotStepEnum.ActionStep3, _doY_FwdCmd, true, Notify);
WaitDiState((int)RobotStepEnum.ActionStep4, RobotCommandTimeout, _diY_Fwd_Ack, true, Notify, Stop);
SetDoState((int)RobotStepEnum.ActionStep5, _doY_FwdCmd, false, Notify);
WaitDiState((int)RobotStepEnum.ActionStep6, RobotCommandTimeout, _diY_Fwd_Ack, false, Notify, Stop);
SetAoValue((int)RobotStepEnum.ActionStep7, _aoYMoveFwdDistance_H, 0, Notify);
SetAoValue((int)RobotStepEnum.ActionStep8, _aoYMoveFwdDistance_L, 0, Notify);
break;
case "YMoveRev":
high16bit = (short)((-1 * pnum) >> 16);
low16bit = (short)((-1 * pnum) & ushort.MaxValue);
SetAoValue((int)RobotStepEnum.ActionStep1, _aoYMoveRevDistance_H, high16bit, Notify);
SetAoValue((int)RobotStepEnum.ActionStep2, _aoYMoveRevDistance_L, low16bit, Notify);
SetDoState((int)RobotStepEnum.ActionStep3, _doY_RevCmd, true, Notify);
WaitDiState((int)RobotStepEnum.ActionStep4, RobotCommandTimeout, _diY_Rev_Ack, true, Notify, Stop);
SetDoState((int)RobotStepEnum.ActionStep5, _doY_RevCmd, false, Notify);
WaitDiState((int)RobotStepEnum.ActionStep6, RobotCommandTimeout, _diY_Rev_Ack, false, Notify, Stop);
SetAoValue((int)RobotStepEnum.ActionStep7, _aoYMoveRevDistance_H, 0, Notify);
SetAoValue((int)RobotStepEnum.ActionStep8, _aoYMoveRevDistance_L, 0, Notify);
break;
case "ZMoveFwd":
SetAoValue((int)RobotStepEnum.ActionStep1, _aoZMoveFwdDistance_H, high16bit, Notify);
SetAoValue((int)RobotStepEnum.ActionStep2, _aoZMoveFwdDistance_L, low16bit, Notify);
SetDoState((int)RobotStepEnum.ActionStep3, _doZ_FwdCmd, true, Notify);
WaitDiState((int)RobotStepEnum.ActionStep4, RobotCommandTimeout, _diZ_Fwd_Ack, true, Notify, Stop);
SetDoState((int)RobotStepEnum.ActionStep5, _doZ_FwdCmd, false, Notify);
WaitDiState((int)RobotStepEnum.ActionStep6, RobotCommandTimeout, _diZ_Fwd_Ack, false, Notify, Stop);
SetAoValue((int)RobotStepEnum.ActionStep7, _aoZMoveFwdDistance_H, 0, Notify);
SetAoValue((int)RobotStepEnum.ActionStep8, _aoZMoveFwdDistance_L, 0, Notify);
break;
case "ZMoveRev":
high16bit = (short)((-1 * pnum) >> 16);
low16bit = (short)((-1 * pnum) & ushort.MaxValue);
SetAoValue((int)RobotStepEnum.ActionStep1, _aoZMoveRevDistance_H, high16bit, Notify);
SetAoValue((int)RobotStepEnum.ActionStep2, _aoZMoveRevDistance_L, low16bit, Notify);
SetDoState((int)RobotStepEnum.ActionStep3, _doZ_RevCmd, true, Notify);
WaitDiState((int)RobotStepEnum.ActionStep4, RobotCommandTimeout, _diZ_Rev_Ack, true, Notify, Stop);
SetDoState((int)RobotStepEnum.ActionStep5, _doZ_RevCmd, false, Notify);
WaitDiState((int)RobotStepEnum.ActionStep6, RobotCommandTimeout, _diZ_Rev_Ack, false, Notify, Stop);
SetAoValue((int)RobotStepEnum.ActionStep7, _aoZMoveRevDistance_H, 0, Notify);
SetAoValue((int)RobotStepEnum.ActionStep8, _aoZMoveRevDistance_L, 0, Notify);
break;
default:
break;
}
}
catch (RoutineBreakException)
{
return false;
}
catch (RoutineFaildException)
{
EV.PostAlarmLog("Alarm", $"Execute command:{command} failed.");
OnError($"Execute {command} failed");
return true;
}
return true;
}
protected override bool fError(object[] param)
{
return true;
}
protected override bool fStartExtendForPick(object[] param)
{
return true;
}
protected override bool fStartExtendForPlace(object[] param)
{
return true;
}
protected override bool fStartRetractFromPick(object[] param)
{
return true;
}
protected override bool fStartRetractFromPlace(object[] param)
{
return true;
}
public override RobotArmWaferStateEnum GetWaferState(RobotArmEnum arm)
{
if (WaferManager.Instance.CheckHasWafer(RobotModuleName, 0))
return RobotArmWaferStateEnum.Present;
return RobotArmWaferStateEnum.Absent;
}
private string BuildBladeTarget()
{
return (CmdRobotArm == RobotArmEnum.Upper ? "ArmB" : "ArmA") + "." + CmdTarget;
}
private static int TwoShortConvInt(short low16bit, short high16bit)
{
return (high16bit << 16) + low16bit + (low16bit<0 ? UInt16.MaxValue+1 :0);
}
private static void IntConvTwoShort(int num,ref short low16bit,ref short high16bit)
{
high16bit = (short)(num >> 16);
low16bit = (short)(num & ushort.MaxValue);
}
#endregion
public DOAccessor ParseDoNode(string name, XmlElement node, string ioModule = "")
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
return IO.DO[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : $"{ioModule}.{node.GetAttribute(name).Trim()}"];
return null;
}
public DIAccessor ParseDiNode(string name, XmlElement node, string ioModule = "")
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
return IO.DI[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : $"{ioModule}.{node.GetAttribute(name).Trim()}"];
return null;
}
public AOAccessor ParseAoNode(string name, XmlElement node, string ioModule = "")
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
return IO.AO[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : $"{ioModule}.{node.GetAttribute(name).Trim()}"];
return null;
}
public AIAccessor ParseAiNode(string name, XmlElement node, string ioModule = "")
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
return IO.AI[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : $"{ioModule}.{node.GetAttribute(name).Trim()}"];
return null;
}
public SCConfigItem ParseScNode(string name, XmlElement node, string ioModule = "", string defaultScPath = "")
{
SCConfigItem result = null;
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
result = SC.GetConfigItem(node.GetAttribute(name));
if (result == null && !string.IsNullOrEmpty(defaultScPath) && SC.ContainsItem(defaultScPath))
result = SC.GetConfigItem(defaultScPath);
return result;
}
public static T ParseDeviceNode<T>(string name, XmlElement node) where T : class, IDevice
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
return DEVICE.GetDevice<T>(node.GetAttribute(name));
LOG.Write(string.Format("{0},未定义{1}", node.InnerXml, name));
return null;
}
public static T ParseDeviceNode<T>(string module, string name, XmlElement node) where T : class, IDevice
{
string device_id = node.GetAttribute(name);
if (!string.IsNullOrEmpty(device_id) && !string.IsNullOrEmpty(device_id.Trim()))
{
return DEVICE.GetDevice<T>($"{module}.{device_id}");
}
LOG.Write(string.Format("{0},undefined {1}", node.InnerXml, name));
return null;
}
public enum CarrierMode
{
Foup,
Fosb,
OpenCassette,
}
private void SetAoValue(int id, AOAccessor ao, short value, Action<string> notify)
{
var ret = Execute(id, () =>
{
notify($"{RobotModuleName} set {ao.Name} to {value}.");
ao.Value = value;
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw new RoutineFaildException();
}
}
}
private void WaitAiValue(int id, int time, AIAccessor ai, short value, Action<string> notify, Action<string> error)
{
var ret = ExecuteAndWait(id, () =>
{
notify($"Wait {RobotModuleName} {ai.Name} to be {value}");
return true;
}, () =>
{
if (ai.Value == value)
return true;
return false;
}, time * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw new RoutineFaildException();
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
//EV.Notify(RobotModuleName);
error($"Wait {RobotModuleName} {ai.Name} to be {value} timeout after {time} seconds");
throw new RoutineFaildException();
}
else
{
throw new RoutineBreakException();
}
}
}
private void WaitDiState(int id, int time, DIAccessor di, bool state, Action<string> notify, Action<string> error)
{
var ret = ExecuteAndWait(id, () =>
{
notify($"Wait {RobotModuleName} {di.Name} to be {state}");
return true;
}, () =>
{
if (di.Value == state)
return true;
return false;
}, time * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw new RoutineFaildException();
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
//EV.Notify();
error($"Wait {RobotModuleName} {di.Name} to be {state} timeout after {time} seconds");
throw new RoutineFaildException();
}
else
{
throw new RoutineBreakException();
}
}
}
private void SetDoState(int id, DOAccessor _do, bool state, Action<string> notify)
{
var ret = Execute(id, () =>
{
notify($"{RobotModuleName} start set {_do.Name} to {state}.");
//if (_do.Value == state)
//{
// _do.Value = !state;
// Thread.Sleep(500);
//}
return _do.SetValue(state, out _);
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw new RoutineFaildException();
}
}
}
protected void Notify(string message)
{
EV.PostMessage(Name, EventEnum.GeneralInfo, string.Format("{0}:{1}", Name, message));
}
protected void Stop(string failReason)
{
OnError(string.Format("Failed {0}, {1} ", Name, failReason));
}
#region Routine Executor
//timer, 计算routine时间
protected DeviceTimer counter = new DeviceTimer();
protected DeviceTimer delayTimer = new DeviceTimer();
private enum STATE
{
IDLE,
WAIT,
}
public int TokenId
{
get { return _id; }
}
private int _id; //step index
/// <summary>
/// already done steps
/// </summary>
private Stack<int> _steps = new Stack<int>();
private STATE state; //step state //idel,wait,
//loop control
private int loop = 0;
private int loopCount = 0;
private int loopID = 0;
private DeviceTimer timer = new DeviceTimer();
public int LoopCounter { get { return loop; } }
public int LoopTotalTime { get { return loopCount; } }
// public int Timeout { get { return (int)(timer.GetTotalTime() / 1000); } }
//状态持续时间,单位为秒
public int Elapsed { get { return (int)(timer.GetElapseTime() / 1000); } }
protected RoutineResult RoutineToken = new RoutineResult() { Result = RoutineState.Running };
public void ResetRoutine()
{
_id = 0;
_steps.Clear();
loop = 0;
loopCount = 0;
state = STATE.IDLE;
counter.Start(60 * 60 * 100); //默认1小时
RoutineToken.Result = RoutineState.Running;
}
protected void PerformRoutineStep(int id, Func<RoutineState> execution, RoutineResult result)
{
if (!Acitve(id))
return;
result.Result = execution();
}
#region interface
public void StopLoop()
{
loop = loopCount;
}
public Tuple<bool, Result> Loop<T>(T id, Func<bool> func, int count)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (!func())
{
return Tuple.Create(bActive, Result.FAIL); //执行错误
}
loopID = idx;
loopCount = count;
next();
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
public Tuple<bool, Result> EndLoop<T>(T id, Func<bool> func)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (++loop >= loopCount) //Loop 结束
{
if (!func())
{
return Tuple.Create(bActive, Result.FAIL); //执行错误
}
loop = 0;
loopCount = 0; // Loop 结束时当前loop和loop总数都清零
next();
return Tuple.Create(true, Result.RUN);
}
//继续下一LOOP
next(loopID);
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
public Tuple<bool, Result> ExecuteAndWait<T>(T id, IRoutine routine)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (state == STATE.IDLE)
{
Result startRet = routine.Start();
if (startRet == Result.FAIL)
{
return Tuple.Create(true, Result.FAIL); //执行错误
}
else if (startRet == Result.DONE)
{
next();
return Tuple.Create(true, Result.DONE);
}
state = STATE.WAIT;
}
Result ret = routine.Monitor();
if (ret == Result.DONE)
{
next();
return Tuple.Create(true, Result.DONE);
}
else if (ret == Result.FAIL || ret == Result.TIMEOUT)
{
return Tuple.Create(true, Result.FAIL);
}
else
{
return Tuple.Create(true, Result.RUN);
}
}
return Tuple.Create(false, Result.RUN);
}
public Tuple<bool, Result> ExecuteAndWait<T>(T id, List<IRoutine> routines)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (state == STATE.IDLE)
{
foreach (var item in routines)
{
if (item.Start() == Result.FAIL)
return Tuple.Create(true, Result.FAIL);
}
state = STATE.WAIT;
}
//wait all sub failed or completedboo
bool bFail = false;
bool bDone = true;
foreach (var item in routines)
{
Result ret = item.Monitor();
bDone &= (ret == Result.FAIL || ret == Result.DONE);
bFail |= ret == Result.FAIL;
}
if (bDone)
{
next();
if (bFail)
return Tuple.Create(true, Result.FAIL);
return Tuple.Create(true, Result.DONE);
}
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
public Tuple<bool, Result> Check<T>(T id, Func<bool> func) //顺序执行
{
return Check(Check(Convert.ToInt32(id), func));
}
public Tuple<bool, Result> Execute<T>(T id, Func<bool> func) //顺序执行
{
return Check(execute(Convert.ToInt32(id), func));
}
public Tuple<bool, Result> Wait<T>(T id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
{
return Check(wait(Convert.ToInt32(id), func, timeout));
}
public Tuple<bool, Result> Wait<T>(T id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition
{
return Check(wait(Convert.ToInt32(id), func, timeout));
}
public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, double timeout = int.MaxValue)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
bool? bExecute = false;
if (bActive)
{
if (state == STATE.IDLE)
{
if (!execute())
{
return Tuple.Create(bActive, Result.FAIL); //执行错误
}
timer.Start(timeout);
state = STATE.WAIT;
}
bExecute = check();
if (bExecute == null)
{
return Tuple.Create(bActive, Result.FAIL); //Termianate
}
else
{
if (bExecute.Value) //检查Success, next
{
next();
return Tuple.Create(true, Result.RUN);
}
}
if (timer.IsTimeout())
return Tuple.Create(true, Result.TIMEOUT);
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, Func<double> time)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
bool? bExecute = false;
double timeout = 0;
if (bActive)
{
if (state == STATE.IDLE)
{
timeout = time();
if (!execute())
{
return Tuple.Create(true, Result.FAIL); //执行错误
}
timer.Start(timeout);
state = STATE.WAIT;
}
bExecute = check();
if (bExecute == null)
{
return Tuple.Create(true, Result.FAIL); //Termianate
}
if (bExecute.Value) //检查Success, next
{
next();
return Tuple.Create(true, Result.RUN);
}
if (timer.IsTimeout())
return Tuple.Create(true, Result.TIMEOUT);
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
public Tuple<bool, Result> Wait<T>(T id, IRoutine rt)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (state == STATE.IDLE)
{
rt.Start();
state = STATE.WAIT;
}
Result ret = rt.Monitor();
return Tuple.Create(true, ret);
}
return Tuple.Create(false, Result.RUN);
}
//Monitor
public Tuple<bool, Result> Monitor<T>(T id, Func<bool> func, Func<bool> check, double time)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
bool bCheck = false;
if (bActive)
{
if (state == STATE.IDLE)
{
if ((func != null) && !func())
{
return Tuple.Create(true, Result.FAIL);
}
timer.Start(time);
state = STATE.WAIT;
}
bCheck = check();
if (!bCheck)
{
return Tuple.Create(true, Result.FAIL); //Termianate
}
if (timer.IsTimeout())
{
next();
}
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
//Delay
public Tuple<bool, Result> Delay<T>(T id, Func<bool> func, double time)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (state == STATE.IDLE)
{
if ((func != null) && !func())
{
return Tuple.Create(true, Result.FAIL);
}
timer.Start(time);
state = STATE.WAIT;
}
if (timer.IsTimeout())
{
next();
}
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
//先delay 再运行
public Tuple<bool, Result> DelayCheck<T>(T id, Func<bool> func, double time)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (state == STATE.IDLE)
{
timer.Start(time);
state = STATE.WAIT;
}
if (timer.IsTimeout())
{
if (func != null && !func())
{
return Tuple.Create(true, Result.FAIL);
}
next();
}
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
#endregion
private Tuple<bool, bool> execute(int id, Func<bool> func) //顺序执行
{
bool bActive = Acitve(id);
bool bExecute = false;
if (bActive)
{
bExecute = func();
if (bExecute)
{
next();
}
}
return Tuple.Create(bActive, bExecute);
}
private Tuple<bool, bool> Check(int id, Func<bool> func) //check
{
bool bActive = Acitve(id);
bool bExecute = false;
if (bActive)
{
bExecute = func();
next();
}
return Tuple.Create(bActive, bExecute);
}
/// <summary>
/// </summary>
/// <param name="id"></param>
/// <param name="func"></param>
/// <param name="timeout"></param>
/// <returns>
/// item1 Active
/// item2 execute
/// item3 Timeout
///</returns>
private Tuple<bool, bool, bool> wait(int id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
{
bool bActive = Acitve(id);
bool bExecute = false;
bool bTimeout = false;
if (bActive)
{
if (state == STATE.IDLE)
{
timer.Start(timeout);
state = STATE.WAIT;
}
bExecute = func();
if (bExecute)
{
next();
}
bTimeout = timer.IsTimeout();
}
return Tuple.Create(bActive, bExecute, bTimeout);
}
private Tuple<bool, bool?, bool> wait(int id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition && Check error
{
bool bActive = Acitve(id);
bool? bExecute = false;
bool bTimeout = false;
if (bActive)
{
if (state == STATE.IDLE)
{
timer.Start(timeout);
state = STATE.WAIT;
}
bExecute = func();
if (bExecute.HasValue && bExecute.Value)
{
next();
}
bTimeout = timer.IsTimeout();
}
return Tuple.Create(bActive, bExecute, bTimeout);
}
/// <summary>
/// </summary>
/// <param name="value"></param>
/// <returns>
/// item1 true, return item2
/// </returns>
private Tuple<bool, Result> Check(Tuple<bool, bool> value)
{
if (value.Item1)
{
if (!value.Item2)
{
return Tuple.Create(true, Result.FAIL);
}
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
private Tuple<bool, Result> Check(Tuple<bool, bool, bool> value)
{
if (value.Item1) // 当前执行
{
if (CheckTimeout(value)) //timeout
{
return Tuple.Create(true, Result.TIMEOUT);
}
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
private Tuple<bool, Result> Check(Tuple<bool, bool?, bool> value)
{
if (value.Item1) // 当前执行
{
if (value.Item2 == null)
{
return Tuple.Create(true, Result.FAIL);
}
else
{
if (value.Item2 == false && value.Item3 == true) //timeout
{
return Tuple.Create(true, Result.TIMEOUT);
}
return Tuple.Create(true, Result.RUN);
}
}
return Tuple.Create(false, Result.RUN);
}
private bool CheckTimeout(Tuple<bool, bool, bool> value)
{
return value.Item1 == true && value.Item2 == false && value.Item3 == true;
}
private bool Acitve(int id) //
{
if (_steps.Contains(id))
return false;
this._id = id;
return true;
}
private void next()
{
_steps.Push(this._id);
state = STATE.IDLE;
}
private void next(int step) //loop
{
while (_steps.Pop() != step) ;
state = STATE.IDLE;
}
public void Delay(int id, double delaySeconds)
{
Tuple<bool, Result> ret = Delay(id, () =>
{
return true;
}, delaySeconds * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.RUN)
{
throw (new RoutineBreakException());
}
}
}
public bool IsActived(int id)
{
return _steps.Contains(id);
}
#endregion
}
}