GoEmptyShelfLineJob.cs 18.4 KB
using Common;
using System;

namespace DeviceLibrary
{
    /// <summary>
    /// 去空料架任务点
    /// </summary>
    public class GoEmptyShelfLineJob : Job
    {
        /// <summary>
        /// 去空料架任务点
        /// </summary>
        /// <param name="agvPlae">小车当前位置,空表示在待机位</param>
        /// <param name="palce">空料架位置点</param>
        public GoEmptyShelfLineJob(string agvPlae, string palce, string rfid)
        {
            EmptyShelfPlace = palce;
            this.agvPlae = agvPlae;
            RFID = rfid;
            JobName = "回收空料架任务";
        }
        public string RFID { get; set; }
        /// <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 string.Format("回收空料架[RFID={0}][{1}]:{2}", RFID, CurTaskID, runInfo); }
        }


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

        /// <summary>
        /// 空架任务执行,去目的地
        /// </summary>
        /// <param name="agv"></param>
        public override Job Execute(Agv_Info agv)
        {
            string msg = string.Format("{0} 回收空料架[RFID={1}]: ", agv.Name, RFID);
            //bool rtn = false;
            StartJobTime = curJobStep.startTime;
            agv.RFID = RFID;
            int nodeIdx = AGVManager.FindNode(EmptyShelfPlace);
            if (curJobStep.IsStep(TAKE_EMPTY_STEP.NONE))
            {
                if (AGVManager.CheckIsInAirDoor(agvPlae) && !AGVManager.CheckIsInAirDoor(EmptyShelfPlace))//风淋门内->风淋门外
                {
                    curJobStep.ToNextStep(TAKE_EMPTY_STEP.OUT_AIR_DOOR_1);
                    runInfo = "去产线" + EmptyShelfPlace + ",先去风淋门停留点[" + agvPlae + "->" + EmptyShelfPlace + "]" + "[RFID=" + RFID + "]";
                    msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                    curJobStep.Msg = msg;
                    MissionSys.AssignMission(agv, $"{SettingString.DoorAirOut}-1");
                    UpdateJobTaskInfo(agv);
                }
                else if (!AGVManager.CheckIsInAirDoor(agvPlae) && AGVManager.CheckIsInAirDoor(EmptyShelfPlace))//风淋门外->风淋门内
                {

                    curJobStep.ToNextStep(TAKE_EMPTY_STEP.IN_AIR_DOOR_1);
                    runInfo = "去产线" + EmptyShelfPlace + ",先去风淋门停留点[" + agvPlae + "->" + EmptyShelfPlace + "]" + "[RFID=" + RFID + "]";
                    msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                    curJobStep.Msg = msg;
                    MissionSys.AssignMission(agv, $"{SettingString.DoorAirIn}-1");
                    UpdateJobTaskInfo(agv);
                }
                else//起始与目的地在风淋门同一侧
                {
                    if (AGVManager.CheckIsInAirDoor(agvPlae) && AGVManager.CheckIsInAirDoor(EmptyShelfPlace))//都在风淋门内
                    {
                        curJobStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
                        runInfo = "开始任务[" + agvPlae + "->" + EmptyShelfPlace + "]" + "[RFID=" + RFID + "]";
                        msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                        curJobStep.Msg = msg;

                    }
                    else if (agvPlae.Equals("") || (!AGVManager.CheckIsInAirDoor(agvPlae)) && !AGVManager.CheckIsInAirDoor(EmptyShelfPlace))//都在风淋门外
                    {
                        curJobStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
                        runInfo = "开始任务[" + agvPlae + "->" + EmptyShelfPlace + "]" + "[RFID=" + RFID + "]";
                        msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                        curJobStep.Msg = msg;

                    }

                }

            }

            else if (curJobStep.IsStep(TAKE_EMPTY_STEP.OUT_AIR_DOOR_1))
            {
                CurTaskState = MissionSys.GetTakJobState(agv);
                if (MissionSys.CheckTaskFinished(agv, $"{SettingString.DoorAirOut}-1", CurTaskState))
                {
                    RecordRunLog(agv, curJobStep.CurStep(), runInfo, agv.Place);
                    curJobStep.ToNextStep(TAKE_EMPTY_STEP.OUT_AIR_DOOR_2);
                    runInfo = string.Format("{0}到达风淋门停留点,进入{1}风淋门", agv.Place, SettingString.RoomD_Name);
                    msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                    curJobStep.Msg = msg;
                    MissionSys.AssignMission(agv, $"{SettingString.DoorAirOut}-2");
                    UpdateJobTaskInfo(agv);
                }
            }
            else if (curJobStep.IsStep(TAKE_EMPTY_STEP.OUT_AIR_DOOR_2))
            {
                CurTaskState = MissionSys.GetTakJobState(agv);
                if (MissionSys.CheckTaskFinished(agv, $"{SettingString.DoorAirOut}-2", CurTaskState))
                {
                    RecordRunLog(agv, curJobStep.CurStep(), runInfo, agv.Place);
                    curJobStep.ToNextStep(TAKE_EMPTY_STEP.OUT_AIR_DOOR_3);
                    runInfo = string.Format("{0}进入风淋门,准备出{1}风淋门", agv.Place, SettingString.RoomD_Name);
                    msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                    curJobStep.Msg = msg;
                    MissionSys.AssignMission(agv, $"{SettingString.DoorAirOut}-3");
                    UpdateJobTaskInfo(agv);
                }
            }
            else if (curJobStep.IsStep(TAKE_EMPTY_STEP.OUT_AIR_DOOR_3))
            {
                CurTaskState = MissionSys.GetTakJobState(agv);
                if (MissionSys.CheckTaskFinished(agv, $"{SettingString.DoorAirOut}-3", CurTaskState))
                {
                    curJobStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
                    runInfo = "到风淋门外,开始任务[" + agvPlae + "->" + EmptyShelfPlace + "]" + "[RFID=" + RFID + "]";
                    msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                    curJobStep.Msg = msg;
                }
            }
            else if (curJobStep.IsStep(TAKE_EMPTY_STEP.IN_AIR_DOOR_1))
            {
                CurTaskState = MissionSys.GetTakJobState(agv);
                if (MissionSys.CheckTaskFinished(agv, $"{SettingString.DoorAirIn}-1", CurTaskState))
                {
                    RecordRunLog(agv, curJobStep.CurStep(), runInfo, agv.Place);
                    curJobStep.ToNextStep(TAKE_EMPTY_STEP.IN_AIR_DOOR_2);
                    runInfo = string.Format("{0}到达风淋门停留点,进入{1}风淋门", agv.Place, SettingString.RoomD_Name);
                    msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                    curJobStep.Msg = msg;
                    MissionSys.AssignMission(agv, $"{SettingString.DoorAirIn}-2");
                    UpdateJobTaskInfo(agv);
                }
            }
            else if (curJobStep.IsStep(TAKE_EMPTY_STEP.IN_AIR_DOOR_2))
            {
                CurTaskState = MissionSys.GetTakJobState(agv);
                if (MissionSys.CheckTaskFinished(agv, $"{SettingString.DoorAirIn}-2", CurTaskState))
                {
                    RecordRunLog(agv, curJobStep.CurStep(), runInfo, agv.Place);
                    curJobStep.ToNextStep(TAKE_EMPTY_STEP.IN_AIR_DOOR_3);
                    runInfo = string.Format("{0}进入风淋门,准备出{1}风淋门", agv.Place, SettingString.RoomD_Name);
                    msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                    curJobStep.Msg = msg;
                    MissionSys.AssignMission(agv, $"{SettingString.DoorAirIn}-3");
                    UpdateJobTaskInfo(agv);
                }
            }
            else if (curJobStep.IsStep(TAKE_EMPTY_STEP.IN_AIR_DOOR_3))
            {
                CurTaskState = MissionSys.GetTakJobState(agv);
                if (MissionSys.CheckTaskFinished(agv, $"{SettingString.DoorAirIn}-3", CurTaskState))
                {
                    curJobStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
                    runInfo = "到风淋门外,开始任务[" + agvPlae + "->" + EmptyShelfPlace + "]" + "[RFID=" + RFID + "]";
                    msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                    curJobStep.Msg = msg;
                }
            }

            else if (curJobStep.IsStep(TAKE_EMPTY_STEP.WAIT_REACH_TEMP_PLACE))
            {
                CurTaskState = MissionSys.GetTakJobState(agv);
                if (MissionSys.CheckTaskFinished(agv, SettingString.C4_STANDBY1, CurTaskState) || MissionSys.CheckTaskFinished(agv, SettingString.C4_STANDBY2, CurTaskState))
                {
                    RecordRunLog(agv, curJobStep.CurStep(), runInfo, agv.Place);
                    if (!AGVManager.CheckRoomCTarget(agv, EmptyShelfPlace))//未占用
                    {
                        curJobStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
                        runInfo = "开始执行回收空料架任务[" + agvPlae + "->" + EmptyShelfPlace + "]" + "[RFID=" + RFID + "]";
                        msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                        curJobStep.Msg = msg;
                        //AGVManager.DeleteStandyInfo(agv);
                    }
                }
            }
            else if (curJobStep.IsStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK))
            {

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

                }
            }
            else if (curJobStep.IsStep(TAKE_EMPTY_STEP.WAIT_LINE_RESPONSE))
            {
                if (nodeIdx == -1)
                {
                    runInfo = EmptyShelfPlace + " 未开启调用";
                    msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                    curJobStep.Msg = msg;
                    return this;
                }
                ClientNode node = AGVManager.nodeInfo[nodeIdx];
                if (node.StateEquals(eNodeStatus.MayLeave))
                {
                    agv.HasError = false;
                    if (!agv.CurTarName.Equals("Enter"))
                    {
                        RecordRunLog(agv, curJobStep.CurStep(), runInfo, agv.Place);
                        curJobStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_TAKE_EMPTY_SHELF);
                        runInfo = "收到产线出料请求[ReadyLeave]的响应 " + EmptyShelfPlace + "出料架,小车链条运行" + "[RFID=" + RFID + "]";
                        msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                        curJobStep.Msg = msg;
                        //agv.RFID = node.RFID;
                        MissionSys.AssignMission(agv, SettingString.Enter);
                        UpdateJobTaskInfo(agv);
                    }

                }
                else if (curJobStep.IsTimeOut(15000, out TimeSpan timeOutValue))
                {
                    curJobStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_REACH_PLACE);
                    agv.HasError = true;

                }
            }
            else if (curJobStep.IsStep(TAKE_EMPTY_STEP.WAIT_TAKE_EMPTY_SHELF))
            {
                CurTaskState = MissionSys.GetTakJobState(agv);
                if (MissionSys.CheckTaskFinished(agv, SettingString.Enter, CurTaskState))
                {
                    agv.HasError = false;
                    ClientNode node = AGVManager.nodeInfo[nodeIdx];
                    //回收空料架数量减少1
                    AGVManager.unlockManager.DelMission(EmptyShelfPlace, RFID);
                    if (!agvPlae.Equals(SettingString.RoomDFeederOut) && !agvPlae.Equals(SettingString.RoomCFeederOut))
                        HttpManager.ClearRFID(EmptyShelfPlace, RFID);
                    runInfo = "空料架在[" + EmptyShelfPlace + "]进入小车完成" + "[RFID=" + RFID + "]";
                    msg += string.Format("[{0}] {1}", curJobStep.CurStep(), runInfo);
                    curJobStep.Msg = msg;
                    RecordRunLog(agv, curJobStep.CurStep(), runInfo, agv.Place);
                    if (RFID.StartsWith("D"))
                        return new EmptyShelfBackJob(EmptyShelfPlace, eShelfType.SmallShelf);

                    else if (RFID.StartsWith("C"))
                    {
                        return new EmptyShelfBackJob(EmptyShelfPlace, eShelfType.BigShelf);
                    }
                    else
                        return new EmptyShelfBackJob(EmptyShelfPlace, eShelfType.SmallShelf);

                }
                else if (curJobStep.IsTimeOut(60000, out TimeSpan timeOutValue))
                {
                    //链条停止
                    runInfo = "空料架在[" + EmptyShelfPlace + "]进入小车超时[RFID=" + RFID + "]";
                    agv.HasError = true;
                    agv.SetErrorMsg("空料架在[" + EmptyShelfPlace + "]进入小车超时", timeOutValue.TotalMinutes.ToString("f2"));
                }
            }
            else if (curJobStep.IsStep(TAKE_EMPTY_STEP.END))
            {

            }
            return this;
        }


        /// <summary>
        /// AGV回收空料架流程
        /// </summary>
        private enum TAKE_EMPTY_STEP
        {
            /// <summary>
            /// 准备,发送给AGV
            /// </summary>
            NONE,
            /// <summary>
            /// 去出3D风淋门等待位
            /// </summary>
            OUT_AIR_DOOR_1,
            /// <summary>
            /// 进风淋门
            /// </summary>
            OUT_AIR_DOOR_2,
            /// <summary>
            /// 出风淋门
            /// </summary>
            OUT_AIR_DOOR_3,
            /// <summary>
            /// 去进3D风淋门等待位
            /// </summary>
            IN_AIR_DOOR_1,
            /// <summary>
            /// 进风淋门
            /// </summary>
            IN_AIR_DOOR_2,
            /// <summary>
            /// 出风淋门
            /// </summary>
            IN_AIR_DOOR_3,
            /// <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
        }
    }

}