using Autofac;
|
using Bro.Common.Base;
|
using Bro.Common.Helper;
|
using Bro.Common.Interface;
|
using Bro.Common.Model;
|
using Bro.Device.AuboRobot;
|
using Bro.Device.SeerAGV;
|
using Newtonsoft.Json;
|
using System;
|
using System.Collections.Generic;
|
using System.Collections.ObjectModel;
|
using System.ComponentModel;
|
using System.Linq;
|
using System.Threading;
|
|
namespace A032.Process
|
{
|
public enum TaskStatus
|
{
|
Available = 1,
|
Running = 2,
|
Warning = 3,
|
}
|
|
public enum TaskAvailableLevel
|
{
|
Robot = 1,
|
AGV = 2,
|
Both = 3,
|
}
|
|
public class AGVTaskModel
|
{
|
public TaskAvailableLevel Level { get; set; } = TaskAvailableLevel.Robot;
|
|
public string MethodName { get; set; }
|
|
public IOperationConfig OpConfig { get; set; }
|
|
public IDevice Device { get; set; }
|
|
//public int Priority { get; set; } = 10;
|
|
public AGVTaskModel() { }
|
|
public AGVTaskModel(TaskAvailableLevel level, string methodName, IOperationConfig opConfig = null, IDevice device = null)
|
{
|
Level = level;
|
MethodName = methodName;
|
OpConfig = opConfig ?? new OperationConfigBase();
|
Device = device;
|
}
|
}
|
|
public class AGVBindUnit : IComplexDisplay
|
{
|
#region 可编辑项目
|
[Category("设备绑定")]
|
[Description("绑定Id")]
|
[Browsable(false)]
|
public string Id { get; set; } = Guid.NewGuid().ToString();
|
|
[Category("设备绑定")]
|
[Description("绑定AGV")]
|
[TypeConverter(typeof(AGVDeviceConverter))]
|
public string AGVId { get; set; }
|
|
[Category("设备绑定")]
|
[Description("绑定Robot")]
|
[TypeConverter(typeof(RobotDeviceConverter))]
|
public string RobotId { get; set; }
|
|
[Category("设备绑定")]
|
[Description("绑定Camera")]
|
[TypeConverter(typeof(CameraDeviceConverter))]
|
public string CameraId { get; set; }
|
|
public string GetDisplayText()
|
{
|
using (var scope = GlobalVar.Container.BeginLifetimeScope())
|
{
|
ProcessConfig config = scope.Resolve<ProcessConfig>();
|
|
string agv = config.AGVConfigCollection.FirstOrDefault(u => u.ID == AGVId)?.Name ?? "未绑定AGV";
|
string robot = config.RobotConfigCollection.FirstOrDefault(u => u.ID == RobotId)?.Name ?? "未绑定机器人";
|
string camera = config.CameraConfigCollection.FirstOrDefault(u => u.ID == CameraId)?.Name ?? "未绑定相机";
|
|
return agv + "-" + robot + "-" + camera;
|
}
|
}
|
#endregion
|
|
[Browsable(false)]
|
[JsonIgnore]
|
public Action<AGVTaskModel> OnMethodInvoke { get; set; }
|
|
public string AGVDest { get; set; } = "";
|
|
private TaskStatus agvStatus = TaskStatus.Available;
|
[Browsable(false)]
|
[JsonIgnore]
|
public TaskStatus AGVStatus
|
{
|
get => agvStatus;
|
set
|
{
|
agvStatus = value;
|
//InvokeTaskCheck();
|
}
|
}
|
|
private TaskStatus robotStatus = TaskStatus.Available;
|
[Browsable(false)]
|
[JsonIgnore]
|
public TaskStatus RobotStatus
|
{
|
get => robotStatus;
|
set
|
{
|
robotStatus = value;
|
//InvokeTaskCheck();
|
}
|
}
|
|
[Browsable(false)]
|
[JsonIgnore]
|
public TaskStatus UnitStatus
|
{
|
get
|
{
|
if (AGVStatus == TaskStatus.Warning || RobotStatus == TaskStatus.Warning)
|
{
|
return TaskStatus.Warning;
|
}
|
else
|
{
|
if (AGVStatus == TaskStatus.Available && RobotStatus == TaskStatus.Available)
|
{
|
return TaskStatus.Available;
|
}
|
}
|
|
return TaskStatus.Running;
|
}
|
}
|
|
[Browsable(false)]
|
[JsonIgnore]
|
public SeerAGVDriver AGV { get; set; } = null;
|
[Browsable(false)]
|
[JsonIgnore]
|
public AuboRobotDriver Robot { get; set; } = null;
|
[Browsable(false)]
|
[JsonIgnore]
|
public CameraBase Camera { get; set; } = null;
|
|
//[Browsable(false)]
|
//[JsonIgnore]
|
//public ObservableCollection<AGVTaskModel> TaskList { get; set; } = new ObservableCollection<AGVTaskModel>();
|
|
[Browsable(false)]
|
[JsonIgnore]
|
public int CurrentEmptyTray { get; set; }
|
[Browsable(false)]
|
[JsonIgnore]
|
public int CurrentFullTray { get; set; }
|
[Browsable(false)]
|
[JsonIgnore]
|
public bool IsFullTrayFull { get; set; }
|
[Browsable(false)]
|
[JsonIgnore]
|
public bool IsFullTrayEmpty { get; set; }
|
[Browsable(false)]
|
[JsonIgnore]
|
public bool IsEmptyTrayEmpty { get; set; }
|
|
[Browsable(false)]
|
[JsonIgnore]
|
public bool IsFullTrayTaskAssigned { get; set; }
|
|
[Browsable(false)]
|
[JsonIgnore]
|
public bool IsEmptyTrayTaskAssigned { get; set; }
|
|
//[Browsable(false)]
|
//[JsonIgnore]
|
//public ManualResetEvent FullTrayFullHandle { get; set; } = new ManualResetEvent(false);
|
|
//[Browsable(false)]
|
//[JsonIgnore]
|
//public ManualResetEvent FullTrayEmptyHandle { get; set; } = new ManualResetEvent(false);
|
|
public ManualResetEvent RobotIOHandle { get; set; } = new ManualResetEvent(false);
|
|
public AGVBindUnit()
|
{
|
//TaskList.CollectionChanged += TaskList_CollectionChanged;
|
}
|
|
object agvStatusLock = new object();
|
public bool SetAGVStatus(TaskStatus status)
|
{
|
lock (agvStatusLock)
|
{
|
switch (status)
|
{
|
case TaskStatus.Available:
|
break;
|
case TaskStatus.Running:
|
if (AGVStatus == TaskStatus.Available)
|
{
|
AGVStatus = status;
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
case TaskStatus.Warning:
|
break;
|
default:
|
break;
|
}
|
|
AGVStatus = status;
|
return true;
|
}
|
}
|
//private void TaskList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
//{
|
// if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
|
// {
|
// InvokeTaskCheck();
|
// }
|
//}
|
|
//private void InvokeTaskCheck()
|
//{
|
// lock (taskLock)
|
// {
|
// for (int i = 0; i < TaskList.Count; i++)
|
// {
|
// var task = TaskList[i];
|
|
// bool isAgvOK = false;
|
// bool isRobotOK = false;
|
|
// if ((task.Level & TaskAvailableLevel.AGV) == TaskAvailableLevel.AGV)
|
// {
|
// isAgvOK = AGVStatus == TaskStatus.Available;
|
// }
|
// else
|
// {
|
// isAgvOK = true;
|
// }
|
|
// if ((task.Level & TaskAvailableLevel.Robot) == TaskAvailableLevel.Robot)
|
// {
|
// isRobotOK = RobotStatus == TaskStatus.Available;
|
// }
|
// else
|
// {
|
// isRobotOK = true;
|
// }
|
|
// if (isRobotOK && isAgvOK)
|
// {
|
// OnMethodInvoke?.Invoke(TaskList[i]);
|
// TaskList.RemoveAt(i);
|
// break;
|
// }
|
// }
|
// }
|
//}
|
|
//object taskLock = new object();
|
//public void AddTask(AGVTaskModel task)
|
//{
|
// lock (taskLock)
|
// {
|
// TaskList.Add(task);
|
// }
|
//}
|
|
//public void ClearTask()
|
//{
|
// lock (taskLock)
|
// {
|
// TaskList.Clear();
|
// }
|
//}
|
|
//public AGVTaskModel GetTask(int index)
|
//{
|
// lock (taskLock)
|
// {
|
// return TaskList[index];
|
// }
|
//}
|
}
|
|
public class AGVDeviceConverter : ComboBoxItemTypeConvert
|
{
|
public override void GetConvertHash()
|
{
|
using (var scope = GlobalVar.Container.BeginLifetimeScope())
|
{
|
ProcessConfig config = scope.Resolve<ProcessConfig>();
|
|
config.AGVConfigCollection.ForEach(plc =>
|
{
|
_hash[plc.ID] = plc.Name;
|
});
|
}
|
}
|
}
|
|
public class RobotDeviceConverter : ComboBoxItemTypeConvert
|
{
|
public override void GetConvertHash()
|
{
|
using (var scope = GlobalVar.Container.BeginLifetimeScope())
|
{
|
ProcessConfig config = scope.Resolve<ProcessConfig>();
|
|
config.RobotConfigCollection.ForEach(robot =>
|
{
|
_hash[robot.ID] = robot.Name;
|
});
|
}
|
}
|
}
|
|
public class CameraDeviceConverter : ComboBoxItemTypeConvert
|
{
|
public override void GetConvertHash()
|
{
|
using (var scope = GlobalVar.Container.BeginLifetimeScope())
|
{
|
ProcessConfig config = scope.Resolve<ProcessConfig>();
|
|
config.CameraConfigCollection.ForEach(camera =>
|
{
|
_hash[camera.ID] = camera.Name;
|
});
|
}
|
}
|
}
|
|
public class PLCDeviceConverter : ComboBoxItemTypeConvert
|
{
|
public override void GetConvertHash()
|
{
|
using (var scope = GlobalVar.Container.BeginLifetimeScope())
|
{
|
_hash[""] = "未指定";
|
|
ProcessConfig config = scope.Resolve<ProcessConfig>();
|
|
config.PLCConfigCollection.ForEach(plc =>
|
{
|
_hash[plc.ID] = plc.Name;
|
});
|
}
|
}
|
}
|
}
|