SendShelfJob.cs 14.6 KB
using Common;
using System;

namespace DeviceLibrary
{
    /// <summary>
    ///送料串
    /// </summary>
    public class SendShelfJob : Job
    {
        /// <summary>
        /// 送料串
        /// </summary>
        /// <param name="agvPlae">agv当前位置</param>
        /// <param name="tarPlace">目的地</param>
        public SendShelfJob(string agvPlae, string tarPlace, string RFID = "")
        {
            this.agvPlace = agvPlae;
            TargetPlace = tarPlace;
            this.RFID = RFID;
            StartJobTime = DateTime.Now;
            JobName = "送料串任务";
        }


        /// <summary>
        /// 接收任务时,agv的位置
        /// </summary>
        private string agvPlace = "";

        private string RFID = "";
        /// <summary>
        /// 目的地
        /// </summary>
        public string TargetPlace { get; private set; }

        /// <summary>
        /// 运行信息
        /// </summary>
        public override string RunInfo
        {
            get
            {
                int t1 = NodeManager.nodeInfo.FindIndex(s => s.Name.Equals(agvPlace));
                string from = "";
                if (t1 > -1)
                    from = NodeManager.nodeInfo[t1].AliceName;
                else
                    from = agvPlace;
                int t2 = NodeManager.nodeInfo.FindIndex(s => s.Name.Equals(TargetPlace));
                string to = "";
                if (t2 > -1)
                    to = NodeManager.nodeInfo[t2].AliceName;
                else
                    to = TargetPlace;
                return string.Format("送料串任务[RFID={4}]:{0} [目的地={1}][任务名称={2}][任务状态={3}]", runInfo, to, CurTaskName, CurTaskState, RFID);
            }
        }

        private JobStep<EXECUTE_STEP> curJobStep = new JobStep<EXECUTE_STEP>(EXECUTE_STEP.P1_NONE);

