RobotBean.cs 11.7 KB
using log4net;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;

namespace OnlineStore.DeviceLibrary
{
    public partial class RobotBean : RobotBase
    {
        public bool IsDebug = false;

        public InputEquip inputEquip;
        public X_RAY_Equip XrayBean;
        public OutputEquip outputEquip;
        public Dictionary<int, EquipBase> equipsMap = new Dictionary<int, EquipBase>();

        public Robot_Config Config = null;

        #region  初始化 
        private bool canStart = false;

        public RobotBean(Robot_Config lineConfig, InputEquip_Config fconfig, XRay_Config xconfig, OutputEquip_Config pconfig)
        {
            equipsMap = new Dictionary<int, EquipBase>();
            if (lineConfig.IOSingle_TimerOut <= 0)
            {
                lineConfig.IOSingle_TimerOut = 5000;
            }
            Init();
            baseConfig = lineConfig;
            this.Config = lineConfig;
            this.DeviceID = lineConfig.Id;

            Name = (" 自动点料机_" + " ").ToUpper();
            MoveInfo = new RobotMoveInfo(Name);

            IsDebug = Config.IsDebug.Equals(1);

           
            List<string> ioList = new List<string>();
            ioList = new List<string>(DeviceConfig.ProIOIpMap.Values);

            inputEquip = new InputEquip("1", fconfig);
            XrayBean = new X_RAY_Equip("2", xconfig);
            outputEquip = new OutputEquip("3", pconfig);
            equipsMap.Add(1, inputEquip);
            equipsMap.Add(2, XrayBean);
            equipsMap.Add(3, outputEquip);
            IOManager.Init();
            CodeManager.LoadConfig();

            AgvClient.NodeList.Add(outputEquip.Config.AgvInName);
            AgvClient.NodeList.Add(outputEquip.Config.AgvOutName);
            AgvClient.NodeList.Add(inputEquip.Config.RightAgvName);
            AgvClient.NodeList.Add(inputEquip.Config.LeftAgvName);
            Task.Factory.StartNew(delegate
            {
                LogUtil.info(Name + "开始连接IO模块 ");
                IOManager.instance.ConnectionIOList(ioList);
                mainTimer.Enabled = true;
                canStart = true;
                AgvClient.Init();
            });
        }
         
        #endregion

        public string CanStart()
        {
            if (!canStart)
            {
                return "启动失败:设备未初始化完成";
            }
            return "";
        }

        public override bool StartRun()
        {
            string result = CanStart();
            if (String.IsNullOrEmpty(result).Equals(false))
            {
                SetWarnMsg(result);
                return false;
            }
            else if (IOValue(IO_Type.SuddenStop_BTN).Equals(IO_VALUE.LOW))
            {
                SetWarnMsg("启动失败:急停未开");
                return false;
            }
            else
            {
                mainTimer.Enabled = false;
                //lineStatus = LineStatus.ResetMove;
                runStatus = RobotRunStatus.HomeMoving;
                StartTime = DateTime.Now;
                LogUtil.info(Name + "开始启动,启动时间:" + StartTime.ToString() + "");

                Thread.Sleep(5);

                mainTimer.Interval = 1000;
                maxSeconds = 10; 
                alarmType = AlarmType.None;
                mainTimer.Enabled = false;
                isInSuddenDown = false;
                isNoAirCheck = false;
                SetWarnMsg("");
                MoveInfo.NewMove(RobotMoveType.Reset);
                MoveInfo.NextMoveStep(StepEnum.Wait);

                foreach (EquipBase moveEquip in this.equipsMap.Values)
                {
                    if (runStatus.Equals(RobotRunStatus.Wait))
                    {
                        LogUtil.error(Name + "启动过程中发现 runStatus=Wait,中断启动");
                        return false;
                    }

                    EquipStartRun(moveEquip);
                }
                if (runStatus.Equals(RobotRunStatus.Wait))
                { return false; }
                RFIDManager.Open(new string[] { });
                mainTimer.Enabled = true;
                return true;
            }
        }
        private void EquipStartRun(EquipBase moveEquip)
        {
            if (moveEquip.IsDebug)
            {
                LogUtil.info(moveEquip.Name + "调试状态,暂不启动");
            }
            else
            {
                bool result = moveEquip.StartRun();
                Thread.Sleep(60);
            }
        }
       

