using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Routine;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Aitex.Core.Util;
namespace CyberX8_RT.Modules.Transporter
{
public class TransporterConflictRoutine : RoutineBase, IRoutine
{
private enum ConflictStep
{
CheckSafeStatus,
SafeWaitOtherStatus,
ReCheckSafeStatus,
CheckOtherStatus,
OtherGantryWait,
End
}
#region 内部变量
private string _otherModule = "";
private int _transporterMinimumDistance=600;
private TransporterEntity _otherTransporterEntity;
private JetAxisBase _otherGantryAxis;
private double _targetPosition;
private bool _isOtherStartPosition = false;
private bool _isOtherGantryChangedToSafeStatus = false;
///
/// 是否为正向运行
///
private bool _runPositive = false;
private bool _isConflict = true;
private double _safeDistace = 0;
#endregion
///
/// 构造函数
///
///
public TransporterConflictRoutine(string module) : base(module)
{
}
///
/// 中止
///
public void Abort()
{
Runner.Stop("Manual Abort");
}
///
/// 监控
///
///
public RState Monitor()
{
Runner.Run(ConflictStep.CheckSafeStatus, CheckSafeConflict,_delay_1ms)
.WaitWithStopCondition(ConflictStep.SafeWaitOtherStatus, ConflictWaitOtherStatus, () => { return false; })
.Run(ConflictStep.ReCheckSafeStatus,CheckSafeConflict,_delay_1ms)
.Run(ConflictStep.CheckOtherStatus, CheckOtherStatus,100)
.WaitWithStopCondition(ConflictStep.OtherGantryWait, CheckOtherAxisPositionEndStatus, CheckOtherAxisPositionStopStatus)
.End(ConflictStep.End, NullFun, _delay_1ms);
return Runner.Status;
}
///
/// 检验是否存在安全冲突
///
///
private bool CheckSafeConflict()
{
var result = CheckOtherIsInSafeDistance(_otherGantryAxis.MotionData.MotorPosition);
if(!result.result)
{
_safeDistace = result.safeDistance;
_isConflict = true;
}
return true;
}
///
/// 冲突时等待其他Idle状态
///
///
private bool ConflictWaitOtherStatus()
{
if(_isConflict)
{
return _otherTransporterEntity.IsIdle;
}
return true;
}
///
/// 检验另一个Axis状态
///
///
private bool CheckOtherStatus()
{
if(_isConflict)
{
bool positionResult= _otherTransporterEntity.CheckToPostMessage(eEvent.ERR_TRANSPORTER,
_otherModule,(int)TransporterMSG.GantrySafeMove,_safeDistace);
if(positionResult)
{
_isOtherStartPosition = true;
}
return positionResult;
}
return true;
}
///
/// 检验另外Gantry运动情况
///
///
private bool CheckOtherAxisPositionEndStatus()
{
if(_isOtherStartPosition)
{
if (_otherTransporterEntity.State == (int)TransporterState.GantrySafeMoving)
{
_isOtherGantryChangedToSafeStatus = true;
}
if (_isOtherGantryChangedToSafeStatus)
{
return _otherTransporterEntity.IsIdle;
}
else
{
return false;
}
}
else
{
return true;
}
}
///
/// 检验另外Gantry运动停止情况
///
///
private bool CheckOtherAxisPositionStopStatus()
{
if (_isOtherStartPosition)
{
return _otherTransporterEntity.IsError;
}
else
{
return true;
}
}
///
/// 检验对方是否在安全距离
///
///
///
private (bool result,double safeDistance) CheckOtherIsInSafeDistance(double position)
{
if (Module.ToString() == ModuleName.Transporter2.ToString())
{
if (_runPositive)
{
double safeDistance = _targetPosition + _transporterMinimumDistance;
if (position <= safeDistance||(Math.Abs(position - safeDistance) <= 10))
{
return (false,safeDistance);
}
}
return (true,0);
}
else
{
if(!_runPositive)
{
double safeDistance = _targetPosition - _transporterMinimumDistance;
if (position >= safeDistance)
{
return (false,safeDistance);
}
}
return (true,0);
}
}
///
/// 启动
///
///
///
public RState Start(params object[] objs)
{
if(Module=="Transporter2")
{
_otherModule = "Transporter1";
}
else
{
_otherModule = "Transporter2";
}
_targetPosition = (double)objs[0];
_runPositive = (bool)objs[1];
_isConflict = false;
_isOtherGantryChangedToSafeStatus = false;
_transporterMinimumDistance = SC.GetValue("Transporter.TransporterMinimumDistance");
_otherGantryAxis = DEVICE.GetDevice($"{_otherModule}.Gantry");
_otherTransporterEntity = Singleton.Instance.GetModule(_otherModule);
Runner.Start(Module, "Transporter Safe Distance");
return RState.Running;
}
}
}