PackingJobType.cs 11.5 KB
using Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Management;

namespace DeviceLibrary
{
    public enum eMarkState
    {
        None,
        Assigned,
        Executing,
        Finished
    }
    /// <summary>
    /// 搜索包装仓任务
    /// </summary>
    public class PackingJobType : JobType
    {
        /// <summary>
        /// 标记
        /// </summary>
        private static Dictionary<string, eMarkState> Marks = new Dictionary<string, eMarkState>();
        private static object locBoj = new object();
        public PackingJobType()
        {

        }
        public static string GetMarks()
        {
            if (Marks != null && Marks.Count > 0)
            {
                StringBuilder temp = new StringBuilder();
                foreach (var item in Marks.Keys)
                {
                    temp.Append(string.Format("{0}={1} ", item, Marks[item]));
                }
                return temp.ToString().Trim();
            }

            return "";
        }
        public static void WriteMarks(string marks = "")
        {
            if (Marks != null && Marks.Count > 0)
            {
                Marks.Clear();
                string[] tempMarks = marks.Split(' ');
                foreach (string item in tempMarks)
                {
                    string[] t1 = item.Split('=');
                    Marks.Add(t1[0], (eMarkState)Enum.Parse(typeof(eMarkState), t1[1]));
                }
            }

        }
        /// <summary>
        /// 判断是否为入库标志
        /// </summary>
        /// <returns></returns>
        public static bool IsInStoreMark(string mark)
        {
            return mark.Equals(SettingString.InStore_Mark);
        }
        public static bool DelMark(string mark)
        {
            lock (locBoj)
            {
                if (Marks != null && Marks.ContainsKey(mark))
                {
                    Marks.Remove(mark);
                    return true;
                }
            }

            return false;
        }
        public static bool AddMark(string mark)
        {
            lock (locBoj)
            {
                if (Marks != null && !Marks.ContainsKey(mark))
                {
                    Marks.Add(mark, eMarkState.None);
                    return true;
                }
            }

            return false;
        }
        public static bool ChangeMarkState(string mark, eMarkState value)
        {
            lock (locBoj)
            {
                if (Marks != null && Marks.ContainsKey(mark))
                {
                    Marks[mark] = value;
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 包装仓任务
        /// </summary>
        /// <param name="currentAgv"></param>
        /// <returns></returns>
        public override Job GetNewJob(Agv_Info currentAgv)
        {
            if (currentAgv.IP.Equals(SettingString.SingleMission_IP1))
                return null;
            if (!CommonVar.CheckCanExecuteMission(currentAgv))
                return null;
            if (!CommonVar.CheckAGVStatusNone(currentAgv))
                return null;
            SearchMarks();
            return FindPackingJob(currentAgv);
        }
        private void SearchMarks()
        {
            //Mark.Length>1防止Mark为0的情况,Mark=0是VMI的进料
            int nodeIdx = CommonVar.nodeInfo.FindIndex(s => s.StateEquals(eNodeStatus.NeedEnter)
                            && s.Mark.Length > 1 && !Marks.ContainsKey(s.Mark) && s.IsUse);
            if (nodeIdx > -1)
            {
                string mark = CommonVar.nodeInfo[nodeIdx].Mark;
                AddMark(mark);
                LogUtil.info(string.Format("包装仓出库任务生成:{0}={1}", mark, Marks[mark].ToString()));
            }
            else
            {
                nodeIdx = CommonVar.nodeInfo.FindIndex(s => s.StateEquals(eNodeStatus.NeedEnter)
                && s.Mark.Equals("0") && !Marks.ContainsKey(SettingString.InStore_Mark) && s.IsUse);
                if (nodeIdx > -1)
                {
                    string mark = SettingString.InStore_Mark;
                    AddMark(mark);
                    LogUtil.info(string.Format("包装仓入库任务生成:{0}={1}", mark, Marks[mark].ToString()));
                }
            }
        }
        /// <summary>
        /// 检查节点mark是否存在
        /// </summary>
        /// <param name="mark"></param>
        /// <returns>true:存在</returns>
        public static bool CheckNodeMark(string mark, string nodeName = "")
        {
            if (nodeName.Equals(""))
            {
                int i = CommonVar.nodeInfo.FindIndex(s => s.Mark.Equals(mark));
                if (i == -1)
                    return false;
                else
                    return true;
            }
            else
            {
                int i = CommonVar.nodeInfo.FindIndex(s => s.Name.Equals(nodeName) && s.Mark.Equals(mark));
                if (i == -1)
                    return false;
                else
                    return true;
            }
        }

        private static object checkObj = new object();
        /// <summary>
        /// 检查是否有包装仓出库任务
        /// </summary>
        /// <returns></returns>
        public static int CheckOutStroePackingJob()
        {
            lock (checkObj)
            {
                return CommonVar.nodeInfo.FindIndex(s => s.StateEquals(eNodeStatus.NeedEnter)
                        && Marks.ContainsKey(s.Mark) && Marks[s.Mark].Equals(eMarkState.None) && s.IsUse);
            }
        }
        /// <summary>
        /// 检查是否有包装仓入库任务
        /// </summary>
        /// <returns></returns>
        public static int CheckInStroePackingJob()
        {
            lock (checkObj)
            {
                int id = CommonVar.nodeInfo.FindIndex(s => s.StateEquals(eNodeStatus.NeedEnter) && s.Mark.Equals("0") && s.IsUse);
                if (id > -1)
                    return CommonVar.nodeInfo.FindIndex(s => s.Name.Equals(SettingString.A1) && s.RFID.StartsWith(SettingString.Packing_RFID_Prefix));
                else
                    return id;
            }
        }

        /// <summary>
        /// 检查是否有包装仓出料架
        /// </summary>
        /// <returns></returns>
        public static int CheckPackingOutShelf(out ClientNode tarNode, out string taskMark)
        {
            lock (checkObj)
            {
                taskMark = SettingString.InStore_Mark;
                tarNode = null;
                int id = CommonVar.nodeInfo.FindIndex(s => s.Name.StartsWith(SettingString.Packing_Box_Prefix) && s.StateEquals(eNodeStatus.NeedLeave) && s.RFID.StartsWith(SettingString.Packing_RFID_Prefix) && s.Mark.Equals("0") && s.IsUse);
                if (id > -1)
                {
                    taskMark = SettingString.InStore_Mark;
                    tarNode = CommonVar.nodeInfo[id];
                    return id;
                }
                else
                {
                    id = CommonVar.nodeInfo.FindIndex(s => s.Name.StartsWith(SettingString.Packing_Box_Prefix) && s.StateEquals(eNodeStatus.NeedLeave)
                    && s.RFID.StartsWith(SettingString.Packing_RFID_Prefix) && Marks.ContainsKey(s.Mark) && s.IsUse);
                    if (id > -1)
                    {
                        taskMark = CommonVar.nodeInfo[id].Mark;
                        tarNode = CommonVar.nodeInfo[id];
                        return id;
                    }
                }
                return -1;
            }
        }
        /// <summary>
        /// 搜索包装仓任务
        /// </summary>
        /// <returns>true:有任务</returns>
        private Job FindPackingJob(Agv_Info agv)
        {
            //检查包装仓出料架
            int nodeIdx = CheckPackingOutShelf(out ClientNode tarNode, out string taskMark);
            if (nodeIdx > -1)
            {
                int agvId = CommonVar.agvInfo.FindIndex(s => !s.IP.Equals(agv.IP) && s.CurJob is PackingJob_TransferShelf && ((PackingJob_TransferShelf)s.CurJob).TargetPlace.Equals(tarNode.Name));
                if (agvId == -1)
                    return new PackingJob_TransferShelf(agv.Place, tarNode.Name, "", taskMark);// tarNode.RFID
            }
            //检查出库任务,没有出库,找入库任务
            nodeIdx = CheckOutStroePackingJob();
            if (nodeIdx == -1) //搜索包装仓入库任务
            {
                LogUtil.debug("B区没有找到需要出库的节点");
                nodeIdx = CheckInStroePackingJob();
                if (nodeIdx > -1)
                {
                    //检查是否有小车去同一个目的地
                    int agvId = CommonVar.agvInfo.FindIndex(s => !s.IP.Equals(agv.IP) && s.CurJob != null && s.CurJob is PackingJob_GetShelf && ((PackingJob_GetShelf)s.CurJob).TargetPlace.Equals(CommonVar.nodeInfo[nodeIdx].Name));
                    if (agvId == -1)
                    {
                        string Place = CommonVar.nodeInfo[nodeIdx].Name;
                        LogUtil.info(string.Format("{0} 任务生成:Place={1},Type={2}", agv.Name, Place, SettingString.InStore_Mark));
                        return new PackingJob_GetShelf(agv.Place, Place, SettingString.InStore_Mark);
                    }

                }
            }
            else//B区域需要出库,寻找空料架
            {
                //检查是否有小车去同一个包装仓
                int agvId = CommonVar.agvInfo.FindIndex(s => !s.IP.Equals(agv.IP) && s.CurJob != null && s.CurJob is PackingJob_GetShelf && ((PackingJob_GetShelf)s.CurJob).TargetPlace.Equals(CommonVar.nodeInfo[nodeIdx].Name));
                if (agvId > -1)
                    return null;
                int n = CommonVar.nodeInfo.FindIndex(s => s.Name.Equals(SettingString.A7) && s.StateEquals(eNodeStatus.NeedLeave) &&
                 s.RFID.StartsWith(SettingString.Packing_RFID_Prefix) && s.IsUse);
                if (n > -1)
                {
                    string Place = CommonVar.nodeInfo[n].Name;
                    string Mark = CommonVar.nodeInfo[nodeIdx].Mark;
                    LogUtil.info(string.Format("{0} 任务生成:Place={1},Type={2}", agv.Name, Place, Mark));
                    return new PackingJob_GetShelf(agv.Place, Place, Mark);
                }
                else
                {
                    //A4没有被占用
                    n = CommonVar.nodeInfo.FindIndex(s => s.Name == SettingString.A4 && s.StateEquals(eNodeStatus.NeedLeave)
                    && s.IsUse);
                    if (n == -1)
                    {
                        nodeIdx = -1;
                        LogUtil.error("A7,A4不是NeedLeave或被占用");
                        agv.AddDisplayBoard("包装料架", "PackingShelf", "分盘线出口A7、包装线出口A4均无包装料架,请检查!");
                    }
                    else
                    {
                        string Place = CommonVar.nodeInfo[n].Name;
                        string Mark = CommonVar.nodeInfo[nodeIdx].Mark;
                        LogUtil.info(string.Format("{0} 任务生成:Place={1},Type={2}", agv.Name, Place, Mark));
                        return new PackingJob_GetShelf(agv.Place, Place, Mark);
                    }
                }

            }

            return null;
        }
    }

}