using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Beckhoff.Station;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Layout;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.Utilities;
using MECF.Framework.Common.WaferHolder;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.AXIS.CANOpen;
using CyberX8_RT.Devices.Facilities;
using CyberX8_RT.Devices.TransPorter;
using CyberX8_RT.Modules.Loader;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CyberX8_RT.Modules.Transporter
{
public class TransporterMoveToRoutine : RoutineBase, IRoutine
{
private enum MoveToStep
{
CheckStatus,
ElevatorPosition,
ElevatorPositionWait,
ImmobilizeExtend,
ImmobilizeExtendWait,
SafeMoveTo,
CheckMoveToStatus,
GantryPosition,
GantryPositionWait,
End
}
#region 内部变量
private string _cellName;
private JetAxisBase _gantryAxis;
private JetAxisBase _elevatorAxis;
private LoaderEntity _loaderEntity;
private JetAxisBase _loaderRotationAxis;
private TransporterCommon _transporterCommon;
private SystemFacilities _facilities;
private TransporterExtendRoutine _extendRoutine;
private TransporterConflictRoutine _conflictRoutine;
ProcessLayoutCellItem _cellItem;
private bool _waferHolderPresent = false;
#endregion
///
/// 构造函数
///
///
public TransporterMoveToRoutine(string module) : base(module)
{
}
///
/// 中止
///
public void Abort()
{
Runner.Stop("Manual Abort");
}
///
/// 监控
///
///
public RState Monitor()
{
Runner.Run(MoveToStep.CheckStatus, CheckStartPreConfition, NullFun,_delay_1ms)
//1.1 Elevator
.Run(MoveToStep.ElevatorPosition, ElevatorPosition, _delay_1ms)
.WaitWithStopCondition(MoveToStep.ElevatorPositionWait, CheckVerticalPositionStatus, CheckVerticalPositionRunStop)
//1.1 Immobilizer extend
.Run(MoveToStep.ImmobilizeExtend, ImmobilizeExtend, _delay_1ms)
.WaitWithStopCondition(MoveToStep.ImmobilizeExtendWait, CheckImmobilizeExtendStatus, CheckImmobilizeExtendRunStop)
//1.2 Move to 安全
.Run(MoveToStep.SafeMoveTo,SafeMoveTo,_delay_1ms)
.WaitWithStopCondition(MoveToStep.CheckMoveToStatus, () => CommonFunction.CheckRoutineEndState(_conflictRoutine),
CheckSafeMoveToStopStatus)
//1.3 Gantry 移动
.Run(MoveToStep.GantryPosition, GantryPositionToCell, _delay_1ms)
.WaitWithStopCondition(MoveToStep.GantryPositionWait, CheckGantryPositionStatus, CheckGantryPositionRunStop)
.End(MoveToStep.End,NullFun,100);
return Runner.Status;
}
///
/// Elevator Position
///
///
private bool ElevatorPosition()
{
bool result= false;
//状态locked住了 则运动至Up
if(_waferHolderPresent)
{
result= _elevatorAxis.PositionStation("Up");
if(!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "elevator goto up failed", 0);
}
}
else//不存在Wafer,则运动至Low
{
result= _elevatorAxis.PositionStation("LOW");
if (!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "elevator goto low failed", 0);
}
}
return result;
}
///
/// Immobile Extend
///
///
private bool ImmobilizeExtend()
{
if(!_waferHolderPresent)
{
return true;
}
else
{
return _extendRoutine.Start(null) == RState.Running;
}
}
///
/// 检验Immobilize状态
///
///
private bool CheckImmobilizeExtendStatus()
{
if(!_waferHolderPresent)
{
return true;
}
else
{
return CommonFunction.CheckRoutineEndState(_extendRoutine);
}
}
///
/// 检验Immobilize状态
///
///
private bool CheckImmobilizeExtendRunStop()
{
if (!_waferHolderPresent)
{
return true;
}
else
{
bool result= CommonFunction.CheckRoutineStopState(_extendRoutine);
if(result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "extend failed", 0);
}
return result;
}
}
///
/// 安全避障移动
///
///
private bool SafeMoveTo()
{
_cellItem = ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
string stationName = _cellName;
if (_cellItem != null)
{
if (_cellName.ToLower() != "loader" && _cellName.ToLower() != "park")
{
stationName = $"Cell{_cellItem.CellId}";
}
}
else
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
return false;
}
var result = _gantryAxis.GetPositionByStation(stationName);
if (result.success)
{
bool isPositive = false;
if (_gantryAxis.MotionData.MotorPosition < result.position)
{
isPositive = true;
}
return _conflictRoutine.Start(result.position, isPositive) == RState.Running;
}
else
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in station list",0);
return false;
}
}
///
/// 检验安全避让异常结束状态
///
///
private bool CheckSafeMoveToStopStatus()
{
bool result = CommonFunction.CheckRoutineStopState(_conflictRoutine);
if (result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "Safe Move failed", 0);
}
return result;
}
///
/// Gantry Position To cell
///
///
private bool GantryPositionToCell()
{
_cellItem= ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
bool result = false;
if (_cellItem != null)
{
if (_cellName.ToLower() != "loader"&&_cellName.ToLower()!="park")
{
result= _gantryAxis.PositionStation($"Cell{_cellItem.CellId}", false);
}
else
{
result= _gantryAxis.PositionStation(_cellName,false);
}
if (!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "gantry axis motion failed", 0);
}
return result;
}
else
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
return false;
}
}
///
/// 检验Vertical移动状态
///
///
private bool CheckVerticalPositionStatus()
{
return _elevatorAxis.Status == RState.End;
}
///
/// 检验Vertical是否还在运动
///
///
private bool CheckVerticalPositionRunStop()
{
bool result= _elevatorAxis.Status == RState.Failed||_elevatorAxis.Status==RState.Timeout;
if (result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "elevator motion failed",0);
}
return result;
}
///
/// 检验Gantry移动状态
///
///
private bool CheckGantryPositionStatus()
{
return _gantryAxis.Status == RState.End;
}
///
/// 检验Gantry是否还在运动
///
///
private bool CheckGantryPositionRunStop()
{
bool result= _gantryAxis.Status == RState.Failed||_gantryAxis.Status==RState.Timeout;
if(result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "gantry motion failed", 0);
}
return result;
}
///
/// 启动
///
///
///
public RState Start(params object[] objs)
{
_cellName = objs[0].ToString();
_elevatorAxis = DEVICE.GetDevice($"{Module}.Elevator");
_gantryAxis = DEVICE.GetDevice($"{Module}.Gantry");
_loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString());
_loaderRotationAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Rotation");
_facilities = DEVICE.GetDevice("System.Facilities");
_extendRoutine = new TransporterExtendRoutine(Module);
_conflictRoutine = new TransporterConflictRoutine(Module);
_transporterCommon = DEVICE.GetDevice($"{Module}.Common");
_waferHolderPresent = _transporterCommon.TransporterData.WhPresent1||_transporterCommon.TransporterData.WhPresent2;
return Runner.Start(Module,$"MoveTo {_cellName}");
}
///
/// 启动校验条件
///
///
private bool CheckStartPreConfition()
{
if(!CheckPreCondition())
{
return false;
}
double elevatorPosition = _elevatorAxis.MotionData.MotorPosition;
if (!_elevatorAxis.CheckPositionIsInStation(elevatorPosition, "Up") &&
!_elevatorAxis.CheckPositionIsInStation(elevatorPosition, "Low"))
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis {elevatorPosition} is not in Up or Low station",-1);
return false;
}
if (!_loaderEntity.IsHomed)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} is not homed",-1);
return false;
}
if (_cellName == "Loader")
{
double loaderRotationPosition = _loaderRotationAxis.MotionData.MotorPosition;
if (!_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPA") &&
!_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPB"))
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} rotation axis {loaderRotationPosition} is not int TRNPA or TRNPB station",-1);
return false;
}
}
if (WaferHolderManager.Instance.HasWaferHolder(Module)&& !_elevatorAxis.CheckPositionIsInStation(elevatorPosition, "Up"))
{
NotifyError(eEvent.ERR_TRANSPORTER,$"{Module} has wafer Shuttle but elevator axis is not in up",-1);
return false;
}
//检验Facilities
var faciltiesResult = _facilities.CheckCDA();
if (!faciltiesResult.result)
{
NotifyError(eEvent.ERR_TRANSPORTER, faciltiesResult.reason,-1);
return false;
}
return true;
}
///
/// 检验前置条件
///
///
private bool CheckPreCondition()
{
if (!_gantryAxis.IsSwitchOn)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not switch on ",-1);
return false;
}
if (!_gantryAxis.IsHomed)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not homed ",-1);
return false;
}
if (!_elevatorAxis.IsSwitchOn)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not switch on ",-1);
return false;
}
if (!_elevatorAxis.IsHomed)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not homed ",-1);
return false;
}
return true;
}
}
}