GoEmptyShelfLineJob.cs 14.5 KB

using AGVControl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AGVControl
{
    /// <summary>
    /// 去空料架任务点
    /// </summary>
    public class GoEmptyShelfLineJob : Job
    {
        /// <summary>
        /// 去空料架任务点
        /// </summary>
        /// <param name="agvPlae">小车当前位置,空表示在待机位</param>
        /// <param name="palce">空料架位置点</param>
        public GoEmptyShelfLineJob(string agvPlae, string palce)
        {
            EmptyShelfPlace = palce;
            this.agvPlae = agvPlae;
        }

        /// <summary>
        /// 空料架位置点
        /// </summary>
        public string EmptyShelfPlace { get; set; }

        /// <summary>
        /// 接收任务时,agv的位置
        /// </summary>
        private string agvPlae { get; set; }


        private string runInfo = "";
        /// <summary>
        /// 运行信息
        /// </summary>
        public override string RunInfo
        {
            get { return runInfo; }
        }


        private JobStep<TAKE_EMPTY_STEP> TakeEmptyStep = new JobStep<TAKE_EMPTY_STEP>(TAKE_EMPTY_STEP.NONE);

        /// <summary>
        /// 空架任务执行,去目的地
        /// </summary>
        /// <param name="agv"></param>
        public override Job Execute(Agv_Info agv)
        {
            string msg = agv.Name + " ";
            bool rtn = false;
            agv.Msg = runInfo;
            int nodeIdx = Common.FindNode(EmptyShelfPlace);
            //if (!CurTaskID.Equals(-1) && Common.mir.Get_Task_State(CurTaskID, out string st))
            //    CurTaskState = st;
            if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.NONE))
            {
                if (agvPlae.StartsWith(SettingString.C4_Name_Prefix) && EmptyShelfPlace.StartsWith(SettingString.D4_Name_Prefix))//4C->4D
                {
                    TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_AGV_REACH_4D_DOOR);
                    runInfo = "去空料架产线" + EmptyShelfPlace + ",先前往4D门[" + agvPlae + "->" + EmptyShelfPlace + "]";
                    msg += runInfo;
                    TakeEmptyStep.Msg = msg;
                    Common.DoorMission(agv, SettingString.DoorCToD);
                    UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
                }
                else if ((agvPlae.StartsWith(SettingString.D4_Name_Prefix) || agvPlae.StartsWith("A") || agvPlae.Equals(SettingString.Standby) || agvPlae.Equals(SettingString.AutoCharge))
                    && EmptyShelfPlace.StartsWith(SettingString.C4_Name_Prefix))//4D->4C
                {
                    TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_AGV_REACH_4C_DOOR);
                    runInfo= "去空料架产线" + EmptyShelfPlace + ",先前往4C门[" + agvPlae + "->" + EmptyShelfPlace + "]";
                    msg += runInfo;
                    TakeEmptyStep.Msg = msg;
                    Common.DoorMission(agv, SettingString.DoorDToC);
                    UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
                }
                else if(agvPlae.StartsWith(SettingString.C4_Name_Prefix) && EmptyShelfPlace.StartsWith(SettingString.C4_Name_Prefix))
                {
                   if(Common.Check4CTarget(agv, EmptyShelfPlace))//被占用
                    {
                        TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_REACH_TEMP_PLACE);
                        runInfo = "目的地" + EmptyShelfPlace + "有小车占用,先到临时待机位";
                        msg += runInfo;
                        TakeEmptyStep.Msg = msg;
                        Common.MoveTo4CStandy(agv);
                        UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
                    } 
                   else
                    {
                        TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
                        runInfo = "开始执行回收空料架任务[" + agvPlae + "->" + EmptyShelfPlace + "]";
                        msg += runInfo;
                        TakeEmptyStep.Msg = msg;
                    }
                }
                else
                {
                    TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
                    runInfo= "开始执行回收空料架任务[" + agvPlae + "->" + EmptyShelfPlace + "]";
                    msg += runInfo;
                    TakeEmptyStep.Msg = msg;
                }
            }
            else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_AGV_REACH_4C_DOOR))
            {
                CurTaskState = Common.GetTakJobState(CurTaskID);
                if (Common.CheckTaskFinished(agv, SettingString.DoorDToC, CurTaskState))
                {
                    if (Common.Check4CTarget(agv, EmptyShelfPlace))//被占用
                    {
                        TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_REACH_TEMP_PLACE);
                        runInfo = "目的地" + EmptyShelfPlace + "有小车占用,先到临时待机位";
                        msg += runInfo;
                        TakeEmptyStep.Msg = msg;
                        Common.MoveTo4CStandy(agv);
                        UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
                    }
                    else
                    {
                        TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
                        runInfo = "开始执行回收空料架任务[" + agvPlae + "->" + EmptyShelfPlace + "]";
                        msg += runInfo;
                        TakeEmptyStep.Msg = msg;
                    }
                }
            }
            else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_REACH_TEMP_PLACE))
            {
                CurTaskState = Common.GetTakJobState(CurTaskID);
                if (Common.CheckTaskFinished(agv, SettingString.C4_STANDBY1, CurTaskState) || Common.CheckTaskFinished(agv, SettingString.C4_STANDBY2, CurTaskState))
                {
                    if (!Common.Check4CTarget(agv, EmptyShelfPlace))//未占用
                    {
                        TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
                        runInfo = "开始执行回收空料架任务[" + agvPlae + "->" + EmptyShelfPlace + "]";
                        msg += runInfo;
                        TakeEmptyStep.Msg = msg;
                        Common.DeleteStandyInfo(agv);
                    }
                }
            }
            else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_AGV_REACH_4D_DOOR))
            {
                CurTaskState = Common.GetTakJobState(CurTaskID);
                if (Common.CheckTaskFinished(agv, SettingString.DoorCToD, CurTaskState))
                {
                    TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
                    runInfo = "开始执行回收空料架任务[" + agvPlae + "->" + EmptyShelfPlace + "]";
                    msg += runInfo;
                    TakeEmptyStep.Msg = msg;
                }
            }
            else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK))
            {

                if (nodeIdx > -1)
                {
                    TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_AGV_START_TASK);
                    runInfo= "AGV 添加任务:移动到" + EmptyShelfPlace;
                    msg += runInfo;
                    TakeEmptyStep.Msg = msg;
                    Common.MoveToNode(agv, EmptyShelfPlace);
                    UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
                }
                else
                {
                    TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
                    runInfo= EmptyShelfPlace + " 不存在或未开启调用";
                    msg += runInfo;
                    TakeEmptyStep.Msg = msg;
                }
            }
            else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_AGV_START_TASK))
            {
                if (agv.CurTaskState.Equals(SettingString.Executing))
                {
                    TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_REACH_PLACE);
                    runInfo= "AGV开始向目的地[" + EmptyShelfPlace + "]移动";
                    msg += runInfo;
                    TakeEmptyStep.Msg = msg;
                }
            }
            else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_REACH_PLACE))
            {
                CurTaskState = Common.GetTakJobState(CurTaskID);
                if (Common.CheckTaskFinished(agv, EmptyShelfPlace, CurTaskState))
                {
                    if (EmptyShelfPlace.Equals(SettingString.C4FeederOut))
                    {
                        runInfo = "AGV到达 " + EmptyShelfPlace;
                        msg += runInfo;
                        TakeEmptyStep.Msg = msg;
                        return new EnterLeaveShelfJob(EmptyShelfPlace, eEnterLeaveType.Enter);
                    }
                    else
                    {
                        TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_LINE_RESPONSE);
                        runInfo= "AGV到达 " + EmptyShelfPlace + " 向产线发送出料架请求[ReadyLeave]";
                        msg += runInfo;
                        TakeEmptyStep.Msg = msg;
                        if (nodeIdx == -1)
                        {
                            runInfo = EmptyShelfPlace + " 未开启调用";
                            msg += runInfo;
                            TakeEmptyStep.Msg = msg;
                            return this;
                        }
                        ClientNode node = Common.nodeInfo[nodeIdx];
                        agv.RFID = node.RFID;
                        Common.server.ReadyLeave(EmptyShelfPlace);
                    }

                }
            }
            else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_LINE_RESPONSE))
            {
                if(nodeIdx==-1)
                {
                    runInfo= EmptyShelfPlace + " 未开启调用";
                    msg += runInfo;
                    TakeEmptyStep.Msg = msg;
                    return this;
                }
                ClientNode node = Common.nodeInfo[nodeIdx];
                agv.RFID = node.RFID;
                if (node.StateEquals(eNodeStatus.MayLeave))
                {
                    if (!agv.CurTaskName.Equals("Enter"))
                    {
                        TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_TAKE_EMPTY_SHELF);
                        runInfo = "收到产线出料请求[ReadyLeave]的响应 " + EmptyShelfPlace + "出料架,小车链条运行";
                        msg += runInfo;
                        TakeEmptyStep.Msg = msg;
                        //agv.RFID = node.RFID;
                        rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["Enter"]);
                        UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
                    }

                }
                else if (TakeEmptyStep.IsTimeOut(15000, out double timeOutValue))
                {
                    TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_REACH_PLACE);
                    //runInfo = "AGV到达 " + EmptyShelfPlace + ",15秒后重新向产线发送出料架请求[ReadyLeave]";
                    //msg += runInfo;
                    //TakeEmptyStep.Msg = msg;
                }
            }
            else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_TAKE_EMPTY_SHELF))
            {
                CurTaskState = Common.GetTakJobState(CurTaskID);
                if (Common.CheckEnterOrLeaveFinished(agv, "Enter", CurTaskState))
                {
                    ClientNode node = Common.nodeInfo[nodeIdx];
                    node.AgvName = "";
                    //回收空料架数量减少1
                    Common.DelEmptyShelfTask(EmptyShelfPlace);
                    runInfo= "空料架在[" + EmptyShelfPlace + "]进入小车完成";
                    msg += runInfo;
                    TakeEmptyStep.Msg = msg;
                    //4DfeederOut默认大料架
                    if (agv.Place.Equals(SettingString.D4FeederOut))
                        return new EmptyShelfBackJob(EmptyShelfPlace, eShelfType.BigShelf);
                    else if (agv.RFID.StartsWith("D"))
                        return new EmptyShelfBackJob(EmptyShelfPlace, eShelfType.SmallShelf);
                    else if (agv.RFID.StartsWith("C"))
                    {
                        return new EmptyShelfBackJob(EmptyShelfPlace, eShelfType.BigShelf);
                    }
                    else
                        return new EmptyShelfBackJob(EmptyShelfPlace, eShelfType.SmallShelf);
                }
                else if (TakeEmptyStep.IsTimeOut(60000, out double timeOutValue))
                {
                    //链条停止
                    runInfo = "空料架在[" + EmptyShelfPlace + "]进入小车超时[" + timeOutValue.ToString("f1") + "秒],请检查料架进入小车的情况";
                   // msg += runInfo;
                    //TakeEmptyStep.Msg = msg;
                }

            }
            else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.END))
            {

            }

            return this;
        }


        /// <summary>
        /// AGV回收空料架流程
        /// </summary>
        private enum TAKE_EMPTY_STEP
        {
            /// <summary>
            /// 准备,发送给AGV
            /// </summary>
            NONE,
            /// <summary>
            /// 等待到达4C门
            /// </summary>
            WAIT_AGV_REACH_4C_DOOR,
            /// <summary>
            /// 等待到达4D门
            /// </summary>
            WAIT_AGV_REACH_4D_DOOR,
            /// <summary>
            /// 给AGV分配任务
            /// </summary>
            ASSIGN_AGV_TASK,
            /// <summary>
            /// 等待AGV开始执行去取架点任务
            /// </summary>
            WAIT_AGV_START_TASK,
            /// <summary>
            /// 等待AGV到达取架点
            /// </summary>
            WAIT_REACH_PLACE,
            /// <summary>
            /// 等待AGV到达临时停车位
            /// </summary>
            WAIT_REACH_TEMP_PLACE,
            /// <summary>
            /// 等待产线回应
            /// </summary>
            WAIT_LINE_RESPONSE,

            /// <summary>
            /// 等待料架进入小车
            /// </summary>
            WAIT_TAKE_EMPTY_SHELF,
            /// <summary>
            /// 料架进入小车完成
            /// </summary>
            END
        }
    }

}