Control.cs 7.1 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 System.Timers.Timer AgvCallTimer;
        private System.Timers.Timer AgvStateTimer;
        public delegate void AgvChangedEvent(int agvIndex);
        public delegate void AgvMissionEvent();
        public event AgvChangedEvent AgvChanged;
        public event AgvChangedEvent AgvOnline;
        /// <summary>
        /// 限制区域
        /// </summary>
        public ScopeLimit limitArea;

        public Control()
        {
            AgvCallTimer = new System.Timers.Timer
            {
                Interval = 500,
                AutoReset = true,
                Enabled = false
            };
            AgvCallTimer.Elapsed += AgvCallTimer_Elapsed;

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

            string[] limitPoints = AppConfigHelper.GetValue(SettingString.LimitPoints).Split(';');
            List<Agv_Info.AgvPosition> clsPositions = new List<Agv_Info.AgvPosition>();
            string[] s1;
            for (int i = 0; i < limitPoints.Length; i++)
            {
                s1 = limitPoints[i].Split(',');
                clsPositions.Add(new Agv_Info.AgvPosition(double.Parse(s1[0]), double.Parse(s1[1])));
            }
            limitArea = new ScopeLimit(clsPositions);
        }


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

        public void Stop()
        {
            AgvCallTimer.Enabled = false;
            AgvStateTimer.Enabled = false;
            AgvCallTimer.Stop();
            AgvStateTimer.Stop();
        }


        private bool AgvStateInProcess = false;
        private void AgvStateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            bool rtn;
            if (AgvStateInProcess) return;
            AgvStateInProcess = true;

            for (int i = 0; i < Context.agvInfo.Count; i++)
            {
                try
                {
                    if (!CheckOnline(i)) continue;
                    bool change = false;
                    MiR_API.Get_Task_State(Context.agvInfo[i], out string stateStr);
                    Thread.Sleep(50);
                    //获取AGV状态
                    rtn = MiR_API.Get_State(Context.agvInfo[i], out eAGVState stateID, out string stateText, out int battery, out string mission_text, out Agv_Info.AgvPosition position);
                    Thread.Sleep(50);
                    change = Context.agvInfo[i].SetState(stateID, stateStr, battery, mission_text, position);

                    //更新状态stateID.Equals(eAGVState.Executing)
                    if (change)
                    {
                        AgvChanged?.Invoke(i);
                    }

                }
                catch (Exception ex)
                {
                    LogUtil.error("AgvStateTimer_" + Context.agvInfo[i].Name + ex.Message + ex.StackTrace);
                }
            }



            AgvStateInProcess = false;
        }

        private static object lockGetObj = new object();
        /// <summary>
        /// 获取任务
        /// </summary>
        /// <param name="agv_Info"></param>
        /// <returns></returns>
        public Job GetJob(Agv_Info agv_Info)
        {
            lock(lockGetObj)
            {
                foreach (JobType find in Context.jobTypeInfo)
                {
                    Job job = null;

                    if (agv_Info.IsUse)
                    {
                        job = find.GetNewJob(agv_Info);

                        if (job != null)
                        {
                            LogUtil.debug(agv_Info.Name + " GetJob OK " + job.ToString());
                            return job;
                        }
                    }
                    else
                    {
                        return null;
                    }
                }
            }

            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 < Context.agvInfo.Count; i++)
            {
                try
                {
                    Agv_Info agv = Context.agvInfo[i];
                    if (!agv.IsCon) continue;   //AGV网络连接
                    if (!Context.agvInfo[i].IsUse) continue;   //AGV是否可用

                    //Ready,Pause,Executing,Error
                    if (!Context.agvInfo[i].StateID.Equals(eAGVState.Ready) && !Context.agvInfo[i].StateID.Equals(eAGVState.Pause)
                        && !Context.agvInfo[i].StateID.Equals(eAGVState.Executing) && !Context.agvInfo[i].StateID.Equals(eAGVState.None))
                    {
                       LogUtil.debug(Context.agvInfo[i].Name + " 不可调用 StateID=" + Context.agvInfo[i].StateID.ToString());
                        continue;
                    }

                    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)
                {
                   LogUtil.error("AgvCall " + ex.Message + ex.StackTrace);
                }
            }

            AgvCallInProcess = false;

        }


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

    }
}