MainMachine_AGV.cs 15.4 KB
using AGVLib;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace DeviceLibrary
{
    public partial class MainMachine
    {
        string serverIp = Setting_Init.AGV_ServerIp;
        int serverPort = Setting_Init.AGV_ServerPort;
        int nodeId = Setting_Init.AGV_NodeId;
        string nodeName = Setting_Init.AGV_NodeName;
        Client client;
        Node curNode;
        MoveInfo AGVMoveInfo;
        void initAgv()
        {

            if (!UseAgv())
                return;
            AGVMoveInfo = new MoveInfo("AGV");
            curNode = new Node()
            {
                id = nodeId,
                name = nodeName,
            };
            client = new Client(new List<Node> { curNode });
            client.ConnectedEvent += Client_ConnectedEvent;
            client.ReceivedEvent += Client_ReceivedEvent;
            client.Connect(serverIp, serverPort);
            LogUtil.LOGGER.Info($"初始化AGV节点,并连接服务端:{serverIp}:{serverPort}");
        }
        public bool UseAgv()
        {
            return Setting_Init.AGV_Enable;
        }
        public void SetStatus(NodeStatus nodeStatus)
        {
            curNode.status = nodeStatus;
            client.SetStatus(curNode);
        }
        private void Client_ReceivedEvent(Node node)
        {
            if (curNode.id == nodeId && curNode.name.Equals(node.name))
            {
                curNode.status = node.status;
                curNode.shelf_id = node.shelf_id;
                curNode.level = node.level;
                LogUtil.LOGGER.Info($"收到AGV服务端信息:【{node.name}】【{node.status}】【{node.shelf_id}】");
            }
        }

        private void Client_ConnectedEvent(bool status)
        {
            if (status)
                LogUtil.LOGGER.Info("已连接AGV服务端");
            else
            {
                LogUtil.LOGGER.Info("已断开AGV服务");
            }
        }
        NodeStatus curNodeStatus;
        /// <summary>
        /// 呼叫AGV--需要料串
        /// </summary>
        void needEnter(NodeStatus nodeStatus)
        {
            if (!UseAgv())
                return;
            if (nodeStatus.Equals(NodeStatus.NeedEnter) ||
               nodeStatus.Equals(NodeStatus.NeedEnter_Empty) ||
               nodeStatus.Equals(NodeStatus.NeedEnter_Full))
            {
                if (AGVMoveInfo.IsStep(MoveStep.Wait))
                {
                    AGVMoveInfo.NextMoveStep(MoveStep.AGV_In01);
                    curNodeStatus = nodeStatus;
                    AGVMoveInfo.log($"需要进入料串,{curNodeStatus}");
                }
            }


        }
        /// <summary>
        /// 呼叫AGV--送出料串
        /// </summary>
        void needLeave(NodeStatus nodeStatus)
        {
            if (!UseAgv())
                return;
            if (nodeStatus.Equals(NodeStatus.NeedLeave) ||
                    nodeStatus.Equals(NodeStatus.NeedLeave_Full) ||
                    nodeStatus.Equals(NodeStatus.NeedLeave_Empty))
            {
                if (AGVMoveInfo.IsStep(MoveStep.Wait))
                {
                    AGVMoveInfo.NextMoveStep(MoveStep.AGV_Out01);
                    curNodeStatus = nodeStatus;
                    AGVMoveInfo.log($"需要离开料串,{curNodeStatus}");
                }
            }

        }
        public void AGVProcess()
        {
            if (!UseAgv())
            {
                return;
            }
            if (CheckWait(AGVMoveInfo))
                return;
            Node curnode = curNode;
            if (curnode == null)
            {
                LogUtil.LOGGER.Error("无节点信息,请检查配置");
                return;
            }
            switch (AGVMoveInfo.MoveStep)
            {
                case MoveStep.Wait:
                    if (StringMoveInfo.IsStep(MoveStep.StringOut_Released) || StringMoveInfo.IsStep(MoveStep.Wait))
                    {
                        if (curnode.status.Equals(NodeStatus.RequsetDock) || curnode.status.Equals(NodeStatus.Arrive))
                        {
                            //AGV已到达,请求开门
                            AGVMoveInfo.NextMoveStep(MoveStep.AGV_OpenDoor);
                            AGVMoveInfo.log($"Wait,AGV到达,准备开门");
                            //AGV已到达,请求开门
                            OpenDoor(AGVMoveInfo);
                        }
                        else if (curnode.status.Equals(NodeStatus.DetachOk))
                        {
                            //AGV分离完成,可关门
                            AGVMoveInfo.NextMoveStep(MoveStep.AGV_CloseDoor);
                            CloseDoor(AGVMoveInfo);
                            AGVMoveInfo.log($"Wait,收到脱离脱离信号,关闭折叠门");
                        }
                        else
                        {
                            AGVMoveInfo.log($"Wait,收到{curnode.status}信号,不处理");
                        }
                    }
                    else//料串不在正常状态
                    {
                        if (curnode.status.Equals(NodeStatus.RequsetDock) || curnode.status.Equals(NodeStatus.Arrive))
                        {
                            //AGV已到达,请求开门
                            SetStatus(NodeStatus.RejectDock);
                            AGVMoveInfo.log($"收到AGV的{NodeStatus.RequsetDock}/{NodeStatus.Arrive}信号,当前料串正在使用,拒绝停靠");
                        }
                        else if (curnode.status.Equals(NodeStatus.RequestEnter))
                        {
                            //AGV请求出料到料仓
                            SetStatus(NodeStatus.RejectEnter);
                            AGVMoveInfo.log($"收到AGV的{NodeStatus.RequestEnter}信号,当前料串正在使用,拒绝AGV出料");
                        }
                        else if (curnode.status.Equals(NodeStatus.RequestLeave))
                        {
                            //AGV请求进料到AGV
                            SetStatus(NodeStatus.RejectLeave);
                            AGVMoveInfo.log($"收到AGV的{NodeStatus.RequestLeave}信号,当前料串正在使用,拒绝AGV进料");
                        }
                    }
                    break;
                #region 进料
                case MoveStep.AGV_In01:
                    AGVMoveInfo.NextMoveStep(MoveStep.AGV_In02);
                    RobotManage.mainMachine.SetStatus(curNodeStatus);
                    AGVMoveInfo.log($"设置{curnode.name}状态为{curNodeStatus}");
                    break;
                case MoveStep.AGV_In02:
                    if (IOMonitor.IODebound(IO_Type.StringFront_Check, Config, IO_VALUE.HIGH, 2000) ||
                                IOMonitor.IODebound(IO_Type.StringBack_Check, Config, IO_VALUE.HIGH, 2000))
                    {
                        RobotManage.mainMachine.SetStatus(NodeStatus.None);
                        AGVMoveInfo.log($"前端信号/后端信号亮,取消呼叫AGV送料串");
                        AGVMoveInfo.EndMove();
                    }
                    else if (AGVMoveInfo.IsTimeOut(5) && curnode.status != curNodeStatus)
                    {
                        AGVMoveInfo.NextMoveStep(MoveStep.AGV_In02);
                        RobotManage.mainMachine.SetStatus(curNodeStatus);
                        AGVMoveInfo.log($"AGV状态不是{curNodeStatus},重新呼叫AGV");
                    }
                    else
                    {
                        if (curnode.status.Equals(NodeStatus.RequsetDock) || curnode.status.Equals(NodeStatus.Arrive))
                        {
                            AGVMoveInfo.NextMoveStep(MoveStep.AGV_OpenDoor);
                            AGVMoveInfo.log($"AGV到达,准备开门");
                            //AGV已到达,请求开门
                            OpenDoor(AGVMoveInfo);
                        }
                    }
                    break;
                case MoveStep.AGV_In03:
                    AGVMoveInfo.NextMoveStep(MoveStep.AGV_In04);
                    break;
                case MoveStep.AGV_In04:
                    AGVMoveInfo.NextMoveStep(MoveStep.AGV_In05);
                    Line.LineRun("n", false, 10);
                    AGVMoveInfo.log($"收到AGV的{NodeStatus.RequestEnter}信号,允许进料");
                    break;
                case MoveStep.AGV_In05:
                    if (curnode.status == NodeStatus.MayEnter)
                    {
                        if (IOValue(IO_Type.StringBack_Check).Equals(IO_VALUE.HIGH))
                        {
                            AGVMoveInfo.NextMoveStep(MoveStep.AGV_In06);
                            RobotManage.mainMachine.SetStatus(NodeStatus.FinishEnter);
                            AGVMoveInfo.log($"料串到位");
                            AGVMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(5000));
                        }
                        else
                        {
                            // ShowInfo("等待料串到位");
                        }
                    }
                    else
                    {
                        RobotManage.mainMachine.SetStatus(NodeStatus.MayEnter);
                    }
                    break;
                case MoveStep.AGV_In06:
                    AGVMoveInfo.NextMoveStep(MoveStep.AGV_DetachOK);
                    RobotManage.mainMachine.SetStatus(NodeStatus.Detach);
                    AGVMoveInfo.log($"向AGV发送脱离信号");
                    break;
                #endregion

                #region 出料
                case MoveStep.AGV_Out01:
                    AGVMoveInfo.NextMoveStep(MoveStep.AGV_Out02);
                    RobotManage.mainMachine.SetStatus(curNodeStatus);
                    AGVMoveInfo.log($"设置{curnode.name}状态为{curNodeStatus}");
                    break;
                case MoveStep.AGV_Out02:
                    if (IOValue(IO_Type.StringFront_Check).Equals(IO_VALUE.LOW) &&
                        IOValue(IO_Type.StringBack_Check).Equals(IO_VALUE.LOW))
                    {
                        RobotManage.mainMachine.SetStatus(NodeStatus.None);
                        AGVMoveInfo.log($"前端信号和后端信号均灭,取消呼叫AGV接料串");
                        AGVMoveInfo.EndMove();
                    }
                    else if (AGVMoveInfo.IsTimeOut(5) && curnode.status != curNodeStatus)
                    {
                        AGVMoveInfo.NextMoveStep(MoveStep.AGV_Out02);
                        RobotManage.mainMachine.SetStatus(curNodeStatus);
                        AGVMoveInfo.log($"AGV状态不是{curNodeStatus},重新呼叫AGV");
                    }
                    else
                    {
                        if (curnode.status.Equals(NodeStatus.RequsetDock) || curnode.status.Equals(NodeStatus.Arrive))
                        {
                            AGVMoveInfo.NextMoveStep(MoveStep.AGV_OpenDoor);
                            AGVMoveInfo.log($"AGV到达,准备开门");
                            //AGV已到达,请求开门
                            OpenDoor(AGVMoveInfo);
                        }
                    }
                    break;
                case MoveStep.AGV_Out03:
                    AGVMoveInfo.NextMoveStep(MoveStep.AGV_Out04);
                    break;
                case MoveStep.AGV_Out04:
                    AGVMoveInfo.NextMoveStep(MoveStep.AGV_Out05);
                    Line.LineRun("n", true, 2);
                    AGVMoveInfo.log($"收到AGV的{NodeStatus.RequestLeave}信号,允许出料");
                    break;
                case MoveStep.AGV_Out05:
                    if (curnode.status != NodeStatus.MayLeave)
                    {
                        RobotManage.mainMachine.SetStatus(NodeStatus.MayLeave);
                    }
                    else
                    {
                        if (IOValue(IO_Type.StringBack_Check).Equals(IO_VALUE.LOW) && IOValue(IO_Type.StringFront_Check).Equals(IO_VALUE.LOW))
                        {
                            AGVMoveInfo.NextMoveStep(MoveStep.AGV_Out06);
                            RobotManage.mainMachine.SetStatus(NodeStatus.FinishLeave);
                            AGVMoveInfo.log($"料串离开");
                            AGVMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(5000));
                        }

                    }
                    break;
                case MoveStep.AGV_Out06:
                    AGVMoveInfo.NextMoveStep(MoveStep.AGV_DetachOK);
                    RobotManage.mainMachine.SetStatus(NodeStatus.Detach);
                    AGVMoveInfo.log($"向AGV发送脱离信号");
                    break;
                #endregion
                case MoveStep.AGV_OpenDoor:
                    if (curnode.status == NodeStatus.RequestEnter)
                    {
                        AGVMoveInfo.NextMoveStep(MoveStep.AGV_In03);
                        RobotManage.mainMachine.SetStatus(NodeStatus.MayEnter);
                        CylinderMove(AGVMoveInfo, IO_Type.StringFix_Bottom, IO_Type.StringFix_Top, IO_VALUE.LOW);
                        Line.LineRun("n", false, 2);
                        AGVMoveInfo.log($"收到AGV的{NodeStatus.RequestEnter}信号,无料串,允许进料");
                    }
                    else if (curnode.status == NodeStatus.RequestLeave)
                    {
                        AGVMoveInfo.NextMoveStep(MoveStep.AGV_Out03);
                        RobotManage.mainMachine.SetStatus(NodeStatus.MayLeave);
                        CylinderMove(AGVMoveInfo, IO_Type.StringFix_Bottom, IO_Type.StringFix_Top, IO_VALUE.LOW);
                        Line.LineRun("n", true, 2);
                        AGVMoveInfo.log($"收到AGV的{NodeStatus.RequestLeave}信号,有料串,允许出料");
                    }
                    else if (curnode.status.Equals(NodeStatus.RequsetDock))
                    {
                        if(IOValue(IO_Type.StringDoor_Open).Equals(IO_VALUE.HIGH))
                        {
                            RobotManage.mainMachine.SetStatus(NodeStatus.MayDock);
                        }
                    }
                    break;
                case MoveStep.AGV_DetachOK:
                    if (curnode.status == NodeStatus.DetachOk)
                    {
                        AGVMoveInfo.NextMoveStep(MoveStep.AGV_CloseDoor);
                        CloseDoor(AGVMoveInfo);
                        AGVMoveInfo.log($"收到脱离脱离信号,关闭折叠门");
                    }
                    else if (AGVMoveInfo.IsTimeOut())
                    {
                        AGVMoveInfo.NextMoveStep(MoveStep.AGV_CloseDoor);
                        CloseDoor(AGVMoveInfo);
                        AGVMoveInfo.log($"收到脱离脱离信号超时,关闭折叠门");
                    }
                    break;
                case MoveStep.AGV_CloseDoor:
                    AGVMoveInfo.EndMove();
                    break;
            }
        }
        void OpenDoor(MoveInfo moveInfo)
        {
            StringDoorOpen(moveInfo);
        }
        void CloseDoor(MoveInfo moveInfo)
        {
            StringDoorClose(moveInfo);
        }
    }
}