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; } } }