using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.Device.LinMot;
using MECF.Framework.Common.Routine;
using CyberX8_Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace CyberX8_RT.Devices.LinMot
{
public class LinMotStartVAIPositionRoutine : RoutineBase, IRoutine
{
private enum VAIPositionStep
{
SwitchOn,
StartGoTopPosition,
Delay,
FirstWaitSendNextCommand,
LoopGoBottomPosition,
LoopWaitBottomCheckDirection,
LoopGoTopPosition,
LoopWaitTopCheckDirection,
LoopEnd,
LastGoBottomPosition,
LastGoBottomPositionWait,
CheckTopMotor,
CheckMotor,
LastDelay,
SwitchOff,
End
}
#region 内部变量
///
/// 所有扫描次数
///
private int _totalScan = 0;
///
/// 当前次数
///
private int _currentScan = 0;
///
/// 参数数据
///
private LinMotDeviceData _linMotDeviceData;
///
/// 电机对象
///
private LinMotAxis _axis;
///
/// 上一次方向
///
private string _lastDirection = "";
///
/// 最开始的方向
///
private string _startDirection = "";
#endregion
#region 属性
///
/// 当前scan次数
///
public int CurrentScan { get { return _currentScan; } }
#endregion
///
/// 构造函数
///
///
public LinMotStartVAIPositionRoutine(string module,LinMotAxis axis) : base(module)
{
_axis = axis;
}
///
/// 手动中止
///
public void Abort()
{
Runner.Stop("Manual Abort");
}
public RState Monitor()
{
if(_totalScan ==1 )
{
Runner.Run(VAIPositionStep.SwitchOn, () => { return _axis.SendOperation(LinMotOperation.SwitchOn); }
, () => { return _axis.IsSwitchOn; },_delay_5s)
.Run(VAIPositionStep.StartGoTopPosition, SendVAIGoTopPosition, CheckMotorOn, _delay_3s)
.Delay(VAIPositionStep.Delay, _delay_2s)
.Run(VAIPositionStep.LastGoBottomPosition, ContinueVAIGoBottomPosition,CheckMotorOn, _delay_3s)
.WaitWithStopCondition(VAIPositionStep.CheckTopMotor, CheckAxisArrivedTop,
() => CheckAxisMotorStopStatus((int)_linMotDeviceData.TopPosition), _delay_60s)
.WaitWithStopCondition(VAIPositionStep.CheckMotor, CheckAxisArrivedBottom,
() => CheckAxisMotorStopStatus((int)_linMotDeviceData.BottomPosition), _delay_60s)
.Wait(VAIPositionStep.CheckMotor, ()=>CheckMotorOff(false))
.Delay(VAIPositionStep.LastDelay,_delay_1s)
.Run(VAIPositionStep.SwitchOff, () => { return _axis.SendOperation(LinMotOperation.SwitchOff); }, CheckSwitchOff, _delay_5s)
.End(VAIPositionStep.End, NullFun, _delay_1ms);
}
else
{
Runner.Run(VAIPositionStep.SwitchOn, () => { return _axis.SendOperation(LinMotOperation.SwitchOn); },
() => { return _axis.IsSwitchOn; }, _delay_5s)
.Run(VAIPositionStep.StartGoTopPosition, SendVAIGoTopPosition, CheckMotorOn, _delay_3s)
.Delay(VAIPositionStep.Delay, _delay_2s)
.LoopStart(VAIPositionStep.LoopGoBottomPosition, "Loop Scan", _totalScan - 1, ContinueVAIGoBottomPosition, _delay_1ms)
.LoopRunWithStopStatus(VAIPositionStep.LoopWaitBottomCheckDirection, CheckDirectionChanged,
()=>CheckMotorOff(true),_delay_30s)
.LoopRun(VAIPositionStep.LoopGoTopPosition, ContinueVAIGoTopPosition, _delay_1ms)
.LoopRunWithStopStatus(VAIPositionStep.LoopWaitTopCheckDirection, CheckDirectionChanged,
()=>CheckMotorOff(true), _delay_30s)
.LoopEnd(VAIPositionStep.LoopEnd, NullFun, _delay_1ms)
.Run(VAIPositionStep.LastGoBottomPosition, ContinueVAIGoBottomPosition,CheckMotorOn, _delay_3s)
.WaitWithStopCondition(VAIPositionStep.LastGoBottomPositionWait, CheckAxisArrivedBottom,
()=>CheckAxisMotorStopStatus((int)_linMotDeviceData.BottomPosition), _delay_60s)
.Wait(VAIPositionStep.CheckMotor,()=>CheckMotorOff(false))
.Delay(VAIPositionStep.LastDelay, _delay_1s)
.Run(VAIPositionStep.SwitchOff, () => { return _axis.SendOperation(LinMotOperation.SwitchOff); }, CheckSwitchOff, _delay_5s)
.End(VAIPositionStep.End, NullFun, _delay_1ms);
}
return Runner.Status;
}
///
/// 前置条件
///
///
private bool CheckPreCondition()
{
if(!_axis.IsHomed)
{
LOG.WriteLog(eEvent.ERR_LINMOT, Module, "axis is not homed");
return false;
}
if (!_axis.IsConnectd)
{
LOG.WriteLog(eEvent.ERR_LINMOT, Module, "axis is not connected");
return false;
}
if(_axis.IsError)
{
LOG.WriteLog(eEvent.ERR_LINMOT, Module, "axis is in error");
return false;
}
return true;
}
///
/// 第一次Goto Top
///
///
private bool SendVAIGoTopPosition()
{
if(!_axis.IsConnectd)
{
LOG.WriteLog(eEvent.ERR_LINMOT, Module, "axis is not connected");
return false;
}
_lastDirection= _axis.Direction;
_currentScan++;
return _axis.SendVAIGoToPosition((int)_linMotDeviceData.TopPosition, (int)_linMotDeviceData.UpMaxSpeed, _linMotDeviceData.UpMaxAcceleration,
_linMotDeviceData.UpMaxDeceleration);
}
///
/// 检验Axis运动状态
///
///
private bool CheckMotorOn()
{
return _axis.IsMotorOn;
}
///
/// 检验Axis运动状态
///
///
private bool CheckMotorOff(bool showError)
{
bool result= !_axis.IsMotorOn;
if (result)
{
if (showError)
{
LOG.WriteLog(eEvent.ERR_LINMOT, Module, "Linmot is stop");
}
}
return result;
}
///
/// 检验电机停止状态
///
///
private bool CheckAxisMotorStopStatus(int targetPosition)
{
bool arrived = CheckAxisArrived(targetPosition);
if (!arrived)
{
return CheckMotorOff(true);
}
else
{
return false;
}
}
///
/// 检验方向是否发生变化
///
///
private bool CheckDirectionChanged()
{
bool result = _lastDirection != _axis.Direction;
if(result)
{
_lastDirection = _axis.Direction;
if(_lastDirection==_startDirection)
{
_currentScan++;
}
}
return result;
}
///
/// 不停止Go Bottom
///
///
private bool ContinueVAIGoBottomPosition()
{
if (!_axis.IsConnectd)
{
LOG.WriteLog(eEvent.ERR_LINMOT, Module, "axis is not connected");
return false;
}
bool result = _axis.IsMotorOn;
if (!result)
{
LOG.WriteLog(eEvent.ERR_LINMOT, Module, "axis is stopped");
return false;
}
return _axis.SendGAIGoToPositionAfterActualCommand((int)_linMotDeviceData.BottomPosition, (int)_linMotDeviceData.DownMaxSpeed,
_linMotDeviceData.DownMaxAcceleration, _linMotDeviceData.DownMaxDeceleration);
}
///
/// 检验电机是还到达顶部
///
///
private bool CheckAxisArrivedTop()
{
return CheckAxisArrived((int)_linMotDeviceData.TopPosition);
}
///
/// 检验电机是还到达底部
///
///
private bool CheckAxisArrivedBottom()
{
return CheckAxisArrived((int)_linMotDeviceData.BottomPosition);
}
private bool CheckAxisArrived(int targetPosition)
{
double bias = Math.Abs(_axis.CurrentIntPosition - targetPosition) / Math.Abs(_linMotDeviceData.TopPosition - _linMotDeviceData.BottomPosition);
return bias <= 0.1;
}
///
/// 不停止Go Top
///
///
private bool ContinueVAIGoTopPosition()
{
if (!_axis.IsConnectd)
{
LOG.WriteLog(eEvent.ERR_LINMOT, Module, "axis is not connected");
return false;
}
return _axis.SendGAIGoToPositionAfterActualCommand((int)_linMotDeviceData.TopPosition, (int)_linMotDeviceData.UpMaxSpeed, _linMotDeviceData.UpMaxAcceleration,
_linMotDeviceData.UpMaxDeceleration);
}
///
/// 检验是否SwitchOff
///
///
private bool CheckSwitchOff()
{
return !_axis.IsSwitchOn;
}
///
/// 启动
///
///
///
public RState Start(params object[] objs)
{
_totalScan=(int)objs[0];
_linMotDeviceData=(LinMotDeviceData)objs[1];
_lastDirection = _axis.Direction;
_startDirection = _axis.Direction;
_currentScan = 0;
if(!CheckPreCondition())
{
return RState.Failed;
}
Runner.Start(Module, "VAI Go to Position");
return RState.Running;
}
}
}