|
@@ -96,31 +96,31 @@ namespace WCS.Service.Works.RGV
|
|
|
//11号站台是取货点,但不是待命点,如需取货,从九号站台调车
|
|
|
//2号站台是一个待命点,但是为了保证入库取货效率,所有后面会跟一个车
|
|
|
//如果3号站台的小车拦住了后一个小车的放货任务,检测一次最近的空车距离值,如果大于或等于618500并且小于被拦住小车的位置值再进行调车,用于避免无效空跑
|
|
|
- obj.EX(obj =>
|
|
|
+ obj.EX(rgvDevice =>
|
|
|
{
|
|
|
- if (obj.Data2.Trigger_1 != obj.Data.Trigger_1) throw new WarnException($"等待执行任务{obj.Data2.TaskID_1}--{obj.Data2.TaskID_2}");
|
|
|
- if (obj.Data2.WorkMode != RGVMode.自动) throw new DoException(obj.Data2.WorkMode.ToString());
|
|
|
- if (obj.Data2.SystemStatus != RGVRunStatus.空闲) throw new DoException(obj.Data2.SystemStatus.ToString());
|
|
|
+ if (rgvDevice.Data2.Trigger_1 != rgvDevice.Data.Trigger_1) throw new WarnException($"等待执行任务{rgvDevice.Data2.TaskID_1}--{rgvDevice.Data2.TaskID_2}");
|
|
|
+ if (rgvDevice.Data2.WorkMode != RGVMode.自动) throw new DoException(rgvDevice.Data2.WorkMode.ToString());
|
|
|
+ if (rgvDevice.Data2.SystemStatus != RGVRunStatus.空闲) throw new DoException(rgvDevice.Data2.SystemStatus.ToString());
|
|
|
//RGV当前是否刚刚完成取货任务,等待放货
|
|
|
- if (obj.IsPut())
|
|
|
+ if (rgvDevice.IsPut())
|
|
|
{
|
|
|
- if (!obj.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.光电)) throw new WarnException("RGV无光电,无法放货,请检查实际情况");
|
|
|
+ if (!rgvDevice.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.光电)) throw new WarnException("RGV无光电,无法放货,请检查实际情况");
|
|
|
//取小车上的任务
|
|
|
DB.Do(db =>
|
|
|
{
|
|
|
- List<int> taskids = new List<int>() { obj.Data2.TaskID_1, obj.Data2.TaskID_2 };
|
|
|
+ var taskids = new List<int>() { rgvDevice.Data2.TaskID_1, rgvDevice.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).Create<StationDeviceGroup>();
|
|
|
- obj.Put(destStation, obj.Data2.TaskID_1, obj.Data2.TaskID_2);
|
|
|
+ var destStation = Device.Find(tasks.FirstOrDefault()!.ADDRNEXT).Create<StationDeviceGroup>();
|
|
|
+ rgvDevice.Put(destStation, rgvDevice.Data2.TaskID_1, rgvDevice.Data2.TaskID_2);
|
|
|
});
|
|
|
return;
|
|
|
}
|
|
|
//当前有rgv的取货站台
|
|
|
- var pickStation = obj.CurrentStation();
|
|
|
+ var pickStation = rgvDevice.CurrentStation();
|
|
|
//RGV是否在任何一个站台
|
|
|
if (pickStation != null)
|
|
|
{
|
|
@@ -135,9 +135,9 @@ namespace WCS.Service.Works.RGV
|
|
|
//开始下达取货任务
|
|
|
DB.Do(db =>
|
|
|
{
|
|
|
- if (obj.Data2.TaskType_1 != RGVTaskType.移动) throw new WarnException($"RGV正在执行{obj.Data2.TaskType_1}");
|
|
|
- if (obj.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.光电)) throw new WarnException("RGV有光电,无法取货,请检查实际情况");
|
|
|
- if (!obj.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.RGV到站)) throw new WarnException("RGV无到站状态,请检查RGV实际状态");
|
|
|
+ if (rgvDevice.Data2.TaskType_1 != RGVTaskType.移动) throw new WarnException($"RGV正在执行{rgvDevice.Data2.TaskType_1}");
|
|
|
+ if (rgvDevice.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.光电)) throw new WarnException("RGV有光电,无法取货,请检查实际情况");
|
|
|
+ if (!rgvDevice.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.RGV到站)) throw new WarnException("RGV无到站状态,请检查RGV实际状态");
|
|
|
|
|
|
var taskids = devs.Select(v => v.Data2.Tasknum);
|
|
|
var tasks = db.Default.Set<WCS_TASK>().Where(p => taskids.Contains(p.ID));
|
|
@@ -149,25 +149,38 @@ namespace WCS.Service.Works.RGV
|
|
|
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}目标地址不一致");
|
|
|
+ if (gw1.Data2.Goodsend != gw2.Data2.Goodsend) throw new WarnException($"{rgvDevice.Entity.CODE}目标地址不一致");
|
|
|
}
|
|
|
- obj.Data.TaskID_1 = gw1.Data2.Tasknum;
|
|
|
- obj.Data.TaskID_2 = gw2.Data2.Tasknum;
|
|
|
- obj.Data.TaskType_1 = RGVTaskType.取货;
|
|
|
- obj.Data.DestPosition_1 = pickStation.Entity.CODE.Replace("G", "").ToShort();
|
|
|
+ rgvDevice.Data.TaskID_1 = gw1.Data2.Tasknum;
|
|
|
+ rgvDevice.Data.TaskID_2 = gw2.Data2.Tasknum;
|
|
|
+ rgvDevice.Data.TaskType_1 = RGVTaskType.取货;
|
|
|
+ rgvDevice.Data.DestPosition_1 = pickStation.Entity.CODE.Replace("G", "").ToShort();
|
|
|
|
|
|
- obj.Data.Trigger_1++;
|
|
|
+ rgvDevice.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}]";
|
|
|
+ var msg = $"下达从{rgvDevice.Data.StartPosition_1}移动至{rgvDevice.Data.DestPosition_1}的RGV PLC指令。";
|
|
|
+ msg += $"[{task.ID}][{rgvDevice.Data.StartPosition_1}][{rgvDevice.Data.DestPosition_1}[{rgvDevice.Data.Trigger_1}]";
|
|
|
|
|
|
task.CreateStatusLog(db, msg, this.GetType());
|
|
|
}
|
|
|
});
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
+ if (rgvDevice.RGVList.Count != 6)//有小车进入维修站时启用该逻辑,避免在正常使用时影响效率
|
|
|
+ {
|
|
|
+ var station11 = rgvDevice.LocationList.Where(v => v.Entity.Is(DF.涂布RGV取货设备组)).Where(v => v.RGVGetTaskedDevice().Any())
|
|
|
+ .Where(v => v.CurrentRGV() == null).MinBy(rgvDevice.Distance);
|
|
|
+
|
|
|
+ //该站台到当前小车的范围中没有车
|
|
|
+ if (rgvDevice.RGVList.Any(v => station11!.Position <= v.Position && rgvDevice.Position > v.Position))
|
|
|
+ {
|
|
|
+ rgvDevice.Move(station11);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
else if (pickStation.Entity.CODE == "G9")
|
|
|
{
|
|
|
//九站台的小车需要额外检测一下11站台是否需要取货
|
|
@@ -175,75 +188,57 @@ namespace WCS.Service.Works.RGV
|
|
|
var station11Dev = station11.RGVGetTaskedDevice();
|
|
|
if (station11Dev != null && station11Dev.Count > 0)
|
|
|
{
|
|
|
- obj.Move(station11);
|
|
|
+ rgvDevice.Move(station11);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//找到自己的后一个小车
|
|
|
- var afterRgv = obj.After();
|
|
|
+ var afterRgv = rgvDevice.After();
|
|
|
|
|
|
//自己是否阻挡了该小车
|
|
|
- if (afterRgv.Data2.WorkMode == RGVMode.自动 && afterRgv.Data2.SystemStatus != RGVRunStatus.空闲 && obj.StopedByMe(afterRgv))
|
|
|
+ if (afterRgv.Data2.WorkMode == RGVMode.自动 && afterRgv.Data2.SystemStatus != RGVRunStatus.空闲 && rgvDevice.StopedByMe(afterRgv))
|
|
|
{
|
|
|
- if (pickStation.Entity.CODE == "G2")
|
|
|
- {
|
|
|
- //此站台因需要进行排队,因此是否需要赶车取决于是否拦住了两个小车的任务
|
|
|
- var afterRgv1 = afterRgv.After();
|
|
|
- //如果是空闲或者没有拦住他,就不执行赶车
|
|
|
- if (afterRgv1.Data2.WorkMode == RGVMode.自动 && (afterRgv1.Data2.SystemStatus == RGVRunStatus.空闲 || !afterRgv.StopedByMe(afterRgv1))) return;
|
|
|
- }
|
|
|
- else if (pickStation.Entity.CODE == "G3")
|
|
|
+ switch (pickStation.Entity.CODE)
|
|
|
{
|
|
|
- //为了减少空跑,需要被阻拦的小车后面的小车任务类型为移动并且位置值要大于618500小于被阻拦小车的位置值
|
|
|
- var afterRgv1 = afterRgv.After();
|
|
|
- if (afterRgv1.Data2.WorkMode == RGVMode.自动 && afterRgv.Data2.TaskType_1 != RGVTaskType.移动 && !(afterRgv1.Position < afterRgv.Position && afterRgv1.Position > 618500)) return;
|
|
|
+ case "G2":
|
|
|
+ {
|
|
|
+ if (rgvDevice.RGVList.Count != 6) break;
|
|
|
+ //此站台因需要进行排队,因此是否需要赶车取决于是否拦住了两个小车的任务
|
|
|
+ var afterRgv1 = afterRgv.After();
|
|
|
+ //如果是空闲或者没有拦住他,就不执行赶车
|
|
|
+ if (afterRgv1.Data2.WorkMode == RGVMode.自动 && (afterRgv1.Data2.SystemStatus == RGVRunStatus.空闲 || !afterRgv.StopedByMe(afterRgv1))) return;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case "G3":
|
|
|
+ {
|
|
|
+ //为了减少空跑,需要被阻拦的小车后面的小车任务类型为移动并且位置值要大于618500小于被阻拦小车的位置值
|
|
|
+ var afterRgv1 = afterRgv.After();
|
|
|
+ if (afterRgv1.Data2.WorkMode == RGVMode.自动 && afterRgv.Data2.TaskType_1 != RGVTaskType.移动 && !(afterRgv1.Position < afterRgv.Position && afterRgv1.Position > 618500)) return;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
//找到当前所在站台的下一个取货点
|
|
|
var beforeStation = Device.Where(v => v.Is(DF.涂布RGV取货设备组) && v.CODE != pickStation.Entity.CODE)
|
|
|
- .Select(v => v.Create<StationDeviceGroup>())
|
|
|
- .OrderBy(v => pickStation.Distance(v))
|
|
|
- .FirstOrDefault();
|
|
|
+ .Select(v => v.Create<StationDeviceGroup>()).MinBy(v => pickStation.Distance(v));
|
|
|
|
|
|
//写入移动任务
|
|
|
- obj.Move(beforeStation);
|
|
|
+ rgvDevice.Move(beforeStation);
|
|
|
return;
|
|
|
}
|
|
|
- else if (pickStation.Entity.CODE == "G11")
|
|
|
+
|
|
|
+ if (pickStation.Entity.CODE == "G11")
|
|
|
{
|
|
|
- obj.Move(Device.Find("G2").Create<StationDeviceGroup>());
|
|
|
+ rgvDevice.Move(Device.Find("G2").Create<StationDeviceGroup>());
|
|
|
return;
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- //找到自己前面的 有货 没有小车 没有正在过来的小车 距离自己最近的 的站台
|
|
|
- var station = Device.Where(v => v.Is(DF.涂布RGV取货设备组))
|
|
|
- .Select(v => v.Create<StationDeviceGroup>())
|
|
|
- .Where(v => v.Position > obj.Position) //前面的
|
|
|
- .Where(v => v.CurrentRGV() == null)
|
|
|
- .Where(v => !v.RgvList.Any(c => c.Data2.SystemStatus != RGVRunStatus.空闲 && c.Data2.DestPosition_1 == v.Entity.CODE.GetShortCode()))
|
|
|
- .Where(v =>
|
|
|
- {
|
|
|
- // 筛选出有任务号和起始及目标地址的设备
|
|
|
- var b = pickStation.RGVGetTaskedDevice();
|
|
|
- //是否需要取货
|
|
|
- if (b != null && b.Count > 0) return true;
|
|
|
- else return false;
|
|
|
- })
|
|
|
- .OrderBy(v => obj.Distance(v)).FirstOrDefault();//取当前小车最近
|
|
|
- if (obj.Data2.TaskType_1 == RGVTaskType.移动 && obj.Distance(station) > 100000)
|
|
|
- {
|
|
|
- obj.Move(station);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
//是否在一个放货站台
|
|
|
if (pickStation.Entity.Is(DF.涂布RGV放货设备组))
|
|
|
{
|
|
|
- pickStation = obj.BeforeStation();
|
|
|
- obj.Move(pickStation);
|
|
|
+ pickStation = rgvDevice.BeforeStation();
|
|
|
+ rgvDevice.Move(pickStation);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
@@ -251,9 +246,9 @@ namespace WCS.Service.Works.RGV
|
|
|
//此时RGV即没有等待执行的放货任务,也不在任何一个取货点,因此需要调往最近的一个取货点
|
|
|
//找到距离这个RGV最近的一个取货点
|
|
|
//必须所有RGV都是空闲状态时才可以进行初始化
|
|
|
- if (obj.RGVList.Any(v => v.Data2.SystemStatus != RGVRunStatus.空闲)) return;
|
|
|
- pickStation = obj.BeforeStation();
|
|
|
- obj.Move(pickStation);
|
|
|
+ if (rgvDevice.RGVList.Any(v => v.Data2.SystemStatus != RGVRunStatus.空闲)) return;
|
|
|
+ pickStation = rgvDevice.BeforeStation();
|
|
|
+ rgvDevice.Move(pickStation);
|
|
|
});
|
|
|
}
|
|
|
|