Control.cs 9.2 KB
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using Common;
using log4net.Util;
using RestSharp;

namespace DeviceLibrary
{
    public class Control
    {
        private static log4net.ILog log = log4net.LogManager.GetLogger("Control");
        static Dictionary<string, RunInfo> runInfoMap = new Dictionary<string, RunInfo>();

        private System.Timers.Timer AgvCallTimer;
        private System.Timers.Timer AgvStateTimer;
        private System.Timers.Timer NodeStateTimer;
        //public List<string> Marks;
        private const int REG_STATUS = 20;
        //private List<string> shelfLockedNodeNames;
        public delegate void AgvChangedEvent(int agvIndex);
        public event AgvChangedEvent AgvChanged;
        public event AgvChangedEvent AgvOnline;
        //public event AgvChangedEvent NodeChangedEvent;
        public Control()
        {
            AgvCallTimer = new System.Timers.Timer
            {
                Interval = 300,
                AutoReset = true,
                Enabled = false
            };
            AgvCallTimer.Elapsed += AgvCallTimer_Elapsed;

            AgvStateTimer = new System.Timers.Timer
            {
                Interval = 3000,
                AutoReset = true,
                Enabled = false
            };
            AgvStateTimer.Elapsed += AgvStateTimer_Elapsed;
            NodeStateTimer = new System.Timers.Timer
            {
                Interval = 5000,
                AutoReset = true,
                Enabled = false
            };
            NodeStateTimer.Elapsed += NodeStateTimer_Elapsed;
        }


        public void Start()
        {
            AgvCallTimer.Enabled = true;
            AgvStateTimer.Enabled = true;
            NodeStateTimer.Enabled = true;
            AgvCallTimer.Start();
            AgvStateTimer.Start();
            NodeStateTimer.Start();
        }

        public void Stop()
        {
            AgvCallTimer.Enabled = false;
            AgvStateTimer.Enabled = false;
            NodeStateTimer.Enabled = false;
            AgvCallTimer.Stop();
            AgvStateTimer.Stop();
            NodeStateTimer.Stop();
        }
        private bool NodeStateInProcess = false;
        private void NodeStateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (NodeStateInProcess) return;
            NodeStateInProcess = true;
            NodeStateInProcess = false;
        }
        private bool AgvStateInProcess = false;
        //private eAGVState preAGVState = eAGVState.None;
        private void AgvStateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            bool rtn;
            if (AgvStateInProcess) return;
            AgvStateInProcess = true;
            //List<AlarmMsg> msglist = new List<AlarmMsg>();
            for (int i = 0; i < AGVManager.agvInfo.Count; i++)
            {
                try
                {
                    AGVManager.agvInfo[i].SetKanban();
                    if (!CheckOnline(i)) continue;
                    bool change = false;
                    MiR_API.Get_Task_State(AGVManager.agvInfo[i]);
                    Thread.Sleep(50);
                    //获取AGV状态
                    rtn = MiR_API.Get_State(AGVManager.agvInfo[i], out eAGVState stateID, out string stateText, out int battery, out string mission_text, out Agv_Info.MirPosition position);
                    Thread.Sleep(50);
                    if (rtn) change = AGVManager.agvInfo[i].SetState(stateID, battery, mission_text, position);

                    // if (change)
                    {
                        AgvChanged?.Invoke(i);
                    }
                }
                catch (Exception ex)
                {
                    log.Error("AgvStateTimer_" + AGVManager.agvInfo[i].Name + ex.Message + ex.StackTrace);
                }
            }

