AGVManager.cs 13.5 KB
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Common;
using static DeviceLibrary.Agv_Info;

namespace DeviceLibrary
{
    public enum LineState
    {
        None,
        Busy
    }
    public static class AGVManager
    {

        static log4net.ILog log = log4net.LogManager.GetLogger("AGVManager");
        /// <summary>
        /// 节点信息
        /// </summary>
        public static List<ClientNode> nodeInfo;
        /// <summary>
        /// 小车信息
        /// </summary>
        public static List<Agv_Info> agvInfo;
        public static AgvServer server;
        public static Control control;
        //public static WebService web;
        //public static UnlockMissionManager unlockManager;
        public static ChargeManager Charge;
        //public static StandbyManager Standby;
        public static List<JobType> jobTypes;
        public static readonly string CONFIG_PATH = AppDomain.CurrentDomain.BaseDirectory + "Config\\";
        /// <summary>
        /// 初始化配置
        /// </summary>
        public static void Init()
        {
            string path;
            string[] line;
            string[] temp;
            bool isuse;
            string rfid = "";

            Charge = new ChargeManager();
            //Standby = new StandbyManager();
            agvInfo = new List<Agv_Info>();
            jobTypes = new List<JobType>();
            jobTypes.Add(new GetEmptyShelfJobType());
            jobTypes.Add(new SendFullShelfJobType());
            jobTypes.Add(new ChargeJobType());
            path = CONFIG_PATH + SettingString.FileName_AGV;
            line = File.ReadAllLines(path, Encoding.UTF8);
            for (int i = 1; i < line.Length; i++)
            {
                temp = line[i].Split(',');
                if (temp.Length != 5) continue;
                bool.TryParse(ReadIni(temp[1], SettingString.IsUse), out isuse);
                rfid = ReadIni(temp[1], SettingString.RFID);
                agvInfo.Add(new Agv_Info(temp[0], temp[1], temp[2], temp[3], temp[4], isuse, rfid));
            }

            //任务加载
            MissionSys.Init();

            //节点加载
            nodeInfo = new List<ClientNode>();
            path = CONFIG_PATH + SettingString.FileName_AgvProductionLine;
            line = System.IO.File.ReadAllLines(path, Encoding.GetEncoding("gb2312"));
            for (int i = 1; i < line.Length; i++)
            {
                temp = line[i].Split(',');
                if (temp.Length != 4) continue;
                Boolean.TryParse(ReadIni(temp[1], SettingString.IsUse), out bool isUse);
                nodeInfo.Add(new ClientNode(temp[0], temp[1], temp[2], temp[3], isUse));
            }
        }


        /// <summary>
        /// 读取配置
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string ReadIni(string section, string key)
        {
            return IniFileHelper.ReadValue(section, key, CONFIG_PATH + SettingString.FileName_tempData);
        }
        /// <summary>
        /// 写入配置
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void WriteIni(string section, string key, string value)
        {
            IniFileHelper.WriteValue(section, key, value, CONFIG_PATH + SettingString.FileName_tempData);
        }

