using ServiceCenter.Extensions; using ServiceCenter.Logs; using ServiceCenter.SqlSugars; using System.ComponentModel; using WCS.Core; using WCS.Entity; using WCS.Entity.Protocol.Protocol.BCR; using WCS.Entity.Protocol.Protocol.RGV; using WCS.Entity.Protocol.Protocol.Robot; using WCS.Entity.Protocol.Protocol.Station; using WCS.Entity.Protocol.Protocol.Truss; using WCS.WorkEngineering.Extensions; using WCS.WorkEngineering.Worlds; using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags; using TaskStatus = WCS.Entity.TaskStatus; namespace WCS.WorkEngineering.Systems { /// /// Agv交互系统 /// [BelongTo(typeof(MainWorld))] [Description("RGV交互系统")] public class RGVSystems : DeviceSystem> { protected override bool ParallelDo => true; protected override bool SaveLogsToFile => true; /// /// 取货点设备集合 /// private readonly Dictionary>> _pickUpDevices = new(); public RGVSystems() { //获取所有的巷道集合 var rgvList = Device.All.Where(v => v.HasFlag(DeviceFlags.RGV)); foreach (var rgv in rgvList) { _pickUpDevices.Add(rgv.Code, rgv.Sources.Where(v => v.HasFlag(DeviceFlags.输送机)).Select(v => new Device(v, this.World)).ToList()); } } public override void Do(Device obj) { if (obj.Data.VoucherNo != obj.Data2.VoucherNo) throw new KnownException($"凭证号不一致,DB520:{obj.Data.VoucherNo}-DB521:{obj.Data2.VoucherNo}", LogLevelEnum.High); if (obj.Data2.WorkMode != RGVWorkMode.Automatic) return; if (obj.Data.RES1 == 1) return; //wcs任务完成确认信号未清除 if (obj.Data2.Status.HasFlag(RGVStatus.Taskfinishi)) { switch (obj.Data2.CmdType) { case RGVCmdType.PickGoods: //单独取货任务完成,默认只有空托盘才会下发单独取货任务 //开始申请读码信息 var bcrCode = obj.Data3.GetBCRCode(); int taskNumber = 0; SqlSugarHelper.Do(_db => { var db = _db.Default; var dev = Device.All.First(x => x.Code == obj.Data2.StartPosition.ToString()); if (dev.HasFlag(DeviceFlags.拆盘机09)) { //开始绑定任务,并下发新的任务信息到小车 WCS_Palletizing palletizingInfo = db.Queryable().Single(x => x.Id == obj.Data2.TaskNumber); if (palletizingInfo == null) return; palletizingInfo.PalleCode = bcrCode; db.Updateable(palletizingInfo).ExecuteCommand(); taskNumber = palletizingInfo.Id; } else if (dev.HasFlag(DeviceFlags.拆盘机非09)) { //开始处理对应的搬运任务信息 var task = db.Queryable().First(x => x.Type == TaskType.Delivery && x.ID == obj.Data2.TaskNumber && x.AddrTo == obj.Data2.DestPosition.ToString()); task.BarCode = bcrCode; db.Updateable(task).ExecuteCommand(); task.AddWCS_TASK_DTL(db, obj.Entity.Code, obj.Data2.DestPosition.ToString(), $"环形库码垛位{obj.Data2.DestPosition}搬运任务绑定条码信息{bcrCode}"); taskNumber = task.ID; } }); if (taskNumber == 0) return; //清空起始点信息 var staDev = new Device(Device.All.FirstOrDefault(x => x.Code == obj.Data2.DestPosition.ToString())!, World); staDev.Data.TaskNumber = 0; staDev.Data.GoodsStart = 0; staDev.Data.GoodsEnd = 0; obj.Data2.TaskNumber = taskNumber; obj.Data.RES1 = 1; break; case RGVCmdType.PutGoods: WCS_TaskInfo finishiTask = null; var startPosition = Device.All.Where(x => x.Code == obj.Data2.StartPosition.ToString()).Select(x => new Device(x, World)).FirstOrDefault(); var destPosition = Device.All.FirstOrDefault(x => x.Code == obj.Data2.DestPosition.ToString()); var isPalletizing = destPosition!.HasFlag(DeviceFlags.桁架码垛位, DeviceFlags.环形库码垛工位); short countQty = 0; short shortCode = 0; SqlSugarHelper.Do(_db => { var db = _db.Default; if (isPalletizing) { if (destPosition.HasFlag(DeviceFlags.桁架码垛位)) { var palletizingInfo = db.Queryable().First(x => x.Id == obj.Data.TaskNumber); countQty = palletizingInfo.CountQty.ToShort(); shortCode = palletizingInfo.ShortCode; } else if (destPosition.HasFlag(DeviceFlags.环形库码垛工位)) { var deliveryTask = db.Queryable().First(x => x.ID == obj.Data.TaskNumber); countQty = deliveryTask.FullQty; shortCode = deliveryTask.PalletType; deliveryTask.Status = TaskStatus.RgvCompleted; deliveryTask.EditTime = DateTime.Now; deliveryTask.LastInteractionPoint = obj.Entity.Code; db.Updateable(deliveryTask).ExecuteCommand(); deliveryTask.AddWCS_TASK_DTL(db, deliveryTask.AddrTo, $"RGV任务执行结束"); } } }); //初始化起始点信息 startPosition.Data.TaskNumber = 0; startPosition.Data.GoodsEnd = 0; //目标地址是码垛工位 if (isPalletizing) { if (destPosition.HasFlag(DeviceFlags.桁架码垛位)) { var dest = new Device(destPosition!, World); dest.Data.MaxQuantity = countQty; dest.Data.Type = shortCode; dest.Data.VoucherNo++; } else if (destPosition.HasFlag(DeviceFlags.环形库码垛工位)) { var dest = new Device(destPosition!, World); dest.Data.MaxQuantity = countQty; dest.Data.Type = shortCode; dest.Data.VoucherNo++; } } obj.Data.RES1 = 1; break; case RGVCmdType.Move: obj.Data.RES1 = 1; break; case RGVCmdType.ChangePutGoods: break; case RGVCmdType.ChangePickGoods: break; case RGVCmdType.PickPutGoods: staDev = new Device(Device.All.FirstOrDefault(x => x.Code == obj.Data.DestPosition.ToString())!, World); staDev.Data.TaskNumber = 0; staDev.Data.GoodsStart = 0; staDev.Data.GoodsEnd = 0; obj.Data.RES1 = 1; break; default: throw new ArgumentOutOfRangeException(); } return; } if (obj.Data2.SystemStatus != RGVSystemStatus.空闲) return; if (obj.Data2.Status.HasFlag(RGVStatus.RES1)) { obj.Data.TaskNumber = obj.Data.TaskNumber; obj.Data.CmdType = RGVCmdType.Move; obj.Data.DestPosition = 1668; obj.Data.VoucherNo++; return; } if (obj.Data2.CmdType == RGVCmdType.PickGoods && !obj.Data2.Status.HasFlag(RGVStatus.Taskfinishi)) { if (obj.Data2.Status.HasFlag(RGVStatus.PH_Status)) { obj.Data.TaskNumber = obj.Data.TaskNumber; obj.Data.CmdType = RGVCmdType.PutGoods; obj.Data.StartPosition = obj.Data2.StartPosition; obj.Data.DestPosition = obj.Data2.DestPosition; obj.Data.VoucherNo++; return; } } var pickUpDevices = _pickUpDevices.FirstOrDefault(x => x.Key == obj.Entity.Code).Value; //有货且需要搬运货物的站台 var devs = pickUpDevices.Where(v => v.Data3.Status.HasFlag(StationStatus.PH_Status) && v.Data.TaskNumber != 0) .Where(v => v.Entity.Code.ToShort() != v.Data.GoodsEnd && v.Data.GoodsEnd != 0) .ToList(); //筛选出目标站台无货的站台 var putDev = obj.Entity.Targets.Where(x => x.HasFlag(DeviceFlags.输送机)) .Select(x => new Device(x, World)) .Where(x => !x.Data3.Status.HasFlag(StationStatus.PH_Status)) .Select(x => x.Entity.Code.ToShort()); var dev = devs.OrderBy(x => x.Entity.Code).FirstOrDefault(x => putDev.Contains(x.Data.GoodsEnd)); if (dev == null) return; //区分任务是拆盘机到码垛工位,还是码垛工位到拆盘机 if (dev.Entity.HasFlag(DeviceFlags.拆盘机09, DeviceFlags.拆盘机非09)) { obj.Data.TaskNumber = dev.Data.TaskNumber; obj.Data.CmdType = RGVCmdType.PickGoods; obj.Data.StartPosition = dev.Entity.Code.ToShort(); obj.Data.DestPosition = dev.Data.GoodsEnd; obj.Data.VoucherNo++; } else //非拆盘机起始任务 { //站台中的任务号 WCS_TaskInfo task = null; SqlSugarHelper.Do(_db => { var db = _db.Default; var taskInfo = db.Queryable().First(p => p.ID == dev.Data.TaskNumber && p.Status == TaskStatus.WaitingToExecute); if (taskInfo == null) return; taskInfo.Status = TaskStatus.RgvExecution; taskInfo.AddrNext = obj.Entity.Code; taskInfo.EditWho = "WCS"; taskInfo.EditTime = DateTime.Now; ; db.Updateable(taskInfo).ExecuteCommand(); taskInfo.AddWCS_TASK_DTL(db, dev.Entity.Code, obj.Entity.Code, $"任务分配至{obj.Entity.Code}"); task = taskInfo; }); if (task == null) return; obj.Data.TaskNumber = task.ID; obj.Data.CmdType = RGVCmdType.PickPutGoods; obj.Data.StartPosition = dev.Entity.Code.ToShort(); obj.Data.DestPosition = dev.Data.GoodsEnd; obj.Data.VoucherNo++; } } public override bool Select(Device dev) { return dev.Code == "RGV1"; //return dev.HasFlag(Extensions.DeviceFlags.RGV); } } }