领胜LDS 键盘AOI检测项目
patrick.xu
2021-07-24 ff7cab72419729ce2c5adc46350ef45d89a5d1e5
src/Bro.M071.Process/M071Process_MotionCard.cs
@@ -7,6 +7,7 @@
using System.ComponentModel;
using System.Drawing.Design;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -17,9 +18,11 @@
    public partial class M071Process
    {
        public Timer ResetTimer = null;
        const int FULLRESETTIME = 5;
        MachineState MeasureState = MachineState.Unknown;
        object machineStateLock = new object();
        //MachineState _machineStatePre = MachineState.Unknown;
        MachineState machineState = MachineState.Unknown;
        public MachineState MachineState
        {
@@ -29,102 +32,124 @@
                if (machineState == value)
                    return;
                LogAsync(DateTime.Now, $"设备状态切换:{machineState.ToString()}->{value.ToString()}", "");
                machineState = value;
                switch (machineState)
                Task.Run(() =>
                {
                    case MachineState.Ready:
                        lock (machineStateLock)
                        {
                            SwitchBeep(false);
                            SwitchLightRed(false);
                            SwitchLightYellow(false);
                        }
                    OnMachineStateChanged?.Invoke(machineState);
                        Task.Run(() =>
                        {
                            while (MachineState == MachineState.Ready)
                    switch (machineState)
                    {
                        case MachineState.Ready:
                            lock (machineStateLock)
                            {
                                lock (machineStateLock)
                                {
                                    SwitchLightGreen(true);
                                    Thread.Sleep(1000);
                                    SwitchLightGreen(false);
                                    Thread.Sleep(1000);
                                }
                                SwitchBeep(false);
                                SwitchLightRed(false);
                                SwitchLightYellow(false);
                            }
                        });
                        break;
                    case MachineState.Running:
                        lock (machineStateLock)
                        {
                            SwitchBeep(false);
                            SwitchLightRed(false);
                            SwitchLightYellow(false);
                            SwitchLightGreen(true);
                        }
                        break;
                    case MachineState.Alarm:
                        lock (machineStateLock)
                        {
                            SwitchBeep(true);
                            SwitchLightRed(true);
                            SwitchLightYellow(false);
                            SwitchLightGreen(false);
                        }
                        break;
                    case MachineState.Pause:
                        lock (machineStateLock)
                        {
                            SwitchBeep(false);
                            SwitchLightRed(false);
                        }
                        Task.Run(() =>
                        {
                            while (MachineState == MachineState.Pause)
                            Task.Run(() =>
                            {
                                lock (machineStateLock)
                                while (MachineState == MachineState.Ready)
                                {
                                    SwitchLightYellow(true);
                                    SwitchLightGreen(true);
                                    Thread.Sleep(1000);
                                    SwitchLightYellow(false);
                                    SwitchLightGreen(false);
                                    Thread.Sleep(1000);
                                    lock (machineStateLock)
                                    {
                                        SwitchLightGreen(true);
                                        Thread.Sleep(1000);
                                        SwitchLightGreen(false);
                                        Thread.Sleep(1000);
                                    }
                                }
                            }
                        });
                        break;
                    case MachineState.Resetting:
                        lock (machineStateLock)
                        {
                            SwitchBeep(false);
                            SwitchLightRed(false);
                            SwitchLightGreen(false);
                        }
                        Task.Run(() =>
                        {
                            while (MachineState == MachineState.Resetting)
                            });
                            break;
                        case MachineState.Running:
                            lock (machineStateLock)
                            {
                                lock (machineStateLock)
                                {
                                    SwitchLightYellow(true);
                                    Thread.Sleep(1000);
                                    SwitchLightYellow(false);
                                    Thread.Sleep(1000);
                                }
                                SwitchBeep(false);
                                SwitchLightRed(false);
                                SwitchLightYellow(false);
                                SwitchLightGreen(true);
                            }
                        });
                        break;
                    default:
                        break;
                }
                OnMachineStateChanged?.Invoke(machineState);
                            break;
                        case MachineState.Alarm:
                            lock (machineStateLock)
                            {
                                SwitchBeep(true);
                                SwitchLightRed(true);
                                SwitchLightYellow(false);
                                SwitchLightGreen(false);
                            }
                            break;
                        case MachineState.Pause:
                            lock (machineStateLock)
                            {
                                SwitchBeep(false);
                                SwitchLightRed(false);
                            }
                            Task.Run(() =>
                            {
                                while (MachineState == MachineState.Pause)
                                {
                                    lock (machineStateLock)
                                    {
                                        SwitchLightYellow(true);
                                        SwitchLightGreen(true);
                                        Thread.Sleep(1000);
                                        SwitchLightYellow(false);
                                        SwitchLightGreen(false);
                                        Thread.Sleep(1000);
                                    }
                                }
                            });
                            break;
                        case MachineState.Resetting:
                            lock (machineStateLock)
                            {
                                SwitchBeep(false);
                                SwitchLightRed(false);
                                SwitchLightGreen(false);
                            }
                            Task.Run(() =>
                            {
                                while (MachineState == MachineState.Resetting)
                                {
                                    lock (machineStateLock)
                                    {
                                        SwitchLightYellow(true);
                                        Thread.Sleep(1000);
                                        SwitchLightYellow(false);
                                        Thread.Sleep(1000);
                                    }
                                }
                            });
                            break;
                        default:
                            break;
                    }
                });
            }
        }
        private void Pause()
        {
            #region 板卡暂停动作
            outputCtrlCard.SetImmediatePause();
            #endregion
            //_pauseHandle.WaitHandle.Reset();
            //_pauseHandle.WaitResult = true;
        }
        private void Resume(bool isResumeContinueMoving)
        {
            #region 板卡恢复动作
            outputCtrlCard.ResetImmediatePause(isResumeContinueMoving);
            #endregion
            //_pauseHandle.WaitHandle.Set();
            //_pauseHandle.WaitResult = false;
        }
        private void MotionCardSettingCheck()
