CommLineJob.cs 7.3 KB
using AGVLib;
using DeviceLib.Model.AGV;
using System;
using System.Reflection;
using static System.Collections.Specialized.BitVector32;

namespace DeviceLib.BLL
{
    internal class CommLineJob : ImpJob
    {
        public CommLineJob(JobParam jobParam) : base(jobParam)
        {
            JobName = $"与【{jobParam.CurDstNode.Name}】通讯";
        }
        public override Job Run(Robot robot)
        {
            Job job = this;
            switch (JobRunStep.CurStep)
            {
                case RunStep.None:
                    ToNextStep(RunStep.CommLine_01_ReadyToCommLine, "准备与目标线体交互");
                    break;
                case RunStep.CommLine_01_ReadyToCommLine:
                    ToNextStep(RunStep.CommLine_02_Request, "请求线体");
                    request();
                    break;
                case RunStep.CommLine_02_Request:
                    ToNextStep(RunStep.CommLine_03_ResponseWait, $"等待线体响应{getAction()}");
                    break;

                case RunStep.CommLine_03_ResponseWait:
                    getResponse();
                    break;
                case RunStep.CommLine_04_ResponseAllow:
                    ToNextStep(RunStep.CommLine_06_ShelfMoving, "料架转移中");
                    transferShelf(robot);
                    break;

                case RunStep.CommLine_05_ResponseDeny:
                    job = (Job)Activator.CreateInstance(JobParam.CallbackJob.Type);
                    job.JobParam = JobParam;
                    job.ToNextStep(JobParam.CallbackJob.RunStep, "与线体交互完成,因线体拒绝");
                    break;

                case RunStep.CommLine_06_ShelfMoving:
                    if (JobRunStep.IsTimeOut(30))
                    {
                        ToNextStep(RunStep.CommLine_07_ShelfMovingTimeOut, "转移料架超时");
                    }
                    else if (ShelfMovingOk())
                    {
                        ToNextStep(RunStep.CommLine_08_ShelfMovingSuccess, "转移料架完成");
                        Turn(robot);
                    }
                    break;
                case RunStep.CommLine_07_ShelfMovingTimeOut:
                    if (ShelfMovingOk())
                    {
                        ToNextStep(RunStep.CommLine_08_ShelfMovingSuccess, "转移料架完成");
                        Turn(robot);
                    }
                    break;

                case RunStep.CommLine_08_ShelfMovingSuccess:
                    if (MissionIsOk())
                    {
                        NodeManager.Complete(JobParam.CurDstNode.Id);
                        //改变负载状态
                        setLodInfo(robot);
                        job = GetCallBackJob();
                        job.ToNextStep(GetCallBackStep(), "与线体交互完成");
                    }
                    break;
            }
            return job;
        }
        bool ShelfMovingOk()
        {
            finish();
            return MissionIsOk()
                && (NodeManager.GetNodeStatus(JobParam.CurDstNode.Id).Equals(NodeStatus.FinishLeave)
                || NodeManager.GetNodeStatus(JobParam.CurDstNode.Id).Equals(NodeStatus.FinishEnter));
        }
        void request()
        {
            switch (JobParam.JobGoal)
            {
                case JobGoal.Send:
                case JobGoal.Return:
                    NodeManager.RequestEnter(JobParam.CurDstNode.Id);
                    break;
                case JobGoal.Get:
                    NodeManager.RequestLeave(JobParam.CurDstNode.Id);
                    break;
            }
        }
        void finish()
        {
            if (MissionIsOk())
            {
                switch (JobParam.JobGoal)
                {
                    case JobGoal.Send:
                    case JobGoal.Return:
                        if (NodeManager.GetNodeStatus(JobParam.CurDstNode.Id).Equals(NodeStatus.MayEnter))
                            NodeManager.Complete(JobParam.CurDstNode.Id);
                        break;
                    case JobGoal.Get:
                        if (NodeManager.GetNodeStatus(JobParam.CurDstNode.Id).Equals(NodeStatus.MayLeave))
                            NodeManager.Complete(JobParam.CurDstNode.Id);
                        break;
                }
            }
        }
        void setLodInfo(Robot robot)
        {
            switch (JobParam.JobGoal)
            {
                case JobGoal.Send:
                case JobGoal.Return:
                    //NodeManager.RequestEnter(JobParam.CurDstNode.Id);
                    RobotManager.SetLoadInfo(robot.id, GetEmptySide(robot), ShelfType.None);
                    break;
                case JobGoal.Get:
                    //NodeManager.RequestLeave(JobParam.CurDstNode.Id);
                    RobotManager.SetLoadInfo(robot.id, GetNoneSide(robot), ShelfType.Full, JobParam.FullBoxId);
                    HttpManager.BoxToAgv(JobParam.FullBoxId, robot.name);
                    break;
            }
        }
        string getAction()
        {
            string action = "";
            switch (JobParam.JobGoal)
            {
                case JobGoal.Send:
                case JobGoal.Return:
                    action = NodeStatus.RequestEnter.ToString();
                    break;
                case JobGoal.Get:
                    action = NodeStatus.RequestLeave.ToString();
                    break;
            }
            return action;
        }
        void getResponse()
        {
            if (JobRunStep.IsTimeOut(30))
            {
                ReTime();
                SetWarnMsg($"线体响应{getAction()}超时,再次请求");
                request();
            }
            else
            {
                if (JobParam.JobGoal.Equals(JobGoal.Send) || JobParam.JobGoal.Equals(JobGoal.Return))
                {
                    switch (NodeManager.GetNodeStatus(JobParam.CurDstNode.Id))
                    {
                        case NodeStatus.MayEnter:
                            ToNextStep(RunStep.CommLine_04_ResponseAllow, "线体允许入料");
                            break;
                        case NodeStatus.RejectEnter:
                            ToNextStep(RunStep.CommLine_05_ResponseDeny, "线体拒绝入料");
                            break;
                    }
                }
                else if (JobParam.JobGoal.Equals(JobGoal.Get))
                {
                    switch (NodeManager.GetNodeStatus(JobParam.CurDstNode.Id))
                    {
                        case NodeStatus.MayLeave:
                            ToNextStep(RunStep.CommLine_04_ResponseAllow, "线体允许出料");
                            break;
                        case NodeStatus.RejectLeave:
                            ToNextStep(RunStep.CommLine_05_ResponseDeny, "线体拒绝出料");
                            break;
                    }
                }
            }

        }

        void transferShelf(Robot robot)
        {
            switch (JobParam.JobGoal)
            {
                case JobGoal.Send:
                    PutDown(robot, GetEmptySide(robot));
                    break;
                case JobGoal.Get:
                case JobGoal.Return:
                    PickUp(robot, GetNoneSide(robot));
                    break;
            }
        }
    }
}