AGVExtensions.cs 5.01 KB
using RCS.Model.Comm;
using RCS.Model.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static RCS.Model.Comm.EnumMsg;
namespace RCS.WinClient.Common;


public static class AGVExtensions
{


    #region AGV通用
    /// <summary>
    /// 判断车是否能接任务
    /// </summary>
    /// <param name="agv"></param>
    /// <returns></returns>
    public static bool IsCanExecTask(this Base_Agv agv)
    {
        var agvPoint = App.PointList.FirstOrDefault(x => x.Barcode == agv.Barcode);
        if (agvPoint == null)
        {
            return false;
        }

        //只有在 站台附属点、充电桩、出库区才能接任务
        if (agv.AgvType == AgvType.叉车 && agvPoint.PointType == EnumMsg.PointType.站台点)
        {
            agv.StopReason = ComnMethod.GetStopReason(agv.StopReason, $"AGV在【站台点】不能接任务!");
            return false;
        }

        if (IsFree(agv) && agv.Voltage > App.GetKeyValue("DangerCharge"))
        {
            return true;
        }
        return false;
    }

    /// <summary>
    /// agv是否正常
    /// </summary>
    /// <param name="agv"></param>
    /// <returns></returns>
    public static bool IsNormal(this Base_Agv agv)
    {
        if (agv != null
            && agv.IsOnline
            && agv.IsEnable
            && string.IsNullOrWhiteSpace(agv.StopReason)
            && string.IsNullOrWhiteSpace(agv.Error))
            return true;
        return false;
    }

    /// <summary>
    /// agv是否空闲
    /// </summary>
    /// <param name="agv"></param>
    /// <returns></returns>
    public static bool IsFree(this Base_Agv agv)
    {

        if (IsNormal(agv)
                   && agv.AgvState == EnumMsg.AGVState.自动空闲

                   && !App.OffAgvNos.Contains(agv.AgvNo)//待关机车辆不属于空闲
                   
                   && !App.TaskList.Any(t => t.TaskAgvNo == agv.AgvNo)//任务可能事先分配

                   && agv.IsNotHaveGoods()

                   && agv.AgvTask == null
                   //非叉车只能低位接任务
                   && (agv.AgvType == AgvType.叉车 || agv.AgvType != AgvType.叉车 && agv.HeightState == HeightState.低位) 
                   )
            return true;
        return false;
    }

    /// <summary>
    /// 全部无货
    /// 或者有货但是agv在站台且处于低位就判定为无货
    /// </summary>
    /// <returns></returns>
    public static bool IsNotHaveGoods(this Base_Agv agv)
    {

        return !agv.SensorStatus.HasFlag(SensorStatus.车顶有货)
               //顶升式agv在站台底下存在误检测可能
               || (agv.AgvType != AgvType.叉车 && agv.SensorStatus.HasFlag(SensorStatus.车顶有货)
                    && App.StationList.Exists(station => station.Barcode == agv.Barcode)
                    && agv.HeightState == HeightState.低位);
    }

    public static Base_SubTask? GetCurrSonTask(this Base_Agv agv)
    {

        var sonTask = agv
            ?.AgvTask
            ?.SubTaskList
            ?.Get(0);

        return sonTask;
    }


    public static bool IsOnPoint(this Base_Agv agv, out Base_Point? point, int error = 25)
    {
        point = App.PointList.Find(x => ComnMethod.IsOnPoint(x, agv.XLength, agv.YLength, error));
        return point != null;
    }



    public static bool IsInMap(this Base_Agv agv, double? tempX = null, double? tempY = null)
    {
        try
        {
            var agvPoint = new Base_Point()
            {
                XLength = (int)(tempX ?? agv.XLength),
                YLength = (int)(tempY ?? agv.YLength)
            };
            var task = agv.AgvTask;
            var sonTask = task?.SubTaskList?.FirstOrDefault();
            if (
                task == null
                || sonTask == null
                || sonTask.SubTaskState <= SubTaskState.建立路径失败
                || sonTask.PathPointList.Count == 0
                )
                return false;
            var pathList = sonTask.PathPointList;
            //任务中点位刷新不及时,当前点实际为上一个点
            var lastPoint = App.PointList.Find(x => x.Barcode == agv.Barcode);
            if (lastPoint == null)
                return false;
            var nextPathPoint = ComnMethod.GetNextPathPoint(agv, agv.Barcode);
            if (nextPathPoint == null)
                return false;

            var res = agvPoint.IsOnLineSegment(lastPoint, nextPathPoint.Point);
            if (!res)
                return false;
            App.ExFile.MessageLog("Motions", $"agv:{agv.AgvNo}在执行{agv.AgvTask?.TaskType}任务{agv.AgvTask?.TaskNo}:{sonTask.TaskNo}的子任务:{sonTask?.SubTaskNo}时agv不在点位上,但是在地图中{agv.Barcode},{agvPoint.IntX},{agvPoint.IntY}");

            return true;
        }
        catch (Exception ex)
        {

            App.ExFile.MessageError("IsInMap", ex.Message + ex.StackTrace);
            return false;
        }
    }

    #endregion


}