        public override bool Reset()
        {
            mainTimer.Enabled = false;
            bool isNeedAllReset = false;
            if (isInSuddenDown || isNoAirCheck)
            {
                //TrayManager.LineNeedEmptyTrayNum = 0;
                isNeedAllReset = true;
                LogUtil.error(Name + "收到复位信号,急停中或没有气压报警中,强制所有设备复位~");
            }
            else if ((runStatus == RobotRunStatus.HomeMoving || runStatus == RobotRunStatus.Reset) && NoAlarm())
            {
                LogUtil.error(Name + "收到复位信号,已经在复位或原点返回中,且当前无报警,不处理复位");
                return false;
            }

            //停止运动
            MoveInfo.EndMove();
             
            runStatus = RobotRunStatus.Reset;

            //重置通用处理
            mainTimer.Interval = 1000;
            maxSeconds = 10; 
            alarmType = AlarmType.None;
            mainTimer.Enabled = false;
            isInSuddenDown = false;
            isNoAirCheck = false;
            SetWarnMsg("");
            MoveInfo.NewMove(RobotMoveType.Reset);
            MoveInfo.NextMoveStep(StepEnum.Wait);

            foreach (EquipBase equip in equipsMap.Values)
            {
                if (runStatus.Equals(RobotRunStatus.Wait))
                {
                    LogUtil.error(Name + "复位过程中发现 runStatus=Wait,中断启动");
                    return false;
                }
                EquipReset(equip, isNeedAllReset);
            }
            if (runStatus.Equals(RobotRunStatus.Wait))
            {
                return false;
            }
            mainTimer.Enabled = true;
            return true;
        }
        private void EquipReset(EquipBase equip, bool isNeedAllReset)
        {
            //调试状态不再重置
            if (!equip.IsDebug)
            {
                if (isNeedAllReset || (!NoAlarm()))
                {
                    LogUtil.info(Name + "收到复位信号," + equip.Name + " 需要复位");
                    equip.Reset();
                    Thread.Sleep(60);
                }
                else
                {
                    LogUtil.info(Name + "收到复位信号," + equip.Name + " 正常无报警,不需要复位");
                }
            } 
        }

        internal override void StopMove()
        {
            MoveInfo.EndMove();
            foreach (EquipBase equip in this.equipsMap.Values)
            {
                if (!equip.IsDebug)
                {
                    equip.StopRun();
                }
            }
        }
        public override void StopRun()
        {
            mainTimer.Enabled = false; 
            StopMove(); 
            AgvClient.SetCancelState(true);
            RFIDManager.Close();
            runStatus = RobotRunStatus.Wait; 
            TimeSpan span = DateTime.Now - StartTime;
            LogUtil.info(Name + ",停止运行,总运行时间:" + span.ToString());
        }

        private bool busyPro = false;
        private DateTime busyProTime = DateTime.Now;
        private int maxSeconds = 3;
        protected override void mainTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                TimeSpan span = DateTime.Now - busyProTime;
                if (busyPro && span.TotalSeconds < maxSeconds)
                {
                    return;
                }
                try
                {
                    busyPro = true;
                    busyProTime = DateTime.Now;
                    switch (runStatus)
                    {
                        case RobotRunStatus.HomeMoving:
                            ResetProcess();
                            break;
                        case RobotRunStatus.Reset:
                            ResetProcess();
                            break;
                        case RobotRunStatus.Runing:
                            if ((isInSuddenDown.Equals(false) && isNoAirCheck.Equals(false)))
                            {
                                //清理超时异常
                                IOTimeOutProcess();
                            }
                            break;
                        default: break;
                    }
                }
                catch (Exception ex)
                {
                    LogUtil.error(Name + "LineTimerPro 出错:", ex);
                }
                busyPro = false;
            }
            catch (Exception ex)
            {
                LogUtil.error(Name + "主定时器出错:" + ex.ToString());
            }
            Thread.Sleep(1);
        }
   

        protected override void ResetProcess()
        {
            if (MoveInfo.IsInWait)
            {
                CheckWait(MoveInfo);
            }
            if (!MoveInfo.IsInWait)
            {
                bool isOk = true;
                string msg = "";
                //判断是否所有的已经返回完成
                TimeSpan span = DateTime.Now - MoveInfo.LastSetpTime;
                foreach (EquipBase moveEquip in this.equipsMap.Values)
                {
                    if (moveEquip.runStatus.Equals(RobotRunStatus.HomeMoving) || moveEquip.runStatus.Equals(RobotRunStatus.Reset) || moveEquip.runStatus.Equals(RobotRunStatus.Wait))
                    {
                        if (moveEquip.NoAlarm())
                        {
                            msg = moveEquip.Name + "复位结束";
                            isOk = false;
                            break;
                        }
                        else
                        {
                            //LogUtil.error(Name + " " + moveEquip.Name + "在复位过程中报警,需要重新复位,调用 moveEquip.Reset();");
                            //moveEquip.Reset();
                            ////如果小于80秒,继续等待
                            //if (span.TotalSeconds < 80)
                            //{
                            //    isOk = false;
                            //    break;
                            //}
                        }
                    }
                }

                if (isOk)
                { 
                    runStatus = RobotRunStatus.Runing; 
                    MoveInfo.EndMove();
                    mainTimer.Interval = 300;
                    maxSeconds = 3;
                    AgvClient.SetCancelState(AgvClient.CurrCancelState);
                    LogUtil.info(Name + "复位完成 [" + FormUtil.GetSpanStr(span) + "]");
                }
                else if (span.TotalSeconds > 120)
                {
                    WarnMsg = Name + "[" + MoveInfo.MoveStep + "][" + msg + "]已等待[" + Math.Round(span.TotalSeconds, 1) + "]秒";
                    LogUtil.error(WarnMsg, 903);
                    Alarm(AlarmType.IoSingleTimeOut);
                }
            }
        }

    }
}