TakeBoxFromLineTask.cs 10.9 KB
using AGVLib;
using CtuDeviceLib;
using Mushiny;
using OnlineStore.Common;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace DeviceLibrary.CtuService
{
    /// <summary>
    /// 手动线取空箱-v1
    /// </summary>
    public class TakeBoxFromLineTask : TakeBoxBase
    {
        public TakeBoxFromLineTask(CTU ctu) : base(ctu)
        {
            Name = "入库线体取料箱";
            setDstName(Setting_Init.rawLine_out);
        }
        int ctuWaitSeconds { get { return ConfigAppSettings.GetIntValue("ManualNextInTaskWaitSeconds", 30); } }
        public override void Excute()
        {
            //当前位置不是目的地,就重新规划路线
            if (MoveInfo.MoveStep != RunStep.Wait && MoveInfo.MoveStep != RunStep.Instore_TakeBoxFromLine_01_MoveToSrc)
            {
                if (ctu.CurLandMark != destination)
                {
                    MoveInfo.NextMoveStep(RunStep.Wait);
                    MoveInfo.Info($"当前点位不在目标点【{DstName}】【{destination}】,重新进入入库线体取料箱");
                }
            }
            switch (MoveInfo.MoveStep)
            {
                case RunStep.Wait:

                    if (targetIsCurPos)
                    {
                        MoveInfo.NextMoveStep(RunStep.Instore_TakeBoxFromLine_02_AtSrc);
                        MoveInfo.Info($"已在【{DstName}】【{destination}】");
                        return;
                    }
                    if (!CalcDst())
                    {
                        Msg.add($"规划去【{DstName}】失败,请检查", MsgLevel.warning);
                        return;
                    }
                    MoveInfo.NextMoveStep(RunStep.Instore_TakeBoxFromLine_01_MoveToSrc);
                    MoveInfo.Info($"去【{DstName}】【{destination}】");
                    break;
                case RunStep.Instore_TakeBoxFromLine_01_MoveToSrc:
                    if (IsFinished)
                    {
                        MoveInfo.NextMoveStep(RunStep.Instore_TakeBoxFromLine_02_AtSrc);
                        MoveInfo.Info($"到达【{DstName}】【{destination}】");
                    }
                    else
                    {
                        Move();
                    }
                    break;

                case RunStep.Instore_TakeBoxFromLine_02_AtSrc:
                    if (CurTask != null)
                    {
                        TaskManager.SetTaskState(CurTask, RobotTaskState.执行中);
                        MoveInfo.NextMoveStep(RunStep.Instore_TakeBoxFromLine_03_RequestLeave);
                        setBoxCode(CurTask.BoxCode);
                        UpdateLocInfo(TaskStatus.EXECUTING, SmfTaskType.Instore);
                        RequestLeave();
                        MoveInfo.Info($"请求取料箱【{boxCode}】");
                        return;
                    }

                    if (TaskManager.HasInstoreBoxReady(out RobotTask robotTask))
                    {
                        CurTask = robotTask;
                        TaskManager.SetTaskState(robotTask, RobotTaskState.执行中);
                        var dstPosInfo = PosInfos.GetPosInfoByName(CurTask.DestPoint);
                        if (dstPosInfo != null)
                        {
                            if (TaskUtil.disabledLancode.Contains(dstPosInfo.Lanway))
                            {
                                Msg.add($"【{DstName}】处的料箱【{boxCode}】所在库位巷道【{dstPosInfo.Lanway}】被屏蔽,请手动处理", MsgLevel.warning);
                                return;
                            }
                        }

                        MoveInfo.NextMoveStep(RunStep.Instore_TakeBoxFromLine_03_RequestLeave);
                        setBoxCode(CurTask.BoxCode);
                        UpdateLocInfo(TaskStatus.EXECUTING, SmfTaskType.Instore);
                        RequestLeave();
                        MoveInfo.Info($"请求取料箱【{boxCode}】");
                    }
                    else if (MoveInfo.IsTimeOut(ctuWaitSeconds)) //超时未等到下一个任务
                    {
                        if (ctu.AllBasketIsEmpty())
                        {
                            ctu.CtuTask = null;
                            MoveInfo.Info($"背篓为空,等待[{ctuWaitSeconds}s]超时无下一入库任务,结束");
                        }
                        else //有背篓不为空
                        {
                            MoveInfo.Info($"背篓不为空,等待[{ctuWaitSeconds}s]超时无下一入库任务");
                            var task = OutTaskHelper.GetNearestPutBoxToShelfTask(ctu, out _);
                            if (task != null)
                            {
                                ctu.CtuTask = task;
                                MoveInfo.Info($"找到任务【{task.Name}】【{task.DstName}】【{task.destination}】");
                                return;
                            }
                            task = new StandbyTask(ctu);
                            ctu.CtuTask = task;
                            MoveInfo.Info($"未找到入库任务,去待命点【{task.Name}】【{task.DstName}】【{task.destination}】");
                        }
                    }
                    break;

                case RunStep.Instore_TakeBoxFromLine_03_RequestLeave:
                    if (TaskManager.InstoreBoxReady(boxCode))
                    {
                        MoveInfo.NextMoveStep(RunStep.Instore_TakeBoxFromLine_04_GetContainer);
                        ShelfOrEquipToBasket();
                        MoveInfo.Info($"取料箱【{boxCode}】");
                    }
                    else
                    {
                        Msg.add($"等待料箱【{boxCode}】到达", MsgLevel.info);
                    }
                    break;
                case RunStep.Instore_TakeBoxFromLine_04_GetContainer:
                    if (IsFinished)
                    {
                        MoveInfo.NextMoveStep(RunStep.Instore_TakeBoxFromLine_05_FinishLeave);
                        FinishLeave();
                        MoveInfo.Info($"取料箱【{boxCode}】完成");
                    }
                    break;

                case RunStep.Instore_TakeBoxFromLine_05_FinishLeave:
                    if (Complete())
                    {
                        MoveInfo.NextMoveStep(RunStep.Instore_TakeBoxFromLine_06_CheckComplete);
                        MoveInfo.Info("收到Complete,出料完成");
                    }
                    else
                    {
                        Msg.add($"等待料箱【{boxCode}】放入线体通知完成", MsgLevel.info);
                    }
                    break;

                case RunStep.Instore_TakeBoxFromLine_06_CheckComplete:
                    if (UpdateLocInfo(TaskStatus.IN_ON_AGV, SmfTaskType.Instore))
                    {
                        MoveInfo.NextMoveStep(RunStep.Instore_TakeBoxFromLine_07_UpdateContainerLoc);
                        MoveInfo.Info($"料箱【{boxCode}】放入背篓完成"); ;
                        UpdateBoxLoc(GenCtuLoc());
                        MoveInfo.Info($"上报已从【{DstName}】取料箱【{boxCode}】");
                    }
                    else
                    {
                        Msg.add($"等待料箱【{boxCode}】放入背篓通知完成", MsgLevel.info);
                    }
                    break;

                case RunStep.Instore_TakeBoxFromLine_07_UpdateContainerLoc:
                    MoveInfo.NextMoveStep(RunStep.CtuTask_ProcessFinished);
                    break;
                case RunStep.CtuTask_ProcessFinished:
                    if (ctu.HasEmptyBasket())
                    {
                        ctu.CtuTask = new TakeBoxFromLineTask(ctu);
                        MoveInfo.Info($"等待下一空箱入库任务");
                    }
                    else //无空背篓
                    {
                        var task = OutTaskHelper.GetNearestPutBoxToShelfTask(ctu, out _);
                        if (task != null)
                        {
                            ctu.CtuTask = task;
                            MoveInfo.Info($"无空余背篓,去放空箱");
                        }
                        else
                        {
                            ctu.CtuTask = new StandbyTask(ctu);
                            MoveInfo.Info($"无空余背篓,未找到去放空箱,去待机点");
                        }
                    }
                    break;
            }

        }
        //protected override bool FindNearInTaskInPath()
        //{
        //    var pointCodes = new List<PointCode>(planedPoints);
        //    var map = new Dictionary<int, byte>();//key=编号,value=层
        //    foreach (var item in ctu.Baskets)
        //    {
        //        if (string.IsNullOrEmpty(item.BoxCode)) continue;
        //        if (item.BoxCode == boxCode) continue;
        //        if (string.IsNullOrEmpty(item.DstName))
        //        {
        //            if (SMFManager.GetBoxTarget(item.BoxCode, out string dst))
        //            {
        //                item.DstName = dst;
        //            }
        //            else
        //            {
        //                continue;
        //            }
        //        }
        //        var pos = PosInfos.GetPosInfoByName(item.DstName);
        //        if (pos != null)
        //        {
        //            if (pos.Name == pos.ShelveCode)//库位号
        //            {
        //                var findIdx = pointCodes.FindIndex(s => s.Id.Equals(pos.PointCode));
        //                if (findIdx != -1)
        //                {
        //                    map[findIdx] = item.Row;
        //                }
        //            }
        //        }
        //    }
        //    if (map.Count > 0)
        //    {
        //        var minIdx = map.Keys.Min();
        //        var basket = ctu.GetBasket(map[minIdx]);
        //        CurTask = TaskManager.GenRobotTask(basket);
        //        setBoxCode(basket.BoxCode);
        //        setDstName(basket.DstName);
        //        CalcDst();
        //        return true;
        //    }
        //    return false;
        //}
        //protected override bool FindNearOutTaskInPath()
        //{
        //    var pointCodes = new List<PointCode>(planedPoints);
        //    var outTask = TaskUtil.Outlet_GetNearestOutBoxInPath(pointCodes);

        //    if (outTask != null)
        //    {
        //        CurTask = TaskManager.GenRobotTask(outTask);
        //        setBoxCode(CurTask.BoxCode);
        //        setDstName(CurTask.SrcPoint);
        //        CalcDst();
        //        return true;
        //    }
        //    return false;
        //}
    }
}