        private string GetShowInfo()
        {
            int t1 = NodeManager.nodeInfo.FindIndex(s => s.Name.Equals(agvPlace));
            string from = "";
            if (t1 > -1)
                from = NodeManager.nodeInfo[t1].AliceName;
            else
                from = agvPlace;
            int t2 = NodeManager.nodeInfo.FindIndex(s => s.Name.Equals(TargetPlace));
            string to = "";
            if (t2 > -1)
                to = NodeManager.nodeInfo[t2].AliceName;
            else
                to = TargetPlace;
            return string.Format("{0} [{1}->{2}]", runInfo, from, to);
        }
        /// <summary>
        /// 任务执行
        /// </summary>
        /// <param name="agv"></param>
        public override Job Execute(Agv_Info agv)
        {
            string msg = agv.Name + " ";
            bool rtn = false;
            agv.Msg = GetShowInfo();
            agv.RFID = RFID;
            StartJobTime = curJobStep.startTime;
            CurTaskState = CommonVar.GetTakJobState(agv);
            if (curJobStep.IsStep(EXECUTE_STEP.P1_NONE))
            {
                agv.HasError = false;
                if (!agvPlace.StartsWith(SettingString.C4_Name_Prefix) && TargetPlace.StartsWith(SettingString.C4_Name_Prefix))//D C
                {
                    curJobStep.ToNextStep(EXECUTE_STEP.P3_WAIT_REACH_4C_DOOR);
                    runInfo = "收到任务,在3D车间,向" + TargetPlace + "运行,先过门";
                    msg += runInfo;
                    curJobStep.Msg = msg;
                    CommonVar.DoorMission(agv, SettingString.DoorDToC);
                    UpdateJobTaskInfo(agv);
                }
                else if (agvPlace.StartsWith(SettingString.C4_Name_Prefix) && !TargetPlace.StartsWith(SettingString.C4_Name_Prefix))//C D
                {
                    curJobStep.ToNextStep(EXECUTE_STEP.P3_WAIT_REACH_4D_DOOR);
                    runInfo = "收到任务,在3C车间,向" + TargetPlace + "运行,先过门";
                    msg += runInfo;
                    curJobStep.Msg = msg;
                    CommonVar.DoorMission(agv, SettingString.DoorCToD);
                    UpdateJobTaskInfo(agv);
                }
                else//DD CC
                {
                    curJobStep.ToNextStep(EXECUTE_STEP.P2_WAIT_REACH_STATION);
                    runInfo = "收到任务,向" + TargetPlace + "运行";
                    msg += runInfo;
                    curJobStep.Msg = msg;
                    CommonVar.MoveToNode(agv, TargetPlace);
                    UpdateJobTaskInfo(agv);
                }

            }
            else if (curJobStep.IsStep(EXECUTE_STEP.P2_WAIT_REACH_STATION))
            {
                if (CommonVar.CheckTaskMoveFinished(agv, TargetPlace, CurTaskState))
                {
                    RecordRunLog(agv, curJobStep.CurStep(), runInfo, TargetPlace);
                    curJobStep.ToNextStep(EXECUTE_STEP.P4_WAIT_STATION_RESPONSE);
                    runInfo = "到达" + TargetPlace + ",并发送进料请求";
                    msg += runInfo;
                    curJobStep.Msg = msg;
                    CommonVar.server.Ready(TargetPlace, RFID);
                }
            }
            else if (curJobStep.IsStep(EXECUTE_STEP.P3_WAIT_REACH_4D_DOOR))
            {
                if (CommonVar.CheckTaskMoveFinished(agv, SettingString.DoorCToD, CurTaskState))
                {
                    RecordRunLog(agv, curJobStep.CurStep(), runInfo, TargetPlace);
                    curJobStep.ToNextStep(EXECUTE_STEP.P2_WAIT_REACH_STATION);
                    runInfo = "到达3D门,去料架处" + TargetPlace;
                    msg += runInfo;
                    curJobStep.Msg = msg;

                    CommonVar.MoveToNode(agv, TargetPlace);
                    UpdateJobTaskInfo(agv);
                }
            }
            else if (curJobStep.IsStep(EXECUTE_STEP.P3_WAIT_REACH_4C_DOOR))
            {
                if (CommonVar.CheckTaskMoveFinished(agv, SettingString.DoorDToC, CurTaskState))
                {
                    RecordRunLog(agv, curJobStep.CurStep(), runInfo, TargetPlace);
                    curJobStep.ToNextStep(EXECUTE_STEP.P2_WAIT_REACH_STATION);
                    runInfo = "到达3C门,去料架处" + TargetPlace;
                    msg += runInfo;
                    curJobStep.Msg = msg;

                    CommonVar.MoveToNode(agv, TargetPlace);
                    UpdateJobTaskInfo(agv);
                }
            }
            else if (curJobStep.IsStep(EXECUTE_STEP.P4_WAIT_STATION_RESPONSE))
            {
                int i = NodeManager.nodeInfo.FindIndex(s => s.Name.Equals(TargetPlace) && s.StateEquals(eNodeStatus.MayEnter));
                if (i > -1)
                {
                    curJobStep.ToNextStep(EXECUTE_STEP.P5_WAIT_SHELF_IN_STATION);
                    //curJobStep.ToNextStep(EXECUTE_STEP.P6_TURN_DIRECTION);
                    runInfo = "收到线体允许进料信号,链条运行";
                    msg += runInfo;
                    curJobStep.Msg = msg;
                    rtn = agv.AssignTask(SettingString.Leave);
                    UpdateJobTaskInfo(agv);
                }
                else if (curJobStep.IsTimeOut(20000, out TimeSpan timeOutTime))
                {
                    curJobStep.ToNextStep(EXECUTE_STEP.P2_WAIT_REACH_STATION);
                    runInfo = string.Format("线体[{0}]允许进料信号[{1}]超时{2}秒,重发进料请求", TargetPlace, eNodeStatus.MayEnter, timeOutTime.TotalSeconds.ToString("f2"));
                    msg += string.Format("线体[{0}]允许进料信号[{1}]超时15S,重发进料请求", TargetPlace, eNodeStatus.MayEnter);
                    curJobStep.Msg = msg;
                }
            }
            else if (curJobStep.IsStep(EXECUTE_STEP.P5_WAIT_SHELF_IN_STATION))
            {
                int idx = NodeManager.nodeInfo.FindIndex(s => s.Name.Equals(TargetPlace) && s.StateEquals(eNodeStatus.FinishEnter));
                if (idx > -1)
                {
                    RecordRunLog(agv, curJobStep.CurStep(), runInfo, TargetPlace);
                    curJobStep.ToNextStep(EXECUTE_STEP.P6_TURN_DIRECTION);
                    runInfo = "料架进入" + TargetPlace + "完成";
                    agv.HasError = false;
                    msg += runInfo;
                    curJobStep.Msg = msg;
                }
                else if (curJobStep.IsTimeOut(30000, out TimeSpan timeSpan))
                {
                    RecordRunLog(agv, curJobStep.CurStep(), runInfo, TargetPlace);
                    curJobStep.ToNextStep(EXECUTE_STEP.P6_TURN_DIRECTION);
                    runInfo = "料架进入" + TargetPlace + "完成";
                    agv.HasError = false;
                    msg += runInfo;
                    curJobStep.Msg = msg;
                    //runInfo = string.Format("等待线体[{0}]进料完成信号[FinishEnter]超时", TargetPlace);
                    //msg += runInfo;
                    //curJobStep.Msg = msg;
                    //agv.HasError = true;
                    //agv.SetErrorMsg($"等待线体[{TargetPlace}]进料完成信号[FinishEnter]超时", timeSpan.TotalMinutes.ToString("f2"));
                }

                if (CommonVar.CheckEnterOrLeaveFinished(agv, SettingString.Leave, CurTaskState))
                    CommonVar.server.CloseDoor(TargetPlace);
            }
            else if (curJobStep.IsStep(EXECUTE_STEP.P6_TURN_DIRECTION))
            {
                if (CommonVar.CheckEnterOrLeaveFinished(agv, SettingString.Leave, CurTaskState))
                {
                    RecordRunLog(agv, curJobStep.CurStep(), runInfo, TargetPlace);
                    curJobStep.ToNextStep(EXECUTE_STEP.P7_END);
                    runInfo = "AGV在" + TargetPlace + "出料完成,开始转向";
                    agv.HasError = false;
                    msg += runInfo;
                    curJobStep.Msg = msg;
                    CommonVar.server.CloseDoor(TargetPlace);
                    rtn = agv.AssignTask(SettingString.Turn);
                    UpdateJobTaskInfo(agv);
                }
                else if (curJobStep.IsTimeOut(120000, out TimeSpan timeSpan))
                {
                    runInfo = string.Format("线体[{0}]出料超时,请检查料架情况", TargetPlace);
                    msg += runInfo;
                    curJobStep.Msg = msg;
                    agv.HasError = true;
                    agv.SetErrorMsg($"线体[{TargetPlace}]出料超时,请检查料架情况", timeSpan.TotalMinutes.ToString("f2"));
                }
            }
            else if (curJobStep.IsStep(EXECUTE_STEP.P7_END))
            {
                if (CommonVar.CheckEnterOrLeaveFinished(agv, SettingString.Turn, CurTaskState))
                {
                    if (IsPlace(SettingString.D23_In) && FindReturnShelf(agv))
                    {
                        runInfo = "AGV在" + TargetPlace + "转向完成,去退料线出口取一个料串回点料机";
                        msg += runInfo;
                        curJobStep.Msg = msg;
                        RecordRunLog(agv, curJobStep.CurStep(), runInfo, TargetPlace);
                        return new GetShelfJob(TargetPlace, SettingString.D24_Out, "B#", true);
                    }
                    else
                    {
                        if (agv.IP.Equals(SettingString.SingleMission_IP1))
                        {
                            if (IsPlace(SettingString.A2) && !CommonVar.control.limitArea.Available)
                            {
                                runInfo = "料架进入" + TargetPlace + "完成,等待限制区域无车";
                                msg += runInfo;
                                curJobStep.Msg = msg;
                            }
                            else
                            {
                                runInfo = "AGV在" + TargetPlace + "转向完成";
                                msg += runInfo;
                                curJobStep.Msg = msg;
                            }
                        }
                        else
                        {
                            runInfo = "AGV在" + TargetPlace + "转向完成";
                            msg += runInfo;
                            curJobStep.Msg = msg;
                            RecordRunLog(agv, curJobStep.CurStep(), runInfo, TargetPlace);
                            return null;
                        }
                    }
                }

            }
            return this;
        }