            AgvStateInProcess = false;
        }
        /// <summary>
        /// 从节点获取任务
        /// </summary>
        /// <param name="agv_Info"></param>
        /// <returns></returns>
        public Job GetJob(Agv_Info agv_Info)
        {
            foreach (JobType jobType in AGVManager.jobTypes)
            {
                Job job = null;
                if (agv_Info.IsUse)
                    job = jobType.GetNewJob(agv_Info);
                else
                    return null;
                if (job != null)
                {
                    log.Debug(agv_Info.Name + " GetJob OK " + job.ToString());
                    return job;
                }
            }
            return null;
        }

        private bool AgvCallInProcess = false;
        private void AgvCallTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (AgvCallInProcess) return;
            AgvCallInProcess = true;
            for (int i = 0; i < AGVManager.agvInfo.Count; i++)
            {
                try
                {
                    Agv_Info agv = AGVManager.agvInfo[i];
                    if (!agv.IsCon) continue;   //AGV网络连接
                    if (!AGVManager.agvInfo[i].IsUse) continue;   //AGV是否可用

                    //Ready,Pause,Executing,Error
                    if(AGVManager.agvInfo[i].StateID.Equals(eAGVState.Pause))
                    {
                        MiR_API.State_Ready(AGVManager.agvInfo[i]);
                        continue;
                    }
                    if (AGVManager.agvInfo[i].StateID.Equals(eAGVState.Error))
                    {
                        MiR_API.Clear_Error(AGVManager.agvInfo[i]);
                        continue;
                    }
                    if (!AGVManager.agvInfo[i].StateID.Equals(eAGVState.Ready) 
                        && !AGVManager.agvInfo[i].StateID.Equals(eAGVState.Executing) && !AGVManager.agvInfo[i].StateID.Equals(eAGVState.None))
                    {
                        log.Warn(string.Format("{0}不能调用 StateID={1}", AGVManager.agvInfo[i].Name, AGVManager.agvInfo[i].StateID.ToString()));
                        continue;
                    }
                    if (agv.TaskRunState.DeWaitTaskQueue(out AgvTask task))
                    {
                        if (agv.CurJob != null)
                        {
                            agv.CurJob.ResendTask(agv);
                        }
                        else
                        {
                            agv.TaskRunState.ClearWaitTaskQueue();
                        }
                    }
                    if (agv.CurJob == null)
                    {
                        Job job = GetJob(agv);
                        if (job != null)
                        {
                            agv.CurJob = job;
                        }
                    }

                    if (agv.CurJob != null)
                    {
                        agv.CurJob = agv.CurJob.Execute(agv);
                    }

                }
                catch (Exception ex)
                {
                    log.Error("AgvCall " + ex.Message + ex.StackTrace);
                }
            }

            AgvCallInProcess = false;

        }


        private bool CheckOnline(int idx)
        {
            bool rtn = MiR_API.CheckIP(AGVManager.agvInfo[idx].IP);
            if (rtn)
            {
                if (AGVManager.agvInfo[idx].IsCon)
                {
                    log.Debug(AGVManager.agvInfo[idx].Name + " Online");
                }
                else
                {
                    AGVManager.agvInfo[idx].IsCon = true;
                    log.Info(AGVManager.agvInfo[idx].Name + " Online");
                    AgvOnline?.Invoke(idx);
                }
            }
            else
            {
                if (AGVManager.agvInfo[idx].IsCon)
                {
                    AGVManager.agvInfo[idx].IsCon = false;
                    log.Info(AGVManager.agvInfo[idx].Name + " Offline");
                    AgvOnline?.Invoke(idx);
                }
                else
                {
                    log.Debug(AGVManager.agvInfo[idx].Name + " Offline");
                }
            }
            return rtn;
        }

    }
}
public class RunInfo
{
    /// <summary>
    /// AGV编号
    /// </summary>
    public string AGVNum { get; set; } = "";
    /// <summary>
    /// 时间
    /// </summary>
    public string DateTime { get; set; } = "";
    /// <summary>
    /// 任务信息
    /// </summary>
    public string MissionInfo { get; set; } = "";
    public RunInfo(string AGVNum, string missionInfo)
    {
        //2006-01-02 15:04:05
        DateTime = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        this.AGVNum = AGVNum;
        MissionInfo = missionInfo;
    }
    public RunInfo() { }
    public override bool Equals(object obj)
    {
        if (obj is RunInfo)
        {
            RunInfo info = (RunInfo)obj;
            if (this.MissionInfo.Equals(info.MissionInfo))
                return true;
            this.MissionInfo = info.MissionInfo;
        }
        return false;
    }
    public override string ToString()
    {
        return JsonHelper.SerializeObject(this);
    }
}