From b0a4c47dd74bc41c5df3bab6ddd8de7bcc6a52b0 Mon Sep 17 00:00:00 2001 From: patrick <patrick.xu@broconcentric.com> Date: 星期五, 06 十二月 2019 18:35:42 +0800 Subject: [PATCH] 1. 重新整理项目,按照A034模式,将设备异步操作修改为类同步操作。使用任务队列来存储和分配任务。 --- src/Bro.Device.SeerAGV/SeerAGVConfig.cs | 51 src/A032.Process/ProcessConfig.cs | 89 src/A032.Process/ProcessControl_Calibration.cs | 180 -- src/Bro.Common.Model/Model/MonitorSet.cs | 20 src/Bro.Common.Model/Interface/IDeviceConfig.cs | 11 src/Bro.Common.Model/Model/CustomizedPoint.cs | 60 src/Bro.Device.AuboRobot/AuboRobotConfig.cs | 205 + src/A032.Process/AGVPath.cs | 17 src/Bro.Device.AuboRobot/AuboRobotDriver.cs | 362 +++- src/Bro.Device.Common/Base/DeviceBase.cs | 42 src/A032.Process/AGVBindUnit.cs | 336 +-- src/A032.Process/Calibration/FrmCalib9PDynamic.cs | 4 src/A032.Process/ProcessControl_Task.cs | 759 +++++++++ src/Bro.Common.Model/Helper/ExceptionHelper.cs | 40 src/A032.Process/Calibration/CtrlCalib9PDynamic.cs | 14 src/A032.Process/Calibration/CalibrationConfig.cs | 16 src/A032.Process/ProcessControl_AGV.cs | 102 + src/A032.Process/ProcessControl_Robot.cs | 24 src/A032.Process/A032.Process.csproj | 3 src/Bro.Device.Common/Helper/AspectHelper.cs | 2 src/Bro.Device.SeerAGV/SeerAGVDriver.cs | 189 ++ src/A032.Process/ProcessControl.cs | 182 - src/Bro.Common.Model/Bro.Common.Model.csproj | 1 src/Bro.Common.Model/Helper/ListHelper.cs | 58 src/Bro.Common.Model/Model/IODefinition.cs | 43 src/Bro.Device.OmronFins/FinsFrame.cs | 6 src/A032.Process/ProcessControl_Method.cs | 1787 ++++++++------------- src/Bro.Device.Common/DeviceBase/HDevEngineTool.cs | 23 src/Bro.Common.Model/Helper/EnumHelper.cs | 9 src/Bro.Common.Model/Interface/IMonitor.cs | 2 src/Bro.Device.Common/Base/DeviceConfigBase.cs | 18 src/Bro.Device.OmronFins/OmronFinsDriver.cs | 145 src/Bro.Device.Common/DeviceBase/PLCBase.cs | 16 src/Bro.Device.SeerAGV/Bro.Device.SeerAGV.csproj | 1 34 files changed, 2,866 insertions(+), 1,951 deletions(-) diff --git a/src/A032.Process/A032.Process.csproj b/src/A032.Process/A032.Process.csproj index 2a1c97b..73afc99 100644 --- a/src/A032.Process/A032.Process.csproj +++ b/src/A032.Process/A032.Process.csproj @@ -90,9 +90,12 @@ </Compile> <Compile Include="Helper\PropertyConvertHelper.cs" /> <Compile Include="ProcessConfig.cs" /> + <Compile Include="ProcessControl_AGV.cs" /> <Compile Include="ProcessControl_Calibration.cs" /> <Compile Include="ProcessControl_Method.cs" /> <Compile Include="ProcessControl.cs" /> + <Compile Include="ProcessControl_Robot.cs" /> + <Compile Include="ProcessControl_Task.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> </ItemGroup> <ItemGroup> diff --git a/src/A032.Process/AGVBindUnit.cs b/src/A032.Process/AGVBindUnit.cs index 5d843f3..f4e06cc 100644 --- a/src/A032.Process/AGVBindUnit.cs +++ b/src/A032.Process/AGVBindUnit.cs @@ -15,42 +15,84 @@ namespace A032.Process { - public enum TaskStatus + public enum TaskState { - Available = 1, + /// <summary> + /// 鏂颁换鍔� + /// </summary> + New = 0, + /// <summary> + /// 浠诲姟瀹屾垚 + /// </summary> + Done = 1, + /// <summary> + /// 浠诲姟澶辫触 + /// </summary> + Failed = 2, + /// <summary> + /// 浠诲姟宸叉坊鍔犻槦鍒楋紝绛夊緟鎵ц + /// </summary> + Queueing = 3, + /// <summary> + /// 浠诲姟宸叉寚娲� + /// </summary> + Assigned = 4, + /// <summary> + /// 浠诲姟鏈寚娲撅紝宸插彇娑� + /// </summary> + Cancelled = 5, + } + + public enum AGVState + { + /// <summary> + /// AGV鐘舵�佷笉鍙煡 + /// </summary> + Unknown = 0, + /// <summary> + /// 绌洪棽鐘舵�侊紝鍙帴鏀朵换鍔� + /// </summary> + Idle = 1, + /// <summary> + /// 浠诲姟鎵ц涓� + /// </summary> Running = 2, + /// <summary> + /// 鎶ヨ涓紝涓嶅彲鎵ц浠诲姟 + /// </summary> Warning = 3, + /// <summary> + /// 鍏呯數涓紝涓嶅彲鎵ц浠诲姟 + /// </summary> + InCharge = 4, + /// <summary> + /// 绌洪棽鍏呯數鐘舵�侊紝鍙帴鏀朵换鍔� + /// </summary> + IdleCharge = 5, } - public enum TaskAvailableLevel - { - Robot = 1, - AGV = 2, - Both = 3, - } + //public class AGVTaskModel + //{ + // public TaskAvailableLevel Level { get; set; } = TaskAvailableLevel.Robot; - public class AGVTaskModel - { - public TaskAvailableLevel Level { get; set; } = TaskAvailableLevel.Robot; + // public string MethodName { get; set; } - public string MethodName { get; set; } + // public IOperationConfig OpConfig { get; set; } - public IOperationConfig OpConfig { get; set; } + // public IDevice Device { get; set; } - public IDevice Device { get; set; } + // //public int Priority { get; set; } = 10; - //public int Priority { get; set; } = 10; + // public AGVTaskModel() { } - 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 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 { @@ -90,60 +132,32 @@ } #endregion + #region 鍚庡彴灞炴�� + #region 鐘舵�� + private AGVState unitState = AGVState.Idle; [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 + public AGVState UnitState { - get => agvStatus; + get => unitState; set { - agvStatus = value; - //InvokeTaskCheck(); - } - } + if (value != unitState) + { + var preState = unitState; + unitState = value; - private TaskStatus robotStatus = TaskStatus.Available; - [Browsable(false)] - [JsonIgnore] - public TaskStatus RobotStatus - { - get => robotStatus; - set - { - robotStatus = value; - //InvokeTaskCheck(); + OnUnitStateChanged?.Invoke(this.Id, preState, unitState); + } } } [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; - } - } + public string WarningMsg { get; set; } = ""; + #endregion - return TaskStatus.Running; - } - } - + #region 璁惧 [Browsable(false)] [JsonIgnore] public SeerAGVDriver AGV { get; set; } = null; @@ -153,150 +167,42 @@ [Browsable(false)] [JsonIgnore] public CameraBase Camera { get; set; } = null; + #endregion - //[Browsable(false)] - //[JsonIgnore] - //public ObservableCollection<AGVTaskModel> TaskList { get; set; } = new ObservableCollection<AGVTaskModel>(); + #region 浠诲姟淇℃伅 + [JsonIgnore] + [Browsable(false)] + public string CurrentTaskId { get; set; } - [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; } + public bool IsTaskCancelled { get; set; } = false; - [Browsable(false)] [JsonIgnore] - public bool IsFullTrayTaskAssigned { get; set; } - [Browsable(false)] + public bool IsTaskCancelling { get; set; } = false; + #endregion + + #region 浜嬩欢 [JsonIgnore] - public bool IsEmptyTrayTaskAssigned { get; set; } + [Browsable(false)] + public Action<string, AGVState, AGVState> OnUnitStateChanged { get; set; } + #endregion - //[Browsable(false)] - //[JsonIgnore] - //public ManualResetEvent FullTrayFullHandle { get; set; } = new ManualResetEvent(false); + #region 鎵樼洏淇℃伅 + [JsonIgnore] + [Browsable(false)] + public int FullTrayNum { get; set; } - //[Browsable(false)] - //[JsonIgnore] - //public ManualResetEvent FullTrayEmptyHandle { get; set; } = new ManualResetEvent(false); - - public ManualResetEvent RobotIOHandle { get; set; } = new ManualResetEvent(false); + [JsonIgnore] + [Browsable(false)] + public int EmptyTrayNum { get; set; } + #endregion + #endregion 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 @@ -364,4 +270,40 @@ } } } + + public class AllDeviceIdConverter : ComboBoxItemTypeConvert + { + public override void GetConvertHash() + { + using (var scope = GlobalVar.Container.BeginLifetimeScope()) + { + _hash[""] = "鏈寚瀹�"; + + List<IDevice> deviceList = scope.Resolve<List<IDevice>>(); + + deviceList.ForEach(d => + { + _hash[d.Id] = d.Name; + }); + } + } + } + + public class AllDeviceNameConverter : ComboBoxItemTypeConvert + { + public override void GetConvertHash() + { + using (var scope = GlobalVar.Container.BeginLifetimeScope()) + { + _hash[""] = "鏈寚瀹�"; + + List<IDevice> deviceList = scope.Resolve<List<IDevice>>(); + + deviceList.ForEach(d => + { + _hash[d.Name] = d.Name; + }); + } + } + } } diff --git a/src/A032.Process/AGVPath.cs b/src/A032.Process/AGVPath.cs index 2e19e32..426a620 100644 --- a/src/A032.Process/AGVPath.cs +++ b/src/A032.Process/AGVPath.cs @@ -3,6 +3,7 @@ using Bro.Common.Model; using Bro.Common.Model.Interface; using Bro.Device.HikCamera; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; @@ -48,6 +49,10 @@ [TypeConverter(typeof(PLCDeviceConverter))] public string DeviceOwner { get; set; } + [Browsable(false)] + [JsonIgnore] + public bool IsOccupied { get; set; } = false; + public string GetDisplayText() { return $"{PositionCode}-{Description}"; @@ -83,6 +88,18 @@ [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] public HikCameraOperationConfig CameraOpConfig { get; set; } = new HikCameraOperationConfig(); + [Category("绀烘暀閰嶇疆")] + [Description("鏈哄櫒浜烘媿鐓т綅缃�")] + [TypeConverter(typeof(ComplexObjectConvert))] + [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] + public RobotPoint RobotSnapshotPoint { get; set; } = new RobotPoint(); + + [Category("绀烘暀閰嶇疆")] + [Description("鏈哄櫒浜虹ず鏁欎綅缃埌瀹為檯鎶撳彇浣嶇疆鐨勫亸绉�")] + [TypeConverter(typeof(ComplexObjectConvert))] + [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] + public RobotPoint RobotShift { get; set; } = new RobotPoint(); + public string GetDisplayText() { return $"{PositionCode}:鏇濆厜锛歿CameraOpConfig.Exposure};鏍囧畾鐭╅樀锛歿string.Join(",", Matrix)}"; diff --git a/src/A032.Process/Calibration/CalibrationConfig.cs b/src/A032.Process/Calibration/CalibrationConfig.cs index 1b8f099..1c02514 100644 --- a/src/A032.Process/Calibration/CalibrationConfig.cs +++ b/src/A032.Process/Calibration/CalibrationConfig.cs @@ -19,8 +19,8 @@ { [Category("鍏宠仈閰嶇疆")] [Description("浣嶇疆搴忓彿")] - [TypeConverter(typeof(PositionNoConverter))] - public int PositionNo { get; set; } + [TypeConverter(typeof(PositionCodeConverter))] + public string PositionCode { get; set; } [Category("鍏宠仈閰嶇疆")] [Description("閫傜敤鐩告満缂栧彿")] @@ -39,7 +39,7 @@ public string GetDisplayText() { - return $"PositionNo:{PositionNo}; Configs:{Configs.Count}"; + return $"PositionNo:{PositionCode}; Configs:{Configs.Count}"; } public List<string> GetHalconToolPathList() @@ -86,11 +86,17 @@ [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] public HalconRelatedCameraOprerationConfigBase CameraOpConfig { get; set; } = new HalconRelatedCameraOprerationConfigBase(); + //[Category("杩愬姩骞冲彴璁剧疆")] + //[Description("骞冲彴褰撳墠鍧愭爣")] + //[TypeConverter(typeof(ComplexObjectConvert))] + //[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] + //public CustomizedPoint CurrentPlatPoint { get; set; } = new CustomizedPoint(); + [Category("杩愬姩骞冲彴璁剧疆")] - [Description("骞冲彴褰撳墠鍧愭爣")] + [Description("鏈哄櫒浜鸿繍鍔ㄥ潗鏍�")] [TypeConverter(typeof(ComplexObjectConvert))] [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] - public CustomizedPoint CurrentPlatPoint { get; set; } = new CustomizedPoint(); + public RobotPoint PlatPoint { get; set; } = new RobotPoint(); public event PropertyChangedEventHandler PropertyChanged; diff --git a/src/A032.Process/Calibration/CtrlCalib9PDynamic.cs b/src/A032.Process/Calibration/CtrlCalib9PDynamic.cs index 1cce895..3edee32 100644 --- a/src/A032.Process/Calibration/CtrlCalib9PDynamic.cs +++ b/src/A032.Process/Calibration/CtrlCalib9PDynamic.cs @@ -30,7 +30,7 @@ InitializeComponent(); } - public CtrlCalib9PDynamic(ProcessControl process, CalibrationConfigCollection calibConfig, AGVBindUnit bind, PathPosition position, Action<AGVBindUnit, int, int> commuAction, Action<CalibrationConfigCollection, AGVBindUnit, PathPosition> finalCalculation) + public CtrlCalib9PDynamic(ProcessControl process, CalibrationConfigCollection calibConfig, AGVBindUnit bind, PathPosition position, Action<CalibrationConfigCollection, AGVBindUnit, PathPosition> finalCalculation) { InitializeComponent(); @@ -42,7 +42,6 @@ Bind = bind; Position = position; - CommuAction = commuAction; FinalCalculation = finalCalculation; } @@ -161,7 +160,8 @@ _canvas.LoadImage(Config.Configs[index].Image); _canvas.Elements.Clear(); - CrossHair ch = new CrossHair(new CalibrationPoint(Config.Configs[index].ImageMarkPoint, Config.Configs[index].CurrentPlatPoint)); + var config = Config.Configs[index]; + CrossHair ch = new CrossHair(new CalibrationPoint(new CustomizedPoint(config.ImageMarkPoint.X, config.ImageMarkPoint.Y), new CustomizedPoint(config.PlatPoint.X, config.PlatPoint.Y))); _canvas.Elements.Add(ch); tsslInfo.Text = $"姝ラ{index + 1}瀹屾垚"; @@ -191,7 +191,9 @@ { _canvas.LoadImage(stepConfig.Image); _canvas.Elements.Clear(); - _canvas.Elements.Add(new CrossHair(new CalibrationPoint(stepConfig.ImageMarkPoint, stepConfig.CurrentPlatPoint))); + + CrossHair ch = new CrossHair(new CalibrationPoint(new CustomizedPoint(stepConfig.ImageMarkPoint.X, stepConfig.ImageMarkPoint.Y), new CustomizedPoint(stepConfig.PlatPoint.X, stepConfig.PlatPoint.Y))); + _canvas.Elements.Add(ch); } } @@ -206,7 +208,7 @@ // //ProcessControl.SendCalibStartSignal(Config.TriggerAddress); //} - ProcessControl.MultipleStepsProcess(Config, Bind, CommuAction); + ProcessControl.MultipleStepsProcess(Config, Bind); } private void btnLoadOfflineImages_Click(object sender, EventArgs e) @@ -236,7 +238,7 @@ //tsslInfo.Text = $"鍗曟杩愮畻瀹屾垚銆傛爣璁扮偣鍧愭爣锛歿config.ImageMarkPoint.X},{config.ImageMarkPoint.Y}"; - ProcessControl.SingleStepProcess(config, CommuAction, Bind, Position.PositionNo, _selectedStepIndex); + ProcessControl.SingleStepProcess(config, Bind, _selectedStepIndex); tsslInfo.Text = $"鍗曟杩愮畻瀹屾垚銆傛爣璁扮偣鍧愭爣锛歿config.ImageMarkPoint.X},{config.ImageMarkPoint.Y}"; } diff --git a/src/A032.Process/Calibration/FrmCalib9PDynamic.cs b/src/A032.Process/Calibration/FrmCalib9PDynamic.cs index 5fe5c52..efbb287 100644 --- a/src/A032.Process/Calibration/FrmCalib9PDynamic.cs +++ b/src/A032.Process/Calibration/FrmCalib9PDynamic.cs @@ -37,7 +37,7 @@ // CtrlCalib9PDynamic = new CtrlCalib9PDynamic(process, device, config, finalCalculation); //} - public FrmCalib9PDynamic(ProcessControl process, CalibrationConfigCollection calibConfig, AGVBindUnit bind, PathPosition position, Action<AGVBindUnit, int, int> commuAction, Action<CalibrationConfigCollection, AGVBindUnit, PathPosition> finalCalculation) + public FrmCalib9PDynamic(ProcessControl process, CalibrationConfigCollection calibConfig, AGVBindUnit bind, PathPosition position, Action<CalibrationConfigCollection, AGVBindUnit, PathPosition> finalCalculation) { InitializeComponent(); @@ -48,7 +48,7 @@ //CommuAction = commuAction; //FinalCalculation = finalCalculation; - CtrlCalib9PDynamic = new CtrlCalib9PDynamic(process, calibConfig, bind, position, commuAction, finalCalculation); + CtrlCalib9PDynamic = new CtrlCalib9PDynamic(process, calibConfig, bind, position, finalCalculation); } //AGVBindUnit Bind { get; set; } diff --git a/src/A032.Process/ProcessConfig.cs b/src/A032.Process/ProcessConfig.cs index c7cbb46..f71d683 100644 --- a/src/A032.Process/ProcessConfig.cs +++ b/src/A032.Process/ProcessConfig.cs @@ -3,6 +3,7 @@ using Bro.Common.Helper; using Bro.Common.Interface; using Bro.Common.Model; +using Bro.Common.Model.Interface; using Bro.Device.AuboRobot; using Bro.Device.HikCamera; using Bro.Device.OmronFins; @@ -20,7 +21,7 @@ namespace A032.Process { - public class ProcessConfig : IStationConfig + public class ProcessConfig : IStationConfig, IHalconToolPath { #region 璁惧閰嶇疆 [Category("璁惧閰嶇疆")] @@ -70,6 +71,10 @@ [TypeConverter(typeof(CollectionCountConvert))] [Editor(typeof(OperationConfigBindEditor), typeof(UITypeEditor))] public Dictionary<string, IOperationConfig> ProcessOpConfigDict { get; set; } = new Dictionary<string, IOperationConfig>(); + + [Category("鎿嶄綔閰嶇疆")] + [Description("鎿嶄綔瓒呮椂璁剧疆锛屽崟浣峬in")] + public int OperationTimeout { get; set; } = 10; //[Category("鐩戝惉鍜屾搷浣滈厤缃�")] //[Description("鐩戝惉鎿嶄綔閰嶇疆闆嗗悎")] @@ -139,6 +144,7 @@ //[Description("鏄惁閲囩敤澶栭儴绠楀瓙銆倀rue锛氶噰鐢ㄥ閮ㄧ畻瀛愶紝false锛氫娇鐢ㄥ唴閮ㄧ畻娉�")] //public bool IsUsingExternalAlgorithem { get; set; } = true; + #region A032 [Category("璺緞鐩稿叧")] [Description("璺緞鑺傜偣閰嶇疆")] [TypeConverter(typeof(CollectionCountConvert))] @@ -155,19 +161,21 @@ [Description("鏄惁鍚敤瑙嗚寮曞")] public bool IsEnableVisionGuide { get; set; } = false; - /// <summary> - /// 绌篢ray涓婃枡闃堝�硷紝AGV涓婄殑绌簍ray鏁伴噺涓嶅ぇ浜庤鏁板�兼椂锛孉GV鍙互鎵ц绌篢ray涓婃枡浠诲姟 - /// </summary> - [Category("闃堝�艰缃�")] - [Description("绌篢ray涓婃枡闃堝�硷紝AGV涓婄殑绌簍ray鏁伴噺涓嶅ぇ浜庤鏁板�兼椂锛孉GV鍙互鎵ц绌篢ray涓婃枡浠诲姟")] - public int AGV_EmptyTrayThreshold { get; set; } = 0; + [Category("瑙嗚閰嶇疆")] + [Description("瑙嗚寮曞娆℃暟")] + public int VisionGuideTimes { get; set; } = 2; - /// <summary> - /// 婊ray涓嬫枡闃堝�硷紝AGV涓婄殑婊ray鏁伴噺涓嶅皬浜庤鏁板�兼椂锛孉GV鍙互鎵ц婊ray涓嬫枡浠诲姟 - /// </summary> - [Category("闃堝�艰缃�")] - [Description("婊ray涓嬫枡闃堝�硷紝AGV涓婄殑婊ray鏁伴噺涓嶅皬浜庤鏁板�兼椂锛孉GV鍙互鎵ц婊ray涓嬫枡浠诲姟")] - public int AGV_FullTrayThreshold { get; set; } = 10; + [Category("璁惧鍙傛暟閰嶇疆")] + [Description("鍏夋簮寮�鍏崇储寮曢厤缃�")] + public int LightOutputIndex { get; set; } + + [Category("璁惧鍙傛暟閰嶇疆")] + [Description("AGV婊¤浇婊ray/绌篢ray鏁伴噺")] + public int AGVAvailableTrayNums { get; set; } = 6; + + [Category("璁惧鍙傛暟閰嶇疆")] + [Description("榛樿绛夊緟浠诲姟杞暟銆傚綋鏌愪簺鏉′欢涓嶆弧瓒冲綋鍓嶄换鍔℃墽琛屽墠鎻愶紝褰撳墠浠诲姟浼氱瓑寰呰嫢骞蹭换鍔℃暟鍚庢墽琛�")] + public int DefaultWaitShift { get; set; } = 3; /// <summary> /// 浜х嚎蹇欐椂鎷嶇収纭绛夊緟闂撮殧锛屼互绉掍负鍗曚綅 @@ -185,11 +193,43 @@ [Category("闃堝�艰缃�")] [Description("鏈哄彴鍘嬫満婊ray鏁伴噺")] - public int Machine_FullTrayNum { get; set; } + public int Machine_FullTrayNum { get; set; } = 6; [Category("闃堝�艰缃�")] [Description("鏈哄彴鍘嬫満绌篢ray鏁伴噺")] - public int Machine_EmptyTrayNum { get; set; } + public int Machine_EmptyTrayNum { get; set; } = 6; + #endregion + + #region IHalconToolPath + public List<string> GetHalconToolPathList() + { + List<string> list = new List<string>(); + + ProcessOpConfigDict.Values.ToList().ForEach(c => + { + if (c is IHalconToolPath) + { + list.AddRange((c as IHalconToolPath).GetHalconToolPathList()); + } + }); + + this.GetType().GetProperties().ToList().ForEach(p => + { + var pValue = p.GetValue(this); + + if (pValue is IHalconToolPath) + { + list.AddRange((pValue as IHalconToolPath).GetHalconToolPathList()); + } + else if (pValue is IEnumerable<IHalconToolPath>) + { + list.AddRange((pValue as IEnumerable<IHalconToolPath>).SelectMany(u => u.GetHalconToolPathList())); + } + }); + + return list.Distinct().ToList(); + } + #endregion #region Ignore [Browsable(false)] @@ -239,4 +279,23 @@ public virtual bool IsDBSave { get; set; } = false; #endregion } + + [Device("OperationTest", "娴嬭瘯鏂规硶閰嶇疆", DeviceAttributeType.OperationConfig)] + public class OperationTestConfig : OperationConfigBase + { + //[Category("娴嬭瘯閰嶇疆")] + //[Description("鏂规硶绫诲瀷")] + //public TaskType TaskType { get; set; } = TaskType.LoadEmptyTrayToAGV; + + [Category("娴嬭瘯閰嶇疆")] + [Description("鏂规硶淇℃伅")] + [TypeConverter(typeof(ComplexObjectConvert))] + [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] + public TrayTask TaskInfo { get; set; } = new TrayTask(); + + [Category("娴嬭瘯閰嶇疆")] + [Description("鎵цAGV璁惧")] + [TypeConverter(typeof(AGVDeviceConverter))] + public string AGVId { get; set; } + } } diff --git a/src/A032.Process/ProcessControl.cs b/src/A032.Process/ProcessControl.cs index 08cba1d..1c21d00 100644 --- a/src/A032.Process/ProcessControl.cs +++ b/src/A032.Process/ProcessControl.cs @@ -5,7 +5,6 @@ using Bro.Common.Model; using Bro.Common.Model.Interface; using Bro.Common.PubSub; -using Bro.Common.UI; using Bro.Device.AuboRobot; using Bro.Device.OmronFins; using Bro.Device.SeerAGV; @@ -14,18 +13,14 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; -using System.Configuration; using System.Diagnostics; using System.Drawing; -using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Reflection; -using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; using static Bro.Common.Helper.EnumHelper; @@ -152,6 +147,11 @@ if (ProcessState == DeviceState.DSClose) return; + List<string> currentTaskIds = Config.AGVBindCollection.Select(u => u.CurrentTaskId).Where(s => !string.IsNullOrWhiteSpace(s)).ToList(); + TrayTaskCollection.RemoveAll(t => !currentTaskIds.Contains(t.TaskId)); + + _bindTaskDoneHandleDict.Values.ToList().ForEach(h => h.WaitOne()); + CloseDevice(PLCDict.Values.ToList()); CloseDevice(RobotDict.Values.ToList()); CloseDevice(AGVDict.Values.ToList()); @@ -168,6 +168,7 @@ return; InitialProcessMethods(); + TrayTaskCollection.OnItemChangedWithItemInfo = OnTaskListChanged; OpenDevices(RobotDict.Values.ToList()); OpenDevices(AGVDict.Values.ToList()); @@ -177,14 +178,15 @@ OpenDevices(PLCDict.Values.ToList()); + //鍔犺浇AGVUnit鐘舵�佷簨浠� + Config.AGVBindCollection.ForEach(b => + { + b.OnUnitStateChanged = OnUnitStateChanged; + + _bindTaskDoneHandleDict[b.Id] = new AutoResetEvent(true); + }); + ProcessState = DeviceState.DSOpen; - - //QueryRobotIO(); - - //Task.Run(() => - //{ - // //PLCMonitor(); - //}); LogAsync(DateTime.Now, "Process Opened", ""); } @@ -291,27 +293,27 @@ #region 涓埆閰嶇疆鐨勭壒鍒鐞� #endregion - _warningRemains.CollectionChanged -= _warningRemains_CollectionChanged; - _warningRemains.CollectionChanged += _warningRemains_CollectionChanged; + WarningRemains.CollectionChanged -= _warningRemains_CollectionChanged; + WarningRemains.CollectionChanged += _warningRemains_CollectionChanged; InitialPLCs(); InitialAGVs(); InitialRobots(); InitialCameras(); InitialAGVBindUnit(); - InitialMachineTrayNums(); + //InitialMachineTrayNums(); AutoFacRegister(); LogAsync(DateTime.Now, "Process Initialized", ""); } - private void InitialMachineTrayNums() - { - machineEmptyTrayDict = Config.PositionCollection.Where(u => u.Description == PathPositionDefinition.UnloadEmptyTray).ToDictionary(p => p.PositionNo, p => 0); + //private void InitialMachineTrayNums() + //{ + // machineEmptyTrayDict = Config.PositionCollection.Where(u => u.Description == PathPositionDefinition.UnloadEmptyTray).ToDictionary(p => p.PositionNo, p => 0); - machineFullTrayDict = Config.PositionCollection.Where(u => u.Description == PathPositionDefinition.LoadFullTray).ToDictionary(p => p.PositionNo, p => 0); - } + // machineFullTrayDict = Config.PositionCollection.Where(u => u.Description == PathPositionDefinition.LoadFullTray).ToDictionary(p => p.PositionNo, p => 0); + //} private void InitialAGVBindUnit() { @@ -390,6 +392,9 @@ agv.InitialConfig = c; AGVDict[agv.InitialConfig.ID] = agv; + agv.OnMonitorAlarm -= OnMonitorAlarm; + agv.OnMonitorInvoke -= OnMonitorInvoke; + agv.OnLog = OnDeviceLog; agv.OnAGVPositoinChanged = OnAGVPositionChanged; agv.OnAGVTaskStatusChanged = OnAGVTaskStatusChanged; @@ -448,7 +453,7 @@ ProcessConfig pConfig = config as ProcessConfig; if (pConfig == null) - throw new ProcessException("鐩墠鍙敮鎸丳rocessConfig绫诲瀷鐨勯潪绌哄唴瀹逛繚瀛�", null); + throw new ProcessException("鐩墠鍙敮鎸丳rocessConfig绫诲瀷鐨勯潪绌哄唴瀹逛繚瀛�"); string newConfig = JsonConvert.SerializeObject(pConfig, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto }); using (StreamWriter writer = new StreamWriter(CONFIG_PATH, false, System.Text.Encoding.UTF8)) @@ -505,71 +510,36 @@ if (attr != null) { _processMethodDict[attr.MethodCode] = m; - - #region 鍒濆鍖朒alconTool 鏍规嵁processMethod鐨勭壒鎬ф潵閰嶇疆 - //if (attr.DeviceType.EndsWith("Camera")) - //{ - // if (StationConfig.ProcessOpConfigDict.Keys.Contains(attr.MethodCode)) - // { - // var opConfig = StationConfig.ProcessOpConfigDict[attr.MethodCode] as HalconRelatedCameraOprerationConfigBase; - - // if (opConfig != null) - // { - // if (!string.IsNullOrWhiteSpace(opConfig.AlgorithemPath)) - // { - // string directoryPath = Path.GetDirectoryName(opConfig.AlgorithemPath); - // string fileName = Path.GetFileNameWithoutExtension(opConfig.AlgorithemPath); - - // HDevEngineTool tool = new HDevEngineTool(directoryPath); - // tool.LoadProcedure(fileName); - - // _halconToolDict[attr.MethodCode] = tool; - // } - // } - // } - //} - #endregion } }); #region 鍒濆鍖朒alconTool 鏍规嵁閰嶇疆鐨勬帴鍙g被鍨嬫潵閰嶇疆 - _halconToolDict = new Dictionary<string, HDevEngineTool>(); - Config.PLCConfigCollection.SelectMany(plcConfig => plcConfig.MonitorSetCollection).Select(ms => ms.OpConfig).ToList().ForEach(c => - { - InitialHalconTool(c as IHalconToolPath); - }); - - Config.VisionConfigCollection.ForEach(c => - { - InitialHalconTool(c as IHalconToolPath); - }); - - Config.ProcessOpConfigDict.Values.ToList().ForEach(c => - { - InitialHalconTool(c as IHalconToolPath); - }); + InitialHalconTool(); #endregion } - private void InitialHalconTool(IHalconToolPath toolPath) + private void InitialHalconTool() { - //IHalconToolPath toolPath = c as IHalconToolPath; - if (toolPath != null) + foreach (HDevEngineTool tool in _halconToolDict.Values) { - toolPath.GetHalconToolPathList().ForEach(path => - { - if (!string.IsNullOrWhiteSpace(path) && !_halconToolDict.ContainsKey(path)) - { - string directoryPath = Path.GetDirectoryName(path); - string fileName = Path.GetFileNameWithoutExtension(path); - - HDevEngineTool tool = new HDevEngineTool(directoryPath); - tool.LoadProcedure(fileName); - - _halconToolDict[path] = tool; - } - }); + tool?.Dispose(); } + + _halconToolDict = new Dictionary<string, HDevEngineTool>(); + + Config.GetHalconToolPathList().ForEach(path => + { + if (!string.IsNullOrWhiteSpace(path) && !_halconToolDict.ContainsKey(path)) + { + string directoryPath = Path.GetDirectoryName(path); + string fileName = Path.GetFileNameWithoutExtension(path); + + HDevEngineTool tool = new HDevEngineTool(directoryPath); + tool.LoadProcedure(fileName); + + _halconToolDict[path] = tool; + } + }); } public List<IDevice> GetDeviceList() @@ -621,7 +591,7 @@ res = new ProcessResponse((int)ReturnValue.EXCEPTIONVALUE); } - var newEx = new ProcessException("鍑芥暟" + methodCode + "鎵ц寮傚父", ex); + var newEx = new ProcessException("鍑芥暟" + methodCode + "鎵ц寮傚父", ExceptionLevel.Warning, ex); } else { @@ -658,60 +628,6 @@ { monitorSet.Response.ResultValue = (int)ReturnValue.OKVALUE; } - #endregion - - //sw.Stop(); - //LogAsync(DateTime.Now, methodCode + " 璋冪敤鑰楁椂: " + sw.ElapsedMilliseconds.ToString() + "ms", ""); - //TimeRecordCSV(DateTime.Now, methodCode + "璋冪敤", (int)sw.ElapsedMilliseconds); - //sw.Start(); - - #region 鍘熸湁PLC鍐欏叆缁撴灉鎿嶄綔锛岀幇杞埌寮傛璋冪敤鍚庡洖璋冨幓鎵ц - //ProcessResponse resValues = res as ProcessResponse; - - //if (resValues.ResultValue == (int)PLCReplyValue.IGNORE) - //{ - // return; - //} - - //if (monitorSet.ReplyDataAddress != -1 && resValues.DataList.Count > 0) - //{ - // PLC_ITEM item = new PLC_ITEM(); - // item.OP_TYPE = 2; - // item.ITEM_LENGTH = resValues.DataList.Count; - // item.ADDRESS = monitorSet.ReplyDataAddress.ToString(); - // item.ITEM_VALUE = String.Join(",", resValues.DataList); - // PLC.WriteItem(item, false); - //} - - //if (monitorSet.NoticeAddress != -1) - //{ - // //娴嬭瘯妯″紡涓嬪缁堝弽棣圤K淇″彿 - // if (StationConfig.IsDemoMode && resValues.ResultValue <= 0) - // { - // resValues.ResultValue = (int)ReturnValue.OKVALUE; - // } - - // int repeatTime = 5; - - // //LogAsync(DateTime.Now, methodCode + "寮�濮嬪弽棣�", ""); - // do - // { - // try - // { - // PLC.WriteSingleAddress(set.NoticeAddress, resValues.ResultValue, false); - // repeatTime = 0; - // } - // catch (Exception ex) - // { - // repeatTime--; - - // if (repeatTime <= 0) - // { - // new ProcessException("PLC鍙嶉鍐欏叆寮傚父", ex); - // } - // } - // } while (repeatTime > 0); - //} #endregion } @@ -1176,7 +1092,7 @@ else { //MessageBox.Show("鏈兘鑾峰彇绂荤嚎鍥剧墖锛�"); - throw new ProcessException("鏈兘鑾峰彇绂荤嚎鍥剧墖锛�", null); + throw new ProcessException("鏈兘鑾峰彇绂荤嚎鍥剧墖锛�"); } } } @@ -1440,7 +1356,7 @@ #endregion #region 鎶ヨ鍜孌ownTime - public ObservableCollection<string> _warningRemains = new ObservableCollection<string>(); + public ObservableCollection<string> WarningRemains { get; set; } = new ObservableCollection<string>(); bool warningRemainFlag = false; bool WarningRemainFlag diff --git a/src/A032.Process/ProcessControl_AGV.cs b/src/A032.Process/ProcessControl_AGV.cs new file mode 100644 index 0000000..dcfacac --- /dev/null +++ b/src/A032.Process/ProcessControl_AGV.cs @@ -0,0 +1,102 @@ +锘縰sing Bro.Common.Helper; +using Bro.Device.SeerAGV; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace A032.Process +{ + public partial class ProcessControl + { + private async void OnAGVBatteryLvlChanged(SeerAGVDriver agv, float preBatteryLvl, float batteryLvl) + { + await Task.Run(() => + { + var bind = Config.AGVBindCollection.FirstOrDefault(u => u.AGVId == agv.Id); + SeerAGVInitialConfig iConfig = bind.AGV.InitialConfig as SeerAGVInitialConfig; + + if (bind.UnitState == AGVState.Idle) + { + if (batteryLvl <= iConfig.BatteryLvlToCharge) + { + bind.CurrentTaskId = "InCharge"; + bind.UnitState = AGVState.InCharge; + + var chargePosition = Config.PositionCollection.FirstOrDefault(u => !u.IsOccupied && u.Description == PathPositionDefinition.Charge); + + if (chargePosition == null) + { + bind.WarningMsg = $"{bind.AGV.Name}鐩墠鏃犲彲鐢ㄥ厖鐢靛湴鍧�"; + new ProcessException(bind.WarningMsg); + bind.UnitState = AGVState.Warning; + } + else + { + bind.AGV.TaskOrder(chargePosition.PositionCode, true); + } + } + else if (batteryLvl <= iConfig.BatteryLvlToCharge_Recommand) + { + ChargeWhenIdle(bind); + } + } + else if (bind.UnitState == AGVState.InCharge) + { + if (batteryLvl >= iConfig.BatteryLvlChargeDone) + { + bind.UnitState = AGVState.Idle; + } + else if (batteryLvl >= iConfig.BatteryLvlToCharge_Recommand) + { + bind.UnitState = AGVState.IdleCharge; + } + } + }); + } + + private async void OnAGVTaskStatusChanged(SeerAGVDriver agv, AGVTaskStatus taskStatus) + { + await Task.Run(() => + { + //濡傛灉鎴愬姛鍒拌揪鍏呯數鍦扮偣锛屽紑濮嬪厖鐢� + if (taskStatus == AGVTaskStatus.Completed && Config.PositionCollection.Any(u => u.Description == PathPositionDefinition.Charge && u.PositionCode == agv.CurrentPosition)) + { + var bind = Config.AGVBindCollection.FirstOrDefault(u => u.AGVId == agv.Id); + if (bind != null) + { + //琛ㄧず鍏呯數鍔ㄤ綔浠诲姟瀹屾垚 + bind.CurrentTaskId = ""; + } + } + }); + } + + private async void OnAGVPositionChanged(SeerAGVDriver agv, string positionCode) + { + await Task.Run(() => + { + + }); + } + + private void ChargeWhenIdle(AGVBindUnit bind) + { + bind.CurrentTaskId = "IdleCharge"; + bind.UnitState = AGVState.IdleCharge; + + //璁剧疆涓烘棤闇�绛夊緟鏄负浜嗘柟渚挎墽琛岃繃绋嬩腑鍙互鍙栨秷褰撳墠鎿嶄綔锛屾墽琛屼换鍔� + var chargePosition = Config.PositionCollection.FirstOrDefault(u => !u.IsOccupied && u.Description == PathPositionDefinition.Charge); + + if (chargePosition != null) + { + bind.AGV.TaskOrder(chargePosition.PositionCode, true); + } + else + { + new ProcessException($"{bind.AGV.Name}鏈兘鑾峰彇鍏呯數鍦板潃"); + } + } + } +} diff --git a/src/A032.Process/ProcessControl_Calibration.cs b/src/A032.Process/ProcessControl_Calibration.cs index 44a19ea..7dad539 100644 --- a/src/A032.Process/ProcessControl_Calibration.cs +++ b/src/A032.Process/ProcessControl_Calibration.cs @@ -3,6 +3,7 @@ using Bro.Common.Helper; using Bro.Common.Interface; using Bro.Common.Model; +using Bro.Device.AuboRobot; using HalconDotNet; using System; using System.Collections.Generic; @@ -16,8 +17,6 @@ { public partial class ProcessControl { - CalibReplyMsg _calibReply = new CalibReplyMsg(); - [ProcessMethod("CalibrationCollection", "RobotCalibration", "鏈哄櫒浜�9鐐规爣瀹�", true)] public ProcessResponse RobotCalibration(IOperationConfig config, IDevice device) { @@ -29,7 +28,7 @@ throw new ProcessException("鏈兘鑾峰彇缁戝畾璁惧淇℃伅"); } - PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == calibConfig.PositionNo); + PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.PositionCode == calibConfig.PositionCode); if (position == null) { throw new ProcessException("鏈兘鑾峰彇姝g‘浣嶇疆淇℃伅"); @@ -42,64 +41,15 @@ if (calibConfig.IsStartedFromUI) { - FrmCalib9PDynamic frm = new FrmCalib9PDynamic(this, calibConfig, bind, position, SendMessageToRobot_Calibration, CalculateMatrix); + FrmCalib9PDynamic frm = new FrmCalib9PDynamic(this, calibConfig, bind, position, CalculateMatrix); frm.ShowDialog(); } else { - MultipleStepsProcess(calibConfig, bind, SendMessageToRobot_Calibration); + MultipleStepsProcess(calibConfig, bind); CalculateMatrix(calibConfig, bind, position); } - - //for (int i = 0; i < calibConfig.Configs.Count; i++) - //{ - // bind.Robot.SendMsg(Bro.Device.AuboRobot.RobotMsgAction.Calibration, Bro.Device.AuboRobot.RobotMsgParas.None, calibConfig.PositionNo, new List<float>() { i + 1 }); - - // _calibReply.CalibHandle.WaitOne(); - - // if (_calibReply.CalibIndex != (i + 1) || _calibReply.CalibPositionNo != calibConfig.PositionNo) - // { - // throw new ProcessException("鏍囧畾鍙嶉鐨勭储寮曟垨浣嶇疆淇℃伅涓嶄竴鑷�"); - // } - - // calibConfig.Configs[i].CurrentPlatPoint = new CustomizedPoint(_calibReply.RobotPosition.X, _calibReply.RobotPosition.Y); - - // using (HObject hImage = CollectHImage(bind.Camera, calibConfig.Configs[i].CameraOpConfig, "RobotCalibration")) - // { - // var tool = _halconToolDict[calibConfig.Configs[i].CameraOpConfig.AlgorithemPath]; - - // tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); - // tool.RunProcedure(); - - // float x = (float)tool.GetResultTuple("OUTPUT_X").D; - // float y = (float)tool.GetResultTuple("OUTPUT_Y").D; - // float angel = (float)tool.GetResultTuple("OUTPUT_Angle").D; - // if (x < 0 || y < 0) - // { - // throw new ProcessException("鑾峰彇鐐逛綅淇℃伅涓嶆纭�"); - // } - - // calibConfig.Configs[i].ImageMarkPoint = new CustomizedPointWithAngle(x, y, angel); - // } - //} - - //HOperatorSet.VectorToHomMat2d(new HTuple(calibConfig.Configs.Select(u => u.ImageMarkPoint.X).ToArray()), new HTuple(calibConfig.Configs.Select(u => u.ImageMarkPoint.Y).ToArray()), new HTuple(calibConfig.Configs.Select(u => u.CurrentPlatPoint.X).ToArray()), new HTuple(calibConfig.Configs.Select(u => u.CurrentPlatPoint.Y).ToArray()), out HTuple matrix); - - //var visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.CameraId == bind.CameraId && u.PositionCode == position.PositionCode); - //if (visionConfig != null) - //{ - // visionConfig.Matrix = new List<double>() { matrix[0], matrix[1], 0, matrix[3], matrix[4], 0 }; - //} - //else - //{ - // Config.VisionConfigCollection.Add(new PositionVisionConfig() - // { - // CameraId = bind.CameraId, - // PositionCode = position.PositionCode, - // Matrix = new List<double>() { matrix[0], matrix[1], 0, matrix[3], matrix[4], 0 }, - // }); - //} return new ProcessResponse(true); } @@ -115,7 +65,7 @@ throw new ProcessException("鏈兘鑾峰彇缁戝畾璁惧淇℃伅"); } - PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == calibConfig.PositionNo); + PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.PositionCode == calibConfig.PositionCode); if (position == null) { throw new ProcessException("鏈兘鑾峰彇姝g‘浣嶇疆淇℃伅"); @@ -128,72 +78,22 @@ if (calibConfig.IsStartedFromUI) { - FrmCalib9PDynamic frm = new FrmCalib9PDynamic(this, calibConfig, bind, position, SendMessageToRobot_Standard, CalculateStandardPoint); + FrmCalib9PDynamic frm = new FrmCalib9PDynamic(this, calibConfig, bind, position, CalculateStandardPoint); frm.ShowDialog(); } else { - MultipleStepsProcess(calibConfig, bind, SendMessageToRobot_Standard); + MultipleStepsProcess(calibConfig, bind); CalculateStandardPoint(calibConfig, bind, position); } - - //for (int i = 0; i < calibConfig.Configs.Count; i++) - //{ - // bind.Robot.SendMsg(Bro.Device.AuboRobot.RobotMsgAction.Calibration, Bro.Device.AuboRobot.RobotMsgParas.None, calibConfig.PositionNo, new List<float>() { i + 1 }); - - // _calibReply.CalibHandle.WaitOne(); - - // if (_calibReply.CalibPositionNo != calibConfig.PositionNo) - // { - // throw new ProcessException("鏍囧畾鍙嶉鐨勪綅缃俊鎭笉涓�鑷�"); - // } - - // calibConfig.Configs[i].CurrentPlatPoint = new CustomizedPoint(_calibReply.RobotPosition.X, _calibReply.RobotPosition.Y); - - // using (HObject hImage = CollectHImage(bind.Camera, calibConfig.Configs[i].CameraOpConfig, "RobotCalibration")) - // { - // var tool = _halconToolDict[calibConfig.Configs[i].CameraOpConfig.AlgorithemPath]; - - // tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); - // tool.RunProcedure(); - - // float x = (float)tool.GetResultTuple("OUTPUT_X").D; - // float y = (float)tool.GetResultTuple("OUTPUT_Y").D; - // float angel = (float)tool.GetResultTuple("OUTPUT_Angle").D; - // if (x < 0 || y < 0) - // { - // throw new ProcessException("鑾峰彇鐐逛綅淇℃伅涓嶆纭�"); - // } - - // calibConfig.Configs[i].ImageMarkPoint = new CustomizedPointWithAngle(x, y, angel); - // } - //} - - //CustomizedPointWithAngle markPoint = calibConfig.Configs[0].ImageMarkPoint; - //var visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.CameraId == bind.CameraId && u.PositionCode == position.PositionCode); - //if (visionConfig != null) - //{ - // visionConfig.StandardPoint = new CustomizedPointWithAngle(markPoint.X, markPoint.Y, markPoint.Angle); - //} - //else - //{ - // Config.VisionConfigCollection.Add(new PositionVisionConfig() - // { - // CameraId = bind.CameraId, - // PositionCode = position.PositionCode, - // StandardPoint = new CustomizedPointWithAngle(markPoint.X, markPoint.Y, markPoint.Angle), - // }); - //} return new ProcessResponse(true); } public void CalculateMatrix(CalibrationConfigCollection calibConfig, AGVBindUnit bind, PathPosition position) { - //HOperatorSet.VectorToHomMat2d(new HTuple(calibConfig.Configs.Select(u => u.ImageMarkPoint.X).ToArray()), new HTuple(calibConfig.Configs.Select(u => u.ImageMarkPoint.Y).ToArray()), new HTuple(calibConfig.Configs.Select(u => u.CurrentPlatPoint.X).ToArray()), new HTuple(calibConfig.Configs.Select(u => u.CurrentPlatPoint.Y).ToArray()), out HTuple matrix); - - List<double> matrix = GetMovementMatrix(calibConfig.Configs.Select(u => u.ImageMarkPoint as CustomizedPoint).ToList(), calibConfig.Configs.Select(u => u.CurrentPlatPoint).ToList(), out string msg); + List<double> matrix = GetMovementMatrix(calibConfig.Configs.Select(u => u.ImageMarkPoint as CustomizedPoint).ToList(), calibConfig.Configs.Select(u => new CustomizedPoint(u.PlatPoint.X, u.PlatPoint.Y)).ToList(), out string msg); var visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.CameraId == bind.CameraId && u.PositionCode == position.PositionCode); if (visionConfig != null) @@ -235,7 +135,6 @@ sum += Math.Sqrt((Math.Pow((m.D - platPoints[i].X), 2) + Math.Pow((n.D - platPoints[i].Y), 2))); } - //sum = ((sum / (double)Config.LengthPulseRatio) * 100.0) / ((double)imagePoints.Count); sum = sum / (double)imagePoints.Count; msg = $"鏍囧畾鐐规暟閲�:{imagePoints.Count};鍗曠偣璇樊:{sum.ToString()}鑴夊啿"; @@ -251,18 +150,6 @@ public void CalculateStandardPoint(CalibrationConfigCollection calibConfig, AGVBindUnit bind, PathPosition position) { - //var bind = Config.AGVBindCollection.FirstOrDefault(u => u.CameraId == calibConfig.CameraId); - //if (bind == null) - //{ - // throw new ProcessException("鏈兘鑾峰彇缁戝畾璁惧淇℃伅"); - //} - - //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == calibConfig.PositionNo); - //if (position == null) - //{ - // throw new ProcessException("鏈兘鑾峰彇姝g‘浣嶇疆淇℃伅"); - //} - CustomizedPointWithAngle markPoint = calibConfig.Configs[0].ImageMarkPoint; var visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.CameraId == bind.CameraId && u.PositionCode == position.PositionCode); if (visionConfig != null) @@ -282,51 +169,25 @@ PubSubCenter.Publish(PubTag.CalibAllDone.ToString(), "", $"鏍囧畾瀹屾垚锛屾爣鍑嗙偣:{markPoint.GetDisplayText()}", true); } - public void MultipleStepsProcess(CalibrationConfigCollection calibConfig, AGVBindUnit bind, Action<AGVBindUnit, int, int> sendMessageToRobot) + public void MultipleStepsProcess(CalibrationConfigCollection calibConfig, AGVBindUnit bind) { for (int i = 0; i < calibConfig.Configs.Count; i++) { - SingleStepProcess(calibConfig.Configs[i], sendMessageToRobot, bind, calibConfig.PositionNo, i); + SingleStepProcess(calibConfig.Configs[i], bind, i); } } - public void SendMessageToRobot_Calibration(AGVBindUnit bind, int positionNo, int index) + public void SingleStepProcess(CalibrationConfig config, AGVBindUnit bind, int index) { - bind.Robot.SendMsg(Bro.Device.AuboRobot.RobotMsgAction.Calibration, Bro.Device.AuboRobot.RobotMsgParas.None, positionNo, new List<float>() { index + 1 }); - - _calibReply.CalibHandle.WaitOne(); - - if (_calibReply.CalibIndex != (index + 1) || _calibReply.CalibPositionNo != positionNo) - { - throw new ProcessException("鏍囧畾鍙嶉鐨勭储寮曟垨浣嶇疆淇℃伅涓嶄竴鑷�"); - } - } - - public void SendMessageToRobot_Standard(AGVBindUnit bind, int positionNo, int index) - { - bind.Robot.SendMsg(Bro.Device.AuboRobot.RobotMsgAction.StandardPoint, Bro.Device.AuboRobot.RobotMsgParas.None, positionNo); - - _calibReply.CalibHandle.WaitOne(); - - if (_calibReply.CalibPositionNo != positionNo) - { - throw new ProcessException("鏍囧畾鍙嶉鐨勪綅缃俊鎭笉涓�鑷�"); - } - } - - //PubSubCenter.Subscribe(PubTag.CalibStepDone.ToString(), CalibStepDone); - //PubSubCenter.Subscribe(PubTag.CalibAllDone.ToString(), CalibAllDone); - public void SingleStepProcess(CalibrationConfig config, Action<AGVBindUnit, int, int> sendMessageToRobot, AGVBindUnit bind, int positionNo, int index) - { - sendMessageToRobot.Invoke(bind, positionNo, index); - - config.CurrentPlatPoint = new CustomizedPoint(_calibReply.RobotPosition.X, _calibReply.RobotPosition.Y); + bind.Robot.Move(config.PlatPoint, MoveType.AbsoluteMove, true); using (HObject hImage = CollectHImage(bind.Camera, config.CameraOpConfig, "RobotCalibration")) { var tool = _halconToolDict[config.CameraOpConfig.AlgorithemPath]; - tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); + tool.InputImageDic.Clear(); + tool.InputImageDic["INPUT_Image"] = hImage; + tool.RunProcedure(); float x = (float)tool.GetResultTuple("OUTPUT_X").D; @@ -342,16 +203,5 @@ PubSubCenter.Publish(PubTag.CalibStepDone.ToString(), index, "", true); } - } - - public class CalibReplyMsg - { - public AutoResetEvent CalibHandle { get; set; } = new AutoResetEvent(false); - - public int CalibIndex { get; set; } = 0; - - public int CalibPositionNo { get; set; } - - public CustomizedPoint RobotPosition { get; set; } = new CustomizedPoint(); } } diff --git a/src/A032.Process/ProcessControl_Method.cs b/src/A032.Process/ProcessControl_Method.cs index dc0d8c8..00c656d 100644 --- a/src/A032.Process/ProcessControl_Method.cs +++ b/src/A032.Process/ProcessControl_Method.cs @@ -8,6 +8,7 @@ using HalconDotNet; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.ComponentModel; using System.Drawing; using System.IO; @@ -20,331 +21,7 @@ { public partial class ProcessControl { - const int WAITTIME = 5000; - - Dictionary<int, int> machineFullTrayDict = new Dictionary<int, int>(); - Dictionary<int, int> machineEmptyTrayDict = new Dictionary<int, int>(); - List<TaskAssignInfo> taskAssignedList = new List<TaskAssignInfo>(); - - #region AGV浜嬩欢 - private void OnAGVBatteryLvlChanged(SeerAGVDriver agv, float preBatteryLvl, float batteryLvl) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.AGVId == agv.Id); - SeerAGVInitialConfig iConfig = agv.InitialConfig as SeerAGVInitialConfig; - if (batteryLvl <= iConfig.BatteryLvlToCharge && preBatteryLvl > iConfig.BatteryLvlToCharge) - { - Task.Run(() => - { - var position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.Charge); - - if (position == null) - { - throw new ProcessException("鏈壘鍒板厖鐢靛湴鐐�"); - } - - while (bind.UnitStatus != TaskStatus.Available) - { - if (bind.SetAGVStatus(TaskStatus.Running)) - { - bind.AGV.TaskOrder(position.PositionCode); - break; - } - - Thread.Sleep(WAITTIME); - } - }); - - return; - } - - if (batteryLvl >= iConfig.BatteryLvlChargeDone && preBatteryLvl < iConfig.BatteryLvlChargeDone) - { - var position = Config.PositionCollection.FirstOrDefault(u => u.PositionCode == agv.CurrentPosition); - - if (position != null && position.Description == PathPositionDefinition.Charge) - { - bind.SetAGVStatus(TaskStatus.Available); - } - return; - } - } - - private void OnAGVTaskStatusChanged(SeerAGVDriver agv, AGVTaskStatus taskStatus) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.AGVId == agv.Id); - - if (bind == null) - { - throw new ProcessException("鏈兘鏍规嵁AGV淇℃伅鑾峰彇缁戝畾璁惧淇℃伅", null); - } - - if (bind.AGVDest == agv.CurrentPosition && taskStatus == AGVTaskStatus.Completed) - { - //PathPosition loadEmptyTrayPosition = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); - - //if (bind.AGVDest == loadEmptyTrayPosition.PositionCode) - //{ - // bind.RobotStatus = TaskStatus.Running; - //} - - bind.SetAGVStatus(TaskStatus.Available); - } - } - - private void OnAGVPositionChanged(SeerAGVDriver agv, string positionCode) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.AGVId == agv.Id); - - if (bind == null) - { - throw new ProcessException("鏈兘鏍规嵁AGV淇℃伅鑾峰彇缁戝畾璁惧淇℃伅", null); - } - - if (bind.AGVDest == positionCode && agv.TaskStatus == AGVTaskStatus.Completed) - { - //PathPosition loadEmptyTrayPosition = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); - - //if (bind.AGVDest == loadEmptyTrayPosition.PositionCode) - //{ - // bind.RobotStatus = TaskStatus.Running; - //} - - bind.SetAGVStatus(TaskStatus.Available); - LogAsync(DateTime.Now, $"AGV鍒颁綅{positionCode}", ""); - - PathPosition position = Config.PositionCollection.FirstOrDefault(p => p.PositionCode == bind.AGVDest); - switch (position.Description) - { - case PathPositionDefinition.LoadEmptyTray: - LogAsync(DateTime.Now, $"AGV瀹屾垚锛屽噯澶囦笂绌篢ray", ""); - Robot_LoadEmptyTray(bind.Id, position); - break; - case PathPositionDefinition.LoadFullTray: - LogAsync(DateTime.Now, $"AGV瀹屾垚锛屽噯澶囦笂婊ray", ""); - Robot_LoadFullTraySnap(bind.Id, position); - break; - case PathPositionDefinition.UnloadEmptyTray: - LogAsync(DateTime.Now, $"AGV瀹屾垚锛屽噯澶囦笅绌篢ray", ""); - Robot_UnloadEmptyTraySnap(bind.Id, position); - break; - case PathPositionDefinition.UnloadFullTray: - LogAsync(DateTime.Now, $"AGV瀹屾垚锛屽噯澶囦笅婊ray", ""); - Robot_UnloadFullTraySnap(bind.Id, position); - break; - default: - break; - } - } - } - #endregion - - private void OnRobotMsgReceived(DateTime dt, AuboRobotDriver robot, RobotMsg msg) - { - LogAsync(dt, robot.Name + "鎺ユ敹淇℃伅", msg.GetDisplayText()); - - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == robot.Id); - - if (bind == null) - { - throw new ProcessException("鏈兘鏍规嵁鏈哄櫒浜轰俊鎭幏鍙栫粦瀹氳澶囦俊鎭�", null); - } - - //List<AGVTaskModel> models = new List<AGVTaskModel>(); - - switch (msg.Action) - { - case RobotMsgAction.Load: - { - switch (msg.Para1) - { - case RobotMsgParas.EmptyTray: - { - bind.RobotStatus = bind.AGVStatus = TaskStatus.Available; - } - break; - case RobotMsgParas.FullTray: - { - machineFullTrayDict[msg.Para2]--; - bind.CurrentFullTray = int.Parse(msg.Datas[1]); - - if (machineFullTrayDict[msg.Para2] > 0 && !bind.IsFullTrayFull) - { - RobotMsg_UnloadEmptyTray.Para2 = msg.Para2; - robot.SendMsg(RobotMsg_UnloadEmptyTray, true); - } - else - { - bind.RobotStatus = TaskStatus.Available; - } - } - break; - default: - break; - } - } - break; - case RobotMsgAction.Unload: - { - switch (msg.Para1) - { - case RobotMsgParas.EmptyTray: - { - machineEmptyTrayDict[msg.Para2]++; - bind.CurrentEmptyTray = int.Parse(msg.Datas[0]); - - if (machineEmptyTrayDict[msg.Para2] < Config.Machine_EmptyTrayNum) - { - //bind.RobotIOHandle.Reset(); - //bind.RobotIOHandle.WaitOne(); - bind.Robot.MonitorHandle.WaitOne(); - //bind.Robot.IOChangedHandle.WaitOne(); - Thread.Sleep((bind.Robot.InitialConfig as AuboRobotInitialConfig).ScanInterval); - - if (!bind.IsFullTrayFull) - { - RobotMsg_UnloadEmptyTray.Para2 = msg.Para2; - robot.SendMsg(RobotMsg_UnloadEmptyTray, true); - } - else - { - bind.RobotStatus = TaskStatus.Available; - } - } - else - { - bind.RobotStatus = TaskStatus.Available; - } - } - break; - case RobotMsgParas.FullTray: - { - bind.CurrentFullTray = int.Parse(msg.Datas[1]); - - //bind.RobotIOHandle.Reset(); - //bind.RobotIOHandle.WaitOne(); - bind.Robot.MonitorHandle.WaitOne(); - //bind.Robot.IOChangedHandle.WaitOne(); - Thread.Sleep((bind.Robot.InitialConfig as AuboRobotInitialConfig).ScanInterval); - - if (!bind.IsFullTrayEmpty) - { - Camera_UnloadFullTray(robot.Id, msg.Para2); - } - else - { - bind.RobotStatus = TaskStatus.Available; - } - } - break; - default: - break; - } - } - break; - case RobotMsgAction.Move: - { - switch (msg.Para1) - { - case RobotMsgParas.LineSnap: - { - Camera_UnloadFullTray(robot.Id, msg.Para2); - } - break; - case RobotMsgParas.LoadFullTraySnap: - { - Camera_LoadFullTray(robot.Id, msg.Para2); - } - break; - case RobotMsgParas.UnloadEmptyTraySnap: - { - Camera_UnloadEmptyTray(robot.Id, msg.Para2); - } - break; - case RobotMsgParas.Home: - { - bind.RobotStatus = TaskStatus.Available; - } - break; - default: - break; - } - } - break; - case RobotMsgAction.Calibration: - { - _calibReply.CalibIndex = int.Parse(msg.Datas[4]); - _calibReply.CalibPositionNo = msg.Para2; - _calibReply.RobotPosition = new CustomizedPoint(float.Parse(msg.Datas[0]), float.Parse(msg.Datas[1])); - - _calibReply.CalibHandle.Set(); - } - break; - case RobotMsgAction.StandardPoint: - { - _calibReply.CalibPositionNo = msg.Para2; - _calibReply.CalibHandle.Set(); - } - break; - default: - break; - } - - //if (models.Count > 0) - //{ - // models.ForEach(model => - // { - // if (!bind.TaskList.Any(t => t.MethodName == model.MethodName)) - // { - // model.OpConfig = new AGVBindOpConfig(bind.Id); - // bind.AddTask(model); - // } - // }); - //} - } - - public void QueryRobotIO() - { - RobotDict.Values.ToList().ForEach(r => - { - r.SendMsg(RobotMsgAction.IO, RobotMsgParas.Query, 0); - }); - } - - //private void OnBindUnitTaskInvoke(AGVTaskModel task) - //{ - // InvokeMethodDict[task.MethodName].Invoke(this, new object[] { task.OpConfig, task.Device }); - - // //var response = task.MethodFunc.Invoke(task.OpConfig, task.Device); - //} - #region Robot鐩戝惉浜嬩欢 - //private void AddNewTaskToBind(string robotId, List<AGVTaskModel> models) - //{ - // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == robotId); - - // if (bind == null) - // { - // throw new ProcessException("鏈兘鏍规嵁鏈哄櫒浜轰俊鎭幏鍙栫粦瀹氳澶囦俊鎭�", null); - // } - - // AddNewTaskToBind(bind, models); - //} - - //private void AddNewTaskToBind(AGVBindUnit bind, List<AGVTaskModel> models) - //{ - // if (models.Count > 0) - // { - // models.ForEach(model => - // { - // if (!bind.TaskList.Any(t => t.MethodName == model.MethodName)) - // { - // model.OpConfig = new AGVBindOpConfig(bind.Id); - // bind.AddTask(model); - // } - // }); - // } - //} - [ProcessMethod("", "Robot_Monitor_Alarm", "鏈哄櫒浜虹洃鍚簨浠�-鎶ヨ", true)] public ProcessResponse Robot_Monitor_Alarm(IOperationConfig config, IDevice device) { @@ -352,11 +29,11 @@ if (bind == null) { - throw new ProcessException("鏈兘鏍规嵁鏈哄櫒浜轰俊鎭幏鍙栫粦瀹氳澶囦俊鎭�", null); + throw new ProcessException($"鏈兘鑾峰彇{device.Name}鐨勭粦瀹氳澶囦俊鎭�"); } - bind.AGV.PauseTask(); - bind.RobotStatus = TaskStatus.Warning; + bind.AGV.CancelTask(); + bind.UnitState = AGVState.Warning; return new ProcessResponse(true); } @@ -364,92 +41,58 @@ [ProcessMethod("", "Robot_Monitor_EmptyTrayEmpty", "鏈哄櫒浜虹洃鍚簨浠�-绌篢ray鍖哄煙娓呯┖", true)] public ProcessResponse Robot_Monitor_EmptyTrayEmpty(IOperationConfig config, IDevice device) { - bool isEmptyTrayEmpty = config.InputPara[0] == 0; var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == device.Id); - if (isEmptyTrayEmpty) + + if (bind == null) { - bind.IsEmptyTrayEmpty = true; - - Task.Run(() => - { - //Func<IOperationConfig, IDevice, ProcessResponse> action = AGV_LoadEmptyTray; - while (bind.IsEmptyTrayEmpty && !bind.IsEmptyTrayTaskAssigned) - { - //if (bind.TaskList.Count == 0) - if (bind.UnitStatus == TaskStatus.Available) - { - //List<AGVTaskModel> models = new List<AGVTaskModel>(); - //models.Add(new AGVTaskModel(TaskAvailableLevel.Both, "AGV_LoadEmptyTray")); - //models.Add(new AGVTaskModel(TaskAvailableLevel.AGV, "AfterEmptyTrayPositionArrived")); - - //AddNewTaskToBind(device.Id, models); - - if (AGV_LoadEmptyTray(bind.Id)) - { - bind.IsEmptyTrayTaskAssigned = true; - } - } - else - { - Thread.Sleep(WAITTIME); - } - } - }); + throw new ProcessException($"鏈兘鑾峰彇{device.Name}鐨勭粦瀹氳澶囦俊鎭�"); } - else - { - bind.IsEmptyTrayEmpty = false; - bind.IsEmptyTrayTaskAssigned = false; - } + + bind.EmptyTrayNum = 0; + + TrayTask task = new TrayTask(); + task.TaskType = TaskType.LoadEmptyTrayToAGV; + //task.Priority = 10; + task.SourceDeviceId = device.Id; + //task.SourceDeviceName = device.Name; + + //濡傛灉鐩墠鍦板潃琚崰鐢紝鍦板潃鏈夊彲鑳戒负绌猴紝闇�瑕佸湪浠诲姟鎸囨淳鏃跺啀娆$‘璁� + task.Location = Config.PositionCollection.FirstOrDefault(u => !u.IsOccupied && u.Description == PathPositionDefinition.LoadEmptyTray); + + InsertTask(task); return new ProcessResponse(true); } + /// <summary> + /// 淇″彿瑕佹眰闀夸俊鍙疯Е鍙戯紝閬垮厤璇Е鍙� + /// </summary> + /// <param name="config"></param> + /// <param name="device"></param> + /// <returns></returns> [ProcessMethod("", "Robot_Monitor_FullTrayFull", "鏈哄櫒浜虹洃鍚簨浠�-婊ray鍖哄煙鏀炬弧", true)] public ProcessResponse Robot_Monitor_FullTrayFull(IOperationConfig config, IDevice device) { - //(device as AuboRobotDriver).IOChangedHandle.Reset(); - bool isFullTrayFull = config.InputPara[0] == 1; var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == device.Id); - if (isFullTrayFull) + + if (bind == null) { - bind.IsFullTrayFull = true; - - Task.Run(() => - { - //Func<IOperationConfig, IDevice, ProcessResponse> action = AGV_UnloadFullTray; - while (bind.IsFullTrayFull && !bind.IsFullTrayTaskAssigned) - { - //if (bind.TaskList.Count == 0) - if (bind.UnitStatus == TaskStatus.Available) - { - //List<AGVTaskModel> models = new List<AGVTaskModel>(); - //models.Add(new AGVTaskModel(TaskAvailableLevel.Both, "AGV_UnloadFullTray")); - //models.Add(new AGVTaskModel(TaskAvailableLevel.AGV, "Robot_UnloadFullTray")); - - //AddNewTaskToBind(device.Id, models); - - if (AGV_UnloadFullTray(bind.Id)) - { - bind.IsFullTrayTaskAssigned = true; - } - } - else - { - Thread.Sleep(WAITTIME); - } - } - }); - } - else - { - bind.IsFullTrayFull = false; - bind.IsFullTrayTaskAssigned = false; + throw new ProcessException($"鏈兘鑾峰彇{device.Name}鐨勭粦瀹氳澶囦俊鎭�"); } - //(device as AuboRobotDriver).IOChangedHandle.Set(); + //if (bind.FullTrayNum >= Config.AGVAvailableTrayNums) + { + bind.FullTrayNum = Config.AGVAvailableTrayNums; - //bind.RobotIOHandle.Set(); + TrayTask task = new TrayTask(); + task.TaskType = TaskType.UnloadFullTrayToLine; + task.SourceDeviceId = device.Id; + + //濡傛灉鐩墠鍦板潃琚崰鐢紝鍦板潃鏈夊彲鑳戒负绌猴紝闇�瑕佸湪浠诲姟鎸囨淳鏃跺啀娆$‘璁� + task.Location = Config.PositionCollection.FirstOrDefault(u => !u.IsOccupied && u.Description == PathPositionDefinition.UnloadFullTray); + + InsertTask(task); + } return new ProcessResponse(true); } @@ -457,13 +100,14 @@ [ProcessMethod("", "Robot_Monitor_FullTrayEmpty", "鏈哄櫒浜虹洃鍚簨浠�-婊ray鍖哄煙娓呯┖", true)] public ProcessResponse Robot_Monitor_FullTrayEmpty(IOperationConfig config, IDevice device) { - //(device as AuboRobotDriver).IOChangedHandle.Reset(); - bool isFullTrayEmpty = config.InputPara[0] == 0; var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == device.Id); - bind.IsFullTrayEmpty = isFullTrayEmpty; - //(device as AuboRobotDriver).IOChangedHandle.Set(); - //bind.RobotIOHandle.Set(); + if (bind == null) + { + throw new ProcessException($"鏈兘鑾峰彇{device.Name}鐨勭粦瀹氳澶囦俊鎭�"); + } + + bind.FullTrayNum = 0; return new ProcessResponse(true); } @@ -499,27 +143,103 @@ if (bind == null) { - throw new ProcessException("鏈兘鏍规嵁鏈哄櫒浜轰俊鎭幏鍙栫粦瀹氳澶囦俊鎭�", null); + throw new ProcessException($"鏈兘鑾峰彇{device.Name}鐨勭粦瀹氳澶囦俊鎭�"); } bind.AGV.CancelTask(); - //isEmptyTrayTaskAssigned = false; - //isFullTrayTaskAssigned = false; - - taskAssignedList.RemoveAll(u => u.AgvId == device.Id); - - //bind.ClearTask(); - bind.RobotStatus = bind.AGVStatus = TaskStatus.Available; + Reset(bind.Id); return new ProcessResponse(true); } #endregion - #region 绌篢ray涓婃枡 - //[ProcessMethod("", "AGV_LoadEmptyTray", "AGV鍘诲線绌篢ray涓婃枡", true)] - //public ProcessResponse AGV_LoadEmptyTray(IOperationConfig config, IDevice device) + #region PLC鐩戝惉浜嬩欢 + [ProcessMethod("", "PLC_NoticeEmptyTray", "PLC閫氱煡闇�瑕佷笂绌篢ray", true)] + public ProcessResponse PLC_NoticeEmptyTray(IOperationConfig config, IDevice device) + { + TrayTask task = new TrayTask(); + task.TaskType = TaskType.UnloadEmptyTrayToMachine; + task.SourceDeviceId = device.Id; + //task.SourceDeviceName = device.Name; + task.Location = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadEmptyTray && u.DeviceOwner == device.Id); + + InsertTask(task); + + return new ProcessResponse(true); + } + + [ProcessMethod("", "PLC_NoticeFullTray", "PLC閫氱煡婊ray闇�瑕佸彇璧�", true)] + public ProcessResponse PLC_NoticeFullTray(IOperationConfig config, IDevice device) + { + TrayTask task = new TrayTask(); + task.TaskType = TaskType.LoadFullTrayFromMachine; + task.SourceDeviceId = device.Id; + //task.SourceDeviceName = device.Name; + task.Location = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadFullTray && u.DeviceOwner == device.Id); + + InsertTask(task); + + return new ProcessResponse(true); + } + #endregion + + [ProcessMethod("OperationTest", "OperationDemo", "鍗曟娴嬭瘯鏂规硶", true)] + public ProcessResponse OperationDemo(IOperationConfig config, IDevice device) + { + string s = (-1).ToString("D2"); + string a = (1).ToString("D2"); + + OperationTestConfig opConfig = config as OperationTestConfig; + + var bind = Config.AGVBindCollection.FirstOrDefault(u => u.AGVId == opConfig.AGVId); + if (bind == null) + throw new ProcessException("鏈兘鑾峰彇鎸囧畾AGV淇℃伅鎴朅GV缁戝畾鐨勮澶囦俊鎭�"); + + switch (opConfig.TaskInfo.TaskType) + { + case TaskType.LoadEmptyTrayToAGV: + LoadEmptyTrayToAGV(opConfig.TaskInfo, bind); + break; + case TaskType.LoadFullTrayFromMachine: + LoadFullTrayFromMachine(opConfig.TaskInfo, bind); + break; + case TaskType.UnloadEmptyTrayToMachine: + UnloadEmptyTrayToMachine(opConfig.TaskInfo, bind); + break; + case TaskType.UnloadFullTrayToLine: + UnloadFullTrayToLine(opConfig.TaskInfo, bind); + break; + default: + throw new ProcessException($"鏈兘鎸囧畾{opConfig.TaskInfo.TaskType.ToString()}鐨勫搴旀柟娉�"); + } + + return new ProcessResponse(true); + } + + #region old + //#region 绌篢ray涓婃枡 + ////[ProcessMethod("", "AGV_LoadEmptyTray", "AGV鍘诲線绌篢ray涓婃枡", true)] + ////public ProcessResponse AGV_LoadEmptyTray(IOperationConfig config, IDevice device) + ////{ + //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); + //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); + + //// if (position == null) + //// { + //// throw new ProcessException("璺緞閰嶇疆鏈缃┖Tray涓婃枡鐐�"); + //// } + + //// bind.AGVDest = position.PositionCode; + //// bind.AGV.TaskOrder(position.PositionCode); + + //// bind.AGVStatus = TaskStatus.Running; + + //// return new ProcessResponse(true); + ////} + + //public bool AGV_LoadEmptyTray(string bindId) //{ - // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); // if (position == null) @@ -527,42 +247,45 @@ // throw new ProcessException("璺緞閰嶇疆鏈缃┖Tray涓婃枡鐐�"); // } - // bind.AGVDest = position.PositionCode; - // bind.AGV.TaskOrder(position.PositionCode); + // if (bind.SetAGVStatus(TaskStatus.Running)) + // { + // bind.AGVDest = position.PositionCode; + // bind.AGV.TaskOrder(position.PositionCode); - // bind.AGVStatus = TaskStatus.Running; - - // return new ProcessResponse(true); + // return true; + // } + // else + // { + // return false; + // } //} - public bool AGV_LoadEmptyTray(string bindId) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); - PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); + ////[ProcessMethod("", "AfterEmptyTrayPositionArrived", "鍒拌揪绌篢ray涓婃枡鐐�", true)] + ////public ProcessResponse AfterEmptyTrayPositionArrived(IOperationConfig config, IDevice device) + ////{ + //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); + //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); - if (position == null) - { - throw new ProcessException("璺緞閰嶇疆鏈缃┖Tray涓婃枡鐐�"); - } + //// if (position == null) + //// { + //// throw new ProcessException("璺緞閰嶇疆鏈缃┖Tray涓婃枡鐐�", null); + //// } - if (bind.SetAGVStatus(TaskStatus.Running)) - { - bind.AGVDest = position.PositionCode; - bind.AGV.TaskOrder(position.PositionCode); + //// if (bind.AGV.CurrentPosition != position.PositionCode) + //// { + //// throw new ProcessException("AGV灏氭湭鍒拌揪绌篢ray涓婃枡鐐�", null); + //// } - return true; - } - else - { - return false; - } - } + //// bind.Robot.SendMsg(RobotMsgAction.Load, RobotMsgParas.EmptyTray, 0); + //// bind.RobotStatus = TaskStatus.Running; - //[ProcessMethod("", "AfterEmptyTrayPositionArrived", "鍒拌揪绌篢ray涓婃枡鐐�", true)] - //public ProcessResponse AfterEmptyTrayPositionArrived(IOperationConfig config, IDevice device) + //// return new ProcessResponse(true); + ////} + + //public void Robot_LoadEmptyTray(string bindId, PathPosition position) //{ - // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); - // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); + // //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); // if (position == null) // { @@ -576,160 +299,166 @@ // bind.Robot.SendMsg(RobotMsgAction.Load, RobotMsgParas.EmptyTray, 0); // bind.RobotStatus = TaskStatus.Running; - - // return new ProcessResponse(true); //} - public void Robot_LoadEmptyTray(string bindId, PathPosition position) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); - //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); + ////[ProcessMethod("", "EmptyTrayReady", "绌篢ray涓婃枡瀹屾垚", true)] + ////public ProcessResponse EmptyTrayReady(IOperationConfig config, IDevice device) + ////{ + //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); + //// bind.RobotStatus = bind.AGVStatus = TaskStatus.Available; - if (position == null) - { - throw new ProcessException("璺緞閰嶇疆鏈缃┖Tray涓婃枡鐐�", null); - } + //// return new ProcessResponse(true); + ////} + //#endregion - if (bind.AGV.CurrentPosition != position.PositionCode) - { - throw new ProcessException("AGV灏氭湭鍒拌揪绌篢ray涓婃枡鐐�", null); - } + //#region 绌篢ray寰�鏈哄彴涓嬫枡 + ////bool isEmptyTrayNeed = false; + ////bool isEmptyTrayTaskAssigned = false; + //RobotMsg RobotMsg_UnloadEmptyTray = new RobotMsg(); - bind.Robot.SendMsg(RobotMsgAction.Load, RobotMsgParas.EmptyTray, 0); - bind.RobotStatus = TaskStatus.Running; - } - - //[ProcessMethod("", "EmptyTrayReady", "绌篢ray涓婃枡瀹屾垚", true)] - //public ProcessResponse EmptyTrayReady(IOperationConfig config, IDevice device) + //private async void CheckUnloadEmptyTrayTask(int positionNo) //{ - // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); - // bind.RobotStatus = bind.AGVStatus = TaskStatus.Available; + // await Task.Run(() => + // { + // var taskStatus = taskAssignedList.FirstOrDefault(u => u.PositionNo == positionNo); - // return new ProcessResponse(true); + // if (taskStatus == null) + // return; + + // while (taskStatus.IsTaskNeed && !taskStatus.IsTaskAssgined) + // { + // //Func<IOperationConfig, IDevice, ProcessResponse> action = AGV_UnloadEmptyTray; + + // //if (!Config.AGVBindCollection.Any(b => b.TaskList.Any(t => t.MethodName == "AGV_UnloadEmptyTray"))) + // { + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.UnitStatus == TaskStatus.Available); + // if (bind != null) + // { + // var position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == positionNo); + // //AGVTaskModel model_AGV = new AGVTaskModel(TaskAvailableLevel.Both, "AGV_UnloadEmptyTray", new AGVBindOpConfig(bind.Id, position)); + // //AGVTaskModel model_Robot = new AGVTaskModel(TaskAvailableLevel.AGV, "Robot_UnloadEmptyTray", new AGVBindOpConfig(bind.Id)); + + // //bind.AddTask(model_AGV); + // //bind.AddTask(model_Robot); + + // if (AGV_UnloadEmptyTray(bind.Id, position)) + // { + // taskStatus.IsTaskAssgined = true; + // taskStatus.AgvId = bind.AGVId; + // } + // } + // } + + // Thread.Sleep(WAITTIME); + // } + // }); //} - #endregion - #region 绌篢ray寰�鏈哄彴涓嬫枡 - //bool isEmptyTrayNeed = false; - //bool isEmptyTrayTaskAssigned = false; - RobotMsg RobotMsg_UnloadEmptyTray = new RobotMsg(); - - [ProcessMethod("", "PLC_NoticeEmptyTray", "PLC閫氱煡闇�瑕佷笂绌篢ray", true)] - public ProcessResponse PLC_NoticeEmptyTray(IOperationConfig config, IDevice device) - { - if (config.InputPara == null || config.InputPara.Count == 0) - { - throw new ProcessException("涓婄┖Tray鏂规硶鏈厤缃緭鍏ュ弬鏁�", null); - } - - bool isEmptyTrayNeed = config.InputPara[0] == 1; - - if (isEmptyTrayNeed) - { - var position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadEmptyTray && u.DeviceOwner == device.Id); - - machineEmptyTrayDict[position.PositionNo] = 0; - - if (!taskAssignedList.Any(u => u.PositionNo == position.PositionNo)) - { - taskAssignedList.Add(new TaskAssignInfo() - { - IsTaskNeed = true, - IsTaskAssgined = false, - PositionNo = position.PositionNo, - }); - } - - CheckUnloadEmptyTrayTask(position.PositionNo); - } - - return new ProcessResponse(true); - } - - private async void CheckUnloadEmptyTrayTask(int positionNo) - { - await Task.Run(() => - { - var taskStatus = taskAssignedList.FirstOrDefault(u => u.PositionNo == positionNo); - - if (taskStatus == null) - return; - - while (taskStatus.IsTaskNeed && !taskStatus.IsTaskAssgined) - { - //Func<IOperationConfig, IDevice, ProcessResponse> action = AGV_UnloadEmptyTray; - - //if (!Config.AGVBindCollection.Any(b => b.TaskList.Any(t => t.MethodName == "AGV_UnloadEmptyTray"))) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.UnitStatus == TaskStatus.Available); - if (bind != null) - { - var position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == positionNo); - //AGVTaskModel model_AGV = new AGVTaskModel(TaskAvailableLevel.Both, "AGV_UnloadEmptyTray", new AGVBindOpConfig(bind.Id, position)); - //AGVTaskModel model_Robot = new AGVTaskModel(TaskAvailableLevel.AGV, "Robot_UnloadEmptyTray", new AGVBindOpConfig(bind.Id)); - - //bind.AddTask(model_AGV); - //bind.AddTask(model_Robot); - - if (AGV_UnloadEmptyTray(bind.Id, position)) - { - taskStatus.IsTaskAssgined = true; - taskStatus.AgvId = bind.AGVId; - } - } - } - - Thread.Sleep(WAITTIME); - } - }); - } - - //[ProcessMethod("", "AGV_UnloadEmptyTray", "AGV鍘诲線鍗歌浇绌篢ray鏂欎綅缃�", true)] - public bool AGV_UnloadEmptyTray(string bindId, PathPosition position) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); - - if (position == null) - { - throw new ProcessException("璺緞閰嶇疆鏈缃┖Tray涓嬫枡鐐�"); - } - - if (bind.SetAGVStatus(TaskStatus.Running)) - { - bind.AGVDest = position.PositionCode; - bind.AGV.TaskOrder(position.PositionCode); - - return true; - } - else - { - return false; - } - } - - //[ProcessMethod("", "Robot_UnloadEmptyTray", "鏈哄櫒浜鸿繍鍔ㄨ嚦绌篢ray鎷嶇収浣嶇疆", true)] - public void Robot_UnloadEmptyTraySnap(string bindId, PathPosition position) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); - //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadEmptyTray && u.PositionCode == bind.AGV.CurrentPosition); - - if (position == null) - { - throw new ProcessException("璺緞閰嶇疆鏈缃┖Tray涓嬫枡鐐�"); - } - - taskAssignedList.RemoveAll(u => u.AgvId == bind.AGVId && u.PositionNo == position.PositionNo); - - bind.RobotStatus = TaskStatus.Running; - bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.UnloadEmptyTraySnap, position.PositionNo); - } - - //[ProcessMethod("", "Camera_UnloadEmptyTray", "鐩告満纭绌篢ray鍗歌浇鏈哄櫒浜轰綅缃皟鏁�", true)] - //public ProcessResponse Camera_UnloadEmptyTray(IOperationConfig config, IDevice device) + ////[ProcessMethod("", "AGV_UnloadEmptyTray", "AGV鍘诲線鍗歌浇绌篢ray鏂欎綅缃�", true)] + //public bool AGV_UnloadEmptyTray(string bindId, PathPosition position) //{ - // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); - // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadEmptyTray); + // if (position == null) + // { + // throw new ProcessException("璺緞閰嶇疆鏈缃┖Tray涓嬫枡鐐�"); + // } + + // if (bind.SetAGVStatus(TaskStatus.Running)) + // { + // bind.AGVDest = position.PositionCode; + // bind.AGV.TaskOrder(position.PositionCode); + + // return true; + // } + // else + // { + // return false; + // } + //} + + ////[ProcessMethod("", "Robot_UnloadEmptyTray", "鏈哄櫒浜鸿繍鍔ㄨ嚦绌篢ray鎷嶇収浣嶇疆", true)] + //public void Robot_UnloadEmptyTraySnap(string bindId, PathPosition position) + //{ + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); + // //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadEmptyTray && u.PositionCode == bind.AGV.CurrentPosition); + + // if (position == null) + // { + // throw new ProcessException("璺緞閰嶇疆鏈缃┖Tray涓嬫枡鐐�"); + // } + + // taskAssignedList.RemoveAll(u => u.AgvId == bind.AGVId && u.PositionNo == position.PositionNo); + + // bind.RobotStatus = TaskStatus.Running; + // bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.UnloadEmptyTraySnap, position.PositionNo); + //} + + ////[ProcessMethod("", "Camera_UnloadEmptyTray", "鐩告満纭绌篢ray鍗歌浇鏈哄櫒浜轰綅缃皟鏁�", true)] + ////public ProcessResponse Camera_UnloadEmptyTray(IOperationConfig config, IDevice device) + ////{ + //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); + + //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadEmptyTray); + + //// if (position == null) + //// { + //// throw new ProcessException("璺緞閰嶇疆鏈缃┖Tray涓嬫枡鐐�"); + //// } + + //// if (bind.AGV.CurrentPosition != position.PositionCode) + //// { + //// throw new ProcessException("AGV褰撳墠鏈浜庣┖Tray涓嬫枡鐐�"); + //// } + + //// PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); + + //// if (visionConfig == null) + //// { + //// throw new ProcessException("鏈厤缃鐩告満鐨勭┖Tray涓嬫枡鐐圭殑瑙嗚鎿嶄綔閰嶇疆"); + //// } + + //// float x = 0; + //// float y = 0; + //// float angle = 0; + + //// using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_UnloadEmptyTray")) + //// { + //// string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; + //// if (!_halconToolDict.ContainsKey(toolPath)) + //// { + //// throw new ProcessException($"鏈厤缃瓹amera_UnloadEmptyTray鐨勮瑙夌畻娉曡矾寰�"); + //// } + + //// var tool = _halconToolDict[toolPath]; + //// tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); + //// tool.RunProcedure(); + + //// x = (float)tool.GetResultTuple("OUTPUT_X").D; + //// y = (float)tool.GetResultTuple("OUTPUT_Y").D; + //// angle = (float)tool.GetResultTuple("OUTPUT_Angle").D; + //// } + + //// if (x <= 0 || y <= 0) + //// { + //// throw new ProcessException("Camera_UnloadEmptyTray瑙嗚璁$畻鑾峰彇鐐逛綅涓嶅彲灏忎簬0"); + //// } + + //// float dx = visionConfig.StandardPoint.X - x; + //// float dy = visionConfig.StandardPoint.Y - y; + + //// HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix[0], visionConfig.Matrix[1], 0, visionConfig.Matrix[3], visionConfig.Matrix[4], 0), dx, dy, out HTuple dx_Robot, out HTuple dy_Robot); + + //// bind.Robot.SendMsg(RobotMsgAction.Unload, RobotMsgParas.EmptyTray, position.PositionNo, new List<float>() { (float)dx_Robot.D, (float)dy_Robot.D, angle }); + + //// return new ProcessResponse(true); + ////} + + //public ProcessResponse Camera_UnloadEmptyTray(string robotId, int positionNum) + //{ + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == robotId); + + // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == positionNum); // if (position == null) // { @@ -741,231 +470,162 @@ // throw new ProcessException("AGV褰撳墠鏈浜庣┖Tray涓嬫枡鐐�"); // } - // PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); + // float adjust_X = 0.0f; + // float adjust_Y = 0.0f; + // float adjust_Angle = 0.0f; - // if (visionConfig == null) + // if (Config.IsEnableVisionGuide) // { - // throw new ProcessException("鏈厤缃鐩告満鐨勭┖Tray涓嬫枡鐐圭殑瑙嗚鎿嶄綔閰嶇疆"); - // } + // PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); - // float x = 0; - // float y = 0; - // float angle = 0; - - // using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_UnloadEmptyTray")) - // { - // string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; - // if (!_halconToolDict.ContainsKey(toolPath)) + // if (visionConfig == null) // { - // throw new ProcessException($"鏈厤缃瓹amera_UnloadEmptyTray鐨勮瑙夌畻娉曡矾寰�"); + // throw new ProcessException("鏈厤缃鐩告満鐨勭┖Tray涓嬫枡鐐圭殑瑙嗚鎿嶄綔閰嶇疆"); // } - // var tool = _halconToolDict[toolPath]; - // tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); - // tool.RunProcedure(); + // float x = 0; + // float y = 0; + // float angle = 0; - // x = (float)tool.GetResultTuple("OUTPUT_X").D; - // y = (float)tool.GetResultTuple("OUTPUT_Y").D; - // angle = (float)tool.GetResultTuple("OUTPUT_Angle").D; + // using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_UnloadEmptyTray")) + // { + // string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; + // if (!_halconToolDict.ContainsKey(toolPath)) + // { + // throw new ProcessException($"鏈厤缃瓹amera_UnloadEmptyTray鐨勮瑙夌畻娉曡矾寰�"); + // } + + // var tool = _halconToolDict[toolPath]; + // tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); + // tool.RunProcedure(); + + // x = (float)tool.GetResultTuple("OUTPUT_X").D; + // y = (float)tool.GetResultTuple("OUTPUT_Y").D; + // angle = (float)tool.GetResultTuple("OUTPUT_Angle").D; + // } + + // if (x <= 0 || y <= 0) + // { + // throw new ProcessException("Camera_UnloadEmptyTray瑙嗚璁$畻鑾峰彇鐐逛綅涓嶅彲灏忎簬0"); + // } + + // float dx = visionConfig.StandardPoint.X - x; + // float dy = visionConfig.StandardPoint.Y - y; + + // HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix[0], visionConfig.Matrix[1], 0, visionConfig.Matrix[3], visionConfig.Matrix[4], 0), dx, dy, out HTuple dx_Robot, out HTuple dy_Robot); + + // adjust_X = (float)dx_Robot.D; + // adjust_Y = (float)dy_Robot.D; + // adjust_Angle = visionConfig.StandardPoint.Angle - angle; // } - // if (x <= 0 || y <= 0) - // { - // throw new ProcessException("Camera_UnloadEmptyTray瑙嗚璁$畻鑾峰彇鐐逛綅涓嶅彲灏忎簬0"); - // } - - // float dx = visionConfig.StandardPoint.X - x; - // float dy = visionConfig.StandardPoint.Y - y; - - // HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix[0], visionConfig.Matrix[1], 0, visionConfig.Matrix[3], visionConfig.Matrix[4], 0), dx, dy, out HTuple dx_Robot, out HTuple dy_Robot); - - // bind.Robot.SendMsg(RobotMsgAction.Unload, RobotMsgParas.EmptyTray, position.PositionNo, new List<float>() { (float)dx_Robot.D, (float)dy_Robot.D, angle }); + // //bind.Robot.SendMsg(RobotMsgAction.Unload, RobotMsgParas.EmptyTray, position.PositionNo, new List<float>() { (float)dx_Robot.D, (float)dy_Robot.D, angle }); + // RobotMsg_UnloadEmptyTray.Action = RobotMsgAction.Unload; + // RobotMsg_UnloadEmptyTray.Para1 = RobotMsgParas.EmptyTray; + // RobotMsg_UnloadEmptyTray.Para2 = position.PositionNo; + // RobotMsg_UnloadEmptyTray.Datas = new List<float>() { adjust_X, adjust_Y, 0, adjust_Angle }.ConvertAll(s => s.ToString()).ToList(); + // bind.Robot.SendMsg(RobotMsg_UnloadEmptyTray, true); // return new ProcessResponse(true); //} + //#endregion - public ProcessResponse Camera_UnloadEmptyTray(string robotId, int positionNum) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == robotId); + //#region 浠庢満鍙颁笂婊ray + ////bool isFullTrayNeed = false; + ////bool isFullTrayTaskAssigned = false; + //RobotMsg RobotMsg_LoadFullTray = new RobotMsg(); - PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == positionNum); - - if (position == null) - { - throw new ProcessException("璺緞閰嶇疆鏈缃┖Tray涓嬫枡鐐�"); - } - - if (bind.AGV.CurrentPosition != position.PositionCode) - { - throw new ProcessException("AGV褰撳墠鏈浜庣┖Tray涓嬫枡鐐�"); - } - - float adjust_X = 0.0f; - float adjust_Y = 0.0f; - float adjust_Angle = 0.0f; - - if (Config.IsEnableVisionGuide) - { - PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); - - if (visionConfig == null) - { - throw new ProcessException("鏈厤缃鐩告満鐨勭┖Tray涓嬫枡鐐圭殑瑙嗚鎿嶄綔閰嶇疆"); - } - - float x = 0; - float y = 0; - float angle = 0; - - using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_UnloadEmptyTray")) - { - string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; - if (!_halconToolDict.ContainsKey(toolPath)) - { - throw new ProcessException($"鏈厤缃瓹amera_UnloadEmptyTray鐨勮瑙夌畻娉曡矾寰�"); - } - - var tool = _halconToolDict[toolPath]; - tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); - tool.RunProcedure(); - - x = (float)tool.GetResultTuple("OUTPUT_X").D; - y = (float)tool.GetResultTuple("OUTPUT_Y").D; - angle = (float)tool.GetResultTuple("OUTPUT_Angle").D; - } - - if (x <= 0 || y <= 0) - { - throw new ProcessException("Camera_UnloadEmptyTray瑙嗚璁$畻鑾峰彇鐐逛綅涓嶅彲灏忎簬0"); - } - - float dx = visionConfig.StandardPoint.X - x; - float dy = visionConfig.StandardPoint.Y - y; - - HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix[0], visionConfig.Matrix[1], 0, visionConfig.Matrix[3], visionConfig.Matrix[4], 0), dx, dy, out HTuple dx_Robot, out HTuple dy_Robot); - - adjust_X = (float)dx_Robot.D; - adjust_Y = (float)dy_Robot.D; - adjust_Angle = visionConfig.StandardPoint.Angle - angle; - } - - //bind.Robot.SendMsg(RobotMsgAction.Unload, RobotMsgParas.EmptyTray, position.PositionNo, new List<float>() { (float)dx_Robot.D, (float)dy_Robot.D, angle }); - RobotMsg_UnloadEmptyTray.Action = RobotMsgAction.Unload; - RobotMsg_UnloadEmptyTray.Para1 = RobotMsgParas.EmptyTray; - RobotMsg_UnloadEmptyTray.Para2 = position.PositionNo; - RobotMsg_UnloadEmptyTray.Datas = new List<float>() { adjust_X, adjust_Y, 0, adjust_Angle }.ConvertAll(s => s.ToString()).ToList(); - bind.Robot.SendMsg(RobotMsg_UnloadEmptyTray, true); - - return new ProcessResponse(true); - } - #endregion - - #region 浠庢満鍙颁笂婊ray - //bool isFullTrayNeed = false; - //bool isFullTrayTaskAssigned = false; - RobotMsg RobotMsg_LoadFullTray = new RobotMsg(); - - [ProcessMethod("", "PLC_NoticeFullTray", "PLC閫氱煡婊ray闇�瑕佸彇璧�", true)] - public ProcessResponse PLC_NoticeFullTray(IOperationConfig config, IDevice device) - { - if (config.InputPara == null || config.InputPara.Count == 0) - { - throw new ProcessException("涓婄┖Tray鏂规硶鏈厤缃緭鍏ュ弬鏁�", null); - } - - bool isFullTrayNeed = config.InputPara[0] == 1; - if (isFullTrayNeed) - { - var position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadFullTray && u.DeviceOwner == device.Id); - - machineFullTrayDict[position.PositionNo] = Config.Machine_FullTrayNum; - - if (!taskAssignedList.Any(u => u.PositionNo == position.PositionNo)) - { - taskAssignedList.Add(new TaskAssignInfo() - { - IsTaskNeed = true, - IsTaskAssgined = false, - PositionNo = position.PositionNo, - }); - } - - CheckFullTrayTask(position.PositionNo); - } - - return new ProcessResponse(true); - } - - private async void CheckFullTrayTask(int positionNo) - { - await Task.Run(() => - { - var taskStatus = taskAssignedList.FirstOrDefault(u => u.PositionNo == positionNo); - - if (taskStatus == null) - return; - - while (taskStatus.IsTaskNeed && !taskStatus.IsTaskAssgined) - { - //Func<IOperationConfig, IDevice, ProcessResponse> action = AGV_LoadFullTray; - - //if (!Config.AGVBindCollection.Any(b => b.TaskList.Any(t => t.MethodFunc.Method.Name == action.Method.Name))) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.UnitStatus == TaskStatus.Available); - if (bind != null) - { - var position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == positionNo); - //AGVTaskModel model_AGV = new AGVTaskModel(TaskAvailableLevel.Both, "AGV_LoadFullTray", new AGVBindOpConfig(bind.Id, position)); - //AGVTaskModel model_Robot = new AGVTaskModel(TaskAvailableLevel.AGV, "Robot_LoadFullTray", new AGVBindOpConfig(bind.Id)); - - //bind.AddTask(model_AGV); - //bind.AddTask(model_Robot); - - if (AGV_LoadFullTray(bind.Id, position)) - { - taskStatus.IsTaskAssgined = true; - taskStatus.AgvId = bind.AGVId; - } - } - } - - Thread.Sleep(300); - } - }); - } - - //[ProcessMethod("", "AGV_LoadFullTray", "AGV鍘诲線婊ray涓婃枡浣嶇疆", true)] - public bool AGV_LoadFullTray(string bindId, PathPosition position) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); - - //PathPosition position = (config as AGVBindOpConfig).Position; - - if (position == null) - { - throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓婃枡鐐�"); - } - - if (bind.SetAGVStatus(TaskStatus.Running)) - { - bind.AGVDest = position.PositionCode; - bind.AGV.TaskOrder(position.PositionCode); - - return true; - } - else - { - return false; - } - - //return new ProcessResponse(true); - } - - //[ProcessMethod("", "Robot_LoadFullTray", "鏈哄櫒浜鸿繍鍔ㄨ嚦婊ray鎷嶇収浣嶇疆", true)] - //public ProcessResponse Robot_LoadFullTray(IOperationConfig config, IDevice device) + //private async void CheckFullTrayTask(int positionNo) //{ - // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); - // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadFullTray && u.PositionCode == bind.AGV.CurrentPosition); + // await Task.Run(() => + // { + // var taskStatus = taskAssignedList.FirstOrDefault(u => u.PositionNo == positionNo); + + // if (taskStatus == null) + // return; + + // while (taskStatus.IsTaskNeed && !taskStatus.IsTaskAssgined) + // { + // //Func<IOperationConfig, IDevice, ProcessResponse> action = AGV_LoadFullTray; + + // //if (!Config.AGVBindCollection.Any(b => b.TaskList.Any(t => t.MethodFunc.Method.Name == action.Method.Name))) + // { + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.UnitStatus == TaskStatus.Available); + // if (bind != null) + // { + // var position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == positionNo); + // //AGVTaskModel model_AGV = new AGVTaskModel(TaskAvailableLevel.Both, "AGV_LoadFullTray", new AGVBindOpConfig(bind.Id, position)); + // //AGVTaskModel model_Robot = new AGVTaskModel(TaskAvailableLevel.AGV, "Robot_LoadFullTray", new AGVBindOpConfig(bind.Id)); + + // //bind.AddTask(model_AGV); + // //bind.AddTask(model_Robot); + + // if (AGV_LoadFullTray(bind.Id, position)) + // { + // taskStatus.IsTaskAssgined = true; + // taskStatus.AgvId = bind.AGVId; + // } + // } + // } + + // Thread.Sleep(300); + // } + // }); + //} + + ////[ProcessMethod("", "AGV_LoadFullTray", "AGV鍘诲線婊ray涓婃枡浣嶇疆", true)] + //public bool AGV_LoadFullTray(string bindId, PathPosition position) + //{ + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); + + // //PathPosition position = (config as AGVBindOpConfig).Position; + + // if (position == null) + // { + // throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓婃枡鐐�"); + // } + + // if (bind.SetAGVStatus(TaskStatus.Running)) + // { + // bind.AGVDest = position.PositionCode; + // bind.AGV.TaskOrder(position.PositionCode); + + // return true; + // } + // else + // { + // return false; + // } + + // //return new ProcessResponse(true); + //} + + ////[ProcessMethod("", "Robot_LoadFullTray", "鏈哄櫒浜鸿繍鍔ㄨ嚦婊ray鎷嶇収浣嶇疆", true)] + ////public ProcessResponse Robot_LoadFullTray(IOperationConfig config, IDevice device) + ////{ + //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); + //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadFullTray && u.PositionCode == bind.AGV.CurrentPosition); + + //// if (position == null) + //// { + //// throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓婃枡鐐�"); + //// } + + //// //if (bind.AGV.CurrentPosition != position.PositionCode) + //// //{ + //// // throw new ProcessException("AGV褰撳墠鏈浜庢弧Tray涓婃枡鐐�"); + //// //} + + //// bind.RobotStatus = TaskStatus.Running; + //// bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.LoadFullTraySnap, position.PositionNo); + + //// return new ProcessResponse(true); + ////} + + //public void Robot_LoadFullTraySnap(string bindId, PathPosition position) + //{ + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); + // //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadFullTray && u.PositionCode == bind.AGV.CurrentPosition); // if (position == null) // { @@ -979,35 +639,73 @@ // bind.RobotStatus = TaskStatus.Running; // bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.LoadFullTraySnap, position.PositionNo); - - // return new ProcessResponse(true); //} - public void Robot_LoadFullTraySnap(string bindId, PathPosition position) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); - //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadFullTray && u.PositionCode == bind.AGV.CurrentPosition); + ////[ProcessMethod("", "Camera_LoadFullTray", "鐩告満纭婊ray涓婃枡鏈哄櫒浜轰綅缃皟鏁�", true)] + ////public ProcessResponse Camera_LoadFullTray(IOperationConfig config, IDevice device) + ////{ + //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); - if (position == null) - { - throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓婃枡鐐�"); - } + //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadFullTray); - //if (bind.AGV.CurrentPosition != position.PositionCode) - //{ - // throw new ProcessException("AGV褰撳墠鏈浜庢弧Tray涓婃枡鐐�"); - //} + //// if (position == null) + //// { + //// throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓婃枡鐐�"); + //// } - bind.RobotStatus = TaskStatus.Running; - bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.LoadFullTraySnap, position.PositionNo); - } + //// if (bind.AGV.CurrentPosition != position.PositionCode) + //// { + //// throw new ProcessException("AGV褰撳墠鏈浜庢弧Tray涓婃枡鐐�"); + //// } - //[ProcessMethod("", "Camera_LoadFullTray", "鐩告満纭婊ray涓婃枡鏈哄櫒浜轰綅缃皟鏁�", true)] - //public ProcessResponse Camera_LoadFullTray(IOperationConfig config, IDevice device) + //// PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); + + //// if (visionConfig == null) + //// { + //// throw new ProcessException("鏈厤缃鐩告満鐨勬弧Tray涓婃枡鐐圭殑瑙嗚鎿嶄綔閰嶇疆"); + //// } + + //// float x = 0; + //// float y = 0; + //// float angle = 0; + + //// using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_LoadFullTray")) + //// { + //// string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; + //// if (!_halconToolDict.ContainsKey(toolPath)) + //// { + //// throw new ProcessException($"鏈厤缃瓹amera_LoadFullTray鐨勮瑙夌畻娉曡矾寰�"); + //// } + + //// var tool = _halconToolDict[toolPath]; + //// tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); + //// tool.RunProcedure(); + + //// x = (float)tool.GetResultTuple("OUTPUT_X").D; + //// y = (float)tool.GetResultTuple("OUTPUT_Y").D; + //// angle = (float)tool.GetResultTuple("OUTPUT_Angle").D; + //// } + + //// if (x <= 0 || y <= 0) + //// { + //// throw new ProcessException("Camera_LoadFullTray瑙嗚璁$畻鑾峰彇鐐逛綅涓嶅彲灏忎簬0"); + //// } + + //// float dx = visionConfig.StandardPoint.X - x; + //// float dy = visionConfig.StandardPoint.Y - y; + + //// HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix[0], visionConfig.Matrix[1], 0, visionConfig.Matrix[3], visionConfig.Matrix[4], 0), dx, dy, out HTuple dx_Robot, out HTuple dy_Robot); + + //// bind.Robot.SendMsg(RobotMsgAction.Load, RobotMsgParas.FullTray, position.PositionNo, new List<float>() { (float)dx_Robot.D, (float)dy_Robot.D, angle }); + + //// return new ProcessResponse(true); + ////} + + //public ProcessResponse Camera_LoadFullTray(string robotId, int positionNum) //{ - // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == robotId); - // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadFullTray); + // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == positionNum); // if (position == null) // { @@ -1019,130 +717,89 @@ // throw new ProcessException("AGV褰撳墠鏈浜庢弧Tray涓婃枡鐐�"); // } - // PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); + // float adjust_X = 0.0f; + // float adjust_Y = 0.0f; + // float adjust_Angle = 0.0f; - // if (visionConfig == null) + // if (Config.IsEnableVisionGuide) // { - // throw new ProcessException("鏈厤缃鐩告満鐨勬弧Tray涓婃枡鐐圭殑瑙嗚鎿嶄綔閰嶇疆"); - // } + // PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); - // float x = 0; - // float y = 0; - // float angle = 0; - - // using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_LoadFullTray")) - // { - // string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; - // if (!_halconToolDict.ContainsKey(toolPath)) + // if (visionConfig == null) // { - // throw new ProcessException($"鏈厤缃瓹amera_LoadFullTray鐨勮瑙夌畻娉曡矾寰�"); + // throw new ProcessException("鏈厤缃鐩告満鐨勬弧Tray涓婃枡鐐圭殑瑙嗚鎿嶄綔閰嶇疆"); // } - // var tool = _halconToolDict[toolPath]; - // tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); - // tool.RunProcedure(); + // float x = 0; + // float y = 0; + // float angle = 0; - // x = (float)tool.GetResultTuple("OUTPUT_X").D; - // y = (float)tool.GetResultTuple("OUTPUT_Y").D; - // angle = (float)tool.GetResultTuple("OUTPUT_Angle").D; + // using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_LoadFullTray")) + // { + // string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; + // if (!_halconToolDict.ContainsKey(toolPath)) + // { + // throw new ProcessException($"鏈厤缃瓹amera_LoadFullTray鐨勮瑙夌畻娉曡矾寰�"); + // } + + // var tool = _halconToolDict[toolPath]; + // tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); + // tool.RunProcedure(); + + // x = (float)tool.GetResultTuple("OUTPUT_X").D; + // y = (float)tool.GetResultTuple("OUTPUT_Y").D; + // angle = (float)tool.GetResultTuple("OUTPUT_Angle").D; + // } + + // if (x <= 0 || y <= 0) + // { + // throw new ProcessException("Camera_LoadFullTray瑙嗚璁$畻鑾峰彇鐐逛綅涓嶅彲灏忎簬0"); + // } + + // float dx = visionConfig.StandardPoint.X - x; + // float dy = visionConfig.StandardPoint.Y - y; + + // HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix[0], visionConfig.Matrix[1], 0, visionConfig.Matrix[3], visionConfig.Matrix[4], 0), dx, dy, out HTuple dx_Robot, out HTuple dy_Robot); + + // adjust_X = (float)dx_Robot.D; + // adjust_Y = (float)dy_Robot.D; + // adjust_Angle = visionConfig.StandardPoint.Angle - angle; // } - // if (x <= 0 || y <= 0) - // { - // throw new ProcessException("Camera_LoadFullTray瑙嗚璁$畻鑾峰彇鐐逛綅涓嶅彲灏忎簬0"); - // } - - // float dx = visionConfig.StandardPoint.X - x; - // float dy = visionConfig.StandardPoint.Y - y; - - // HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix[0], visionConfig.Matrix[1], 0, visionConfig.Matrix[3], visionConfig.Matrix[4], 0), dx, dy, out HTuple dx_Robot, out HTuple dy_Robot); - - // bind.Robot.SendMsg(RobotMsgAction.Load, RobotMsgParas.FullTray, position.PositionNo, new List<float>() { (float)dx_Robot.D, (float)dy_Robot.D, angle }); + // //bind.Robot.SendMsg(RobotMsgAction.Load, RobotMsgParas.FullTray, position.PositionNo, new List<float>() { (float)dx_Robot.D, (float)dy_Robot.D, angle }); + // RobotMsg_LoadFullTray.Action = RobotMsgAction.Load; + // RobotMsg_LoadFullTray.Para1 = RobotMsgParas.FullTray; + // RobotMsg_LoadFullTray.Para2 = position.PositionNo; + // RobotMsg_LoadFullTray.Datas = new List<float>() { adjust_X, adjust_Y, 0, adjust_Angle }.ConvertAll(s => s.ToString()).ToList(); + // bind.Robot.SendMsg(RobotMsg_LoadFullTray, true); // return new ProcessResponse(true); //} + //#endregion - public ProcessResponse Camera_LoadFullTray(string robotId, int positionNum) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == robotId); + //#region 婊ray浜х嚎涓嬫枡 + ////[ProcessMethod("", "AGV_UnloadFullTray", "AGV鍘诲線鍗歌浇婊ray鏂�", true)] + ////public ProcessResponse AGV_UnloadFullTray(IOperationConfig config, IDevice device) + ////{ + //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); + //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray); - PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == positionNum); + //// if (position == null) + //// { + //// throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓嬫枡鐐�"); + //// } - if (position == null) - { - throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓婃枡鐐�"); - } + //// bind.AGVDest = position.PositionCode; + //// bind.AGV.TaskOrder(position.PositionCode); - if (bind.AGV.CurrentPosition != position.PositionCode) - { - throw new ProcessException("AGV褰撳墠鏈浜庢弧Tray涓婃枡鐐�"); - } + //// bind.AGVStatus = TaskStatus.Running; - float adjust_X = 0.0f; - float adjust_Y = 0.0f; - float adjust_Angle = 0.0f; + //// return new ProcessResponse(true); + ////} - if (Config.IsEnableVisionGuide) - { - PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); - - if (visionConfig == null) - { - throw new ProcessException("鏈厤缃鐩告満鐨勬弧Tray涓婃枡鐐圭殑瑙嗚鎿嶄綔閰嶇疆"); - } - - float x = 0; - float y = 0; - float angle = 0; - - using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_LoadFullTray")) - { - string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; - if (!_halconToolDict.ContainsKey(toolPath)) - { - throw new ProcessException($"鏈厤缃瓹amera_LoadFullTray鐨勮瑙夌畻娉曡矾寰�"); - } - - var tool = _halconToolDict[toolPath]; - tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); - tool.RunProcedure(); - - x = (float)tool.GetResultTuple("OUTPUT_X").D; - y = (float)tool.GetResultTuple("OUTPUT_Y").D; - angle = (float)tool.GetResultTuple("OUTPUT_Angle").D; - } - - if (x <= 0 || y <= 0) - { - throw new ProcessException("Camera_LoadFullTray瑙嗚璁$畻鑾峰彇鐐逛綅涓嶅彲灏忎簬0"); - } - - float dx = visionConfig.StandardPoint.X - x; - float dy = visionConfig.StandardPoint.Y - y; - - HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix[0], visionConfig.Matrix[1], 0, visionConfig.Matrix[3], visionConfig.Matrix[4], 0), dx, dy, out HTuple dx_Robot, out HTuple dy_Robot); - - adjust_X = (float)dx_Robot.D; - adjust_Y = (float)dy_Robot.D; - adjust_Angle = visionConfig.StandardPoint.Angle - angle; - } - - //bind.Robot.SendMsg(RobotMsgAction.Load, RobotMsgParas.FullTray, position.PositionNo, new List<float>() { (float)dx_Robot.D, (float)dy_Robot.D, angle }); - RobotMsg_LoadFullTray.Action = RobotMsgAction.Load; - RobotMsg_LoadFullTray.Para1 = RobotMsgParas.FullTray; - RobotMsg_LoadFullTray.Para2 = position.PositionNo; - RobotMsg_LoadFullTray.Datas = new List<float>() { adjust_X, adjust_Y, 0, adjust_Angle }.ConvertAll(s => s.ToString()).ToList(); - bind.Robot.SendMsg(RobotMsg_LoadFullTray, true); - - return new ProcessResponse(true); - } - #endregion - - #region 婊ray浜х嚎涓嬫枡 - //[ProcessMethod("", "AGV_UnloadFullTray", "AGV鍘诲線鍗歌浇婊ray鏂�", true)] - //public ProcessResponse AGV_UnloadFullTray(IOperationConfig config, IDevice device) + //public bool AGV_UnloadFullTray(string bindId) //{ - // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray); // if (position == null) @@ -1150,42 +807,45 @@ // throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓嬫枡鐐�"); // } - // bind.AGVDest = position.PositionCode; - // bind.AGV.TaskOrder(position.PositionCode); + // if (bind.SetAGVStatus(TaskStatus.Running)) + // { + // bind.AGVDest = position.PositionCode; + // bind.AGV.TaskOrder(position.PositionCode); - // bind.AGVStatus = TaskStatus.Running; - - // return new ProcessResponse(true); + // return true; + // } + // else + // { + // return false; + // } //} - public bool AGV_UnloadFullTray(string bindId) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); - PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray); + ////[ProcessMethod("", "Robot_UnloadFullTray", "鏈哄櫒浜哄嵏杞芥弧Tray", true)] + ////public ProcessResponse Robot_UnloadFullTray(IOperationConfig config, IDevice device) + ////{ + //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); + //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray); - if (position == null) - { - throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓嬫枡鐐�"); - } + //// if (position == null) + //// { + //// throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓嬫枡鐐�"); + //// } - if (bind.SetAGVStatus(TaskStatus.Running)) - { - bind.AGVDest = position.PositionCode; - bind.AGV.TaskOrder(position.PositionCode); + //// if (bind.AGV.CurrentPosition != position.PositionCode) + //// { + //// throw new ProcessException("AGV褰撳墠鏈浜庢弧Tray涓嬫枡鐐�"); + //// } - return true; - } - else - { - return false; - } - } + //// bind.RobotStatus = TaskStatus.Running; + //// bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.LineSnap, position.PositionNo); - //[ProcessMethod("", "Robot_UnloadFullTray", "鏈哄櫒浜哄嵏杞芥弧Tray", true)] - //public ProcessResponse Robot_UnloadFullTray(IOperationConfig config, IDevice device) + //// return new ProcessResponse(true); + ////} + + //public void Robot_UnloadFullTraySnap(string bindId, PathPosition position) //{ - // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); - // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray); + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); + // //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray); // if (position == null) // { @@ -1199,148 +859,97 @@ // bind.RobotStatus = TaskStatus.Running; // bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.LineSnap, position.PositionNo); + // //LogAsync(DateTime.Now, "Robot杩愬姩鑷充笅婊ray鎷嶇収", ""); + //} + + ////[ProcessMethod("", "Camera_UnloadFullTray", "鐩告満鎿嶄綔鍗歌浇婊ray", true)] + ////public ProcessResponse Camera_UnloadFullTray(IOperationConfig config, IDevice device) + //public ProcessResponse Camera_UnloadFullTray(string robotId, int positionNum) + //{ + // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == robotId); + // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray && u.PositionNo == positionNum); + + // if (position == null) + // { + // throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓嬫枡鐐�"); + // } + + // if (bind.AGV.CurrentPosition != position.PositionCode) + // { + // throw new ProcessException("AGV褰撳墠鏈浜庢弧Tray涓嬫枡鐐�"); + // } + + // //float adjust_X = 0.0f; + // //float adjust_Y = 0.0f; + // //float adjust_Angle = 0.0f; + // bool isLineReady = false; + + // if (Config.IsEnableVisionGuide) + // { + // PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); + + // if (visionConfig == null) + // { + // throw new ProcessException("鏈厤缃鐩告満鐨勬弧Tray涓嬫枡鐐圭殑瑙嗚鎿嶄綔閰嶇疆"); + // } + + + // int reTryTime = Config.LineBusyRetryTimes; + + // do + // { + // using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_UnloadFullTray")) + // { + // string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; + // if (!_halconToolDict.ContainsKey(toolPath)) + // { + // throw new ProcessException($"鏈厤缃瓹amera_UnloadFullTray鐨勮瑙夌畻娉曡矾寰�"); + // } + + // _halconToolDict[toolPath].SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_Result", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); + // _halconToolDict[toolPath].RunProcedure(); + + // isLineReady = _halconToolDict[toolPath].GetResultTuple("OUTPUT_Result").I == 1; + // } + + // if (!isLineReady) + // { + // Thread.Sleep(Config.LineBusyWaitInterval * 1000); + // reTryTime--; + // } + // else + // { + // reTryTime = 0; + // } + // } while (reTryTime > 0); + + // //if (!isLineReady) + // //{ + // // bind.Robot.SendMsg(RobotMsgType.Send, -1, true, RobotMsgAction.State, RobotMsgParas.LineSnap, new List<string>() { "-1" }); + // // throw new ProcessException("浜х嚎蹇欙紝绛夊緟瓒呮椂"); + // //} + // //else + // //{ + // // bind.Robot.SendMsg(RobotMsgType.Send, -1, true, RobotMsgAction.State, RobotMsgParas.LineSnap, new List<string>() { "1" }); + // //} + // } + // else + // { + // isLineReady = true; + // } + + // if (isLineReady) + // { + // bind.Robot.SendMsg(RobotMsgAction.Unload, RobotMsgParas.FullTray, position.PositionNo); + // } + // else + // { + // bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.Home, position.PositionNo); + // } // return new ProcessResponse(true); //} - - public void Robot_UnloadFullTraySnap(string bindId, PathPosition position) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); - //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray); - - if (position == null) - { - throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓嬫枡鐐�"); - } - - if (bind.AGV.CurrentPosition != position.PositionCode) - { - throw new ProcessException("AGV褰撳墠鏈浜庢弧Tray涓嬫枡鐐�"); - } - - bind.RobotStatus = TaskStatus.Running; - bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.LineSnap, position.PositionNo); - //LogAsync(DateTime.Now, "Robot杩愬姩鑷充笅婊ray鎷嶇収", ""); - } - - //[ProcessMethod("", "Camera_UnloadFullTray", "鐩告満鎿嶄綔鍗歌浇婊ray", true)] - //public ProcessResponse Camera_UnloadFullTray(IOperationConfig config, IDevice device) - public ProcessResponse Camera_UnloadFullTray(string robotId, int positionNum) - { - var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == robotId); - PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray && u.PositionNo == positionNum); - - if (position == null) - { - throw new ProcessException("璺緞閰嶇疆鏈缃弧Tray涓嬫枡鐐�"); - } - - if (bind.AGV.CurrentPosition != position.PositionCode) - { - throw new ProcessException("AGV褰撳墠鏈浜庢弧Tray涓嬫枡鐐�"); - } - - //float adjust_X = 0.0f; - //float adjust_Y = 0.0f; - //float adjust_Angle = 0.0f; - bool isLineReady = false; - - if (Config.IsEnableVisionGuide) - { - PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); - - if (visionConfig == null) - { - throw new ProcessException("鏈厤缃鐩告満鐨勬弧Tray涓嬫枡鐐圭殑瑙嗚鎿嶄綔閰嶇疆"); - } - - - int reTryTime = Config.LineBusyRetryTimes; - - do - { - using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_UnloadFullTray")) - { - string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; - if (!_halconToolDict.ContainsKey(toolPath)) - { - throw new ProcessException($"鏈厤缃瓹amera_UnloadFullTray鐨勮瑙夌畻娉曡矾寰�"); - } - - _halconToolDict[toolPath].SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_Result", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); - _halconToolDict[toolPath].RunProcedure(); - - isLineReady = _halconToolDict[toolPath].GetResultTuple("OUTPUT_Result").I == 1; - } - - if (!isLineReady) - { - Thread.Sleep(Config.LineBusyWaitInterval * 1000); - reTryTime--; - } - else - { - reTryTime = 0; - } - } while (reTryTime > 0); - - //if (!isLineReady) - //{ - // bind.Robot.SendMsg(RobotMsgType.Send, -1, true, RobotMsgAction.State, RobotMsgParas.LineSnap, new List<string>() { "-1" }); - // throw new ProcessException("浜х嚎蹇欙紝绛夊緟瓒呮椂"); - //} - //else - //{ - // bind.Robot.SendMsg(RobotMsgType.Send, -1, true, RobotMsgAction.State, RobotMsgParas.LineSnap, new List<string>() { "1" }); - //} - } - else - { - isLineReady = true; - } - - if (isLineReady) - { - bind.Robot.SendMsg(RobotMsgAction.Unload, RobotMsgParas.FullTray, position.PositionNo); - } - else - { - bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.Home, position.PositionNo); - } - - return new ProcessResponse(true); - } + //#endregion #endregion - } - - //[Device("AGVBind", "AGVBind", EnumHelper.DeviceAttributeType.OperationConfig)] - public class AGVBindOpConfig : OperationConfigBase - { - [Category("璁惧淇℃伅")] - [Description("鎿嶄綔鐩稿叧鐨勮澶囩紪鍙�")] - public string BindId { get; set; } - - [Category("浣嶇疆淇℃伅")] - [Description("鎿嶄綔鐩稿叧鐨勪綅缃�")] - public PathPosition Position { get; set; } - - public AGVBindOpConfig() { } - - public AGVBindOpConfig(string bindId, PathPosition position = null) - { - BindId = bindId; - Position = position; - } - } - - public class TaskAssignInfo - { - public int PositionNo { get; set; } - - public bool IsTaskNeed { get; set; } = false; - - public bool IsTaskAssgined { get; set; } = false; - - public string AgvId { get; set; } } } diff --git a/src/A032.Process/ProcessControl_Robot.cs b/src/A032.Process/ProcessControl_Robot.cs new file mode 100644 index 0000000..ef57b2e --- /dev/null +++ b/src/A032.Process/ProcessControl_Robot.cs @@ -0,0 +1,24 @@ +锘縰sing Bro.Device.AuboRobot; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace A032.Process +{ + public partial class ProcessControl + { + private void OnRobotMsgReceived(DateTime dt, AuboRobotDriver robot, RobotMsg msg) + { + } + + private void SwitchLight(AuboRobotDriver robot, bool isOn) + { + if (Config.LightOutputIndex > 0) + { + robot.SetIO(Config.LightOutputIndex, isOn); + } + } + } +} diff --git a/src/A032.Process/ProcessControl_Task.cs b/src/A032.Process/ProcessControl_Task.cs new file mode 100644 index 0000000..4bf24ed --- /dev/null +++ b/src/A032.Process/ProcessControl_Task.cs @@ -0,0 +1,759 @@ +锘縰sing 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 HalconDotNet; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Drawing.Design; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace A032.Process +{ + public class TrayTask : IComplexDisplay + { + [Browsable(false)] + public string TaskId { get; set; } = Guid.NewGuid().ToString(); + + /// <summary> + /// 浼樺厛绾ц秺楂橈紝瓒婂揩鎵ц + /// </summary> + [Category("浠诲姟閰嶇疆")] + [Description("浼樺厛绾с�備紭鍏堢骇瓒婇珮锛岃秺蹇墽琛�")] + public int Priority { get; set; } + + private string locationCode = ""; + + [Category("浠诲姟閰嶇疆")] + [Description("浠诲姟鎵ц鍦板潃浠g爜")] + [TypeConverter(typeof(PositionCodeConverter))] + public string LocationCode + { + get => locationCode; + set + { + if (locationCode != value) + { + locationCode = value; + + using (var scope = GlobalVar.Container.BeginLifetimeScope()) + { + ProcessConfig config = scope.Resolve<ProcessConfig>(); + + Location = config.PositionCollection.FirstOrDefault(u => u.PositionCode == locationCode); + } + } + } + } + + [Browsable(false)] + public PathPosition Location { get; set; } = new PathPosition(); + + private TaskType taskType = TaskType.LoadEmptyTrayToAGV; + [Category("浠诲姟閰嶇疆")] + [Description("浠诲姟绫诲瀷")] + public TaskType TaskType + { + get => taskType; + set + { + taskType = value; + + var attr = taskType.GetEnumAttribute<PriorityAttribute>(); + if (attr != null) + { + Priority = attr.Priority; + } + } + } + + private string sourceDeviceId = ""; + [Category("浠诲姟閰嶇疆")] + [Description("浠诲姟鏉ユ簮璁惧")] + [TypeConverter(typeof(AllDeviceIdConverter))] + public string SourceDeviceId + { + get => sourceDeviceId; + set + { + if (sourceDeviceId != value) + { + sourceDeviceId = value; + + using (var scope = GlobalVar.Container.BeginLifetimeScope()) + { + List<IDevice> deviceList = scope.Resolve<List<IDevice>>(); + + var device = deviceList.FirstOrDefault(u => u.Id == value); + SourceDeviceName = device.Name; + } + } + } + } + + [Browsable(false)] + [JsonIgnore] + public string SourceDeviceName { get; set; } = ""; + + [Browsable(false)] + [JsonIgnore] + public string BindId { get; set; } = ""; + + [Browsable(false)] + [JsonIgnore] + public int WaitShift { get; set; } = 0; + + public string GetDisplayText() + { + return $"{SourceDeviceName}鍙戣捣鐨剓TaskType.ToString()}浠诲姟"; + } + } + + public enum TaskType + { + [Priority(30)] + UnloadEmptyTrayToMachine, + + [Priority(20)] + LoadEmptyTrayToAGV, + + [Priority(30)] + LoadFullTrayFromMachine, + + [Priority(20)] + UnloadFullTrayToLine, + + [Priority(50)] + Charge, + + [Priority(10)] + IdleCharge, + } + + public class PriorityAttribute : Attribute + { + public int Priority { get; set; } + + public PriorityAttribute(int priority) + { + Priority = priority; + } + } + + public partial class ProcessControl + { + private bool isEnableExecuteTask = true; + public bool IsEnableExecuteTask + { + get => isEnableExecuteTask; + set + { + isEnableExecuteTask = value; + + LogAsync(DateTime.Now, $"Set IsEnableExecuteTask {value.ToString()}", $"{(value ? "鎵撳紑" : "鍏抽棴")}浠诲姟鎵ц"); + } + } + List<AGVState> _disableStates = new List<AGVState>() { AGVState.InCharge, AGVState.Warning, AGVState.Unknown }; + + private void Reset(string bindId = "") + { + WarningRemains.Clear(); + IsEnableExecuteTask = true; + + if (string.IsNullOrWhiteSpace(bindId)) + { + Config.AGVBindCollection.ForEach(bind => + { + if (bind.UnitState == AGVState.Warning) + { + bind.WarningMsg = ""; + bind.UnitState = AGVState.Idle; + } + }); + + LogAsync(DateTime.Now, "Reset", "鎵ц鍏ㄤ綋澶嶄綅鎿嶄綔"); + } + else + { + var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); + + if (bind != null && bind.UnitState == AGVState.Warning) + { + bind.WarningMsg = ""; + bind.UnitState = AGVState.Idle; + + LogAsync(DateTime.Now, "Reset", $"鎵ц{bind.AGV.Name}澶嶄綅鎿嶄綔"); + } + } + } + + static object _taskLock = new object(); + NoticedList<TrayTask> TrayTaskCollection = new NoticedList<TrayTask>(); + + private void InsertTask(TrayTask task) + { + lock (_taskLock) + { + if (TrayTaskCollection.Any(u => u.TaskType == task.TaskType && u.SourceDeviceId == task.SourceDeviceId)) + { + LogAsync(DateTime.Now, "閲嶅浠诲姟", $"{task.SourceDeviceName}鍙戣捣鐨剓task.TaskType.ToString()}浠诲姟宸插瓨鍦ㄤ换鍔″垪琛ㄤ腑"); + return; + } + + int insertIndex = TrayTaskCollection.Count; + var nextTask = TrayTaskCollection.FirstOrDefault(u => u.Priority < task.Priority && u.WaitShift == 0); + if (nextTask != null) + { + insertIndex = TrayTaskCollection.IndexOf(nextTask); + } + + TrayTaskCollection.Insert(insertIndex, task); + } + } + + #region 浠诲姟瑙﹀彂 + private async void OnTaskListChanged(NotifyCollectionChangedAction action, List<TrayTask> task) + { + await Task.Run(() => + { + if (action == NotifyCollectionChangedAction.Add) + { + ExecuteTask(); + } + }); + } + + private async void OnUnitStateChanged(string unitId, AGVState preState, AGVState currentState) + { + await Task.Run(() => + { + if (currentState == AGVState.Idle || currentState == AGVState.IdleCharge) + { + ExecuteTask(unitId); + } + }); + } + + private void ExecuteTask(string unitId = "") + { + TrayTask task = null; + + lock (_taskLock) + { + if (TrayTaskCollection.Count <= 0) + { + return; + } + + task = TrayTaskCollection.FirstOrDefault(u => string.IsNullOrWhiteSpace(u.BindId)); + } + + //浠诲姟鏄惁宸插湪鎵ц涓� + if (Config.AGVBindCollection.Any(u => u.CurrentTaskId == task.TaskId)) + { + LogAsync(DateTime.Now, "浠诲姟鎵ц涓�", $"{task.GetDisplayText()}姝e湪鎵ц涓�"); + return; + } + + AGVBindUnit bind = null; + + if (string.IsNullOrWhiteSpace(unitId)) + { + var available = Config.AGVBindCollection.Where(u => u.UnitState == AGVState.Idle || u.UnitState == AGVState.IdleCharge); + + switch (task.TaskType) + { + case TaskType.LoadFullTrayFromMachine: + available = available.Where(u => u.FullTrayNum < Config.AGVAvailableTrayNums); + break; + case TaskType.UnloadEmptyTrayToMachine: + available = available.Where(u => u.EmptyTrayNum > 0); + break; + default: + break; + } + + bind = available.FirstOrDefault(); + } + else + { + bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == unitId); + } + + if (bind == null) + { + LogAsync(DateTime.Now, $"鏆傛椂娌℃湁鍙墽琛屼换鍔$殑鍗曞厓", ""); + ReArrangeTask(task); + return; + } + + if (task.Location == null) + { + switch (task.TaskType) + { + case TaskType.LoadEmptyTrayToAGV: + task.Location = Config.PositionCollection.FirstOrDefault(u => !u.IsOccupied && u.Description == PathPositionDefinition.LoadEmptyTray); + break; + case TaskType.LoadFullTrayFromMachine: + task.Location = Config.PositionCollection.FirstOrDefault(u => !u.IsOccupied && u.Description == PathPositionDefinition.LoadFullTray && u.DeviceOwner == task.SourceDeviceId); + break; + case TaskType.UnloadEmptyTrayToMachine: + task.Location = Config.PositionCollection.FirstOrDefault(u => !u.IsOccupied && u.Description == PathPositionDefinition.UnloadEmptyTray && u.DeviceOwner == task.SourceDeviceId); + break; + case TaskType.UnloadFullTrayToLine: + task.Location = Config.PositionCollection.FirstOrDefault(u => !u.IsOccupied && u.Description == PathPositionDefinition.UnloadFullTray && u.DeviceOwner == task.SourceDeviceId); + break; + default: + break; + } + } + + if (task.Location == null) + { + ReArrangeTask(task); + return; + } + else + { + task.Location.IsOccupied = true; + } + + task.BindId = bind.Id; + + if (!string.IsNullOrWhiteSpace(bind.CurrentTaskId)) + { + bind.AGV.CancelTask(); + } + + LogAsync(DateTime.Now, $"寮�濮嬫墽琛屼换鍔�", task.GetDisplayText()); + + bind.IsTaskCancelled = false; + bind.IsTaskCancelling = false; + + bind.UnitState = AGVState.Running; + bind.CurrentTaskId = task.TaskId; + + try + { + switch (task.TaskType) + { + case TaskType.LoadEmptyTrayToAGV: + LoadEmptyTrayToAGV(task, bind); + break; + case TaskType.LoadFullTrayFromMachine: + LoadFullTrayFromMachine(task, bind); + break; + case TaskType.UnloadEmptyTrayToMachine: + UnloadEmptyTrayToMachine(task, bind); + break; + case TaskType.UnloadFullTrayToLine: + UnloadFullTrayToLine(task, bind); + break; + default: + break; + } + + ////浠诲姟瀹屾垚鍚庢鏌ョ數閲� + //bind.AGV.BatteryHandle.Reset(); + //bool isNotTimeout = bind.AGV.BatteryHandle.WaitOne((bind.AGV.InitialConfig as SeerAGVInitialConfig).ScanInterval * 10); + + //if (!isNotTimeout) + //{ + // throw new ProcessException($"{bind.AGV.Name}鑾峰彇鐢垫睜鐘舵�佽秴鏃�"); + //} + } + catch (TaskCanceledException ex) + { + try + { + CancelTask(bind); + } + catch (Exception) + { + ExceptionHandle(task, bind, ex, $"浠诲姟{task.TaskId}鍙栨秷澶辫触锛�"); + return; + } + finally + { + bind.IsTaskCancelled = false; + bind.IsTaskCancelling = false; + } + } + catch (Exception ex) + { + ExceptionHandle(task, bind, ex); + return; + } + finally + { + //lock (_taskListLock) + //{ + // _taskList.RemoveAt(0); + //} + } + + LogAsync(DateTime.Now, $"浠诲姟{task.TaskId}娴佺▼缁撴潫", ""); + + AfterTaskHandle(task, bind); + } + + private void ReArrangeTask(TrayTask task) + { + task.WaitShift++; + + TrayTaskCollection.Remove(task); + + if (task.WaitShift > Config.DefaultWaitShift) + { + LogAsync(DateTime.Now, "浠诲姟鏃犳硶鎵ц", $"{task.GetDisplayText()}绛夊緟{task.WaitShift}娆℃棤娉曟墽琛岋紝宸茬Щ鍑轰换鍔¢槦鍒�"); + } + else + { + InsertTask(task); + } + } + + //AutoResetEvent _taskDoneHandle = new AutoResetEvent(true); + Dictionary<string, AutoResetEvent> _bindTaskDoneHandleDict = new Dictionary<string, AutoResetEvent>(); + private void AfterTaskHandle(TrayTask task, AGVBindUnit bind, string warningMsg = "", bool isWarningRaised = false) + { + lock (_taskLock) + { + task.Location.IsOccupied = false; + TrayTaskCollection.Remove(task); + } + + bind.CurrentTaskId = ""; + if (isWarningRaised) + { + bind.WarningMsg = warningMsg; + bind.UnitState = AGVState.Warning; + } + else + { + //浠诲姟瀹屾垚鍚庢鏌ョ數閲� + bind.AGV.BatteryHandle.Reset(); + bool isNotTimeout = bind.AGV.BatteryHandle.WaitOne((bind.AGV.InitialConfig as SeerAGVInitialConfig).ScanInterval * 10); + + if (!isNotTimeout) + { + bind.WarningMsg = $"{bind.AGV.Name}鑾峰彇鐢垫睜鐘舵�佽秴鏃�"; + new ProcessException(bind.WarningMsg); + bind.UnitState = AGVState.Warning; + } + else + { + SeerAGVInitialConfig iConfig = bind.AGV.InitialConfig as SeerAGVInitialConfig; + if (bind.AGV.BatteryLvl <= iConfig.BatteryLvlToCharge) + { + bind.UnitState = AGVState.InCharge; + + var chargePosition = Config.PositionCollection.FirstOrDefault(u => !u.IsOccupied && u.Description == PathPositionDefinition.Charge); + + if (chargePosition == null) + { + bind.WarningMsg = $"{bind.AGV.Name}鐩墠鏃犲彲鐢ㄥ厖鐢靛湴鍧�"; + new ProcessException(bind.WarningMsg); + bind.UnitState = AGVState.Warning; + } + else + { + bind.AGV.TaskOrder(chargePosition.PositionCode, true); + } + } + else + { + bind.UnitState = AGVState.Idle; + } + } + } + + _bindTaskDoneHandleDict[bind.Id].Set(); + } + + /// <summary> + /// 鍙栨秷褰撳墠浠诲姟锛屽鏋滃凡鍙栧嵎瀹楋紝褰掕繕鍒板師澶� + /// </summary> + /// <param name="bind"></param> + private void CancelTask(AGVBindUnit bind) + { + bind.IsTaskCancelling = true; + + bind.AGV.CancelTask(); + bind.Robot.Move(new RobotPoint(), MoveType.Origin, true); + } + + /// <summary> + /// 杩囩▼寮傚父澶勭悊锛屽弽棣堝紓甯告秷鎭埌RabbitMQ + /// </summary> + /// <param name="task"></param> + /// <param name="bind"></param> + /// <param name="ex"></param> + /// <param name="errorMsg"></param> + private void ExceptionHandle(TrayTask task, AGVBindUnit bind, Exception ex, string errorMsg = "") + { + bool isWarningEx = false; + if (ex is ProcessException) + { + isWarningEx = (ex as ProcessException).Level > 0; + errorMsg += (ex as ProcessException).ErrorCode; + } + else + { + isWarningEx = true; + errorMsg += ex.Message; + LogAsync(DateTime.Now, $"{task.TaskId}寮傚父", ex.GetExceptionMessage()); + } + + try + { + SwitchLight(bind.Robot, false); + bind.Robot.Move(new RobotPoint(), MoveType.Origin, true); + } + catch (Exception) + { + } + + LogAsync(DateTime.Now, $"浠诲姟{task.GetDisplayText()}寮傚父鍙嶉", errorMsg); + + AfterTaskHandle(task, bind, errorMsg, isWarningEx); + } + #endregion + + #region 浠诲姟鎵ц + /// <summary> + /// 灏嗘弧Tray鏀剧疆鍒颁骇绾夸笂 + /// </summary> + /// <param name="task"></param> + /// <param name="bind"></param> + private void UnloadFullTrayToLine(TrayTask task, AGVBindUnit bind) + { + string methodName = "UnloadFullTrayToLine"; + + bind.AGV.TaskOrder(task.Location.PositionCode, true); + + var visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.CameraId == bind.CameraId && u.PositionCode == task.Location.PositionCode); + + if (visionConfig == null) + throw new ProcessException($"鏈兘鑾峰彇{bind.Camera.Name}鍦▄task.Location.PositionCode}鐨勮瑙夐厤缃�"); + + while (bind.FullTrayNum > 0) + { + bind.Robot.Move(visionConfig.RobotSnapshotPoint, MoveType.AbsoluteMove, true); + + bool isLineReady = false; + if (Config.IsEnableVisionGuide) + { + int reTryTime = Config.LineBusyRetryTimes; + + HDevEngineTool tool = null; + if (!_halconToolDict.ContainsKey(visionConfig.CameraOpConfig.AlgorithemPath)) + { + throw new ProcessException($"鏈厤缃畕methodName}鐨勭畻娉曞伐鍏�"); + } + + tool = _halconToolDict[visionConfig.CameraOpConfig.AlgorithemPath]; + + SwitchLight(bind.Robot, true); + Thread.Sleep(500);//绛夊緟鐏紑 + + do + { + RobotPoint point = new RobotPoint(); + using (var hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, methodName)) + { + tool.InputImageDic.Clear(); + tool.InputImageDic["INPUT_Image"] = hImage; + + tool.RunProcedure(); + + if (!tool.IsSuccessful) + { + throw new ProcessException($"{visionConfig.CameraOpConfig.AlgorithemPath}绠楁硶杩愯澶辫触"); + } + + isLineReady = tool.GetResultTuple("OUTPUT_Result").I == 1; + } + + if (!isLineReady) + { + LogAsync(DateTime.Now, $"{task.Location.PositionCode}浣嶇疆绾夸綋绻佸繖", ""); + Thread.Sleep(Config.LineBusyWaitInterval * 1000); + reTryTime--; + } + else + { + reTryTime = 0; + } + } while (reTryTime > 0); + + SwitchLight(bind.Robot, false); + } + else + { + isLineReady = true; + } + + if (isLineReady) + { + bind.Robot.UnLoad(bind.Robot.CurrentPoint, TrayType.FullTray, true); + } + else + { + bind.Robot.Move(new RobotPoint(), MoveType.Origin, true); + break; + } + } + } + + /// <summary> + /// 灏嗙┖Tray鏀剧疆鍒板帇鏈轰笂 + /// </summary> + /// <param name="task"></param> + /// <param name="bind"></param> + private void UnloadEmptyTrayToMachine(TrayTask task, AGVBindUnit bind) + { + string methodName = "UnloadEmptyTrayToMachine"; + + MachineRelatedOperation(task, bind, methodName); + + RobotPoint point = bind.Robot.CurrentPoint.DeepSerializeClone(); + + int emptyTrayNum = 0; + do + { + bind.Robot.UnLoad(point, TrayType.EmptyTray, true); + emptyTrayNum++; + + bind.Robot.MonitorHandle.Reset(); + var isNotTimeout = bind.Robot.MonitorHandle.WaitOne((bind.Robot.InitialConfig as AuboRobotInitialConfig).ReplyTimeout * 3); + if (!isNotTimeout) + throw new ProcessException($"{bind.Robot.Name}鐩戝惉鎿嶄綔瓒呮椂"); + + } while (emptyTrayNum < Config.Machine_EmptyTrayNum && bind.EmptyTrayNum > 0); + } + + /// <summary> + /// 浠庡帇鏈轰笂鍙栨弧Tray鍒癆GV + /// </summary> + /// <param name="task"></param> + /// <param name="bind"></param> + private void LoadFullTrayFromMachine(TrayTask task, AGVBindUnit bind) + { + string methodName = "LoadFullTrayFromMachine"; + + MachineRelatedOperation(task, bind, methodName); + + RobotPoint point = bind.Robot.CurrentPoint.DeepSerializeClone(); + + int fullTrayNum = Config.Machine_FullTrayNum; + do + { + bind.Robot.Load(point, TrayType.FullTray, true); + fullTrayNum--; + bind.FullTrayNum++; + + bind.Robot.MonitorHandle.Reset(); + var isNotTimeout = bind.Robot.MonitorHandle.WaitOne((bind.Robot.InitialConfig as AuboRobotInitialConfig).ReplyTimeout * 3); + if (!isNotTimeout) + throw new ProcessException($"{bind.Robot.Name}鐩戝惉鎿嶄綔瓒呮椂"); + + } while (fullTrayNum > 0 && bind.FullTrayNum < Config.AGVAvailableTrayNums); + } + + private void MachineRelatedOperation(TrayTask task, AGVBindUnit bind, string methodName) + { + bind.AGV.TaskOrder(task.Location.PositionCode, true); + + var visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.CameraId == bind.CameraId && u.PositionCode == task.Location.PositionCode); + + if (visionConfig == null) + throw new ProcessException($"鏈兘鑾峰彇{bind.Camera.Name}鍦▄task.Location.PositionCode}鐨勮瑙夐厤缃�"); + + bind.Robot.Move(visionConfig.RobotSnapshotPoint, MoveType.AbsoluteMove, true); + + if (Config.IsEnableVisionGuide) + { + int repeatTime = Config.VisionGuideTimes; + + HDevEngineTool tool = null; + if (!_halconToolDict.ContainsKey(visionConfig.CameraOpConfig.AlgorithemPath)) + { + throw new ProcessException($"鏈厤缃畕methodName}鐨勭畻娉曞伐鍏�"); + } + + tool = _halconToolDict[visionConfig.CameraOpConfig.AlgorithemPath]; + + SwitchLight(bind.Robot, true); + Thread.Sleep(500);//绛夊緟鐏紑 + + do + { + RobotPoint point = new RobotPoint(); + using (var hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, methodName)) + { + tool.InputImageDic.Clear(); + tool.InputImageDic["INPUT_Image"] = hImage; + + tool.RunProcedure(); + + if (!tool.IsSuccessful) + { + throw new ProcessException($"{visionConfig.CameraOpConfig.AlgorithemPath}绠楁硶杩愯澶辫触"); + } + + double du = tool.GetResultTuple("OUTPUT_X").D; + double dv = tool.GetResultTuple("OUTPUT_Y").D; + + if (du < 0 || dv < 0) + { + throw new ProcessException($"{visionConfig.CameraOpConfig.AlgorithemPath}绠楁硶缁撴灉寮傚父锛岀偣浣嶄俊鎭幏鍙栧け璐�"); + } + + du -= visionConfig.StandardPoint.X; + dv -= visionConfig.StandardPoint.Y; + + HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix), du, dv, out HTuple dx, out HTuple dy); + + point.X = (float)dx.D; + point.Y = (float)dy.D; + point.A = (float)tool.GetResultTuple("OUTPUT_Angle").D; + } + + LogAsync(DateTime.Now, $"{methodName}寮曞鍧愭爣", point.GetDisplayText()); + + bind.Robot.Move(point, MoveType.RobotRelativeMove, true); + + repeatTime--; + } while (repeatTime > 0); + + SwitchLight(bind.Robot, false); + + //瑙嗚瀵煎紩鍚庡啀鍋氬浐瀹氬亸绉� + bind.Robot.Move(visionConfig.RobotShift, MoveType.RobotRelativeMove, true); + } + } + + /// <summary> + /// 浜哄伐瑁呯┖Tray鍒癆GV + /// </summary> + /// <param name="task"></param> + /// <param name="bind"></param> + private void LoadEmptyTrayToAGV(TrayTask task, AGVBindUnit bind) + { + bind.AGV.TaskOrder(task.Location.PositionCode, true); + bind.Robot.Load(new RobotPoint(), TrayType.EmptyTray, true); + } + #endregion + } +} diff --git a/src/Bro.Common.Model/Bro.Common.Model.csproj b/src/Bro.Common.Model/Bro.Common.Model.csproj index 2a3bf1d..fa82c2b 100644 --- a/src/Bro.Common.Model/Bro.Common.Model.csproj +++ b/src/Bro.Common.Model/Bro.Common.Model.csproj @@ -89,6 +89,7 @@ <Compile Include="Interface\IStationProcess.cs" /> <Compile Include="Model\CustomizedPoint.cs" /> <Compile Include="Model\DeviceCmmd.cs" /> + <Compile Include="Model\IODefinition.cs" /> <Compile Include="Model\ModbusFrame.cs" /> <Compile Include="Model\MonitorSet.cs" /> <Compile Include="Model\NGDesc.cs" /> diff --git a/src/Bro.Common.Model/Helper/EnumHelper.cs b/src/Bro.Common.Model/Helper/EnumHelper.cs index 21a319e..d50b5d9 100644 --- a/src/Bro.Common.Model/Helper/EnumHelper.cs +++ b/src/Bro.Common.Model/Helper/EnumHelper.cs @@ -73,6 +73,15 @@ } } + public static T GetEnumAttribute<T>(this Enum enumObj) where T : Attribute + { + Type t = enumObj.GetType(); + FieldInfo f = t.GetField(enumObj.ToString()); + + T attr = f.GetCustomAttribute<T>(); + return attr; + } + public static string GetPartSFCName(this PartType partType) { Type t = partType.GetType(); diff --git a/src/Bro.Common.Model/Helper/ExceptionHelper.cs b/src/Bro.Common.Model/Helper/ExceptionHelper.cs index db85703..87763af 100644 --- a/src/Bro.Common.Model/Helper/ExceptionHelper.cs +++ b/src/Bro.Common.Model/Helper/ExceptionHelper.cs @@ -8,8 +8,17 @@ namespace Bro.Common.Helper { + public enum ExceptionLevel + { + Info = 0, + Warning = 1, + Fatal = 2, + } + public class ProcessException : Exception { + public ExceptionLevel Level { get; set; } = ExceptionLevel.Warning; + public static Action<DateTime, string, string> OnExceptionNotice; //PubSubCenter pubSub = PubSubCenter.GetInstance(); @@ -38,9 +47,11 @@ { } - public ProcessException(Exception ex) + public ProcessException(Exception ex, ExceptionLevel lvl = ExceptionLevel.Warning) { OriginalException = ex; + Level = lvl; + ExceptionNotice(); } @@ -50,9 +61,10 @@ // PositionIndex = positionIndex; //} - public ProcessException(string error, Exception ex = null) : base(error, ex) + public ProcessException(string error, ExceptionLevel lvl = ExceptionLevel.Warning, Exception ex = null) : base(error, ex) { ErrorCode = error; + Level = lvl; OriginalException = ex; ExceptionNotice(); @@ -74,29 +86,5 @@ //pubSub.Publish(PubTag.ExceptionUpdate.ToString(), ErrorCode, OriginalException, true); OnExceptionNotice?.Invoke(DateTime.Now, ErrorCode, OriginalException?.GetExceptionMessage()); } - } - - public class Level3Exception : ProcessException - { - public Level3Exception() : base() { } - - public Level3Exception(string error, Exception ex) : base(error, ex) { } - } - - /// <summary> - /// 鏉ユ枡妫�娴嬪紓甯� - /// </summary> - public class IncomingMaterialException : ProcessException - { - public IncomingMaterialException() : base() { } - - public IncomingMaterialException(string error, Exception ex) : base(error, ex) { } - } - - public class BarcodeScanFailureException : ProcessException - { - public BarcodeScanFailureException() : base() { } - - public BarcodeScanFailureException(string msg, Exception ex) : base(msg, ex) { } } } diff --git a/src/Bro.Common.Model/Helper/ListHelper.cs b/src/Bro.Common.Model/Helper/ListHelper.cs index ad17def..1331583 100644 --- a/src/Bro.Common.Model/Helper/ListHelper.cs +++ b/src/Bro.Common.Model/Helper/ListHelper.cs @@ -1,18 +1,17 @@ 锘縰sing System; using System.Collections.Generic; +using System.Collections.Specialized; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Bro.Common.Helper { public class NoticedList<T> : List<T> where T : class { - public Action OnItemChanged; + public Action<NotifyCollectionChangedAction> OnItemChanged; - public Action<List<T>> OnItemChangedWithItemInfo; + public Action<NotifyCollectionChangedAction, List<T>> OnItemChangedWithItemInfo; - public Action<NoticedList<T>> OnItemChangedWithSelf; + //public Action<NotifyCollectionChangedAction, NoticedList<T>> OnItemChangedWithSelf; public new T this[int index] { @@ -33,9 +32,8 @@ if (base[index] != value) { base[index] = value; - OnItemChanged?.Invoke(); - OnItemChangedWithItemInfo?.Invoke(new List<T>() { value }); - OnItemChangedWithSelf?.Invoke(this); + OnItemChanged?.Invoke(NotifyCollectionChangedAction.Replace); + OnItemChangedWithItemInfo?.Invoke(NotifyCollectionChangedAction.Replace, new List<T>() { value }); } } } @@ -43,40 +41,36 @@ public new void Add(T item) { base.Add(item); - OnItemChanged?.Invoke(); - OnItemChangedWithItemInfo?.Invoke(new List<T>() { item }); - OnItemChangedWithSelf?.Invoke(this); + OnItemChanged?.Invoke(NotifyCollectionChangedAction.Add); + OnItemChangedWithItemInfo?.Invoke(NotifyCollectionChangedAction.Add, new List<T>() { item }); } public new void AddRange(IEnumerable<T> collection) { base.AddRange(collection); - OnItemChanged?.Invoke(); - OnItemChangedWithItemInfo?.Invoke(collection.ToList()); - OnItemChangedWithSelf?.Invoke(this); + OnItemChanged?.Invoke(NotifyCollectionChangedAction.Add); + OnItemChangedWithItemInfo?.Invoke(NotifyCollectionChangedAction.Add, collection.ToList()); } public new void Clear() { base.Clear(); - OnItemChanged?.Invoke(); - OnItemChangedWithSelf?.Invoke(this); + OnItemChanged?.Invoke(NotifyCollectionChangedAction.Reset); + OnItemChangedWithItemInfo?.Invoke(NotifyCollectionChangedAction.Reset, this); } public new void Insert(int index, T item) { base.Insert(index, item); - OnItemChanged?.Invoke(); - OnItemChangedWithItemInfo?.Invoke(new List<T>() { item }); - OnItemChangedWithSelf?.Invoke(this); + OnItemChanged?.Invoke(NotifyCollectionChangedAction.Add); + OnItemChangedWithItemInfo?.Invoke(NotifyCollectionChangedAction.Add, new List<T>() { item }); } public new void InsertRange(int index, IEnumerable<T> collection) { base.InsertRange(index, collection); - OnItemChanged?.Invoke(); - OnItemChangedWithItemInfo?.Invoke(collection.ToList()); - OnItemChangedWithSelf?.Invoke(this); + OnItemChanged?.Invoke(NotifyCollectionChangedAction.Add); + OnItemChangedWithItemInfo?.Invoke(NotifyCollectionChangedAction.Add, collection.ToList()); } public new bool Remove(T item) @@ -85,9 +79,8 @@ if (flag) { - OnItemChanged?.Invoke(); - OnItemChangedWithItemInfo?.Invoke(new List<T>() { item }); - OnItemChangedWithSelf?.Invoke(this); + OnItemChanged?.Invoke(NotifyCollectionChangedAction.Remove); + OnItemChangedWithItemInfo?.Invoke(NotifyCollectionChangedAction.Remove, new List<T>() { item }); } return flag; @@ -95,11 +88,12 @@ public new int RemoveAll(Predicate<T> match) { + List<T> temp = this.Where(u => match.Invoke(u)).ToList(); int i = base.RemoveAll(match); if (i > 0) { - OnItemChanged?.Invoke(); - OnItemChangedWithSelf?.Invoke(this); + OnItemChanged?.Invoke(NotifyCollectionChangedAction.Remove); + OnItemChangedWithItemInfo?.Invoke(NotifyCollectionChangedAction.Remove, temp); } return i; @@ -107,16 +101,18 @@ public new void RemoveAt(int index) { + var item = this[index]; base.RemoveAt(index); - OnItemChanged?.Invoke(); - OnItemChangedWithSelf?.Invoke(this); + OnItemChanged?.Invoke(NotifyCollectionChangedAction.Remove); + OnItemChangedWithItemInfo?.Invoke(NotifyCollectionChangedAction.Remove, new List<T>() { item }); } public new void RemoveRange(int index, int count) { + List<T> temp = this.Skip(index).Take(count).ToList(); base.RemoveRange(index, count); - OnItemChanged?.Invoke(); - OnItemChangedWithSelf?.Invoke(this); + OnItemChanged?.Invoke(NotifyCollectionChangedAction.Remove); + OnItemChangedWithItemInfo?.Invoke(NotifyCollectionChangedAction.Remove, temp); } } } diff --git a/src/Bro.Common.Model/Interface/IDeviceConfig.cs b/src/Bro.Common.Model/Interface/IDeviceConfig.cs index 40ee6d1..ec8236f 100644 --- a/src/Bro.Common.Model/Interface/IDeviceConfig.cs +++ b/src/Bro.Common.Model/Interface/IDeviceConfig.cs @@ -20,7 +20,7 @@ /// <summary> /// 璁惧鍒濆閰嶇疆 /// </summary> - public interface IInitialConfig + public interface IInitialConfig : ILog { /// <summary> /// 璁惧搴忓彿 GUID @@ -31,5 +31,14 @@ string Name { get; set; } bool IsEnabled { get; set; } + + string DriverType { get; set; } + } + + public interface ILog + { + string LogPath { get; set; } + + bool IsEnableLog { get; set; } } } diff --git a/src/Bro.Common.Model/Interface/IMonitor.cs b/src/Bro.Common.Model/Interface/IMonitor.cs index 2d9e1b3..be201fb 100644 --- a/src/Bro.Common.Model/Interface/IMonitor.cs +++ b/src/Bro.Common.Model/Interface/IMonitor.cs @@ -11,7 +11,7 @@ public delegate void OnMonitorAlarmDelegate(DateTime dt, IDevice device, WarningSet warning, bool isAlarmRaised); public interface IMonitor { - List<int> GetMonitorValues(int startAddress, int length); + //List<int> GetMonitorValues(int startAddress, int length); void Monitor(); event OnMonitorInvokeDelegate OnMonitorInvoke; diff --git a/src/Bro.Common.Model/Model/CustomizedPoint.cs b/src/Bro.Common.Model/Model/CustomizedPoint.cs index 942c76b..00bf7cd 100644 --- a/src/Bro.Common.Model/Model/CustomizedPoint.cs +++ b/src/Bro.Common.Model/Model/CustomizedPoint.cs @@ -599,4 +599,64 @@ return data.TrimEnd(new char[] { ',' }); } } + + public class RobotPoint : IComplexDisplay + { + [Category("鐐逛綅淇℃伅")] + [Description("鍧愭爣X")] + public float X { get; set; } + + [Category("鐐逛綅淇℃伅")] + [Description("鍧愭爣Y")] + public float Y { get; set; } + + [Category("鐐逛綅淇℃伅")] + [Description("鍧愭爣Z")] + public float Z { get; set; } + + [Category("鐐逛綅淇℃伅")] + [Description("瑙掑害A")] + public float A { get; set; } + + [Category("鐐逛綅淇℃伅")] + [Description("瑙掑害B")] + public float B { get; set; } + + [Category("鐐逛綅淇℃伅")] + [Description("瑙掑害C")] + public float C { get; set; } + + public string GetDisplayText() + { + return $"X:{X.ToString()} Y:{Y.ToString()} Z:{Z.ToString()} A:{A.ToString()} B:{B.ToString()} C:{C.ToString()}"; + } + + public double[] GetArray() + { + return new double[] { X, Y, Z, A, B, C }; + } + + public static RobotPoint GetRobotPointByArray(double[] array) + { + if (array.Length != 6) + { + return null; + } + + RobotPoint point = new RobotPoint(); + point.X = (float)array[0]; + point.Y = (float)array[1]; + point.Z = (float)array[2]; + point.A = (float)array[3]; + point.B = (float)array[4]; + point.C = (float)array[5]; + + return point; + } + + public static float GetDistance(RobotPoint pointA, RobotPoint pointB) + { + return (float)Math.Sqrt(Math.Pow(pointA.X - pointB.X, 2) + Math.Pow(pointA.Y - pointB.Y, 2) + Math.Pow(pointA.Z - pointB.Z, 2)); + } + } } diff --git a/src/Bro.Common.Model/Model/IODefinition.cs b/src/Bro.Common.Model/Model/IODefinition.cs new file mode 100644 index 0000000..6ff8d25 --- /dev/null +++ b/src/Bro.Common.Model/Model/IODefinition.cs @@ -0,0 +1,43 @@ +锘縰sing Bro.Common.Helper; +using Newtonsoft.Json; +using System; +using System.ComponentModel; + +namespace Bro.Common.Model +{ + public class IODefinition : IComplexDisplay + { + [Category("IO閰嶇疆")] + [Description("IO绱㈠紩锛屼粠0寮�濮�")] + public int IOIndex { get; set; } + + [Category("IO閰嶇疆")] + [Description("IO鎻忚堪")] + public string IODesc { get; set; } = ""; + + [Category("IO閰嶇疆")] + [Description("true锛氭帴閫氳Е鍙� false锛氭柇寮�瑙﹀彂")] + public bool TriggerValue { get; set; } = true; + + [Browsable(false)] + [JsonIgnore] + public bool CurrentValue { get; set; } = true; + + [Category("IO閰嶇疆")] + [Description("IO瀹氫箟绫诲瀷")] + public IODefinitionType IOType { get; set; } = IODefinitionType.Warning; + + public string GetDisplayText() + { + return $"{IOIndex}{(string.IsNullOrWhiteSpace(IODesc) ? "" : (":" + IODesc))}:{IOType.ToString()}"; + } + } + + public enum IODefinitionType + { + Start, + Stop, + Reset, + Warning, + } +} diff --git a/src/Bro.Common.Model/Model/MonitorSet.cs b/src/Bro.Common.Model/Model/MonitorSet.cs index 6a29c6f..fe435a2 100644 --- a/src/Bro.Common.Model/Model/MonitorSet.cs +++ b/src/Bro.Common.Model/Model/MonitorSet.cs @@ -47,6 +47,10 @@ [Description("瑙﹀彂鍊硷紝璁剧疆涓�-999鏃跺彉鍖栧嵆瑙﹀彂")] public int TriggerValue { get; set; } = -1; + [Browsable(false)] + [JsonIgnore] + public int CurrentValue { get; set; } + /// <summary> /// 浼犲叆鏁版嵁鍦板潃鐨勭储寮� 鎸夌収PLC鐩戝惉鍦板潃浠�0寮�濮嬬殑绱㈠紩闆嗗悎 /// </summary> @@ -68,32 +72,18 @@ [Category("鍥炰紶璁剧疆")] [Description("閫氱煡鍦板潃 瀹為檯PLC瀵勫瓨鍣ㄧ殑鍦板潃,10杩涘埗锛屼緥濡� 40012")] public int NoticeAddress { get; set; } = -1; - - //[Browsable(false)] - //[JsonIgnore] - //public List<int> InputDatas { get; set; } = new List<int>(); - + [Browsable(false)] [JsonIgnore] public ProcessResponse Response { get; set; } = new ProcessResponse(); public MonitorSet() { } - //public MonitorSet(int triggerIndex, int triggerValue, List<int> inputDataIndex, int dataIndex, int noticeIndex) - //{ - // TriggerIndex = triggerIndex; - // TriggerValue = triggerValue; - // InputDataIndex = inputDataIndex; - // ReplyDataAddress = dataIndex; - // NoticeAddress = noticeIndex; - //} - public string GetDisplayText() { using (var scope = GlobalVar.Container.BeginLifetimeScope()) { List<ProcessMethodAttribute> methodList = scope.Resolve<List<ProcessMethodAttribute>>(); - //List<IDevice> deviceList = scope.Resolve<List<IDevice>>(); string desc = ""; diff --git a/src/Bro.Device.AuboRobot/AuboRobotConfig.cs b/src/Bro.Device.AuboRobot/AuboRobotConfig.cs index 8c70b49..043faec 100644 --- a/src/Bro.Device.AuboRobot/AuboRobotConfig.cs +++ b/src/Bro.Device.AuboRobot/AuboRobotConfig.cs @@ -1,7 +1,6 @@ 锘縰sing Bro.Common.Base; using Bro.Common.Helper; using Bro.Common.Model; -using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing.Design; @@ -25,12 +24,20 @@ public int ReplyTimeout { get; set; } = 1000; [Category("閫氫俊璁剧疆")] + [Description("鍙嶉瓒呮椂閲嶈瘯娆℃暟")] + public int TimeoutRetryTimes { get; set; } = 5; + + [Category("閫氫俊璁剧疆")] [Description("鍗忚鏂囨湰缁撴潫瀛楃")] public string EndChar { get; set; } = "#"; [Category("閫氫俊璁剧疆")] [Description("鍗忚鍐呭鍒嗛殧瀛楃")] public string Seperator { get; set; } = ","; + + [Category("鍔ㄤ綔璁剧疆")] + [Description("鍔ㄤ綔瓒呮椂璁剧疆锛屽崟浣峬in")] + public float OperationTimeout { get; set; } = 1; [Category("IO鐩戝惉璁剧疆")] [Description("IO鐩戝惉鎿嶄綔閰嶇疆闆嗗悎")] @@ -40,12 +47,54 @@ [Category("IO鐩戝惉璁剧疆")] [Description("IO鐩戝惉闂撮殧锛屼互ms涓哄崟浣�")] - public int ScanInterval { get; set; } = 100; + public int ScanInterval { get; set; } = 9999; + + [Category("IO鐩戝惉璁剧疆")] + [Description("鏄惁鍚敤IO鐩戝惉,true锛氱洃鍚� false锛氫笉鐩戝惉")] + public bool IsEnableMonitor { get; set; } = false; + + [Category("鎶ヨ閰嶇疆")] + [Description("鎶ヨ浠g爜閰嶇疆")] + [TypeConverter(typeof(CollectionCountConvert))] + [Editor(typeof(ComplexCollectionEditor<RobotWarningCode>), typeof(UITypeEditor))] + public List<RobotWarningCode> RobotWarnings { get; set; } = new List<RobotWarningCode>(); + } + + public class RobotWarningCode + { + [Category("鎶ヨ閰嶇疆")] + [Description("鎶ヨ浠g爜")] + public int WarningCode { get; set; } + + [Category("鎶ヨ閰嶇疆")] + [Description("鎶ヨ浠g爜鎻忚堪")] + public string WarningDescription { get; set; } } [Device("AuboRobot", "濂ュ崥鏈哄櫒浜�", EnumHelper.DeviceAttributeType.OperationConfig)] public class AuboRobotOperationConfig : OperationConfigBase { + [Category("鍔ㄤ綔鎸囦护")] + [Description("鍔ㄤ綔鎸囦护")] + public RobotMsgAction Action { get; set; } = RobotMsgAction.Move; + + [Category("鍙傛暟")] + [Description("鍙傛暟1")] + public int Para1 { get; set; } = 0; + + [Category("鍙傛暟")] + [Description("鍙傛暟2")] + public int Para2 { get; set; } = 0; + + [Category("杩愬姩閰嶇疆")] + [Description("鏈哄櫒浜鸿繍鍔ㄧ偣浣�")] + [TypeConverter(typeof(ComplexObjectConvert))] + [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] + public RobotPoint Point { get; set; } = new RobotPoint(); + + [Category("鎿嶄綔閰嶇疆")] + [Description("鏄惁绛夊緟瀹屾垚淇″彿")] + public bool IsWaitFinished { get; set; } = true; } public class RobotMsg : IComplexDisplay @@ -56,16 +105,13 @@ public RobotMsgAction Action { get; set; } = RobotMsgAction.Move; - public RobotMsgParas Para1 { get; set; } = RobotMsgParas.None; + public int Para1 { get; set; } public int Para2 { get; set; } = 0; - /// <summary> - /// Paras涓嶅寘鍚玃ara1,Para2鍐呭 - /// </summary> - public List<string> Datas { get; set; } = new List<string>(); + public RobotPoint Point { get; set; } = new RobotPoint(); - public byte[] GetMsgBytes(string seperator, string endChar) + public byte[] GetMsgBytes(string seperator, string endChar, out string msg) { List<string> list = new List<string>() { ((int)Type).ToString("D2"), ID.ToString("D2") }; @@ -73,34 +119,51 @@ { list.Add(((int)Action).ToString("D2")); - list.Add(((int)Para1).ToString("D2")); + list.Add(Para1.ToString("D2")); list.Add(Para2.ToString("D2")); - if (Datas == null) - { - Datas = new List<string>(); - } - - while (Datas.Count < 5) - { - Datas.Add("0"); - } - - list.AddRange(Datas.ConvertAll(s => - { - string res = float.Parse(s).ToString("F7"); - - while (res.Length < 11) - { - res = "0" + res; - } - return res; - })); + list.Add(GetFormatString(Point.X)); + list.Add(GetFormatString(Point.Y)); + list.Add(GetFormatString(Point.Z)); + list.Add(GetFormatString_Angle(Point.A)); + list.Add(GetFormatString_Angle(Point.B)); + list.Add(GetFormatString_Angle(Point.C)); } - string msg = string.Join(seperator, list); + msg = string.Join(seperator, list) + seperator + endChar; - return System.Text.Encoding.ASCII.GetBytes(msg + endChar); + return System.Text.Encoding.ASCII.GetBytes(msg); + } + + private string GetFormatString(float x) + { + string s = x.ToString("f10"); + + s = s.TrimEnd(new char[] { '0' }); + + bool isNegative = x < 0; + + while (s.Length < 11) + { + s = s.Insert(isNegative ? 1 : 0, "0"); + } + + return s; + } + + /// <summary> + /// 灏嗚搴︽暟鍊艰浆鎹负11浣嶅瓧绗︿覆锛岃緭鍏ヨ搴﹀尯闂�0~360锛岃緭鍑鸿搴﹀尯闂�-180~+180 + /// </summary> + /// <param name="x"></param> + /// <returns></returns> + private string GetFormatString_Angle(float x) + { + if (x > 180) + { + x = x - 360; + } + + return GetFormatString(x); } public static RobotMsg GetRobotMsg(string data, string seperator) @@ -116,10 +179,22 @@ { msg.Action = (RobotMsgAction)int.Parse(datas[2]); - msg.Para1 = (RobotMsgParas)int.Parse(datas[3]); + msg.Para1 = int.Parse(datas[3]); msg.Para2 = int.Parse(datas[4]); - msg.Datas = datas.Skip(5).ToList(); + msg.Point = new RobotPoint() + { + X = float.Parse(datas[5]), + Y = float.Parse(datas[6]), + Z = float.Parse(datas[7]), + A = float.Parse(datas[8]) < 0 ? float.Parse(datas[8]) + 360 : float.Parse(datas[8]), + B = float.Parse(datas[9]) < 0 ? float.Parse(datas[9]) + 360 : float.Parse(datas[9]), + C = float.Parse(datas[10]) < 0 ? float.Parse(datas[10]) + 360 : float.Parse(datas[10]), + }; + } + else + { + msg.Para1 = int.Parse(datas[2]); } return msg; @@ -127,7 +202,7 @@ public string GetDisplayText() { - string msg = $"搴忓彿锛歿ID},{Action.ToString()}_{Para1.ToString()}_{Para2.ToString()}_{(Datas.Count > 0 ? ("_" + string.Join(",", Datas)) : "")}"; + string msg = $"搴忓彿锛歿ID},{Action.ToString()}_{Para1.ToString()}_{Para2.ToString()}_{Point.GetDisplayText()}"; return msg; } } @@ -143,20 +218,62 @@ Move = 1, Unload = 2, Load = 3, - IO = 6, + GetPosition = 4, + /// <summary> + /// 鎸囧畾褰撳墠鐐逛綅涓哄熀鍑嗙偣 + /// </summary> + BasePoint = 5, + IOSet = 6, + IOQuery = 7, Calibration = 9, StandardPoint = 10, } - public enum RobotMsgParas + public enum MoveType { - None = 0, - Home = 1, - LineSnap = 2, - EmptyTray = 3, - FullTray = 4, - UnloadEmptyTraySnap = 5, - LoadFullTraySnap = 6, - Query = 7, + [Description("缁濆杩愬姩")] + AbsoluteMove = 1, + [Description("鏈哄櫒浜哄潗鏍囩郴鐩稿杩愬姩")] + RobotRelativeMove = 2, + [Description("鐩稿鏌愪釜鍩哄噯鐐逛綅鐨勭浉瀵硅繍鍔�")] + BasedPointRelativeMove = 3, + [Description("鍥炲師鐐�")] + Origin = 4, + [Description("宸︿晶濮垮娍")] + LeftPose = 6, + [Description("鍙充晶濮垮娍")] + RightPose = 5, + [Description("鍓嶄晶濮垮娍")] + FrontPose = 7, + [Description("鐩告満鍧愭爣绯荤浉瀵硅繍鍔�")] + CameraRelativeMove = 12, } + + public enum TrayType + { + FullTray = 1, + EmptyTray = 2, + } + + //public enum RobotMsgAction + //{ + // Move = 1, + // Unload = 2, + // Load = 3, + // IO = 6, + // Calibration = 9, + // StandardPoint = 10, + //} + + //public enum RobotMsgParas + //{ + // None = 0, + // Home = 1, + // LineSnap = 2, + // EmptyTray = 3, + // FullTray = 4, + // UnloadEmptyTraySnap = 5, + // LoadFullTraySnap = 6, + // Query = 7, + //} } diff --git a/src/Bro.Device.AuboRobot/AuboRobotDriver.cs b/src/Bro.Device.AuboRobot/AuboRobotDriver.cs index 11f343f..02691de 100644 --- a/src/Bro.Device.AuboRobot/AuboRobotDriver.cs +++ b/src/Bro.Device.AuboRobot/AuboRobotDriver.cs @@ -10,6 +10,7 @@ using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; +using static Bro.Common.Helper.EnumHelper; namespace Bro.Device.AuboRobot { @@ -38,7 +39,7 @@ if (string.IsNullOrWhiteSpace(IConfig.EndChar)) { - throw new ProcessException("鍗忚鏂囨湰鐨勭粨鏉熷瓧绗︿笉鍙负绌猴紝璇锋鏌ラ厤缃�", null); + throw new ProcessException("鍗忚鏂囨湰鐨勭粨鏉熷瓧绗︿笉鍙负绌猴紝璇锋鏌ラ厤缃�"); } client = new TcpClient(); @@ -46,6 +47,10 @@ client.Client.Blocking = true; client.NoDelay = true; client.BeginConnect(IPAddress.Parse(IConfig.RobotIP), IConfig.RobotPort, OnConnect, null); + + replyHandleDict = new Dictionary<int, AutoResetEvent>(); + replyErrorCodeDict = new Dictionary<int, int>(); + taskHandleDict = new Dictionary<int, ManualResetEvent>(); } protected override void Pause() @@ -62,18 +67,24 @@ //Query Robot IOs //SendMsg(RobotMsgType.Send, 0, true, RobotMsgAction.IO, RobotMsgParas.Query, new List<string>()); - scanMsg = new RobotMsg(); - scanMsg.Action = RobotMsgAction.IO; - scanMsg.Para1 = RobotMsgParas.Query; + //scanMsg = new RobotMsg(); + //scanMsg.Action = RobotMsgAction.IO; + //scanMsg.Para1 = RobotMsgParas.Query; - Task.Run(() => - { - Monitor(); - }); + //Task.Run(() => + //{ + // Monitor(); + //}); } protected override void Stop() { + replyHandleDict.Values.ToList().ForEach(h => h.Set()); + replyHandleDict.Clear(); + + taskHandleDict.Values.ToList().ForEach(h => h.Set()); + taskHandleDict.Clear(); + if (client != null && client.Connected) { client.Close(); @@ -95,7 +106,8 @@ } catch (Exception ex) { - OnLog?.Invoke(DateTime.Now, this, ex.GetExceptionMessage()); + //OnLog?.Invoke(DateTime.Now, this, ex.GetExceptionMessage()); + LogAsync(DateTime.Now, "杩炴帴寮傚父", ex.GetExceptionMessage()); if (client != null && client.Connected) { @@ -110,13 +122,12 @@ try { int dataLength = stream.EndRead(ar); - if (dataLength > 0) { byte[] data = buffer.Take(dataLength).ToArray(); string dataStr = System.Text.Encoding.ASCII.GetString(data).Trim(); - //OnLog?.BeginInvoke(DateTime.Now, this, $"{Name}鎺ユ敹鏁版嵁锛歿dataStr}", null, null); + AnalyzeData(dataStr); stream.BeginRead(buffer, 0, buffer.Length, OnDataReceived, null); @@ -125,19 +136,21 @@ { if (!client.Connected) { - OnLog?.Invoke(DateTime.Now, this, "杩斿洖绌烘暟鎹紝杩炴帴涓柇"); + //OnLog?.Invoke(DateTime.Now, this, "杩斿洖绌烘暟鎹紝杩炴帴涓柇"); + LogAsync(DateTime.Now, "杩炴帴涓柇", "杩斿洖绌烘暟鎹紝杩炴帴涓柇"); client.BeginConnect(IPAddress.Parse(IConfig.RobotIP), IConfig.RobotPort, OnConnect, null); } } } catch (Exception ex) { - OnLog?.Invoke(DateTime.Now, this, $"{Name}鏁版嵁鎺ユ敹寮傚父锛歿ex.GetExceptionMessage()}"); + //OnLog?.Invoke(DateTime.Now, this, $"{Name}锛歿ex.GetExceptionMessage()}"); + LogAsync(DateTime.Now, "鏁版嵁鎺ユ敹寮傚父", ex.GetExceptionMessage()); } } string msg = ""; - static object analyzeLock = new object(); + object analyzeLock = new object(); private async void AnalyzeData(string data) { await Task.Run(() => @@ -168,41 +181,58 @@ await Task.Run(() => { Array.ForEach(datas, data => - { - RobotMsg msg = RobotMsg.GetRobotMsg(data, IConfig.Seperator); + { + RobotMsg msg = RobotMsg.GetRobotMsg(data, IConfig.Seperator); - if (msg.Type == RobotMsgType.Rec) - { - if (replyHandleDict.ContainsKey(msg.ID)) - { - replyHandleList.Remove(msg.ID); + if (msg.Type == RobotMsgType.Rec) + { + replyErrorCodeDict[msg.ID] = msg.Para1; + if (replyHandleDict.ContainsKey(msg.ID)) + { + replyHandleDict[msg.ID].Set(); + } + } + else + { + if (msg.Action == RobotMsgAction.IOQuery) + { + newValues = new List<int>(); - replyHandleDict[msg.ID].Set(); - replyHandleDict.Remove(msg.ID); - } - } - else - { - canMonitor = true; + for (int i = msg.Para1.ToString().Length - 1; i >= 0; i--) + { + newValues.Add((msg.Para1 >> i) & 1); + } - if (msg.Action == RobotMsgAction.IO && msg.Para1 == RobotMsgParas.Query) - { - string resultStr = msg.Datas[0]; - newValues = new List<int>(); + MonitorHandle.Set(); + } + else + { + canMonitor = true; + switch (msg.Action) + { + case RobotMsgAction.Move: + CurrentPoint = msg.Point; + break; + //case RobotMsgAction.Load: + // //SlotIndex = msg.Para1; + // break; + case RobotMsgAction.GetPosition: + CurrentPoint = msg.Point; + break; + default: + break; + } - for (int i = resultStr.Length - 1; i >= 0; i--) - { - newValues.Add(int.Parse(resultStr[i].ToString())); - } + if (taskHandleDict.ContainsKey(msg.ID)) + { + taskHandleDict[msg.ID].Set(); + } - MonitorHandle.Set(); - } - else - { - OnMsgReceived?.BeginInvoke(DateTime.Now, this, msg, null, null); - } - } - }); + LogAsync(DateTime.Now, "鎸囦护鍙嶉", msg.GetDisplayText()); + OnMsgReceived?.BeginInvoke(DateTime.Now, this, msg, null, null); + } + } + }); }); } @@ -220,24 +250,9 @@ } } - List<int> replyHandleList = new List<int>(); Dictionary<int, AutoResetEvent> replyHandleDict = new Dictionary<int, AutoResetEvent>(); - - public void SendMsg(RobotMsgAction action, RobotMsgParas para1, int para2, List<float> paras = null) - { - RobotMsg msg = new RobotMsg(); - msg.Type = RobotMsgType.Send; - msg.ID = SID; - - msg.Action = action; - msg.Para1 = para1; - msg.Para2 = para2; - - msg.Datas = new List<string>((paras ?? new List<float>()).ConvertAll(i => i.ToString())); - - OnLog?.BeginInvoke(DateTime.Now, this, $"{Name}鍙戦�佹寚浠わ細{msg.GetDisplayText()}", null, null); - SendMsg(msg, true); - } + Dictionary<int, int> replyErrorCodeDict = new Dictionary<int, int>(); + Dictionary<int, ManualResetEvent> taskHandleDict = new Dictionary<int, ManualResetEvent>(); public void SendReplyMsg(int replyId) { @@ -253,37 +268,183 @@ object monitorLock = new object(); public void SendMsg(RobotMsg msg, bool isWaitReply = true, bool isMonitorMsg = false) { + replyErrorCodeDict[msg.ID] = 0; + if (isWaitReply) { - replyHandleList.Add(msg.ID); replyHandleDict[msg.ID] = new AutoResetEvent(false); } - byte[] bytes = msg.GetMsgBytes(IConfig.Seperator, IConfig.EndChar); - - lock (monitorLock) + byte[] bytes = msg.GetMsgBytes(IConfig.Seperator, IConfig.EndChar, out string dataStr); + if (!isMonitorMsg) { - if (!isMonitorMsg) - { - canMonitor = false; - } - - if (isMonitorMsg && !canMonitor) - return; - - //lock (this) - { - stream.Write(bytes, 0, bytes.Length); - } + LogAsync(DateTime.Now, "鎸囦护鍙戦��", dataStr); } + + bool isNotTimeout = true; + int reTryTime = IConfig.TimeoutRetryTimes; + do + { + lock (monitorLock) + { + if (!isMonitorMsg) + { + canMonitor = false; + } + + if (isMonitorMsg && !canMonitor) + return; + + stream.Write(bytes, 0, bytes.Length); + + if (!isMonitorMsg) + { + LogAsync(DateTime.Now, "鏁版嵁鍙戦��", BitConverter.ToString(bytes)); + } + } + + if (isWaitReply) + { + int errorCode = replyErrorCodeDict[msg.ID]; + + if (errorCode != 0) + { + var desc = IConfig.RobotWarnings.FirstOrDefault(u => u.WarningCode == errorCode); + throw new ProcessException($"{Name}{msg.ID}浠诲姟鍙嶉寮傚父{errorCode},寮傚父鎻忚堪锛歿(desc == null ? "鏃�" : desc.WarningDescription)}"); + } + + isNotTimeout = replyHandleDict[msg.ID].WaitOne(IConfig.ReplyTimeout); + + if (!isNotTimeout) + { + reTryTime--; + } + } + } while (reTryTime > 0 && !isNotTimeout); if (isWaitReply) { - replyHandleDict[msg.ID].WaitOne(IConfig.ReplyTimeout); + replyHandleDict.Remove(msg.ID); + } - if (replyHandleList.Contains(msg.ID)) + if (!isNotTimeout) + { + throw new ProcessException($"{Name}鍙嶉鏁版嵁瓒呮椂\r\n" + msg.GetDisplayText()); + } + } + + #region 鎵ц缁撴灉灞炴�� + public RobotPoint CurrentPoint { get; set; } = null; + //public int SlotIndex { get; set; } = 0; + #endregion + + public void Move(RobotPoint point, MoveType isAbs, bool isWaitFinished) + { + CurrentPoint = null; + + RobotMsg msg = new RobotMsg(); + msg.Type = RobotMsgType.Send; + msg.ID = SID; + + msg.Action = RobotMsgAction.Move; + msg.Para1 = (int)isAbs; + + msg.Point = point ?? new RobotPoint(); + + SendMsg(msg, true); + + TaskTimeoutCheck(isWaitFinished, msg.ID, $"{Name}{(isAbs.GetEnumDescription())}鑷硔point.GetDisplayText()}鍔ㄤ綔瓒呮椂"); + } + + public void Load(RobotPoint point, TrayType trayType, bool isWaitFinished) + { + //SlotIndex = 0; + + RobotMsg msg = new RobotMsg(); + msg.Type = RobotMsgType.Send; + msg.ID = SID; + + msg.Action = RobotMsgAction.Load; + msg.Para1 = (int)trayType; + msg.Point = point; + + SendMsg(msg, true); + + TaskTimeoutCheck(isWaitFinished, msg.ID, $"{Name}鍙杮trayType.ToString()}{point.GetDisplayText()}鍔ㄤ綔瓒呮椂"); + + //if (isWaitFinished && SlotIndex <= 0) + //{ + // throw new ProcessException($"{Name}娌℃湁鍙敤鐨勭┖鐧芥牸浣�,鏃犳硶鏀剧疆鍗峰畻"); + //} + } + + public void UnLoad(RobotPoint point, TrayType trayType, bool isWaitFinished) + { + RobotMsg msg = new RobotMsg(); + msg.Type = RobotMsgType.Send; + msg.ID = SID; + + msg.Action = RobotMsgAction.Unload; + msg.Para1 = (int)trayType; + msg.Point = point; + + SendMsg(msg, true); + + TaskTimeoutCheck(isWaitFinished, msg.ID, $"{Name}鍗竰trayType.ToString()}{point.GetDisplayText()}鍔ㄤ綔瓒呮椂"); + } + + public void GetPosition(bool isWaitFinished) + { + CurrentPoint = null; + + RobotMsg msg = new RobotMsg(); + msg.Type = RobotMsgType.Send; + msg.ID = SID; + + msg.Action = RobotMsgAction.GetPosition; + + SendMsg(msg, true); + + TaskTimeoutCheck(isWaitFinished, msg.ID, $"{Name}鑾峰彇褰撳墠鍧愭爣瓒呮椂"); + } + + public void SetBasePoint() + { + RobotMsg msg = new RobotMsg(); + msg.Type = RobotMsgType.Send; + msg.ID = SID; + + msg.Action = RobotMsgAction.BasePoint; + + SendMsg(msg, true); + } + + public void SetIO(int outputIndex, bool isOn) + { + RobotMsg msg = new RobotMsg(); + msg.Type = RobotMsgType.Send; + msg.ID = SID; + + msg.Action = RobotMsgAction.IOSet; + msg.Para1 = outputIndex; + msg.Para2 = isOn ? 1 : 0; + + SendMsg(msg, true); + } + + private void TaskTimeoutCheck(bool isWaitFinished, int msgId, string errorMsg) + { + if (isWaitFinished) + { + taskHandleDict[msgId] = new ManualResetEvent(false); + taskHandleDict[msgId].Reset(); + bool isNotTimeout = taskHandleDict[msgId].WaitOne((int)(IConfig.OperationTimeout * 60 * 1000)); + + taskHandleDict.Remove(msgId); + + if (!isNotTimeout) { - throw new ProcessException("鍙嶉鏁版嵁瓒呮椂\r\n" + msg.GetDisplayText(), null); + throw new ProcessException(errorMsg); } } } @@ -295,14 +456,16 @@ protected List<int> oldValues = new List<int>(); List<int> newValues = new List<int>(); public ManualResetEvent MonitorHandle { get; set; } = new ManualResetEvent(false); - //public ManualResetEvent IOChangedHandle { get; set; } = new ManualResetEvent(true); - public List<int> GetMonitorValues(int startAddress, int length) + public List<int> GetIOValues() { MonitorHandle.Reset(); scanMsg.ID = SID; SendMsg(scanMsg, true, true); - MonitorHandle.WaitOne(IConfig.ReplyTimeout); + var isNotTimeout = MonitorHandle.WaitOne(IConfig.ReplyTimeout * 3); + + if (!isNotTimeout) + throw new ProcessException($"{Name}鐩戝惉鎿嶄綔瓒呮椂"); return newValues; } @@ -313,29 +476,32 @@ { try { - List<int> newValues = GetMonitorValues(0, 0); - - if (newValues == null || newValues.Count == 0) - continue; - - if (oldValues.Count == 0) + if (IConfig.IsEnableMonitor) { - oldValues = newValues.ConvertAll(s => -1).ToList(); - } + List<int> newValues = GetIOValues(); - if (oldValues.Count == newValues.Count) - { - var tempNew = new List<int>(newValues); - var tempOld = new List<int>(oldValues); - MonitorCheckAndInvoke(tempNew, tempOld); + if (newValues == null || newValues.Count == 0) + continue; + + if (oldValues.Count == 0) + { + oldValues = newValues.ConvertAll(s => -1).ToList(); + } + + if (oldValues.Count == newValues.Count) + { + var tempNew = new List<int>(newValues); + var tempOld = new List<int>(oldValues); + MonitorCheckAndInvoke(tempNew, tempOld); + } + oldValues = new List<int>(newValues); } - oldValues = new List<int>(newValues); Thread.Sleep(IConfig.ScanInterval); } catch (Exception ex) { - OnLog?.Invoke(DateTime.Now, this, $"{Name}鐩戝惉寮傚父:{ex.GetExceptionMessage()}"); + LogAsync(DateTime.Now, "鐩戝惉寮傚父", ex.GetExceptionMessage()); } } } diff --git a/src/Bro.Device.Common/Base/DeviceBase.cs b/src/Bro.Device.Common/Base/DeviceBase.cs index 11aa9cf..25b45fb 100644 --- a/src/Bro.Device.Common/Base/DeviceBase.cs +++ b/src/Bro.Device.Common/Base/DeviceBase.cs @@ -14,6 +14,7 @@ //using BroCComn.PubSub; using static Bro.Common.Helper.EnumHelper; using System.ComponentModel; +using System.IO; namespace Bro.Common.Base { @@ -393,7 +394,7 @@ { string currentStateStr = CurrentStateToBe.GetEnumDescription(); string stateToBeStr = stateToBe.GetEnumDescription(); - throw new ProcessException($"{InitialConfig.Name}璁惧鐨勫綋鍓嶇姸鎬佷负{currentStateStr}锛屾棤娉曞垏鎹㈣嚦{stateToBeStr}", null); + throw new ProcessException($"{InitialConfig.Name}璁惧鐨勫綋鍓嶇姸鎬佷负{currentStateStr}锛屾棤娉曞垏鎹㈣嚦{stateToBeStr}"); } CurrentState = EnumHelper.DeviceState.TBD; @@ -417,7 +418,7 @@ } else { - throw new ProcessException($"{InitialConfig.Name}璁惧鎿嶄綔瓒呮椂", null); + throw new ProcessException($"{InitialConfig.Name}璁惧鎿嶄綔瓒呮椂"); } } @@ -489,7 +490,7 @@ //this.CurrentState = EnumHelper.DeviceState.DSExcept; //this.CurrentStateToBe = EnumHelper.DeviceState.DSExcept; - throw new ProcessException($"璁惧{InitialConfig.Name}鐨剓CurrentStateToBe.GetEnumDescription()}鎿嶄綔閲嶅3娆″け璐�", ex); + throw new ProcessException($"璁惧{InitialConfig.Name}鐨剓CurrentStateToBe.GetEnumDescription()}鎿嶄綔閲嶅3娆″け璐�", ExceptionLevel.Warning, ex); } } } @@ -515,5 +516,40 @@ CurrentUserId = obj; } #endregion + + #region 鏃ュ織澶勭悊 + object logObject = new object(); + public virtual async void LogAsync(DateTime dt, string prefix, string msg) + { + await Task.Run(() => + { + if (InitialConfig.IsEnableLog) + { + OnLog?.Invoke(dt, this, prefix + "\t" + msg); + + if (string.IsNullOrWhiteSpace(InitialConfig.LogPath) || !Path.IsPathRooted(InitialConfig.LogPath)) + { + return; + } + + if (!Directory.Exists(InitialConfig.LogPath)) + { + Directory.CreateDirectory(InitialConfig.LogPath); + } + + string filePath = Path.Combine(InitialConfig.LogPath, $"Log_{Name}_{DateTime.Now.ToString("yyyyMMdd")}.txt"); + lock (logObject) + { + using (StreamWriter writer = new StreamWriter(filePath, true, Encoding.UTF8)) + { + writer.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}\t{prefix}\t{msg}"); + writer.Flush(); + writer.Close(); + } + } + } + }); + } + #endregion } } diff --git a/src/Bro.Device.Common/Base/DeviceConfigBase.cs b/src/Bro.Device.Common/Base/DeviceConfigBase.cs index 1150d4e..0f28653 100644 --- a/src/Bro.Device.Common/Base/DeviceConfigBase.cs +++ b/src/Bro.Device.Common/Base/DeviceConfigBase.cs @@ -1,7 +1,9 @@ -锘縰sing Bro.Common.Interface; +锘縰sing Bro.Common.Helper; +using Bro.Common.Interface; using System; using System.Collections.Generic; using System.ComponentModel; +using System.Drawing.Design; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -28,6 +30,18 @@ /// </summary> [Category("閫氱敤閰嶇疆")] [Description("璁惧鏄惁鍚敤")] - public bool IsEnabled { get; set; } = false; + public bool IsEnabled { get; set; } = false; + + [Browsable(false)] + public virtual string DriverType { get; set; } = ""; + + [Category("鏃ュ織閰嶇疆")] + [Description("鏃ュ織璁板綍鐩綍")] + [Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))] + public string LogPath { get; set; } + + [Category("鏃ュ織閰嶇疆")] + [Description("true锛氬惎鐢ㄦ棩蹇楄褰� false锛氫笉鍚敤鏃ュ織璁板綍")] + public bool IsEnableLog { get; set; } = false; } } diff --git a/src/Bro.Device.Common/DeviceBase/HDevEngineTool.cs b/src/Bro.Device.Common/DeviceBase/HDevEngineTool.cs index 6e3645f..bb3966c 100644 --- a/src/Bro.Device.Common/DeviceBase/HDevEngineTool.cs +++ b/src/Bro.Device.Common/DeviceBase/HDevEngineTool.cs @@ -12,7 +12,7 @@ namespace Bro.Common.Base { - public class HDevEngineTool + public class HDevEngineTool : IDisposable { #region 甯搁噺 @@ -41,7 +41,7 @@ /// <summary> /// 绋嬪簭杩愯鏄惁鎴愬姛 /// </summary> - private bool isSuccess = false; + public bool IsSuccessful { get; set; } = false; /// <summary> /// 鎺у埗鍙傛暟瀛楀吀 @@ -132,11 +132,11 @@ procedureCall.Execute(); - isSuccess = true; + IsSuccessful = true; } catch (HDevEngineException ex) { - isSuccess = false; + IsSuccessful = false; Trace.TraceInformation("HDevProgram {0} Run fail , Line number: {1}, Halcon error number : {2},ex:{3}", ex.ProcedureName, ex.LineNumber, ex.HalconError, ex.Message); return; } @@ -144,7 +144,7 @@ public HTuple GetResultTuple(string key) { - if (isSuccess) + if (IsSuccessful) { return procedureCall.GetOutputCtrlParamTuple(key); } @@ -157,7 +157,7 @@ public HObject GetResultObject(string key, bool ignoreError = false) { - if (ignoreError || isSuccess) + if (ignoreError || IsSuccessful) { return procedureCall.GetOutputIconicParamObject(key); } @@ -166,6 +166,17 @@ return new HObject(); } } + + public void Dispose() + { + //foreach (HObject obj in InputImageDic.Values) + //{ + // obj.Dispose(); + //} + + procedureCall.Dispose(); + myEngine.Dispose(); + } } public static class HalconHelper diff --git a/src/Bro.Device.Common/DeviceBase/PLCBase.cs b/src/Bro.Device.Common/DeviceBase/PLCBase.cs index 10d42f1..2141644 100644 --- a/src/Bro.Device.Common/DeviceBase/PLCBase.cs +++ b/src/Bro.Device.Common/DeviceBase/PLCBase.cs @@ -147,7 +147,7 @@ }); } - private void OnMethodInvoked(IAsyncResult ar) + protected virtual void OnMethodInvoked(IAsyncResult ar) { MonitorSet monitorSet = ar.AsyncState as MonitorSet; @@ -186,7 +186,7 @@ if (repeatTime <= 0) { - new ProcessException("PLC鍙嶉鍐欏叆寮傚父", ex); + new ProcessException("PLC鍙嶉鍐欏叆寮傚父", ExceptionLevel.Info, ex); } } } while (repeatTime > 0); @@ -234,13 +234,13 @@ [Description("瓒呮椂璁剧疆锛屽崟浣嶏細ms")] public int Timeout { get; set; } = 500; - [Category("杈撳嚭璁剧疆")] - [Description("鏄惁鏃ュ織杈撳嚭")] - public bool IsEnabelLog { get; set; } = false; + //[Category("杈撳嚭璁剧疆")] + //[Description("鏄惁鏃ュ織杈撳嚭")] + //public bool IsEnabelLog { get; set; } = false; - [Category("杈撳嚭璁剧疆")] - [Description("杈撳嚭鏂囦欢璺緞")] - public string LogPath { get; set; } = @"D:\PLCLog.txt"; + //[Category("杈撳嚭璁剧疆")] + //[Description("杈撳嚭鏂囦欢璺緞")] + //public string LogPath { get; set; } = @"D:\PLCLog.txt"; #region 鍦板潃璁剧疆 [Category("浜嬩欢鍦板潃璁剧疆")] diff --git a/src/Bro.Device.Common/Helper/AspectHelper.cs b/src/Bro.Device.Common/Helper/AspectHelper.cs index 0176023..0c3178f 100644 --- a/src/Bro.Device.Common/Helper/AspectHelper.cs +++ b/src/Bro.Device.Common/Helper/AspectHelper.cs @@ -45,7 +45,7 @@ IOperationConfig config = args.Arguments.FirstOrDefault() as IOperationConfig; if (config == null) { - throw new ProcessException("璁惧鎿嶄綔杞叆鍙傛暟绫诲瀷閿欒锛�", null); + throw new ProcessException("璁惧鎿嶄綔杞叆鍙傛暟绫诲瀷閿欒锛�"); } if (device.DeviceMode == DeviceMode.Run) diff --git a/src/Bro.Device.OmronFins/FinsFrame.cs b/src/Bro.Device.OmronFins/FinsFrame.cs index dabb024..4189eba 100644 --- a/src/Bro.Device.OmronFins/FinsFrame.cs +++ b/src/Bro.Device.OmronFins/FinsFrame.cs @@ -292,7 +292,7 @@ List<byte> errorCode = bytes.Skip(4 + 4 + 4).Take(4).ToList(); if (errorCode.Any(u => u != 0x00)) { - throw new ProcessException($"杩斿洖寮傚父锛岄敊璇爜{string.Join("", errorCode)}", null); + throw new ProcessException($"杩斿洖寮傚父锛岄敊璇爜{string.Join("", errorCode)}"); } bytes = bytes.Skip(4 + 4 + 4 + 4).ToArray(); @@ -323,7 +323,7 @@ if (beginIndex == -1) { - throw new ProcessException("娆у榫橮LC閫氳甯ч敊璇�", null); + throw new ProcessException("娆у榫橮LC閫氳甯ч敊璇�"); } List<byte> singleBytes = bytes.Skip(beginIndex).ToList(); @@ -411,7 +411,7 @@ if (wordAddress == 0 && byteAddress == 0) { - throw new ProcessException("娆у榫橮LC鐩戝惉鍦板潃璁剧疆閿欒", null); + throw new ProcessException("娆у榫橮LC鐩戝惉鍦板潃璁剧疆閿欒"); } //瀛楀湴鍧� diff --git a/src/Bro.Device.OmronFins/OmronFinsDriver.cs b/src/Bro.Device.OmronFins/OmronFinsDriver.cs index 534c13e..695423b 100644 --- a/src/Bro.Device.OmronFins/OmronFinsDriver.cs +++ b/src/Bro.Device.OmronFins/OmronFinsDriver.cs @@ -13,6 +13,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using static Bro.Common.Helper.EnumHelper; namespace Bro.Device.OmronFins { @@ -31,11 +32,11 @@ } byte[] data = opFrame.GetSendReadFrameBytes(item, CurrentSid); - var stream = opClient.GetStream(); - stream.Write(data, 0, data.Length); + //var stream = opClient.GetStream(); + opStream.Write(data, 0, data.Length); byte[] buffer = new byte[2048]; - int readSize = stream.Read(buffer, 0, buffer.Length); + int readSize = opStream.Read(buffer, 0, buffer.Length); if (readSize > 0) { @@ -70,7 +71,7 @@ Stopwatch sw = new Stopwatch(); sw.Start(); - NetworkStream stream = null; + //NetworkStream stream = null; lock (opClientLock) { do @@ -80,13 +81,13 @@ InitialOpClient(); byte[] data = opFrame.GetSendWriteFrameBytes(item, CurrentSid); - stream = opClient.GetStream(); - stream.Write(data, 0, data.Length); + //stream = opClient.GetStream(); + opStream.Write(data, 0, data.Length); sw.Stop(); if (sw.ElapsedMilliseconds > 10) { - LogAsync(DateTime.Now, $"鍙戦�佸畬鎴愶紝鑰楁椂锛歿sw.ElapsedMilliseconds}"); + LogAsync(DateTime.Now, $"鍙戦�佸畬鎴�", $"鍙戦�佽�楁椂锛歿sw.ElapsedMilliseconds}"); } repeatTime = 0; @@ -101,7 +102,7 @@ } else { - LogAsync(DateTime.Now, "Send Exception:" + ex.GetExceptionMessage()); + LogAsync(DateTime.Now, "Send Exception", ex.GetExceptionMessage()); } } } while (repeatTime > 0); @@ -111,7 +112,7 @@ try { byte[] buffer = new byte[1024]; - int bufferCount = stream.Read(buffer, 0, buffer.Length); + int bufferCount = opStream.Read(buffer, 0, buffer.Length); if (bufferCount > 0) { opFrame.AnalyseReceivedItems(buffer.Take(bufferCount).ToArray(), item); @@ -119,7 +120,7 @@ } catch (Exception ex) { - LogAsync(DateTime.Now, "鍐欏叆鍙嶉寮傚父\r\n" + ex.GetExceptionMessage()); + LogAsync(DateTime.Now, "鍐欏叆鍙嶉寮傚父", ex.GetExceptionMessage()); } } else @@ -129,7 +130,7 @@ try { byte[] buffer = new byte[1024]; - int bufferCount = stream.Read(buffer, 0, buffer.Length); + int bufferCount = opStream.Read(buffer, 0, buffer.Length); if (bufferCount > 0) { opFrame.AnalyseReceivedItems(buffer.Take(bufferCount).ToArray(), item); @@ -137,7 +138,7 @@ } catch (Exception ex) { - LogAsync(DateTime.Now, "鍐欏叆鍙嶉寮傚父\r\n" + ex.GetExceptionMessage()); + LogAsync(DateTime.Now, "鍐欏叆鍙嶉寮傚父", ex.GetExceptionMessage()); } }); } @@ -163,6 +164,7 @@ item.ADDRESS = "D" + address.ToString(); item.ITEM_LENGTH = 1; + item.ITEM_VALUE_TYPE = 1; item.ITEM_VALUE = writeValue.ToString(); //lock (opClient) @@ -403,7 +405,9 @@ static object opClientLock = new object(); TcpClient scanClient = new TcpClient(); + NetworkStream scanStream = null; TcpClient opClient = new TcpClient(); + NetworkStream opStream = null; IPEndPoint plcEP; @@ -455,10 +459,10 @@ scanFrame = new FinsFrame(IConfig.DNA, serverNode, IConfig.DA2, IConfig.SNA, scanNode, IConfig.SA2, false); byte[] dataRequest = scanFrame.GetTcpRequestFrame(0); - var stream = scanClient.GetStream(); - stream.Write(dataRequest, 0, dataRequest.Length); + scanStream = scanClient.GetStream(); + scanStream.Write(dataRequest, 0, dataRequest.Length); byte[] dataRead = new byte[2048]; - int readSize = stream.Read(dataRead, 0, dataRead.Length); + int readSize = scanStream.Read(dataRead, 0, dataRead.Length); if (readSize <= 0) { @@ -489,10 +493,10 @@ opFrame = new FinsFrame(IConfig.DNA, serverNode, IConfig.DA2, IConfig.SNA, opNode, IConfig.SA2, false); byte[] dataRequest = opFrame.GetTcpRequestFrame(0); - var stream = opClient.GetStream(); - stream.Write(dataRequest, 0, dataRequest.Length); + opStream = opClient.GetStream(); + opStream.Write(dataRequest, 0, dataRequest.Length); byte[] dataRead = new byte[2048]; - int readSize = stream.Read(dataRead, 0, dataRead.Length); + int readSize = opStream.Read(dataRead, 0, dataRead.Length); if (readSize <= 0) { @@ -524,14 +528,15 @@ PLC_ITEM item = new PLC_ITEM(); item.ADDRESS = "D" + startAddress; item.OP_TYPE = 1; + item.ITEM_VALUE_TYPE = 1; item.ITEM_LENGTH = length; var data = opFrame.GetSendReadFrameBytes(item, CurrentSid); - var stream = opClient.GetStream(); - stream.Write(data, 0, data.Length); + opStream.Write(data, 0, data.Length); + opStream.Flush(); byte[] buffer = new byte[2048]; - int readSize = stream.Read(buffer, 0, buffer.Length); + int readSize = opStream.Read(buffer, 0, buffer.Length); if (readSize > 0) { @@ -555,6 +560,7 @@ PLC_ITEM item = new PLC_ITEM(); item.ADDRESS = "D" + startAddress; item.OP_TYPE = 1; + item.ITEM_VALUE_TYPE = 1; item.ITEM_LENGTH = length; if (scanBuffer == null) @@ -562,11 +568,11 @@ scanBuffer = scanFrame.GetSendReadFrameBytes(item, CurrentSid); } - var stream = scanClient.GetStream(); - stream.Write(scanBuffer, 0, scanBuffer.Length); + //var stream = scanClient.GetStream(); + scanStream.Write(scanBuffer, 0, scanBuffer.Length); byte[] buffer = new byte[2048]; - int readSize = stream.Read(buffer, 0, buffer.Length); + int readSize = scanStream.Read(buffer, 0, buffer.Length); if (readSize > 0) { @@ -578,69 +584,52 @@ return new List<int>(); } } - #endregion - #region Log - object logLock = new object(); - private async void LogAsync(DateTime dt, string info) + protected override void OnMethodInvoked(IAsyncResult ar) { - await Task.Run(() => + MonitorSet monitorSet = ar.AsyncState as MonitorSet; + + ProcessResponse resValues = monitorSet.Response; + + if (resValues.ResultValue == (int)PLCReplyValue.IGNORE) { - if (IConfig.IsEnabelLog) + return; + } + + if (monitorSet.ReplyDataAddress != -1 && resValues.DataList.Count > 0) + { + PLC_ITEM item = new PLC_ITEM(); + item.OP_TYPE = 2; + item.ITEM_LENGTH = resValues.DataList.Count; + item.ADDRESS = "D" + monitorSet.ReplyDataAddress.ToString(); + item.ITEM_VALUE = String.Join(",", resValues.DataList); + item.ITEM_VALUE_TYPE = (int)PLCItemType.Integer; + WriteItem(item, false); + } + + if (monitorSet.NoticeAddress != -1) + { + int repeatTime = 5; + + do { - lock (logLock) + try { - DirectoryInfo dir = new DirectoryInfo(IConfig.LogPath); - if (!dir.Exists) + this.WriteSingleAddress(monitorSet.NoticeAddress, resValues.ResultValue, false); + repeatTime = 0; + } + catch (Exception ex) + { + repeatTime--; + + if (repeatTime <= 0) { - dir.Create(); - } - - string filePath = Path.Combine(IConfig.LogPath, "PLC_" + DateTime.Now.ToString("yyyyMMdd") + ".txt"); - - using (StreamWriter writer = new StreamWriter(filePath, true)) - { - writer.WriteLine(dt.ToString("HH:mm:ss.fff")); - writer.WriteLine(info); - writer.WriteLine(); - - writer.Flush(); - writer.Close(); + new ProcessException("PLC鍙嶉鍐欏叆寮傚父", ExceptionLevel.Info, ex); } } - } - }); + } while (repeatTime > 0); + } } - - //private async void LogAsync(DateTime dt, IModbusFrame frame) - //{ - // await Task.Run(() => - // { - // if (IConfig.IsEnabelLog) - // { - // lock (logLock) - // { - // DirectoryInfo dir = new DirectoryInfo(IConfig.LogPath); - // if (!dir.Exists) - // { - // dir.Create(); - // } - - // string filePath = Path.Combine(IConfig.LogPath, "PLC_" + DateTime.Now.ToString("yyyyMMdd") + ".txt"); - - // using (StreamWriter writer = new StreamWriter(filePath, true)) - // { - // writer.WriteLine(dt.ToString("HH:mm:ss.fff")); - // writer.WriteLine(frame.GetFrameString()); - // writer.WriteLine(); - - // writer.Flush(); - // writer.Close(); - // } - // } - // } - // }); - //} #endregion } } diff --git a/src/Bro.Device.SeerAGV/Bro.Device.SeerAGV.csproj b/src/Bro.Device.SeerAGV/Bro.Device.SeerAGV.csproj index 9b12646..927736b 100644 --- a/src/Bro.Device.SeerAGV/Bro.Device.SeerAGV.csproj +++ b/src/Bro.Device.SeerAGV/Bro.Device.SeerAGV.csproj @@ -36,6 +36,7 @@ </Reference> <Reference Include="System" /> <Reference Include="System.Core" /> + <Reference Include="System.Drawing" /> <Reference Include="System.Xml.Linq" /> <Reference Include="System.Data.DataSetExtensions" /> <Reference Include="Microsoft.CSharp" /> diff --git a/src/Bro.Device.SeerAGV/SeerAGVConfig.cs b/src/Bro.Device.SeerAGV/SeerAGVConfig.cs index 3866776..55214f0 100644 --- a/src/Bro.Device.SeerAGV/SeerAGVConfig.cs +++ b/src/Bro.Device.SeerAGV/SeerAGVConfig.cs @@ -1,16 +1,12 @@ 锘縰sing Bro.Common.Base; using Bro.Common.Helper; -using Bro.Common.Model.Helper; +using Bro.Common.Model; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using System; using System.Collections.Generic; using System.ComponentModel; +using System.Drawing.Design; using System.Linq; -using System.Net; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; namespace Bro.Device.SeerAGV { @@ -31,7 +27,19 @@ [Category("鐩戝惉閰嶇疆")] [Description("鐩戝惉闂撮殧锛屽崟浣峬s")] - public int ScanInterval { get; set; } = 200; + public int ScanInterval { get; set; } = 500; + + //[Category("鐩戝惉閰嶇疆")] + //[Description("鐩戝惉鐨処O淇℃伅閰嶇疆闆嗗悎")] + //[TypeConverter(typeof(CollectionCountConvert))] + //[Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))] + //public List<IODefinition> IOCollection { get; set; } = new List<IODefinition>(); + + [Category("鐩戝惉璁剧疆")] + [Description("鐩戝惉鎿嶄綔閰嶇疆闆嗗悎")] + [TypeConverter(typeof(CollectionCountConvert))] + [Editor(typeof(ComplexCollectionEditor<MonitorSet>), typeof(UITypeEditor))] + public List<MonitorSet> MonitorSetCollection { get; set; } = new List<MonitorSet>(); [Category("鐩戝惉閰嶇疆")] [Description("鏄惁閲囩敤绠�鍗曠洃鍚ā寮忋�倀rue锛氱畝鍗曟ā寮忥紝鍙幏鍙栦换鍔$姸鎬侊紱false锛氬叏閮ㄦā寮忥紝鑾峰彇浠诲姟鎵�鏈変俊鎭�")] @@ -53,6 +61,22 @@ } } + private float batteryLvlToCharge_Recommand = 0.3f; + [Category("鍏呯數閰嶇疆")] + [Description("鍏呯數鐢垫睜瀹归噺锛岀數姹犲閲忎綆浜庤鍊兼椂锛岃澶囩┖闂叉椂寤鸿鍏呯數")] + public float BatteryLvlToCharge_Recommand + { + get => batteryLvlToCharge_Recommand; + set + { + if (value >= 1 || value <= 0) + { + value = 0.3f; + } + batteryLvlToCharge_Recommand = value; + } + } + private float batteryLvlChargeDone = 0.9f; [Category("鍏呯數閰嶇疆")] [Description("鍏呯數瀹屾垚鐢垫睜瀹归噺锛岀數姹犲閲忛珮浜庤鍊兼椂纭鍏呯數瀹屾垚")] @@ -68,12 +92,22 @@ batteryLvlChargeDone = value; } } + + [Category("鍔ㄤ綔璁剧疆")] + [Description("鍔ㄤ綔瓒呮椂璁剧疆锛屽崟浣峬in")] + public float OperationTimeout { get; set; } = 5; } [Device("SeerAGV", "SeerAGV", EnumHelper.DeviceAttributeType.OperationConfig)] public class SeerAGVOperationConfig : OperationConfigBase { + [Category("瀵艰埅閰嶇疆")] + [Description("AGV琛岄┒鐩殑鍦�")] + public string Location { get; set; } + [Category("瀵艰埅閰嶇疆")] + [Description("鏄惁绛夊緟瀹屾垚淇″彿")] + public bool IsWaitFinished { get; set; } = true; } public class SeerMessage : IComplexDisplay @@ -143,7 +177,7 @@ if (data.Length < 16 + msg.DataLength) { - throw new ProcessException("鏁版嵁闀垮害閿欒", null); + throw new ProcessException("鏁版嵁闀垮害閿欒"); } msg.JsonData = data.Skip(16).Take(msg.DataLength).ToArray(); @@ -171,6 +205,7 @@ { QueryPosition = 0x03EC, QueryTaskStatus = 0x03FC, + QueryIO = 0x03F5, CancelTask = 0x0BBB, PauseTask = 0x0BB9, diff --git a/src/Bro.Device.SeerAGV/SeerAGVDriver.cs b/src/Bro.Device.SeerAGV/SeerAGVDriver.cs index b875bda..bb05aee 100644 --- a/src/Bro.Device.SeerAGV/SeerAGVDriver.cs +++ b/src/Bro.Device.SeerAGV/SeerAGVDriver.cs @@ -1,25 +1,27 @@ 锘縰sing Bro.Common.Base; using Bro.Common.Helper; using Bro.Common.Interface; +using Bro.Common.Model; +using Bro.Common.Model.Interface; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; -using System.Runtime.InteropServices; -using System.Text; using System.Threading; using System.Threading.Tasks; namespace Bro.Device.SeerAGV { [Device("SeerAGV", "SeerAGV", EnumHelper.DeviceAttributeType.Device)] - public class SeerAGVDriver : DeviceBase + public class SeerAGVDriver : DeviceBase, IMonitor { public Action<SeerAGVDriver, string> OnAGVPositoinChanged; public Action<SeerAGVDriver, AGVTaskStatus> OnAGVTaskStatusChanged; public Action<SeerAGVDriver, float, float> OnAGVBatteryLvlChanged; + public Action<SeerAGVDriver, IODefinition> OnAGVIOChanged; SeerAGVInitialConfig IConfig { @@ -39,6 +41,15 @@ { InitialTcpClient(ref client_State, IConfig.StatusPort); InitialTcpClient(ref client_Guide, IConfig.GuidePort); + + StateHandle = new ManualResetEvent(false); + PositionHandle = new ManualResetEvent(false); + BatteryHandle = new ManualResetEvent(false); + IOHandle = new ManualResetEvent(false); + + _taskDoneHandle = new ManualResetEvent(false); + _monitorLock = new ManualResetEvent(true); + _isTaskRunning = false; } private void InitialTcpClient(ref TcpClient client, int port) @@ -66,6 +77,15 @@ msg_Position = new SeerMessage((int)AGVCode.QueryPosition, SID); msg_GuideStatus = new SeerMessage((int)AGVCode.QueryTaskStatus, SID, IConfig.IsSimpleMonitor ? JsonConvert.SerializeObject(new { simple = true }) : ""); msg_Battery = new SeerMessage((int)AGVCode.QueryBattery, SID, IConfig.IsSimpleMonitor ? JsonConvert.SerializeObject(new { simple = true }) : ""); + msg_IO = new SeerMessage((int)AGVCode.QueryIO, SID); + + _taskDoneHandle.Reset(); + _monitorLock.Set(); + + Task.Run(() => + { + Monitor(); + }); Task.Run(() => { @@ -75,6 +95,14 @@ protected override void Stop() { + StateHandle.Set(); + PositionHandle.Set(); + BatteryHandle.Set(); + IOHandle.Set(); + + _taskDoneHandle.Set(); + _monitorLock.Set(); + if (client_Guide != null && client_Guide.Connected) { CancelTask(); @@ -126,6 +154,8 @@ } } + List<AGVTaskStatus> _taskRunningStates = new List<AGVTaskStatus>() { AGVTaskStatus.Running, AGVTaskStatus.Waiting, AGVTaskStatus.Suspended }; + List<AGVTaskStatus> _taskDoneStates = new List<AGVTaskStatus>() { AGVTaskStatus.Cancelled, AGVTaskStatus.Completed, AGVTaskStatus.Failed }; AGVTaskStatus taskStatus = AGVTaskStatus.None; public AGVTaskStatus TaskStatus { @@ -138,6 +168,12 @@ if (taskStatus != AGVTaskStatus.None) { + if (_isTaskRunning && _taskDoneStates.Contains(taskStatus)) + { + _taskDoneHandle.Set(); + _isTaskRunning = false; + } + OnAGVTaskStatusChanged?.Invoke(this, taskStatus); } } @@ -159,13 +195,24 @@ } } + public string LastStation { get; set; } + public string Destination { get; set; } = ""; + SeerMessage msg_Position = new SeerMessage(); SeerMessage msg_GuideStatus = new SeerMessage(); SeerMessage msg_Battery = new SeerMessage(); + SeerMessage msg_IO = new SeerMessage(); + + public ManualResetEvent StateHandle { get; set; } = new ManualResetEvent(false); + public ManualResetEvent PositionHandle { get; set; } = new ManualResetEvent(false); + public ManualResetEvent BatteryHandle { get; set; } = new ManualResetEvent(false); + public ManualResetEvent IOHandle { get; set; } = new ManualResetEvent(false); + private void MonitorAGV() { while (CurrentState != EnumHelper.DeviceState.DSClose && CurrentState != EnumHelper.DeviceState.DSExcept) { + _monitorLock.WaitOne(); try { SendMsg(client_State, IConfig.StatusPort, msg_Position); @@ -174,10 +221,12 @@ Thread.Sleep(IConfig.ScanInterval); SendMsg(client_State, IConfig.StatusPort, msg_Battery); Thread.Sleep(IConfig.ScanInterval); + SendMsg(client_State, IConfig.StatusPort, msg_IO); + Thread.Sleep(IConfig.ScanInterval); } catch (Exception ex) { - OnLog?.Invoke(DateTime.Now, this, $"{Name}鐩戝惉寮傚父锛歿ex.GetExceptionMessage()}"); + LogAsync(DateTime.Now, "鐩戝惉寮傚父", ex.GetExceptionMessage()); } } } @@ -194,7 +243,7 @@ var stream = client.GetStream(); stream.Write(msg.Frame, 0, msg.Frame.Length); - + stream.Flush(); int recSize = stream.Read(buffer, 0, buffer.Length); if (recSize > 0) { @@ -202,7 +251,7 @@ SeerMessage recMsg = SeerMessage.GetSeerMessage(rec); if (recMsg.TypeCode != (10000 + msg.TypeCode) || recMsg.SeqNum != msg.SeqNum) { - throw new ProcessException("鍙嶉淇℃伅鍜屽彂閫佷俊鎭笉涓�鑷�", null); + throw new ProcessException("鍙嶉淇℃伅鍜屽彂閫佷俊鎭笉涓�鑷�"); } if (recMsg.JValues.ContainsKey("ret_code")) @@ -210,7 +259,7 @@ int retCode = recMsg.JValues.Value<int>("ret_code"); if (retCode != 0) { - throw new ProcessException($"鍙嶉淇℃伅寮傚父,寮傚父鐮�:{retCode}", null); + throw new ProcessException($"鍙嶉淇℃伅寮傚父,寮傚父鐮�:{retCode}"); } } @@ -222,18 +271,18 @@ catch (SocketException ex) { repeatTime--; - new ProcessException("AGV缃戠粶閫氫俊寮傚父", ex); + new ProcessException("AGV缃戠粶閫氫俊寮傚父", ExceptionLevel.Warning, ex); if (repeatTime <= 0) { - throw new ProcessException("AGV缃戠粶閫氫俊澶辫触", ex); + throw new ProcessException("AGV缃戠粶閫氫俊澶辫触", ExceptionLevel.Warning, ex); } Thread.Sleep(IConfig.ScanInterval); } catch (Exception ex) { - throw new ProcessException("AGV淇℃伅鍙戦�佸紓甯�", ex); + throw new ProcessException("AGV淇℃伅鍙戦�佸紓甯�", ExceptionLevel.Warning, ex); } } while (repeatTime > 0); @@ -247,12 +296,35 @@ { case (int)AGVCode.QueryPosition: CurrentPosition = recMsg.JValues.Value<string>("current_station"); + LastStation = recMsg.JValues.Value<string>("last_station"); + + PositionHandle.Set(); break; case (int)AGVCode.QueryTaskStatus: TaskStatus = (AGVTaskStatus)recMsg.JValues.Value<int>("task_status"); + + StateHandle.Set(); break; case (int)AGVCode.QueryBattery: BatteryLvl = recMsg.JValues.Value<float>("battery_level"); + + BatteryHandle.Set(); + break; + case (int)AGVCode.QueryIO: + //recMsg.JValues.Value<JArray>("DI").ToList().ForEach(j => + //{ + // var ioDefinition = IConfig.IOCollection.FirstOrDefault(i => i.IOIndex == j.Value<int>("id")); + + // if (ioDefinition != null && j.Value<bool>("status") != ioDefinition.CurrentValue) + // { + // ioDefinition.CurrentValue = j.Value<bool>("status"); + // OnAGVIOChanged?.Invoke(this, ioDefinition); + // } + //}); + + //楂樼數骞� 1 浣庣數骞� 0 + _ioDict = recMsg.JValues.Value<JArray>("DI").ToDictionary(u => u.Value<int>("id"), u => u.Value<bool>("status") ? 1 : 0); + IOHandle.Set(); break; default: break; @@ -272,13 +344,102 @@ SendMsg(client_Guide, IConfig.GuidePort, msg); } - public void TaskOrder(string dest) + ManualResetEvent _taskDoneHandle = new ManualResetEvent(false); + ManualResetEvent _monitorLock = new ManualResetEvent(true); + bool _isTaskRunning = false; + public void TaskOrder(string dest, bool isWaitFinished) { - CurrentPosition = ""; - SeerMessage msg = new SeerMessage((int)AGVCode.TaskOrder, SID, JsonConvert.SerializeObject(new { id = dest })); + _monitorLock.Reset(); + Thread.Sleep(IConfig.ScanInterval); - OnLog?.BeginInvoke(DateTime.Now, this, $"{Name}琛岄┒鍚� {dest}", null, null); + CurrentPosition = ""; + Destination = dest; + TaskStatus = AGVTaskStatus.None; + + SeerMessage msg = new SeerMessage((int)AGVCode.TaskOrder, SID, JsonConvert.SerializeObject(new { id = dest })); + //OnLog?.BeginInvoke(DateTime.Now, this, $"{Name}琛岄┒鍚� {dest}", null, null); + LogAsync(DateTime.Now, "", $"{Name}琛岄┒鍚� {dest}"); + SendMsg(client_Guide, IConfig.GuidePort, msg); + //Thread.Sleep(IConfig.ScanInterval); + _monitorLock.Set(); + + if (isWaitFinished) + { + _isTaskRunning = true; + _taskDoneHandle.Reset(); + bool isNotTimeout = _taskDoneHandle.WaitOne((int)(IConfig.OperationTimeout * 60 * 1000)); + if (!isNotTimeout) + { + throw new ProcessException($"{Name}鎵ц鍘诲線{dest}鍔ㄤ綔瓒呮椂"); + } + + if (TaskStatus == AGVTaskStatus.Failed) + { + throw new ProcessException($"{Name}鎵ц鍘诲線{dest}鍔ㄤ綔澶辫触"); + } + else if (TaskStatus == AGVTaskStatus.Cancelled) + { + //OnLog?.Invoke(DateTime.Now, this, $"{Name}鎵ц鍘诲線{dest}鍔ㄤ綔鍙栨秷"); + LogAsync(DateTime.Now, "", $"{Name}鎵ц鍘诲線{dest}鍔ㄤ綔鍙栨秷"); + } + } } + + #region IMonitor + public event OnMonitorInvokeDelegate OnMonitorInvoke; + public event OnMonitorAlarmDelegate OnMonitorAlarm; + + Dictionary<int, int> _ioDict = new Dictionary<int, int>(); + public void Monitor() + { + while (CurrentState != EnumHelper.DeviceState.DSClose && CurrentState != EnumHelper.DeviceState.DSExcept) + { + try + { + IOHandle.Reset(); + + var isNotTimeout = IOHandle.WaitOne(IConfig.ScanInterval * 3); + + if (!isNotTimeout) + throw new ProcessException($"{Name}鐩戝惉瓒呮椂"); + + IConfig.MonitorSetCollection.ForEach(m => + { + if (_ioDict.ContainsKey(m.TriggerIndex)) + { + if ((m.TriggerValue == _ioDict[m.TriggerIndex] || m.TriggerIndex == -999) && _ioDict[m.TriggerIndex] != m.CurrentValue) + { + if (m.OpConfig == null) + { + m.OpConfig = new OperationConfigBase(); + } + + m.OpConfig.InputPara = m.InputDataIndex.ConvertAll(index => + { + if (_ioDict.ContainsKey(index)) + { + return _ioDict[index]; + } + else + { + return -1; + } + }).ToList(); + + OnMonitorInvoke?.BeginInvoke(DateTime.Now, this, m, null, null); + } + + m.CurrentValue = _ioDict[m.TriggerIndex]; + } + }); + } + catch (Exception ex) + { + OnLog?.Invoke(DateTime.Now, this, $"{Name}鐩戝惉寮傚父:{ex.GetExceptionMessage()}"); + } + } + } + #endregion } } -- Gitblit v1.8.0