        private bool IsPlace(string place)
        {
            return TargetPlace.Equals(place);
        }

        private bool FindReturnShelf(Agv_Info currentAgv)
        {
            string rfid = "";
            if (BoxReelStringJobType.FindNeedLeaveMission(currentAgv, SettingString.D24_Out, out rfid))
            {
                if (BoxReelStringJobType.FindNeedEnterMission(currentAgv, SettingString.D3))
                {
                    LogUtil.info(string.Format("{0} 在退料线生成任务(D3需要满料串,D24出满料串):Place={1},rfid={2}", currentAgv.Name, SettingString.D3, rfid));
                    return true;
                }
            }
            if (BoxReelStringJobType.FindNeedLeaveMission(currentAgv, SettingString.D4, out rfid))
            {
                if (BoxReelStringJobType.FindNeedEnterMission(currentAgv, SettingString.D23_In))
                {
                    LogUtil.info(string.Format("{0} 在退料线生成任务(D4需要满料串,D24出满料串):Place={1},rfid={2}", currentAgv.Name, SettingString.D4, rfid));
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 执行流程
        /// </summary>
        private enum EXECUTE_STEP
        {
            /// <summary>
            /// 接收到任务
            /// </summary>
            P1_NONE,
            /// <summary>
            /// 等待到达目的地
            /// </summary>
            P2_WAIT_REACH_STATION,
            /// <summary>
            /// 等待到达4D
            /// </summary>
            P3_WAIT_REACH_4D_DOOR,
            /// <summary>
            /// 等待到达4C
            /// </summary>
            P3_WAIT_REACH_4C_DOOR,
            /// <summary>
            /// 等待线体回复
            /// </summary>
            P4_WAIT_STATION_RESPONSE,
            /// <summary>
            /// 等待料架进入线体
            /// </summary>
            P5_WAIT_SHELF_IN_STATION,
            /// <summary>
            /// 转向
            /// </summary>
            P6_TURN_DIRECTION,
            /// <summary>
            /// 任务结束
            /// </summary>
            P7_END
        }
    }

}