AgvClient.cs 12.2 KB

using Agv;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace OnlineStore.DeviceLibrary
{
    public class AgvClient
    {
        private static string ServerIp = ConfigAppSettings.GetValue(Setting_Init.AgvServerIp);
        private static int ServerPort = ConfigAppSettings.GetIntValue(Setting_Init.AgvServerPort);
        private static Agv.AgvClient agvClient;
        public static Dictionary<string, Agv.ClientAction> actionMap = new Dictionary<string, Agv.ClientAction>();
        public static List<string> NodeList = new List<string>();
        private static bool isInit = false;
        public static void Init()
        {
            try
            {
                if (!isInit)
                {
                    isInit = true;
                    agvClient = new Agv.AgvClient();
                    agvClient.Received += AgvClient_Received; 
                }
                actionMap = new Dictionary<string, Agv.ClientAction>();
                //foreach (string key in NodeList)
                //{
                //    actionMap.Add(key, Agv.ClientAction.None);
                //}
               
                agvClient.Connect(ServerIp,ServerPort);
                foreach (string str in NodeList)
                {
                    SetStatus(str);
                    LogUtil.info("agv init ,SetStatus[" + str + "]=none ");
                }
                SetCancelState(false);
            }
            catch (Exception ex)
            {
                LogUtil.error("初始化agvClient " + ServerIp + " 出错:", ex);
            }
        }

        private static void AgvClient_Received(Agv.Node node)
        {
            switch(node.Action)
            {
                //case ClientAction.ReadyLeave:
                //    AgvClient_ReadyLeave(node.Name,node.RFID);
                //    break;
                //case ClientAction.ReadyEnter:
                //    AgvClient_ReadyEnter(node.Name,node.RFID);
                //    break;
                //default:
                //    log.info(node.ToText());
                //    break;
                case ClientAction.Ready:
                    AgvClient_Ready(node.Name, node.RFID);
                    break;
                case ClientAction.None:
                    log.debug("收到心跳包");
                    break;
                default:
                    log.info(node.ToText());
                    break;
            }
            log.debug(node.ToText());
        }

        /// <summary>
        /// 设置是否屏蔽AGV状态
        /// </summary>
        /// <param name="cancel"></param>
        public static void SetCancelState(bool cancel)
        {
            agvClient.CancelState = cancel;
        }

        public static void SetStatus(string id, string shelfId = "", Agv.ClientAction action = Agv.ClientAction.None, Agv.ClientLevel level = Agv.ClientLevel.Low, Agv.ClientShelf shelf = ClientShelf.None)
        {
          //  ClientAction currA = GetAction(id);
            if (actionMap.ContainsKey(id))
            {
                Agv.ClientAction currA = actionMap[id]; //相同状态就设置一次
                if (currA.Equals(action))
                {
                    return;
                }
            }
           
            agvClient.SetStatus(id, "",shelfId, action, level,shelf);
            UpdateAction(id, action);
        }
        private static void AgvClient_Ready(string id, string rfid)
        {
            string logName = "收到 AgvClient_Ready [" + id + "] [" + rfid + "]   ";
            LogUtil.info(logName);

            UpdateAction(id, Agv.ClientAction.Ready);
            if (id.Equals(LineManager.Config.L1_Out_AgvName))
            {
                string shefId = LineManager.Line.LastL1OutShelfId;
                if (IOManager.IOValue(IO_Type.L1_OutCheck).Equals(IO_VALUE.HIGH))
                {
                    SetStatus(id, shefId, ClientAction.MayLeave);
                    LineManager.Line.UpdateSleep(false);
                    LineManager.Line.StopIOMove(IO_Type.L1_OutStopDown, 2000);

                    LogUtil.info(logName + "下降 L1_OutStopDown ,  " + shefId);

                    Task.Factory.StartNew(delegate
                    {
                        //两秒后改为离开状态
                        Thread.Sleep(5000);
                        LogUtil.info(logName + "  ,调用  FinishLeave " + shefId);
                        SetStatus(id, shefId, ClientAction.FinishLeave);

                        Thread.Sleep(5000);

                        LogUtil.info(logName + "  ,处理结束  更新状态为None ");
                        SetStatus(id, "", ClientAction.None);
                    });
                }
                else
                {
                    LogUtil.error(logName + "  L1_OutCheck 未检测到料架,无法将料架进入AGV");
                    SetStatus(id, "", ClientAction.None, ClientLevel.High);
                }
            }

            else if (id.Equals(LineManager.Config.L2_Out_AgvName))
            {
                string shefId = LineManager.Line.LastL2OutShelfId;
                if (IOManager.IOValue(IO_Type.L2_OutCheck).Equals(IO_VALUE.HIGH))
                {
                    SetStatus(id, shefId, ClientAction.MayLeave);
                    LineManager.Line.UpdateSleep(false);
                    LineManager.Line.StopIOMove(IO_Type.L2_OutStopDown, 2000);
                    //agvClient.MayLeave(id);

                    LogUtil.info(logName + "下降 L2_OutStopDown ,  " + shefId);

                    Task.Factory.StartNew(delegate
                    {
                        //两秒后改为离开状态
                        Thread.Sleep(5000);
                        LogUtil.info(logName + "  ,调用  FinishLeave " + shefId);
                        SetStatus(id, shefId, ClientAction.FinishLeave);

                        Thread.Sleep(5000);

                        LogUtil.info(logName + "  ,处理结束  更新状态为None ");
                        SetStatus(id, "", ClientAction.None);
                    });
                }
                else
                {
                    LogUtil.error(logName + "  L2_OutCheck 未检测到料架,无法将料架进入AGV");
                    SetStatus(id, "", ClientAction.None, ClientLevel.High);
                }
            }

            if (id.Equals(LineManager.Config.L1_In_AgvName))
            {
                LineManager.Line.UpdateSleep(false);
                if (IOManager.IOValue(IO_Type.L1_InCheck).Equals(IO_VALUE.LOW))
                {
                    Task.Factory.StartNew(delegate
                    {
                        SetStatus(id, "", ClientAction.MayEnter);
                        LogUtil.info(logName + "  ,等待L1_InCheck");
                        try
                        {
                            WaitUtil.Wait(60000, delegate
                            {
                                return IOManager.IOValue(IO_Type.L1_InCheck).Equals(IO_VALUE.HIGH);
                            }, "等待L1_InCheck=HIGH");
                        }
                        catch (Exception ex)
                        {
                            LogUtil.error(logName + ":" + ex.ToString());
                        }

                        //两秒后改为离开状态
                        Thread.Sleep(3000);
                        LogUtil.info(logName + "  ,调用  FinishEnter ");
                        SetStatus(id, "", ClientAction.FinishEnter);

                        Thread.Sleep(5000);
                        LogUtil.info(logName + "  ,处理结束  更新状态为None ");
                        SetStatus(id, "", ClientAction.None);

                    });
                }
                else
                {
                    LogUtil.error(logName + " L1_InCheck 检测到有料架,AGV的料架无法进入");
                    SetStatus(id, "", ClientAction.None, ClientLevel.High);
                }
            }

            else if (id.Equals(LineManager.Config.L2_In_AgvName))
            {
                LineManager.Line.UpdateSleep(false);
                if (IOManager.IOValue(IO_Type.L2_InCheck).Equals(IO_VALUE.LOW))
                {
                    Task.Factory.StartNew(delegate
                    {
                        SetStatus(id, "", ClientAction.MayEnter);
                        LogUtil.info(logName + "  ,等待L2_InCheck");
                        try
                        {
                            WaitUtil.Wait(60000, delegate
                            {
                                return IOManager.IOValue(IO_Type.L2_InCheck).Equals(IO_VALUE.HIGH);
                            }, "等待L2_InCheck=HIGH");
                        }
                        catch (Exception ex)
                        {
                            LogUtil.error(logName + ":" + ex.ToString());
                        }

                        //两秒后改为离开状态
                        Thread.Sleep(3000);
                        LogUtil.info(logName + "  ,调用  FinishEnter ");
                        SetStatus(id, "", ClientAction.FinishEnter);

                        Thread.Sleep(5000);
                        LogUtil.info(logName + "  ,处理结束  更新状态为None ");
                        SetStatus(id, "", ClientAction.None);

                    });
                }
                else
                {
                    LogUtil.error(logName + " L2_InCheck 检测到有料架,AGV的料架无法进入");
                    SetStatus(id, "", ClientAction.None, ClientLevel.High);
                }
            }
        }
        public static bool SetToNone(string id, string shelfId = "")
        {
            Agv.ClientAction currA = GetAction(id);
            if (currA.Equals(Agv.ClientAction.None) || currA.Equals(Agv.ClientAction.NeedLeave) || currA.Equals(Agv.ClientAction.NeedEnter))
            {
                SetStatus(id, shelfId, Agv.ClientAction.None);
                return true;
            }
            return false;
        }
        public static bool NeedEnter(string id, string shelfId)
        {
            Agv.ClientAction currA = GetAction(id);
            if (currA.Equals(Agv.ClientAction.None) ||   currA.Equals(Agv.ClientAction.NeedLeave) || currA.Equals(Agv.ClientAction.NeedEnter))
            {
                SetStatus(id, shelfId, Agv.ClientAction.NeedEnter);
                return true;
            }
            return false;
        }
        public static bool NeedLeave(string id, string shelfId,ClientShelf shelf = ClientShelf.None)
        {
            Agv.ClientAction currA = GetAction(id);
            if (currA.Equals(Agv.ClientAction.None) ||   currA.Equals(Agv.ClientAction.NeedLeave) || currA.Equals(Agv.ClientAction.NeedEnter))
            {
                SetStatus(id, shelfId, Agv.ClientAction.NeedLeave,ClientLevel.None,shelf);
                return true;
            }
            return false;
        }
        public static bool ISConnected()
        {
            if (agvClient == null)
            {
                return false;
            }
            return agvClient.IsConn;
        }

        public static Agv.ClientAction GetAction(string NodeName)
        {
            if (actionMap.ContainsKey(NodeName))
            {
                return actionMap[NodeName];
            }
            return Agv.ClientAction.None;
        }
        public static void UpdateAction(string name,   Agv.ClientAction action)
        {
            if (actionMap.ContainsKey(name))
            {
                actionMap[name] = action;
            }
            else
            {
                actionMap.Add(name, action);
            }
        }
        public static void Dispose()
        {
            try
            { 
                if (agvClient != null)
                {
                    SetCancelState(true);
                    agvClient.Close();
                }
            }
            catch (Exception ex)
            {
                LogUtil.error("agvClient.Close " + ServerIp + " 出错:", ex);
            }
        }
    } 
}