@@ -203,24 +228,6 @@
        [ProcessMethod("MotionCardBase", "Reset", "简单复位操作", InvokeType.TestInvoke)]
        public ProcessResponse Reset(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
        {
            //if (opConfig == null)
            //{
            //    var monitorSet = Config.MonitorSetCollection.FirstOrDefault(u => u.MethodCode == "Reset");
            //    if (monitorSet == null)
            //        throw new ProcessException("未配置默认复位操作");
            //    opConfig = monitorSet.OpConfig;
            //    if (opConfig == null)
            //        throw new ProcessException("未配置复位操作具体配置动作");
            //    if (invokeDevice == null)
            //    {
            //        invokeDevice = DeviceCollection.FirstOrDefault(u => u.Id == monitorSet.InvokeDevice);
            //        if (invokeDevice == null)
            //            throw new ProcessException("未配置复位操作执行设备");
            //    }
            //}
            if (ResetTimer == null)
            {
                ResetTimer = new Timer(FullReset, null, -1, -1);
@@ -229,7 +236,7 @@
            if (opConfig?.InputPara != null && opConfig.InputPara.Count > 0)
            {
                //大复位信号
                ResetTimer.Change(opConfig.InputPara[0] == 1 ? FULLRESETTIME * 1000 : -1, -1);
                ResetTimer.Change(opConfig.InputPara[0] == 1 ? Config.FullResetRequiredDuration * 1000 : -1, -1);
                if (opConfig.InputPara[0] == 0)
                    return new ProcessResponse(true);
@@ -244,29 +251,31 @@
            MotionCardDefaultRun("Reset", ref opConfig, ref invokeDevice);
            (invokeDevice as MotionCardBase).ResetAlarm();
            _isdoing = false;
            _pausedHandle.Set();
            RaisedAlarm("");
            OnCheckHintUpload?.Invoke("", false);
            //if (MachineState != MachineState.Pause)
            //{
            MachineState = MachineState.Ready;
            //}
            //else
            //{
            //    LogAsync(DateTime.Now, "设备暂停中,无法复位", "");
            //    return new ProcessResponse(true);
            //}
            if (IsEmergencyStopped)
            {
                RaisedAlarm("急停按钮未恢复,请执行大复位");
                MachineState = MachineState.Alarm;
                return new ProcessResponse(true);
            }
            //if (opConfig.InputPara?.Count > 0)
            //{
            //    //大复位信号
            //    ResetTimer.Change(-1, opConfig.InputPara[0] == 1 ? FULLRESETTIME * 1000 : -1);
            //}
            //if (invokeDevice is MotionCardBase motionCard)
            //{
            //    motionCard.Run(opConfig);
            //}
            LogAsync(DateTime.Now, "普通复位动作完成", "");
            OnResetDone?.Invoke();
            return new ProcessResponse(true);
        }
@@ -287,34 +296,25 @@
        [ProcessMethod("MotionCardBase", "FullReset", "大复位操作", InvokeType.TestInvoke)]
        public ProcessResponse FullReset(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
        {
            //if (opConfig == null)
            //{
            //    var monitorSet = Config.MonitorSetCollection.FirstOrDefault(u => u.MethodCode == "FullReset");
            //    if (monitorSet == null)
            //        throw new ProcessException("未配置默认大复位操作");
            if (!IsAllowedWork)
            {
                LogAsync(DateTime.Now, $"{SafetyMsg},大复位失败", "");
                return new ProcessResponse(false);
            }
            //    opConfig = monitorSet.OpConfig;
            //    if (opConfig == null)
            //        throw new ProcessException("未配置大复位操作具体配置动作");
            //    if (invokeDevice == null)
            //    {
            //        invokeDevice = DeviceCollection.FirstOrDefault(u => u.Id == monitorSet.InvokeDevice);
            //        if (invokeDevice == null)
            //            throw new ProcessException("未配置大复位操作执行设备");
            //    }
            //}
            //if (invokeDevice is MotionCardBase motionCard)
            //{
            //    motionCard.Run(opConfig);
            //}
            if (MachineState == MachineState.Pause)
            {
                Resume(false);
            }
            MachineState = MachineState.Resetting;
            MotionCardDefaultRun("FullReset", ref opConfig, ref invokeDevice);
            productionList.ForEach(u => u.Dispose());
            productionList.Clear();
            lock (productionLock)
            {
                productionList.ForEach(u => u.Dispose());
                productionList.Clear();
            }
            OnFullResetDone?.Invoke();
@@ -335,12 +335,12 @@
        /// WaitHandle 暂停句柄  默认为非阻塞 可执行
        /// WaitResult 暂停标志 true 正常执行  false 暂停中
        /// </summary>
        ManualWaitConfirm _pauseHandle = new ManualWaitConfirm()
        {
            WaitHandle = new ManualResetEvent(true),
            WaitResult = true,
        };
        MachineState _machineStateBeforePause = MachineState.Unknown;
        //ManualWaitConfirm _pauseHandle = new ManualWaitConfirm()
        //{
        //    WaitHandle = new ManualResetEvent(true),
        //    WaitResult = true,
        //};
        List<MachineState> _statesAllowPause = new List<MachineState>() { MachineState.Running, MachineState.Ready, MachineState.Pause };
        [ProcessMethod("", "SwitchJobStatus", "流程状态切换", InvokeType.TestInvoke)]
        public ProcessResponse SwitchJobStatus(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
@@ -358,66 +358,53 @@
                throw new ProcessException("未获取板卡设备");
            bool? isToPause = null; //true 暂停 false 继续
            if (opConfig.InputPara != null && opConfig.InputPara.Count > 0)
            if (opConfig.InputPara[0] == 10)
            {
                isToPause = opConfig.InputPara[0] == 1;
                isToPause = false;
            }
            else if (opConfig.InputPara[0] == 11)
            {
                isToPause = true;
            }
            if (isToPause == null)
            {
                if (!_pauseHandle.WaitResult)
                {
                    #region 板卡暂停动作
                    motionDevice.SetImmediatePause();
                    #endregion
                    _pauseHandle.WaitHandle.Reset();
                    _pauseHandle.WaitResult = true;
                    _machineStateBeforePause = MachineState;
                    MachineState = MachineState.Pause;
                }
                else if (!_pauseHandle.WaitResult)
                {
                    #region 板卡恢复动作
                    motionDevice.ResetImmediatePause();
                    #endregion
                    _pauseHandle.WaitHandle.Set();
                    _pauseHandle.WaitResult = false;
                    MachineState = _machineStateBeforePause;
                }
                IsManualPaused = !IsManualPaused;
            }
            else
            {
                if (isToPause.Value)
                {
                    if (!_pauseHandle.WaitResult)
                    {
                        #region 板卡暂停动作
                        motionDevice.SetImmediatePause();
                        #endregion
                //if (isToPause.Value)
                //{
                //    if (!_pauseHandle.WaitResult)
                //    {
                //        //#region 板卡暂停动作
                //        //motionDevice.SetImmediatePause();
                //        //#endregion
                        _pauseHandle.WaitHandle.Reset();
                        _pauseHandle.WaitResult = true;
                        MachineState = MachineState.Pause;
                    }
                }
                else
                {
                    if (!_pauseHandle.WaitResult)
                    {
                        #region 板卡恢复动作
                        motionDevice.ResetImmediatePause();
                        #endregion
                //        //_pauseHandle.WaitHandle.Reset();
                //        //_pauseHandle.WaitResult = true;
                //        MachineState = MachineState.Pause;
                //    }
                //}
                //else
                //{
                //    if (!_pauseHandle.WaitResult)
                //    {
                //        //#region 板卡恢复动作
                //        //motionDevice.ResetImmediatePause();
                //        //#endregion
                        _pauseHandle.WaitHandle.Set();
                        _pauseHandle.WaitResult = false;
                        MachineState = _machineStateBeforePause;
                    }
                }
                //        //_pauseHandle.WaitHandle.Set();
                //        //_pauseHandle.WaitResult = false;
                //        MachineState = _machineStatePre;
                //    }
                //}
                IsManualPaused = isToPause.Value;
            }
            return new ProcessResponse(_pauseHandle.WaitResult);
            return new ProcessResponse(IsManualPaused);
        }
        ////[ProcessMethod("", "PauseJob", "暂停流程", InvokeType.TestInvoke)]
@@ -625,6 +612,7 @@
        {
            get => !(IsSafetyBeamTrigged || IsSafetyDoorTrigged || IsEmergencyStopped);
        }
        string SafetyMsg
        {
            get => $"{(IsSafetyBeamTrigged ? "安全光幕" : "")}{(IsSafetyDoorTrigged ? " 安全门" : "")}{(IsEmergencyStopped ? " 急停按钮" : "")}触发中";
@@ -633,21 +621,98 @@
        #region 安全门 & 安全光线
        bool isSafetyDoorTrigged = false;
        bool isSafetyBeamTrigged = false;
        bool isManualPaused = false;
        public bool IsSafetyDoorTrigged
        {
            get => !Config.IsSafetyDoorBlocked && isSafetyDoorTrigged;
            set => isSafetyDoorTrigged = value;
            get => (!Config.IsSafetyDoorBlocked) && isSafetyDoorTrigged;
            set
            {
                isSafetyDoorTrigged = value;
                CheckMachinePauseState();
            }
        }
        public bool IsSafetyBeamTrigged
        {
            get => !Config.IsSafetyBeamBlocked && isSafetyBeamTrigged;
            set => isSafetyBeamTrigged = value;
            get => (!Config.IsSafetyBeamBlocked) && isSafetyBeamTrigged;
            set
            {
                isSafetyBeamTrigged = value;
                CheckMachinePauseState();
            }
        }
        public bool IsManualPaused
        {
            get => isManualPaused;
            set
            {
                isManualPaused = value;
                CheckMachinePauseState();
            }
        }
        ManualResetEventSlim _pausedHandle = new ManualResetEventSlim(true);
        MachineState _machineStateBeforePause = MachineState.Unknown;
        object _pauseLock = new object();
        private async void CheckMachinePauseState()
        {
            await Task.Run(() =>
            {
                lock (_pauseLock)
                {
                    if (IsMachinePaused)
                    {
                        if (MachineState == MachineState.Ready || MachineState == MachineState.Running)
                        {
                            _machineStateBeforePause = MachineState;
                        }
                        MachineState = MachineState.Pause;
                        _pausedHandle.Reset();
                        if (_machineStateBeforePause == MachineState.Running)
                        {
                            Pause();
                        }
                    }
                    else
                    {
                        if (MachineState == MachineState.Pause)
                        {
                            if (_machineStateBeforePause == MachineState.Running || _machineStateBeforePause == MachineState.Ready)
                            {
                                Resume(true);
                            }
                            _pausedHandle.Set();
                            RaisedAlarm("");
                            if (_machineStateBeforePause == MachineState.Running && MeasureState == MachineState.Ready)
                            {
                                MachineState = MachineState.Ready;
                            }
                            else
                            {
                                MachineState = _machineStateBeforePause;
                            }
                        }
                    }
                }
            }
            );
        }
        public bool IsMachinePaused
        {
            get => IsSafetyBeamTrigged || IsSafetyDoorTrigged || IsManualPaused;
        }
        [ProcessMethod("", "SafetyDoorSignal", "安全门信号监控,正常ON,OFF时报警", InvokeType.TestInvoke)]
        [MethodImpl(MethodImplOptions.Synchronized)]
        public ProcessResponse SafetyDoorSignal(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
        {
            //if (MachineState != MachineState.Running && MachineState != MachineState.Pause)
            //    return new ProcessResponse(true);
            if (opConfig.InputPara == null || opConfig.InputPara.Count == 0)
                throw new ProcessException("安全门监控未配置输入信号");
@@ -656,18 +721,15 @@
            if (IsSafetyDoorTrigged)
            {
                RaisedAlarm("安全门未正常关闭");
                MachineState = MachineState.Alarm;
            }
            return new ProcessResponse(true);
        }
        [ProcessMethod("", "SafetyBeamSignal", "安全光幕信号监控,正常ON,OFF时报警", InvokeType.TestInvoke)]
        [MethodImpl(MethodImplOptions.Synchronized)]
        public ProcessResponse SafetyBeamSignal(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
        {
            if (MachineState != MachineState.Running || MachineState != MachineState.Alarm)
                return new ProcessResponse(true);
            if (opConfig.InputPara == null || opConfig.InputPara.Count == 0)
                throw new ProcessException("安全光幕监控未配置输入信号");
@@ -676,7 +738,6 @@
            if (IsSafetyBeamTrigged)
            {
                RaisedAlarm("安全光线被遮挡");
                MachineState = MachineState.Alarm;
            }
            return new ProcessResponse(true);
@@ -711,7 +772,7 @@
            IsEmergencyStopped = opConfig.InputPara[0] == 0;
            if (IsEmergencyStopped)
            if (isEmergencyStopped)
            {
                RaisedAlarm("急停按钮被拍下");
                MachineState = MachineState.Alarm;