AC_BOX_Bean_Shelf.cs 19.4 KB
using Asa;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace OnlineStore.DeviceLibrary
{
    /// <summary>
    /// 料架进出料仓处理:出入库模块共用
    /// </summary>
    public partial class AC_BOX_Bean
    {
        /// <summary>
        /// 开始料架入库
        /// </summary>
        public void StartShelfInStore()
        {

            bool canStart = (storeRunStatus.Equals(StoreRunStatus.Runing)
                && MoveInfo.MoveType.Equals(StoreMoveType.None));
            if (!canStart || isInSuddenDown || isNoAirCheck || (alarmType.Equals(StoreAlarmType.None).Equals(false)))
            {
                return;
            }
            clearNGShelfPos();
            setStatus(StoreRunStatus.Busy, StoreStatus.InStoreExecute);
            //    EmprtShelfList = new ConcurrentQueue<string>();
            if (IOValue(IO_Type.LineIn_Check).Equals(IO_VALUE.HIGH))
            {
                MoveInfo.NewMove(StoreMoveType.InStore, new InOutParam());
                MoveInfo.MoveParam.MoveP = new LineMoveP(Config);
                MoveInfo.ShelfPositionList = new List<string>(ShelfPosList);
                MoveInfo.NextMoveStep(StoreMoveStep.BI_01_DoorOpen);
                LogInfo(" 空闲中,检测到入料口有料架,启动料架入库 ");
                //   CylinderMove(MoveInfo, IO_Type.EntranceDoor_Close, IO_Type.EntranceDoor_Open);
                // DoorBean.StartOpen(MoveInfo);
            }
            else if (IOValue(IO_Type.LineTake_Check).Equals(IO_VALUE.HIGH))
            {
                MoveInfo.NewMove(StoreMoveType.InStore, new InOutParam());
                MoveInfo.MoveParam.MoveP = new LineMoveP(Config);
                MoveInfo.ShelfPositionList = new List<string>(ShelfPosList);
                MoveInfo.NextMoveStep(StoreMoveStep.BI_06_DoorClose);
                LogInfo(" 空闲中,检测到入料口有料架,启动料架入库 ");
            }
            else
            {

                LogInfo(" 空闲中,需要料架入库,料架入库 " + ":入料口移门打开,更新 WaitShelfEnter=false");
                WaitShelfEnter = false;
                MoveInfo.NewMove(StoreMoveType.InStore, new InOutParam());
                MoveInfo.MoveParam.MoveP = new LineMoveP(Config);
                MoveInfo.ShelfPositionList = new List<string>(ShelfPosList);
                MoveInfo.NextMoveStep(StoreMoveStep.BI_01_DoorOpen);

                DoorBean.StartOpen(MoveInfo);
            }
        }

        private void ShelfEnterProcess()
        {
            string mark = GetMarkInfo();
            string moveName = "入库料架[" + CurrShelfID + "]";
            bool instoreShelf = true;
            if (MoveInfo.MoveType.Equals(StoreMoveType.OutStore))
            {
                instoreShelf = false;
                moveName = "出库料架[" + CurrShelfID + "][" + mark + "]";
            }
            if (MoveInfo.MoveStep.Equals(StoreMoveStep.BI_00_ReadyShelf))
            {
                if (IOValue(IO_Type.LineIn_Check).Equals(IO_VALUE.HIGH))
                {
                    BI_04_WaitTakeSingle(moveName);
                }
                else if (IOValue(IO_Type.LineTake_Check).Equals(IO_VALUE.HIGH))
                {
                    BI_04_WaitTakeSingle(moveName);
                }
                else
                {
                    // MoveInfo.ShelfPositionList = new List<string>(ShelfPosList);
                    LogRunStepInfo($"{moveName} AGV已到达,打开入料口移门");
                    MoveInfo.NextMoveStep(StoreMoveStep.BI_01_DoorOpen);
                    DoorBean.StartOpen(MoveInfo);
                }
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BI_01_DoorOpen))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BI_03_LineRun);
                LogRunStepInfo($"{moveName}调用AgvClient.MayEnter,线体正转,等待LineIn_Check 或LineTake_Check 信号");
                setAgvStatus(mark, "", ClientAction.MayEnter, ClientLevel.High, true);
                LineRun();

                MoveInfo.WaitList.Add(WaitResultInfo.WaitIO(IO_Type.LineIn_Check, IO_VALUE.HIGH));
                MoveInfo.WaitList.Add(WaitResultInfo.WaitIO(IO_Type.LineTake_Check, IO_VALUE.HIGH));
                MoveInfo.OneWaitCanEndStep = true;
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BI_03_LineRun))
            {
                BI_04_WaitTakeSingle(moveName);
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BI_04_WaitTakeSingle))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BI_05_LineStop);
                LogRunStepInfo($"{moveName}调用Agv Config.AgvNodeName FinishEnter,取料位检测到信号,继续转动");

                LineRun();
                setAgvStatus(mark, "", ClientAction.FinishEnter, ClientLevel.High, true);
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BI_05_LineStop))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BI_06_DoorClose);
                LogRunStepInfo($"{moveName}入料口移门关闭 ");
                DoorBean.StartClose(MoveInfo);
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BI_06_DoorClose))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BI_07_LineRun);
                MoveInfo.WaitList.Add(WaitResultInfo.WaitTime(7000));
                LogRunStepInfo($"{moveName}继续转动 7000ms");
                LineRun();
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BI_07_LineRun))
            {
                LineStop();
                UpdateShelfId();

                //如果未读到料架号,将料架送出
                if (CurrShelfID.EndsWith("00") && MoveInfo.MoveType.Equals(StoreMoveType.OutStore))
                {
                    LogRunStepInfo($" 执行出库【{MoveInfo.MoveParam.ToStr()}】失败,料架号[{CurrShelfID}]无效,加入等待队列并送出料架,稍后重新出库");
                    waitOutStoreList.Enqueue(MoveInfo.MoveParam.NewParam());
                    MoveInfo.MoveParam.rfid = CurrShelfID;
                    //送出料架,并且记录出库信息,等会重新出库
                    StartShelfOut();
                    return;
                }
                //如果该料架为入库料架,此时有出库任务,执行入库任务
                if (StoreManager.CheckShelfInfo(CurrShelfID) && MoveInfo.MoveType.Equals(StoreMoveType.OutStore))
                {
                    LogRunStepInfo($"出库 {mark}->入库 料架号[{CurrShelfID}]为入库料架,进行入库");
                    MoveInfo.NewMove(StoreMoveType.InStore, new InOutParam());
                    MoveInfo.MoveParam.MoveP = new LineMoveP(Config);
                    MoveInfo.ShelfPositionList = new List<string>(ShelfPosList);
                    mark = "0";
                    instoreShelf = true;
                }
                MoveInfo.NextMoveStep(StoreMoveStep.BI_08_LocationUp);
                LogRunStepInfo($"{moveName}停止线体,读取料架{CurrShelfID},设置{Config.AgvNodeName}=None");
                setAgvStatus(mark);
                // CylinderMove(MoveInfo, IO_Type.LocationCylinder_Down, IO_Type.LocationCylinder_Up);

                if (!instoreShelf)
                {
                    if (MoveInfo.MoveParam.CurShelfPosID.Equals(""))
                    {
                        MoveInfo.MoveParam.UpdateShelfPosId(ShelfPosList[0]);
                        LogRunStepInfo($"ShelfPosID未设置,默认ShelfPosID={MoveInfo.MoveParam.CurShelfPosID}");
                    }
                    // LastRfidID = MoveInfo.MoveParam.rfid;
                    LastOutParam = MoveInfo.MoveParam;
                }
                else
                {
                    LastOutParam = new InOutParam();
                    //   LastRfidID = "";
                }
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BI_08_LocationUp))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BI_09_TopCylinderUp);
                LogRunStepInfo(moveName + CurrShelfID + "顶升上升");
                CylinderMove(MoveInfo, IO_Type.TopCylinder_Down, IO_Type.TopCylinder_Up);
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BI_09_TopCylinderUp))
            {
                if (instoreShelf)
                {
                    MoveInfo.NextMoveStep(StoreMoveStep.BI_10_StartGetTray);
                    MoveInfo.WaitList.Add(WaitResultInfo.WaitTime((int)TimeSpan.FromMinutes(75).TotalMilliseconds));
                    //获取料架的锁定状态
                    bool lockState = StoreManager.GetShelfLockInfo(Name, CID, CurrShelfID, out MoveInfo.shelfLockDatas);

                    if (lockState && MoveInfo.shelfLockDatas != null)
                    {

                        MoveInfo.IsShelfLocked = true;
                        if (MoveInfo.shelfLockDatas.Count.Equals(0))
                            LogRunStepInfo(moveName + "该锁定料架上的料盘不属于该料仓,即将送出锁定料架");
                        else
                            LogRunStepInfo(moveName + "开始到料架指定位置取料盘 ");
                    }
                    else
                    {
                        MoveInfo.IsShelfLocked = false;
                        LogRunStepInfo(moveName + "开始循环料架取料盘 ");
                    }
                    MoveInfo.EndStepWait();
                }
                else
                {
                    if (string.IsNullOrEmpty(StoreManager.FindRealRfidByTempRfid(MoveInfo.MoveParam.rfid)))
                    {
                        //新料架,检查料架上是否有治具
                        MoveInfo.NextMoveStep(StoreMoveStep.SO_PreCheck_01_StartGetTray);
                    }
                    else
                    {
                        SO_03_ToBagPosition();
                    }
                }
            }
        }
        private void UpdateShelfId()
        {
            //读取RFID
            RFIDData data = RFIDManager.ReadRFID(Config.RFID_IP, true);
            CurrShelfID = data.NumStr();
            LogRunStepInfo("更新当前料架号CurrShelfID=【" + CurrShelfID + "】,LastRfidID=【" + GetLastRfid() + "】");
        }
        /// <summary>
        /// 等待取料位检测到信号
        /// </summary>
        /// <param name="moveName"></param>
        private void BI_04_WaitTakeSingle(string moveName)
        {
            MoveInfo.NextMoveStep(StoreMoveStep.BI_04_WaitTakeSingle);
            LogRunStepInfo($"{moveName} 线体正转,等待LineIn_Check=Low, 信号LineTake_Check=High");
            LineRun();
            MoveInfo.WaitList.Add(WaitResultInfo.WaitIO(IO_Type.LineIn_Check, IO_VALUE.LOW));
            MoveInfo.WaitList.Add(WaitResultInfo.WaitIO(IO_Type.LineTake_Check, IO_VALUE.HIGH));
        }
        /// <summary>
        /// 所有料盘已取料完成,送出料架
        /// </summary>
        private void StartShelfOut()
        {
            MoveInfo.NextMoveStep(StoreMoveStep.BS_01_TopDown);
            if (MoveInfo.MoveType.Equals(StoreMoveType.OutStore))
            {
                string mark = GetMarkInfo();
                LogRunStepInfo("送出[" + CurrShelfID + "][" + mark + "]:顶升下降,调用 NeedLeave[" + mark + "][" + CurrShelfID + "] ");
                AgvClient.NeedLeave(Config.AgvNodeName, mark, CurrShelfID);
            }
            else
            {
                LogRunStepInfo("送出空料架[" + CurrShelfID + "]:顶升下降,调用 NeedLeave[0][" + CurrShelfID + "],clearPutInRfid[" + CurrShelfID + "]");
                AgvClient.NeedLeave(Config.AgvNodeName, "0", CurrShelfID);
                StoreManager.clearPutInRfid(Name, CurrShelfID);
                ACAxisMove(Config.UpDown_Axis, Config.UpDownAxis_P1, Config.UpDownAxis_P1_Speed);
            }
            CylinderMove(MoveInfo, IO_Type.TopCylinder_Up, IO_Type.TopCylinder_Down);
        }


        private void ShelfOutProcess()
        {
            string mark = GetMarkInfo();
            string moveName = "送出入库料架[" + CurrShelfID + "][" + mark + "]";

            if (MoveInfo.MoveType.Equals(StoreMoveType.OutStore))
            {
                moveName = "送出出库料架[" + CurrShelfID + "][" + mark + "]";
            }
            //  LogCPU();
            if (MoveInfo.MoveStep.Equals(StoreMoveStep.BS_01_TopDown))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BS_02_LocatinDown);
                LogRunStepInfo(moveName + "定位气缸下降");
                // CylinderMove(MoveInfo, IO_Type.LocationCylinder_Up, IO_Type.LocationCylinder_Down);
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BS_02_LocatinDown))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BS_03_WaitEmptyAgv);
                MoveInfo.TimeOutSeconds = 600;
                //MoveInfo.WaitList.Add(WaitResultInfo.WaitTime(30000));
                //等待agv到达
                MoveInfo.WaitList.Add(WaitResultInfo.WaitAgvAction((int)ClientAction.Arrive));
                LogRunStepInfo(moveName + "再次调用 NeedLeave[" + mark + "][" + CurrShelfID + "],等待Agv " + Config.AgvNodeName + " Arrive ,最多等待1200秒");
                setAgvStatus(mark, CurrShelfID, ClientAction.NeedLeave, ClientLevel.High, true);
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BS_03_WaitEmptyAgv))
            {

                //agv到达
                if (AgvClient.GetAction(Config.AgvNodeName).Equals(ClientAction.Arrive))
                {
                    MoveInfo.NextMoveStep(StoreMoveStep.BS_04_DoorOpen);
                    LogRunStepInfo(moveName + "agv到达,打开入料口移门");
                    DoorBean.StartOpen(MoveInfo);
                }
                else
                {
                    //如果料架已被拉出,也算结束
                    if (IOValue(IO_Type.LineIn_Check).Equals(IO_VALUE.LOW) && IOValue(IO_Type.LineTake_Check).Equals(IO_VALUE.LOW))
                    {
                        MoveInfo.NextMoveStep(StoreMoveStep.BS_06_LineBackRun);
                        AgvClient.SetToNone(Config.AgvNodeName);
                        //如果agv未到达,直接结束 
                        MoveEndToRuningStatus();
                        //EmprtShelfList = new ConcurrentQueue<string>();
                        InOutStoreLog(moveName + "等待Agv " + Config.AgvNodeName + " Arrive超时,检测不到料架信号,认为料架已离开,出库结束,设置" + Config.AgvNodeName + "=None");
                    }
                    else
                    {
                        TimeSpan span = DateTime.Now - MoveInfo.LastSetpTime;
                        MoveInfo.WaitList.Add(WaitResultInfo.WaitTime((int)span.TotalMilliseconds + 30000));
                        LogRunStepInfo(moveName + "等待Agv " + Config.AgvNodeName + " Arrive超时,再等待30秒");
                    }
                }
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BS_04_DoorOpen))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BS_05_WaitReady);
                MoveInfo.TimeOutSeconds = 120;
                LogRunStepInfo(moveName + "移门已打开,调用 MayLeave [" + mark + "][" + CurrShelfID + "],等待agv " + Config.AgvNodeName + " Ready");
                setAgvStatus(mark, CurrShelfID, ClientAction.MayLeave, ClientLevel.High, true);

                //等待agv到达
                MoveInfo.WaitList.Add(WaitResultInfo.WaitAgvAction((int)ClientAction.Ready));
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BS_05_WaitReady))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BS_06_LineBackRun);
                MoveInfo.WaitList.Add(WaitResultInfo.WaitTime(500));
                LogRunStepInfo(moveName + "收到agv " + Config.AgvNodeName + " Ready ,线体开始反转");
                LineBackRun();
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BS_06_LineBackRun))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BS_07_WaitShelfOut);
                LogRunStepInfo(moveName + "等待取料工位无信号 ");
                MoveInfo.WaitList.Add(WaitResultInfo.WaitIO(IO_Type.LineTake_Check, IO_VALUE.LOW));
                //  MoveInfo.WaitList.Add(WaitResultInfo.WaitIO(IO_Type.LineIn_Check, IO_VALUE.HIGH));
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BS_07_WaitShelfOut))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BS_08_WaitLineIn);
                LogRunStepInfo(moveName + "等待 入料口有信号,最多等待30秒");
                //  MoveInfo.WaitList.Add(WaitResultInfo.WaitIO(IO_Type.LineTake_Check, IO_VALUE.LOW));
                MoveInfo.OneWaitCanEndStep = true;
                MoveInfo.WaitList.Add(WaitResultInfo.WaitTime(30000));
                MoveInfo.WaitList.Add(WaitResultInfo.WaitIO(IO_Type.LineIn_Check, IO_VALUE.HIGH));
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BS_08_WaitLineIn))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BS_09_WaitTime);
                LogRunStepInfo(moveName + "再转动1000 , 等待入料口无信号,清理RFID");
                RFIDManager.ReadRFID(Config.RFID_IP, true);
                MoveInfo.WaitList.Add(WaitResultInfo.WaitTime(1000));
                MoveInfo.WaitList.Add(WaitResultInfo.WaitIO(IO_Type.LineIn_Check, IO_VALUE.LOW));
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BS_09_WaitTime))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BS_10_WaitAGVLeave);
                MoveInfo.TimeOutSeconds = 180;
                LogRunStepInfo(moveName + "等待DoorClose事件,最多等待180000 ");
                MoveInfo.OneWaitCanEndStep = true;
                MoveInfo.WaitList.Add(WaitResultInfo.WaitTime(180000));
                MoveInfo.WaitList.Add(WaitResultInfo.WaitDoorClose());
                //MoveInfo.WaitList.Add(WaitResultInfo.WaitAgvAction(action.FinishOut));
            }

            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BS_10_WaitAGVLeave))
            {
                MoveInfo.NextMoveStep(StoreMoveStep.BS_11_CloseDoor);
                LogRunStepInfo(moveName + "停止线体转动,关闭仓门 ,发送FinishLeave ,等待最少5000");
                setAgvStatus(mark, CurrShelfID, ClientAction.FinishLeave, ClientLevel.High, true);
                MoveInfo.WaitList.Add(WaitResultInfo.WaitTime(5000));
                LineStop();
                DoorBean.StartClose(MoveInfo);
            }
            else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BS_11_CloseDoor))
            {
                //结束 
                MoveEndToRuningStatus();
                setAgvStatus();
                //EmprtShelfList = new ConcurrentQueue<string>();
                LogRunStepInfo(moveName + "料架" + CurrShelfID + $"已离开[{getNGShelfPos()}],设置" + Config.AgvNodeName + "=None,清理rfid");
                clearNGShelfPos();
                RFIDManager.ReadRFID(Config.RFID_IP, true);
                CurrShelfID = "";
                LastOutParam = new InOutParam();
                //LastRfidID = "";
            }
        }

    }
}