Selaa lähdekoodia

debug:涂布环穿

林豪 左 3 vuotta sitten
vanhempi
commit
24409aadc5

+ 37 - 11
Projects/永冠OPP/WCS.Service/Extensions/DeviceExtension.cs

@@ -336,11 +336,12 @@ namespace WCS.Service.Extensions
         /// <summary>
         /// 与当前RGV处于同一环穿的站台
         /// </summary>
-        public List<StationLocation> LocationList
+        public List<StationDeviceGroup> LocationList
         {
             get
             {
-                return StationLocation.ALLlocations.Where(v => Entity.PROTOCOLS.Any(p => p.DB.PLC.CODE == v.PLC)).ToList();
+                return StationLocation.ALLlocations.Where(v => Entity.PROTOCOLS.Any(p => p.DB.PLC.CODE == v.PLC))
+                                      .Select(v => Device.Find(v.Station).Create<StationDeviceGroup>()).ToList();
             }
         }
 
@@ -385,6 +386,15 @@ namespace WCS.Service.Extensions
             }
         }
 
+        /// <summary>
+        /// 获取前一个取货点
+        /// </summary>
+        /// <returns></returns>
+        public StationDeviceGroup BeforeStation()
+        {
+            return LocationList.Where(v => v.Entity.Is(DF.涂布RGV取货站台)).OrderBy(v => Distance(v)).FirstOrDefault();
+        }
+
         /// <summary>
         /// 前一个RGV
         /// </summary>
@@ -412,6 +422,21 @@ namespace WCS.Service.Extensions
             return rgv;
         }
 
+        /// <summary>
+        /// 获取当前所在的取货站台
+        /// </summary>
+        /// <returns></returns>
+        public StationDeviceGroup CurrentStation()
+        {
+            return LocationList.Where(v => v.Entity.Is(DF.涂布RGV取货站台)).Where(v =>
+            {
+                //RGV与站台距离误差为 正负50500
+                var max = v.Position + 500;
+                var min = v.Position - 500;
+                return Data2.Position < max && Data2.Position > min;
+            }).FirstOrDefault();
+        }
+
         /// <summary>
         /// 计算当前RGV与指定RGV之间的距离
         /// </summary>
@@ -423,7 +448,7 @@ namespace WCS.Service.Extensions
         }
 
         /// <summary>
-        /// 计算当前RGV与指定RGV之间的距离
+        /// 计算当前RGV与指定R站台之间的距离
         /// </summary>
         /// <param name="after"></param>
         /// <returns></returns>
@@ -433,11 +458,16 @@ namespace WCS.Service.Extensions
         }
 
         /// <summary>
-        /// 是否可用
+        /// 是否需要执行放货任务
         /// </summary>
         /// <returns></returns>
-        public bool Valid()
+        public bool IsPut()
         {
+            if (Data2.TaskType_1 != RGVTaskType.取货) return false;
+            if (!Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.RGV到站)) return false;
+            if (!Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.任务完成)) return false;
+            if (!Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.任务完成)) return false;
+            if (!Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.光电)) return false;
             return true;
         }
 
@@ -512,12 +542,8 @@ namespace WCS.Service.Extensions
         public StationDeviceGroup NextStation()
         {
             //先取当前RGV与所有站台的距离
-            var dev = LocationList.OrderBy(v =>
-            {
-                var dev = Device.Find(v.Station).Create<StationDeviceGroup>();
-                return dev.Distance(this);
-            }).FirstOrDefault();
-            return Device.Find(dev.Station).Create<StationDeviceGroup>(); ;
+            var dev = LocationList.OrderBy(v => v.Distance(this)).FirstOrDefault();
+            return dev;
         }
     }
 

+ 4 - 0
Projects/永冠OPP/WCS.Service/Worker.cs

@@ -104,6 +104,10 @@ namespace WCS.Service
                 Device.AddFlag(DF.涂布RGV取货站台, "G2", "G3", "G5", "G7", "G9", "G11");
                 Device.AddFlag(DF.涂布RGV放货站台, "G1", "G4", "G6", "G8", "G10");
                 Device.AddFlag(DF.拉膜RGV, "RGV1", "RGV2", "RGV3", "RGV4", "RGV5", "RGV6", "RGV7");