        /// <summary>
        /// 根据线体名获取节点名
        /// </summary>
        /// <param name="lineName"></param>
        /// <param name="nodeName"></param>
        /// <returns></returns>
        public static bool GetNodeNameByLineName(string lineName, out string nodeName)
        {
            nodeName = "";
            int id = nodeInfo.FindIndex(s => s.LineName.Equals(lineName));
            if (id > -1)
            {
                nodeName = nodeInfo[id].Name;
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 根据节点名获取线体名
        /// </summary>
        /// <param name="nodeName"></param>
        /// <param name="lineName"></param>
        /// <returns></returns>
        public static bool GetLineNameByNodeName(string nodeName, out string lineName)
        {
            lineName = "";
            int id = nodeInfo.FindIndex(s => s.Name.Equals(nodeName));
            if (id > -1)
            {
                lineName = nodeInfo[id].LineName;
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 查找节点是否存在以及是否调用
        /// </summary>
        /// <param name="nodeName">节点名称</param>
        /// <returns>-1:不存在/未调用</returns>
        public static int FindNode(string nodeName)
        {
            int idx = nodeInfo.FindIndex(s => s.Name.Equals(nodeName) && s.IsUse);
            return idx;
        }

        //private static object checkLocObj = new object();
        /// <summary>
        /// 查看云仓需要料架的状况
        /// </summary>
        /// <param name="agv"></param>
        /// <param name="node"></param>
        public static bool CheckBoxNeedShelfState(Agv_Info agv, out string nodeName)
        {
            nodeName = "";

            // if (Monitor.TryEnter(checkLocObj))
            {
                try
                {
                    int tarIdx = nodeInfo.FindIndex(s => s.Name == SettingString.D1 && s.StateEquals(eNodeStatus.NeedEnter) && s.IsUse);
                    if (tarIdx > -1)
                    {
                        if (CheckAgvEmptyJob(agv, SettingString.D1))
                        {
                            nodeName = SettingString.D1;
                            log.Debug(string.Format("{0} {1}需要料架", agv.Name, SettingString.D1));
                            return true;
                        }
                    }

                    tarIdx = nodeInfo.FindIndex(s => s.Name == SettingString.D2 && s.StateEquals(eNodeStatus.NeedEnter) && s.IsUse);
                    if (tarIdx > -1)
                    {
                        if (CheckAgvEmptyJob(agv, SettingString.D2))
                        {
                            nodeName = SettingString.D2;
                            log.Debug(string.Format("{0} {1}需要料架", agv.Name, SettingString.D2));
                            return true;
                        }
                    }
                    tarIdx = nodeInfo.FindIndex(s => s.Name == SettingString.D3 && s.StateEquals(eNodeStatus.NeedEnter) && s.IsUse);
                    if (tarIdx > -1)
                    {
                        if (CheckAgvEmptyJob(agv, SettingString.D3))
                        {
                            nodeName = SettingString.D3;
                            log.Debug(string.Format("{0} {1}需要料架", agv.Name, SettingString.D3));
                            return true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    log.Error("CheckBoxNeedShelfState", ex);
                }
                finally
                {
                    // Monitor.Exit(checkLocObj);
                }
            }

            return false;
        }

        /// <summary>
        /// 检查是否有AGV送空架子
        /// </summary>
        /// <param name="nodeName"></param>
        /// <returns></returns>
        public static bool CheckAgvEmptyJob(Agv_Info agv, string nodename)
        {
            int i = agvInfo.FindIndex(s => !s.IP.Equals(agv.IP) && s.CurJob is EmptyShelfBackJob &&
            ((EmptyShelfBackJob)s.CurJob).EmptyShelfTargetPlace.Equals(nodename));
            if (i > -1) return false;
            return true;
        }
        /// <summary>
        /// 查看料架存放处是否可以放空料架
        /// </summary>
        /// <param name="agv"></param>
        /// <param name="node"></param>
        public static bool CheckShelfStorageInState(Agv_Info agv)
        {
            int tarIdx = nodeInfo.FindIndex(s => s.Name == SettingString.A2
                        && (s.StateEquals(eNodeStatus.NeedEnter)) && s.IsUse);
            if (tarIdx > -1)
            {
                log.Debug(string.Format("{0} {1}可以存放料架", agv.Name, SettingString.A2));
                return true;
            }
            return false;
        }

        /// <summary>
        /// 检查需要空料架的地方
        /// </summary>
        /// <param name="agv"></param>
        /// <param name="nodeName"></param>
        /// <returns></returns>
        public static bool CheckNeedEmptyShelf(Agv_Info agv, out string nodeName)
        {

            if (!CheckBoxNeedShelfState(agv, out nodeName))
            {
                if (CheckShelfStorageInState(agv))
                {
                    nodeName = SettingString.A2;
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 存放空料架出口是否有空料架
        /// </summary>
        /// <param name="agv"></param>
        /// <param name="node"></param>
        public static bool CheckShelfStorageOutState(Agv_Info agv)
        {
            int tarIdx = nodeInfo.FindIndex(s => s.Name == SettingString.A1
                        && (s.StateEquals(eNodeStatus.NeedLeave)) && s.IsUse);
            int idx = AGVManager.agvInfo.FindIndex(s => !s.IP.Equals(agv.IP) && s.CurJob is GoEmptyShelfLineJob &&
                        ((GoEmptyShelfLineJob)s.CurJob).EmptyShelfPlace.Equals(SettingString.A1));
            if (tarIdx > -1 && idx == -1)
            {
                log.Debug(string.Format("{0} {1}可以出料架", agv.Name, SettingString.A1));
                return true;
            }
            return false;
        }
        //双层线工单信息
        public static string doubleLine_WO = "";
        public static string warnMsg = "";

        /// <summary>
        /// 查找出满料架任务
        /// </summary>
        /// <returns></returns>
        //public static bool FindFullShelfTask(Agv_Info agv)
        //{
        //    if (!CheckCanExecuteMission(agv))
        //        return false;
        //    int idx = nodeInfo.FindIndex(s => s.Name.Equals(SettingString.A6)
        //        && (s.StateEquals(eNodeStatus.NeedEnterLeave) || (s.StateEquals(eNodeStatus.NeedLeave))) && !s.RFID.Equals(""));
        //    if (idx > -1)
        //    {
        //        if (HttpManager.FindFullShelfTarget(nodeInfo[idx].RFID, out HttpManager.BoxDestInfo FullShelfDestInfo))
        //        {
        //            if (FullShelfDestInfo.location.StartsWith(SettingString.RoomC_Name_Prefix) && SettingString.RoomC_AGV_IPs.Contains(agv.IP))
        //            {
        //                int i = agvInfo.FindIndex(s => s.CurJob is GoFullShelfStationJob && !s.IP.Equals(agv.IP));
        //                if (i == -1)
        //                    return true;

        //            }
        //            else if (FullShelfDestInfo.location.StartsWith(SettingString.RoomS_Name_Prefix) && !SettingString.RoomC_AGV_IPs.Contains(agv.IP))
        //            {
        //                int i = agvInfo.FindIndex(s => s.CurJob is SendFullShelfToLineJob && !s.IP.Equals(agv.IP)
        //                        && ((SendFullShelfToLineJob)s.CurJob).FullShelfPlace.Equals(FullShelfDestInfo.location));
        //                if (i > -1)
        //                    return false;
        //                i = agvInfo.FindIndex(s => s.CurJob is GoFullShelfStationJob && !s.IP.Equals(agv.IP));
        //                if (i == -1)
        //                    return true;
        //            }
        //        }
        //        else
        //        {
        //            if (FullShelfDestInfo != null)
        //            {
        //                log.Error("A6的出料信息不正确,请检查:" + FullShelfDestInfo.ShowInfo("ERROR"));
        //            }
        //        }
        //    }
        //    return false;
        //}

        /// <summary>
        /// 判断电量是否够执行任务
        /// </summary>
        /// <param name="agv"></param>
        /// <returns></returns>
        public static bool CheckCanExecuteMission(Agv_Info agv)
        {
            if (agv.Battery <= Charge.BatteryMin)
            {
                log.Debug(agv.Name + " 电量小于" + Charge.BatteryMin + "%,不执行任务");
                return false;
            }


            return true;
        }

        /// <summary>
        /// 判断小车是否能接任务
        /// </summary>
        /// <param name="agv"></param>
        /// <returns></returns>
        public static bool CheckAGVStatusNone(Agv_Info agv)
        {
            if ((agv.CurJob == null || agv.CurJob is ChargeJob) && !agv.IsExistShelf)
                return true;
            else
                return false;
        }
    }

    public static class Window_API
    {
        [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
        public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
        [DllImport("user32.dll ", SetLastError = true)]
        public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
        public const int SW_RESTORE = 9;

    }


}