ChargeManage.cs 10.9 KB
using RCS.Model.Comm;
using RCS.Model.Entity;
using RCS.WinClient.Common;

namespace RCS.WinClient.Service
{
    public class ChargeManager
    {
        /// <summary>
        /// 充电或是回家
        /// </summary>
        public static void AgvCharge()
        {
            try
            {
                foreach (Base_Agv agv in App.AgvList)
                {
                    //当前点不在地图中,禁止充电
                    var startPoint = App.PointList.FirstOrDefault(t => t.Barcode == agv.Barcode);
                    if (startPoint == null) continue;

                    if (!agv.IsFree() && agv.AgvState != EnumMsg.AGVState.充电中) continue;



                    if (agv.AgvState == EnumMsg.AGVState.充电中)
                    {
                        //满电结束充电
                        if (agv.Voltage >= App.GetKeyValue("FullCharge"))
                        {
                            var taskBuild = new TaskBuildDto(EnumMsg.TaskType.取消充电.ToString())
                            {
                                TaskGroup = EnumMsg.TaskGroup.RCS单步任务.ToString(),
                                AgvNo = agv.AgvNo,
                                StartBarcode = agv.Barcode,
                                EndBarcode = agv.Barcode,
                            };
                            var result = TaskManage.TaskBuild(taskBuild);
                            if (!result.IsSuccess)
                            {
                                App.ExFile.MessageBusinessErr("ChargeManager", $"生成AGV【{agv.AgvNo}】的【取消充电】任务失败,原因:{result.Message}!");
                            }
                            continue;
                        }
                        ////当前电量小于安全电量,继续充电
                        if (agv.Voltage < App.GetKeyValue("SafeCharge")) continue;
                        //如果充电时间小于最少充电时间,继续充电
                        if ((DateTime.Now - agv.ChargeTime).TotalSeconds < App.GetKeyValue("MinChargeTime")) continue;
                    }

                    //当前AGV所在群组能够执行的所有任务群组
                    var taskGroupList = App.TaskAgvGroupList.Where(t => t.AgvGroup == agv.Group).Select(t => t.TaskType).ToList();
                    ////找出任务列表中【未提交、不是指定小车、相同任务分组】的任务
                    var noSubmitTask = App.TaskList.FirstOrDefault(t => !t.IsSubmit && string.IsNullOrEmpty(t.TaskErrMsg) && string.IsNullOrEmpty(t.TaskAgvNo) && taskGroupList.Contains(t.TaskGroup));
                    if (agv.IsFree())
                    {
                        //车低于危险电量,或者低于安全电量且无任务,都去充电
                        if ((DateTime.Now - agv.FreeTime).TotalSeconds > App.GetKeyValue("MinFreeTime"))
                        {
                            if (App.TaskList.Any(t => t.TaskAgvNo == agv.AgvNo && t.TaskType == EnumMsg.TaskType.充电.ToString())) continue;
                            if (agv.Voltage <= App.GetKeyValue("DangerCharge"))
                            {
                                GoCharge(agv);
                                return;
                            }
                            if (agv.Voltage <= App.GetKeyValue("SafeCharge") && noSubmitTask == null)
                            {
                                GoCharge(agv);
                                continue;
                            }
                        }
                        //回家
                        if ((DateTime.Now - agv.FreeTime).TotalSeconds > App.GetKeyValue("GoHomeTime"))
                        {
                            //如果已经在待机点,就不处理
                            //if (App.PointList.Any(t => t.IsHomePoint(agv))) continue;
                            var currPoint = App.PointList.Find(x => x.Barcode == agv.Barcode);

                            if (currPoint != null && currPoint.IsHomePoint(agv)) continue;
                            //如果有回家任务,就不处理
                            if (App.TaskList.Any(t => t.TaskAgvNo == agv.AgvNo && t.TaskType == EnumMsg.TaskType.回家.ToString())) continue;

                            Base_Point? stopPoint = ComnMethod.GetMinHomePoint(agv);
                            if (stopPoint != null && stopPoint.Barcode != agv.Barcode)
                            {
                                var taskBuild = new TaskBuildDto
                                {
                                    TaskType = EnumMsg.TaskType.回家.ToString(),
                                    TaskGroup = EnumMsg.TaskGroup.RCS单步任务.ToString(),
                                    AgvNo = agv.AgvNo,
                                    StartBarcode = startPoint.Barcode,
                                    EndBarcode = stopPoint.Barcode,
                                };
                                var result = TaskManage.TaskBuild(taskBuild);

                                if (result.IsSuccess)
                                {
                                    App.ExFile.MessageLog("TaskBuild", $"生成AGV【{agv.AgvNo}】的【回家】任务!");
                                }
                                else
                                {
                                    var msg = $"生成【回家】任务失败,原因:{result.Message}!";
                                    App.ExFile.MessageBusinessErr("TaskBuild", msg);
                                    agv.StopReason = ComnMethod.GetStopReason(agv.StopReason, msg);
                                    return;
                                }
                            }
                        }
                    }
                    //当前AGV所属任务群组有未提交的任务,就找个车取消充电
                    if (noSubmitTask != null)
                    {
                        var agvGroupList = App.AgvList.FindAll(x => x.Group == agv.Group);

                        //判断是否有取消充电任务,已经有取消充电的任务,就不处理。有充电任务也不处理,因为会自动删除执行中的充电任务。
                        var flag = App.TaskList.Any(t => agvGroupList.Any(x => x.AgvNo == t.TaskAgvNo)
                            && (t.TaskType == EnumMsg.TaskType.取消充电.ToString()
                                || (t.TaskType == EnumMsg.TaskType.充电.ToString()
                                && agvGroupList.Find(x => x.AgvNo == t.TaskAgvNo) is Base_Agv agv1
                                && agv1.AgvType != EnumMsg.AgvType.叉车)));

                        if (flag) continue;
                        var existEnableAgv = App.AgvList.Any(t => agvGroupList.Any(x => x.Group == t.Group) && t.IsCanExecTask());
                        if (existEnableAgv) continue;
                        //找到电量最大的超过危险电量的车,来取消充电,好执行任务
                        var cancleChargeAgv = App.AgvList
                            .Where(t => t.IsEnable
                                && t.IsOnline
                                && t.AgvState == EnumMsg.AGVState.充电中
                                && t.AgvTask == null
                                && agvGroupList.Any(x => x.Group == t.Group)
                                && (DateTime.Now - t.ChargeTime).TotalSeconds > App.GetKeyValue("MinChargeTime"))
                            .OrderByDescending(a => a.Voltage)
                            .FirstOrDefault();
                        if (cancleChargeAgv != null)
                        {

                            var taskBuild = new TaskBuildDto
                            {
                                TaskType = EnumMsg.TaskType.取消充电.ToString(),
                                TaskGroup = EnumMsg.TaskGroup.RCS单步任务.ToString(),
                                AgvNo = cancleChargeAgv.AgvNo,
                                StartBarcode = cancleChargeAgv.Barcode,
                                EndBarcode = cancleChargeAgv.Barcode,
                            };
                            var result = TaskManage.TaskBuild(taskBuild);
                            if (!result.IsSuccess)
                            {
                                App.ExFile.MessageBusinessErr("ChargeManager", $"生成AGV【{agv.AgvNo}】的【取消充电】任务失败,原因:{result.Message}!");
                            }
                            continue;
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                App.ExFile.MessageError("AgvCharge", $"充电和回家发生异常,原因:{ex.Message},堆栈:{ex.StackTrace}");
            }
        }

        /// <summary>
        /// 充电
        /// </summary>
        /// <param name="agv"></param>
        /// <param name="flag"></param>
        public static bool GoCharge(Base_Agv agv, Func<Base_Agv, Base_Station?> GetChargeStation)
        {
            try
            {
                //一个车对应一个充电桩

                Base_Station? chargeStation = GetChargeStation(agv);
                if (chargeStation == null)
                {
                    App.ExFile.MessageBusinessErr("TaskBuild", $"生成AGV【{agv.AgvNo}】的【充电】任务失败,原因:未找到可用充电桩!");
                    return false;
                }


                var taskBuild = new TaskBuildDto
                {
                    TaskType = EnumMsg.TaskType.充电.ToString(),
                    TaskGroup = EnumMsg.TaskGroup.RCS单步任务.ToString(),
                    AgvNo = agv.AgvNo,
                    StartBarcode = agv.Barcode,
                    EndBarcode = chargeStation.Barcode,
                    EndStationName = chargeStation.Name,
                };
                var result = TaskManage.TaskBuild(taskBuild);
                if (result.IsSuccess)
                {
                    App.ExFile.MessageLog("TaskBuild", $"生成AGV【{agv.AgvNo}】的【充电】任务!");
                    return true;
                }
                else
                {
                    App.ExFile.MessageBusinessErr("TaskBuild", $"生成AGV【{agv.AgvNo}】的【充电】任务失败,原因:{result.Message}!");
                    return false;
                }


            }
            catch (Exception ex)
            {
                App.ExFile.MessageError("NeedCharge", ex.Message.Replace(Environment.NewLine, ""));
                return false;
            }
        }

        /// <summary>
        /// 充电
        /// </summary>
        /// <param name="agv"></param>
        /// <param name="flag"></param>
        public static bool GoCharge(Base_Agv agv)
        {
            return GoCharge(agv, ComnMethod.GetMinChargeStation);
        }
    }
}