+                //Device.AddFlag(DF.涂布出库取货站台, "G5", "G7", "G9", "G11");
+                //Device.AddFlag(DF.涂布入库取货站台, "G2", "G3");
+                Device.AddFlag(DF.涂布出库取货站台, "1285", "1286", "1294", "1295", "1303", "1304", "1312", "1313", "");
+                Device.AddFlag(DF.涂布入库取货站台, "1391", "1392", "1399", "1400");
 
                 #endregion 设备扩展数据配置
 

+ 115 - 1
Projects/永冠OPP/WCS.Service/Works/RGV/RGVWorks.cs

@@ -1,5 +1,6 @@
 using DBHelper;
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using WCS.Core;
 using WCS.Entity;
@@ -75,7 +76,120 @@ namespace WCS.Service.Works.RGV
         }
     }
 
-    [WorkTitle(typeof(RGVHandler), "涂布环穿取货")]
+    [WorkTitle(typeof(RGVHandler), "涂布环穿")]
+    public class 涂布环穿 : DeviceWork<RGVDevice>
+    {
+        protected override void Do(RGVDevice obj)
+        {
+            obj.EX(obj =>
+            {
+                if (obj.Data2.Trigger_1 != obj.Data.Trigger_1) throw new WarnException($"等待执行任务{obj.Data2.TaskID_1}{obj.Data2.TaskID_2}");
+                if (!obj.Data2.WorkMode.HasFlag(RGVMode.自动)) throw new DoException(obj.Data2.WorkMode.ToString());
+                if (!obj.Data2.SystemStatus.HasFlag(RGVRunStatus.空闲)) throw new DoException(obj.Data2.SystemStatus.ToString());
+                //RGV当前是否刚刚完成取货任务,等待放货
+                if (obj.IsPut())
+                {
+                    //取小车上的任务
+                    DB.Do(db =>
+                    {
+                        List<int> taskids = new List<int>() { obj.Data2.TaskID_1, obj.Data2.TaskID_2 };
+                        var tasks = db.Default.Set<WCS_TASK>().Where(p => taskids.Contains(p.ID));
+                        if (tasks.GroupBy(p => p.TaskGroupKey).Count() > 1)
+                            throw new WarnException("任务组ID不一致");
+                        if (!tasks.GroupBy(p => p.TaskGroupKey).Any())
+                            throw new WarnException("无任务组ID");
+                        var destStation = Device.Find(tasks.FirstOrDefault().ADDRNEXT.Replace("G", "")).Create<StationDeviceGroup>();
+                        obj.Put(destStation, obj.Data2.TaskID_1, obj.Data2.TaskID_2);
+                    });
+
+                    return;
+                }
+
+                var pickStation = obj.CurrentStation();
+                //RGV是否在任何一个取货站点
+                if (pickStation != null)
+                {
+                    // 检查取货点是否需要取货
+                    pickStation.WhetherToExecute();
+                    // 筛选出有任务号和起始及目标地址的设备
+                    var devs = pickStation.RGVGetTaskedDevice();
+                    //是否需要取货
+                    if (devs.Count > 0)
+                    {
+                        //开始下达取货任务
+                        DB.Do(db =>
+                        {
+                            var taskids = devs.Select(v => v.Data2.Tasknum);
+                            var tasks = db.Default.Set<WCS_TASK>().Where(p => taskids.Contains(p.ID));
+                            if (tasks.GroupBy(p => p.TaskGroupKey).Count() > 1)
+                                throw new WarnException("任务组ID不一致");
+                            if (!tasks.GroupBy(p => p.TaskGroupKey).Any())
+                                throw new WarnException("无任务组ID");
+                            var gw1 = pickStation.Items.ToArray()[0];
+                            var gw2 = pickStation.Items.ToArray()[1];
+                            if (gw1.Data2.Tasknum != 0 && gw2.Data2.Tasknum != 0)
+                            {
+                                if (gw1.Data2.Goodsend != gw2.Data2.Goodsend) throw new WarnException($"{obj.Entity.Code}目标地址不一致");
+                            }
+                            obj.Data.TaskID_1 = gw1.Data2.Tasknum;
+                            obj.Data.TaskID_2 = gw2.Data2.Tasknum;
+                            obj.Data.TaskType_1 = RGVTaskType.取货;
+                            if (gw1.Data2.Tasknum != 0)
+                            {
+                                obj.Data.DestPosition_1 = gw1.Data2.Goodsend;
+                            }
+                            else
+                            {
+                                obj.Data.DestPosition_1 = gw2.Data2.Goodsend;
+                            }
+                            obj.Data.Trigger_1++;
+
+                            foreach (var task in tasks)
+                            {
+                                var msg = $"下达从{obj.Data.StartPosition_1}移动至{ obj.Data.DestPosition_1}的RGV PLC指令。";
+                                msg += $"[{ task.ID}][{obj.Data.StartPosition_1}][{obj.Data.DestPosition_1}[{ obj.Data.Trigger_1}]";
+
+                                task.CreateStatusLog(db, msg, this.GetType());
+                            }
+                        });
+                        return;
+                    }
+                    //找到自己的后一个小车
+                    var afterStation = obj.After();
+                    //后面的小车是否在执行任务
+                    if (afterStation.Data2.WorkMode == RGVMode.自动 && afterStation.Data2.SystemStatus == RGVRunStatus.空闲) return;
+                    //自己是否阻挡了该小车
+                    if (obj.StopedByMe(afterStation))
+                    {
+                        //取小车的目标位置值
+                        var destStation = Device.Find($"G{afterStation.Data2.DestPosition_1}").Create<StationDeviceGroup>();
+                        //取被挡住小车的目标位置的下一个取货点
+                        var beforeSickStation = Device.Where(v => v.Is(DF.涂布RGV取货站台) && v.CODE != destStation.Entity.CODE)
+                                      .Select(v => v.Create<StationDeviceGroup>())
+                                      .OrderBy(v => destStation.Distance(v))
+                                      .FirstOrDefault();
+
+                        //写入移动任务
+                        obj.Move(beforeSickStation);
+                    }
+
+                    return;
+                }
+
+                //此时RGV即没有等待执行的放货任务,也不在任何一个取货点,因此需要调往最近的一个取货点
+                //找到距离这个RGV最近的一个取货点
+                pickStation = obj.BeforeStation();
+                obj.Move(pickStation);
+            });
+        }
+
+        protected override bool SelectDevice(WCS_DEVICE dev)
+        {
+            return dev.Is(DF.涂布RGV);
+        }
+    }
+
+    //[WorkTitle(typeof(RGVHandler), "涂布环穿取货")]
     public class 涂布环穿取货 : Work<StationDeviceGroup>
     {
         protected override void Do(StationDeviceGroup obj)

+ 95 - 0
Projects/永冠OPP/WCS.Service/Works/Station/涂布出入库.cs

@@ -0,0 +1,95 @@
+using DBHelper;
+using System.Linq;
+using WCS.Core;
+using WCS.Entity;
+using WCS.Entity.Protocol;
+using WCS.Service.Extensions;
+
+namespace WCS.Service.Works.Station
+{
+    /// <summary>
+    /// 涂布出库分配出库口
+    /// </summary>
+    //[WorkTitle(typeof(ProductHandler), "涂布出库分配出库口")]
+    public class 涂布出库分配出库口 : DeviceWork<StationDevice>
+    {
+        protected override void Do(StationDevice obj)
+        {
+            obj.EX(obj =>
+            {
+                if (!obj.Data2.Status.HasFlag(IstationStatus.光电状态)) throw new DoException("无光电");
+                if (obj.Data3.Status.HasFlag(StationStatus.运行状态位)) throw new DoException("设备运行中");
+                if (obj.Data.VoucherNo != obj.Data2.VoucherNo)
+                    throw new WarnException($"等待任务[{obj.Data2.Tasknum}]执行--凭证号不一致[{obj.Data.VoucherNo}][{obj.Data2.VoucherNo}]");
+                if (obj.Data2.Tasknum < 10000) throw new DoException("无任务");
+                if (obj.Data2.Request != IstationRequest.请求分配目标地址) throw new WarnException("有任务无请求");
+
+                DB.Do(db =>
+                {
+                    var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.TYPE == TaskType.出库 && v.SRMSTATION == obj.Entity.CODE && v.STATUS == WCS.Entity.TaskStatus.堆垛机完成);
+                    var tasks = db.Default.Set<WCS_TASK>().Where(v => v.TaskGroupKey == task.TaskGroupKey);
+                    if (tasks.Any(v => v.STATUS != WCS.Entity.TaskStatus.堆垛机完成 && v.STATUS != WCS.Entity.TaskStatus.执行中))
+                        throw new WarnException("任务异常,同组任务状态不为堆垛机完成或执行中");
+                    if (task == null) throw new WarnException("WCS无该任务信息");
+                    if (task.SRMSTATION != obj.Entity.CODE && task.STATUS != WCS.Entity.TaskStatus.堆垛机完成) throw new WarnException("任务状态不是堆垛机完成");
+                    task.STATUS = WCS.Entity.TaskStatus.执行中;
+                    db.Default.SaveChanges();
+                    task.CreateStatusLog(db, $"状态由[{WCS.Entity.TaskStatus.堆垛机完成}]变更为[{task.STATUS}]-{obj.Entity.Code}", this.GetType());
+                    //开始写入目标地址
+                    obj.Data.Tasknum = task.ID;
+                    obj.Data.Goodsstart = obj.Entity.CODE.ToShort();
+                    obj.Data.Goodsend = task.ADDRNEXT.ToShort();
+                    obj.Data.CmdType = IstationCmdType.堆垛机放货完成请求目标地址;
+                    obj.Data.VoucherNo++;
+                });
+            });
+        }
+
+        protected override bool SelectDevice(WCS_DEVICE dev)
+        {
+            return dev.Is(DF.涂布出库取货站台);
+        }
+    }
+
+    /// <summary>
+    /// 涂布出库分配AGV取货点
+    /// </summary>
+    //[WorkTitle(typeof(ProductHandler), "涂布出库分配AGV取货点")]
+    public class 涂布出库分配AGV取货点 : DeviceWork<StationDevice>
+    {
+        protected override void Do(StationDevice obj)
+        {
+            obj.EX(obj =>
+            {
+                if (!obj.Data2.Status.HasFlag(IstationStatus.光电状态)) throw new DoException("无光电");
+                if (obj.Data3.Status.HasFlag(StationStatus.运行状态位)) throw new DoException("设备运行中");
+                if (obj.Data.VoucherNo != obj.Data2.VoucherNo)
+                    throw new WarnException($"等待任务[{obj.Data2.Tasknum}]执行--凭证号不一致[{obj.Data.VoucherNo}][{obj.Data2.VoucherNo}]");
+                if (obj.Data2.Tasknum < 10000) throw new DoException("无任务");
+                if (obj.Data2.Request != IstationRequest.请求分配目标地址) throw new WarnException("有任务无请求");
+
+                DB.Do(db =>
+                {
+                    var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.TYPE == TaskType.出库 && v.SRMSTATION == obj.Entity.CODE && v.STATUS == WCS.Entity.TaskStatus.执行中);
+                    if (task == null) throw new WarnException("WCS无该任务信息");
+
+                    //全部统一分配目标地址至
+
+                    db.Default.SaveChanges();
+                    task.CreateStatusLog(db, $"状态由[{WCS.Entity.TaskStatus.堆垛机完成}]变更为[{task.STATUS}]-{obj.Entity.Code}", this.GetType());
+                    //开始写入目标地址
+                    obj.Data.Tasknum = task.ID;
+                    obj.Data.Goodsstart = obj.Entity.CODE.ToShort();
+                    obj.Data.Goodsend = task.ADDRNEXT.ToShort();
+                    obj.Data.CmdType = IstationCmdType.堆垛机放货完成请求目标地址;
+                    obj.Data.VoucherNo++;
+                });
+            });
+        }
+
+        protected override bool SelectDevice(WCS_DEVICE dev)
+        {
+            return dev.CODE == "1332" || dev.CODE == "1333";
+        }
+    }
+}

+ 2 - 2
WCS.Core/Device.cs

@@ -169,8 +169,8 @@ public enum DF
     拉膜RGV = 1 << 7,
     涂布RGV取货站台 = 1 << 8,
     涂布RGV放货站台 = 1 << 9,
-    备用5 = 1 << 10,
-    备用6 = 1 << 11,
+    涂布出库取货站台 = 1 << 10,
+    涂布入库取货站台 = 1 << 11,
     备用7 = 1 << 12,
     备用8 = 1 << 13,
     备用9 = 1 << 14,