From 7971d855ba2cf9772b46a7f67e2b669c0afcb91b Mon Sep 17 00:00:00 2001 From: patrick <patrick.xu@broconcentric.com> Date: 星期二, 22 十月 2019 11:30:35 +0800 Subject: [PATCH] 1. 添加标定操作及界面 2. 修改配置界面方法调用参数 3. SeerAGV添加电池信息监听 4. 添加AGV电池充电操作 5. 修改AGV状态变化操作,添加操作锁 --- src/A032.Process/Calibration/CalibrationConfig.cs | 32 + src/Bro.Device.SeerAGV/SeerAGVConfig.cs | 34 ++ src/Bro.Common.Model/Interface/IStationConfig.cs | 4 src/A032.Config/ConfigFrm.cs | 52 ++- src/A032.Process/ProcessControl_Calibration.cs | 372 +++++++++++++++++++--- src/Bro.Device.SeerAGV/SeerAGVDriver.cs | 24 + src/A032.Process/ProcessControl.cs | 15 src/A032.Process/AGVPath.cs | 22 + src/A032.Process/ProcessControl_Method.cs | 157 +++++++-- src/A032.Config/ConfigFrm.designer.cs | 57 +++ src/A032.Process/Forms/OperationConfigBindFrm.cs | 36 - src/A032.Process/AGVBindUnit.cs | 37 ++ src/Bro.Common.Model/Helper/UIHelper.cs | 15 src/A032.Process/Calibration/FrmCalib9PDynamic.cs | 40 ++ src/A032.Process/Calibration/CtrlCalib9PDynamic.cs | 52 ++- 15 files changed, 747 insertions(+), 202 deletions(-) diff --git a/src/A032.Config/ConfigFrm.cs b/src/A032.Config/ConfigFrm.cs index cb7c154..388f59d 100644 --- a/src/A032.Config/ConfigFrm.cs +++ b/src/A032.Config/ConfigFrm.cs @@ -42,6 +42,8 @@ { InitialCalibrationMethod(); InitialAllTestMethod(); + + InitialDevices(); } } } @@ -285,7 +287,7 @@ private void btnStartCalibration_Click(object sender, EventArgs e) { btnStartCalibration.Enabled = false; - + IDevice device = cboCalibDevices.SelectedItem as IDevice; try { IOperationConfig config = propCalibrationConfig.SelectedObject as IOperationConfig; @@ -294,7 +296,7 @@ config.InputPara = null; } - _calibrationMethod.Invoke(Process, new object[] { config }); + _calibrationMethod.Invoke(Process, new object[] { config, device }); } catch (Exception ex) { @@ -314,6 +316,16 @@ #region Test Dictionary<ProcessMethodAttribute, MethodInfo> _allTestMethod = new Dictionary<ProcessMethodAttribute, MethodInfo>(); MethodInfo _testMethod = null; + + List<IDevice> _deviceList = new List<IDevice>(); + private void InitialDevices() + { + _deviceList = (Process as ProcessControl).GetDeviceList(); + + List<ISimpleDevice> list = _deviceList.Select(u => u as ISimpleDevice).ToList(); + UIHelper.SetCombo(cboCalibDevices, list, "Name", "Id"); + UIHelper.SetCombo(cboDevices, list, "Name", "Id"); + } private void InitialAllTestMethod() { @@ -337,28 +349,29 @@ private void cboTestMethod_SelectedIndexChanged(object sender, EventArgs e) { - //if (cboTestMethod.SelectedIndex >= 0) - //{ - // string methodCode = cboTestMethod.SelectedValue.ToString(); - // var attr = _allTestMethod.Keys.FirstOrDefault(u => u.MethodCode == methodCode); - // if (attr == null) - // return; + if (cboTestMethod.SelectedIndex >= 0) + { + string methodCode = cboTestMethod.SelectedValue.ToString(); + var attr = _allTestMethod.Keys.FirstOrDefault(u => u.MethodCode == methodCode); + if (attr == null) + return; - // _testMethod = _allTestMethod[attr]; + _testMethod = _allTestMethod[attr]; - // if (Process.StationConfig.ProcessOpConfigDict.Keys.Contains(methodCode)) - // { - // propGridTestMethod.SelectedObject = Process.StationConfig.ProcessOpConfigDict[methodCode]; - // } - // else - // { - // MessageBox.Show(@"Config of " + methodCode + @" is not found"); - // } - //} + if (Process.StationConfig.ProcessOpConfigDict.Keys.Contains(methodCode)) + { + propGridTestMethod.SelectedObject = Process.StationConfig.ProcessOpConfigDict[methodCode]; + } + else + { + MessageBox.Show(@"Config of " + methodCode + @" is not found"); + } + } } private void btnManualTrigger_Click(object sender, EventArgs e) { + IDevice device = cboDevices.SelectedItem as IDevice; new Task((m) => { MethodInfo method = m as MethodInfo; @@ -370,14 +383,13 @@ invokeTimes = 1; } ProcessResponse response = null; - if (invokeTimes == 1) { try { Stopwatch sw = new Stopwatch(); sw.Start(); - response = method.Invoke(Process, new object[] { propGridTestMethod.SelectedObject as IOperationConfig }) as ProcessResponse; + response = method.Invoke(Process, new object[] { propGridTestMethod.SelectedObject as IOperationConfig, device }) as ProcessResponse; sw.Stop(); //RecordMsg($"{method.Name}璋冪敤鑰楁椂锛歿sw.ElapsedMilliseconds}ms"); diff --git a/src/A032.Config/ConfigFrm.designer.cs b/src/A032.Config/ConfigFrm.designer.cs index 5c1f834..5b9fb52 100644 --- a/src/A032.Config/ConfigFrm.designer.cs +++ b/src/A032.Config/ConfigFrm.designer.cs @@ -75,6 +75,10 @@ this.cboProductionCode = new System.Windows.Forms.ComboBox(); this.statusStrip1 = new System.Windows.Forms.StatusStrip(); this.tsslLoginStatus = new System.Windows.Forms.ToolStripStatusLabel(); + this.cboDevices = new System.Windows.Forms.ComboBox(); + this.label5 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.cboCalibDevices = new System.Windows.Forms.ComboBox(); this.tabControl1.SuspendLayout(); this.tbConfig.SuspendLayout(); this.tbCalibration.SuspendLayout(); @@ -162,6 +166,8 @@ // // tbCalibration // + this.tbCalibration.Controls.Add(this.label6); + this.tbCalibration.Controls.Add(this.cboCalibDevices); this.tbCalibration.Controls.Add(this.label1); this.tbCalibration.Controls.Add(this.propCalibrationConfig); this.tbCalibration.Controls.Add(this.btnStartCalibration); @@ -177,7 +183,7 @@ // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(22, 20); + this.label1.Location = new System.Drawing.Point(262, 12); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(53, 12); this.label1.TabIndex = 7; @@ -211,7 +217,7 @@ | System.Windows.Forms.AnchorStyles.Right))); this.cboCalibrationMethod.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.cboCalibrationMethod.FormattingEnabled = true; - this.cboCalibrationMethod.Location = new System.Drawing.Point(12, 41); + this.cboCalibrationMethod.Location = new System.Drawing.Point(252, 33); this.cboCalibrationMethod.Name = "cboCalibrationMethod"; this.cboCalibrationMethod.Size = new System.Drawing.Size(185, 20); this.cboCalibrationMethod.TabIndex = 4; @@ -220,8 +226,10 @@ // this.tbTest.Controls.Add(this.label3); this.tbTest.Controls.Add(this.txtInvokeTimes); + this.tbTest.Controls.Add(this.label5); this.tbTest.Controls.Add(this.label2); this.tbTest.Controls.Add(this.propGridTestMethod); + this.tbTest.Controls.Add(this.cboDevices); this.tbTest.Controls.Add(this.btnTrigger); this.tbTest.Controls.Add(this.cboTestMethod); this.tbTest.Location = new System.Drawing.Point(4, 22); @@ -254,7 +262,7 @@ // label2 // this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(21, 13); + this.label2.Location = new System.Drawing.Point(262, 12); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(53, 12); this.label2.TabIndex = 11; @@ -288,7 +296,7 @@ | System.Windows.Forms.AnchorStyles.Right))); this.cboTestMethod.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.cboTestMethod.FormattingEnabled = true; - this.cboTestMethod.Location = new System.Drawing.Point(11, 34); + this.cboTestMethod.Location = new System.Drawing.Point(252, 33); this.cboTestMethod.Name = "cboTestMethod"; this.cboTestMethod.Size = new System.Drawing.Size(185, 20); this.cboTestMethod.TabIndex = 9; @@ -606,6 +614,43 @@ this.tsslLoginStatus.Text = "鏈櫥褰�"; this.tsslLoginStatus.Click += new System.EventHandler(this.tsslLoginStatus_Click); // + // cboDevices + // + this.cboDevices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboDevices.FormattingEnabled = true; + this.cboDevices.Location = new System.Drawing.Point(21, 33); + this.cboDevices.Name = "cboDevices"; + this.cboDevices.Size = new System.Drawing.Size(185, 20); + this.cboDevices.TabIndex = 9; + this.cboDevices.SelectedIndexChanged += new System.EventHandler(this.cboTestMethod_SelectedIndexChanged); + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(31, 12); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(53, 12); + this.label5.TabIndex = 11; + this.label5.Text = "閫夋嫨璁惧"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(31, 12); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(53, 12); + this.label6.TabIndex = 13; + this.label6.Text = "閫夋嫨璁惧"; + // + // cboCalibDevices + // + this.cboCalibDevices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboCalibDevices.FormattingEnabled = true; + this.cboCalibDevices.Location = new System.Drawing.Point(21, 33); + this.cboCalibDevices.Name = "cboCalibDevices"; + this.cboCalibDevices.Size = new System.Drawing.Size(185, 20); + this.cboCalibDevices.TabIndex = 12; + // // ConfigFrm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); @@ -688,6 +733,10 @@ private System.Windows.Forms.StatusStrip statusStrip1; private System.Windows.Forms.ToolStripStatusLabel tsslLoginStatus; private System.Windows.Forms.CheckBox chkHardwareTrigger; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.ComboBox cboDevices; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.ComboBox cboCalibDevices; } } diff --git a/src/A032.Process/AGVBindUnit.cs b/src/A032.Process/AGVBindUnit.cs index 507d8c8..4aa8d0b 100644 --- a/src/A032.Process/AGVBindUnit.cs +++ b/src/A032.Process/AGVBindUnit.cs @@ -191,6 +191,35 @@ //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) @@ -288,9 +317,9 @@ { ProcessConfig config = scope.Resolve<ProcessConfig>(); - config.RobotConfigCollection.ForEach(plc => + config.RobotConfigCollection.ForEach(robot => { - _hash[plc.ID] = plc.Name; + _hash[robot.ID] = robot.Name; }); } } @@ -304,9 +333,9 @@ { ProcessConfig config = scope.Resolve<ProcessConfig>(); - config.CameraConfigCollection.ForEach(plc => + config.CameraConfigCollection.ForEach(camera => { - _hash[plc.ID] = plc.Name; + _hash[camera.ID] = camera.Name; }); } } diff --git a/src/A032.Process/AGVPath.cs b/src/A032.Process/AGVPath.cs index 1bfb3e0..2e19e32 100644 --- a/src/A032.Process/AGVPath.cs +++ b/src/A032.Process/AGVPath.cs @@ -25,6 +25,8 @@ LoadFullTray = 3, [Description("鍗歌浇婊ray鍦扮偣")] UnloadFullTray = 4, + [Description("鍏呯數鍦扮偣")] + Charge = 5, } public class PathPosition : IComplexDisplay @@ -73,7 +75,7 @@ [Description("璇ヤ綅缃爣鍑嗙偣浣嶄俊鎭�")] [TypeConverter(typeof(ComplexObjectConvert))] [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] - public CustomizedPoint StandardPoint { get; set; } = new CustomizedPoint(); + public CustomizedPointWithAngle StandardPoint { get; set; } = new CustomizedPointWithAngle(); [Category("瑙嗚閰嶇疆")] [Description("璇ヤ綅缃媿鎽勯厤缃�")] @@ -102,7 +104,23 @@ config.PositionCollection.ForEach(p => { - _hash[p.PositionCode] = $"{p.PositionCode}-{p.Description.GetEnumDescription()}"; + _hash[p.PositionCode] = $"{p.PositionCode}-{p.PositionNo}-{p.Description.GetEnumDescription()}"; + }); + } + } + } + + public class PositionNoConverter : ComboBoxItemTypeConvert + { + public override void GetConvertHash() + { + using (var scope = GlobalVar.Container.BeginLifetimeScope()) + { + var config = scope.Resolve<ProcessConfig>(); + + config.PositionCollection.ForEach(p => + { + _hash[p.PositionNo] = $"{p.PositionNo}-{p.PositionCode}-{p.Description.GetEnumDescription()}"; }); } } diff --git a/src/A032.Process/Calibration/CalibrationConfig.cs b/src/A032.Process/Calibration/CalibrationConfig.cs index 8c0d7fe..1b8f099 100644 --- a/src/A032.Process/Calibration/CalibrationConfig.cs +++ b/src/A032.Process/Calibration/CalibrationConfig.cs @@ -1,6 +1,7 @@ 锘縰sing Bro.Common.Base; using Bro.Common.Helper; using Bro.Common.Model; +using Bro.Common.Model.Interface; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -14,12 +15,12 @@ namespace A032.Process.Calibration { [Device("CalibrationCollection", "澶氭鏍囧畾閰嶇疆", EnumHelper.DeviceAttributeType.OperationConfig)] - public class CalibrationConfigCollection : OperationConfigBase + public class CalibrationConfigCollection : OperationConfigBase, IComplexDisplay,IHalconToolPath { [Category("鍏宠仈閰嶇疆")] - [Description("浣嶇疆浠g爜")] - [TypeConverter(typeof(PositionCodeConverter))] - public string PositionCode { get; set; } + [Description("浣嶇疆搴忓彿")] + [TypeConverter(typeof(PositionNoConverter))] + public int PositionNo { get; set; } [Category("鍏宠仈閰嶇疆")] [Description("閫傜敤鐩告満缂栧彿")] @@ -31,10 +32,24 @@ [TypeConverter(typeof(CollectionCountConvert))] [Editor(typeof(ComplexCollectionEditor<CalibrationConfig>), typeof(UITypeEditor))] public List<CalibrationConfig> Configs { get; set; } = new List<CalibrationConfig>(); + + [Category("鏄剧ず閰嶇疆")] + [Description("鏄惁鏄剧ずUI锛屼粠UI鍚姩鏍囧畾")] + public bool IsStartedFromUI { get; set; } = false; + + public string GetDisplayText() + { + return $"PositionNo:{PositionNo}; Configs:{Configs.Count}"; + } + + public List<string> GetHalconToolPathList() + { + return Configs.SelectMany(c => c.GetHalconToolPathList()).ToList(); + } } //[Device("Calibration", "鍗曟鏍囧畾閰嶇疆", EnumHelper.DeviceAttributeType.OperationConfig)] - public class CalibrationConfig : OperationConfigBase, IComplexDisplay, INotifyPropertyChanged + public class CalibrationConfig : OperationConfigBase, IComplexDisplay, INotifyPropertyChanged, IHalconToolPath { private Bitmap image = null; [JsonIgnore] @@ -63,7 +78,7 @@ [Description("鍥惧儚鏍囧噯鐐瑰潗鏍�")] [TypeConverter(typeof(ComplexObjectConvert))] [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] - public CustomizedPoint ImageMarkPoint { get; set; } = new CustomizedPoint(); + public CustomizedPointWithAngle ImageMarkPoint { get; set; } = new CustomizedPointWithAngle(); [Category("鐩告満閰嶇疆")] [Description("鐩告満鎿嶄綔閰嶇疆")] @@ -83,5 +98,10 @@ { return JsonConvert.SerializeObject(this); } + + public List<string> GetHalconToolPathList() + { + return CameraOpConfig.GetHalconToolPathList(); + } } } diff --git a/src/A032.Process/Calibration/CtrlCalib9PDynamic.cs b/src/A032.Process/Calibration/CtrlCalib9PDynamic.cs index dcf6c73..1cce895 100644 --- a/src/A032.Process/Calibration/CtrlCalib9PDynamic.cs +++ b/src/A032.Process/Calibration/CtrlCalib9PDynamic.cs @@ -20,7 +20,7 @@ namespace A032.Process.Calibration { [Device("Calibration_9P_Dynamic", "鍔ㄦ��9鐐规爣瀹�", EnumHelper.DeviceAttributeType.OperationConfigCtrl)] - public partial class CtrlCalib9PDynamic : UserControl, IConfigCtrl<CameraBase, CalibrationConfigCollection> + public partial class CtrlCalib9PDynamic : UserControl//, IConfigCtrl<CameraBase, CalibrationConfigCollection> { PubSubCenter PubSubCenter = PubSubCenter.GetInstance(); AutoResetEvent _confirmHandle = new AutoResetEvent(false); @@ -30,20 +30,29 @@ InitializeComponent(); } - public CtrlCalib9PDynamic(ProcessControl process, IDevice device, IOperationConfig config, Action<List<CalibrationConfig>> finalCalculation) + public CtrlCalib9PDynamic(ProcessControl process, CalibrationConfigCollection calibConfig, AGVBindUnit bind, PathPosition position, Action<AGVBindUnit, int, int> commuAction, Action<CalibrationConfigCollection, AGVBindUnit, PathPosition> finalCalculation) { InitializeComponent(); ProcessControl = process; - Camera = device as CameraBase; - Config = config as CalibrationConfigCollection; + + Config = calibConfig as CalibrationConfigCollection; + + Camera = bind.Camera as CameraBase; + + Bind = bind; + Position = position; + CommuAction = commuAction; FinalCalculation = finalCalculation; } - public CalibrationConfigCollection Config { get; set; } - public CameraBase Camera { get; set; } - public ProcessControl ProcessControl { get; set; } - public Action<List<CalibrationConfig>> FinalCalculation { get; set; } + AGVBindUnit Bind { get; set; } + PathPosition Position { get; set; } + Action<AGVBindUnit, int, int> CommuAction; + CalibrationConfigCollection Config { get; set; } + CameraBase Camera { get; set; } + ProcessControl ProcessControl { get; set; } + Action<CalibrationConfigCollection, AGVBindUnit, PathPosition> FinalCalculation { get; set; } public CalibrationConfigCollection GetConfig() { @@ -159,7 +168,7 @@ if (chkManualConfirm.Checked) { - this.Invoke(new Action(() => btnContinueCalib.Visible = true)); ; + this.Invoke(new Action(() => btnContinueCalib.Visible = true)); ; _confirmHandle.WaitOne(); } @@ -188,14 +197,16 @@ private void btnStartCalib_Click(object sender, EventArgs e) { - if (chkOfflineCalib.Checked) - { - //ProcessControl.Calibration_Pick_9P_Dynamic_Offline(Config.Configs); - } - else - { - //ProcessControl.SendCalibStartSignal(Config.TriggerAddress); - } + //if (chkOfflineCalib.Checked) + //{ + // //ProcessControl.Calibration_Pick_9P_Dynamic_Offline(Config.Configs); + //} + //else + //{ + // //ProcessControl.SendCalibStartSignal(Config.TriggerAddress); + //} + + ProcessControl.MultipleStepsProcess(Config, Bind, CommuAction); } private void btnLoadOfflineImages_Click(object sender, EventArgs e) @@ -213,7 +224,7 @@ private void btnStepRun_Click(object sender, EventArgs e) { - //CalibrationConfig config = propGridConfig.SelectedObject as CalibrationConfig; + CalibrationConfig config = propGridConfig.SelectedObject as CalibrationConfig; //if (!chkOfflineRun.Checked) //{ // ProcessControl.CalibMarkPoint(Camera, config, _selectedStepIndex + 1); @@ -224,11 +235,14 @@ //} //tsslInfo.Text = $"鍗曟杩愮畻瀹屾垚銆傛爣璁扮偣鍧愭爣锛歿config.ImageMarkPoint.X},{config.ImageMarkPoint.Y}"; + + ProcessControl.SingleStepProcess(config, CommuAction, Bind, Position.PositionNo, _selectedStepIndex); + tsslInfo.Text = $"鍗曟杩愮畻瀹屾垚銆傛爣璁扮偣鍧愭爣锛歿config.ImageMarkPoint.X},{config.ImageMarkPoint.Y}"; } private void btnCalcuMatrix_Click(object sender, EventArgs e) { - FinalCalculation.Invoke(Config.Configs); + FinalCalculation.Invoke(Config, Bind, Position); } private void btnSnap_Click(object sender, EventArgs e) diff --git a/src/A032.Process/Calibration/FrmCalib9PDynamic.cs b/src/A032.Process/Calibration/FrmCalib9PDynamic.cs index e780681..5fe5c52 100644 --- a/src/A032.Process/Calibration/FrmCalib9PDynamic.cs +++ b/src/A032.Process/Calibration/FrmCalib9PDynamic.cs @@ -16,25 +16,49 @@ { public partial class FrmCalib9PDynamic : Form { + //private CalibrationConfigCollection calibConfig; + //private AGVBindUnit bind; + //private PathPosition position; + //private Action<AGVBindUnit, int, int> sendMessageToRobot_Calibration; + //private Action<CalibrationConfigCollection, AGVBindUnit, PathPosition> calculateMatrix; + public FrmCalib9PDynamic() { InitializeComponent(); } - public FrmCalib9PDynamic(ProcessControl process, IDevice device, IOperationConfig config, Action<List<CalibrationConfig>> finalCalculation) + //public FrmCalib9PDynamic(ProcessControl process, IDevice device, IOperationConfig config, Action<List<CalibrationConfig>> finalCalculation) + //{ + // InitializeComponent(); + + // Device = device as CameraBase; + // Config = config as CalibrationConfigCollection; + // FinalCalculation = finalCalculation; + // 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) { InitializeComponent(); - Device = device as CameraBase; - Config = config as CalibrationConfigCollection; - FinalCalculation = finalCalculation; - CtrlCalib9PDynamic = new CtrlCalib9PDynamic(process, device, config, finalCalculation); + //Config = calibConfig; + //Bind = bind; + //Camera = Bind.Camera; + //Position = position; + //CommuAction = commuAction; + //FinalCalculation = finalCalculation; + + CtrlCalib9PDynamic = new CtrlCalib9PDynamic(process, calibConfig, bind, position, commuAction, finalCalculation); } - CameraBase Device { get; set; } - CalibrationConfigCollection Config { get; set; } + //AGVBindUnit Bind { get; set; } + //CameraBase Camera { get; set; } + //CalibrationConfigCollection Config { get; set; } + //PathPosition Position { get; set; } + //Action<AGVBindUnit, int, int> CommuAction; + //Action<CalibrationConfigCollection, AGVBindUnit, PathPosition> FinalCalculation { get; set; } + CtrlCalib9PDynamic CtrlCalib9PDynamic { get; set; } - Action<List<CalibrationConfig>> FinalCalculation { get; set; } private void FrmCalib9PDynamic_Load(object sender, EventArgs e) { diff --git a/src/A032.Process/Forms/OperationConfigBindFrm.cs b/src/A032.Process/Forms/OperationConfigBindFrm.cs index 8896b86..b8e498c 100644 --- a/src/A032.Process/Forms/OperationConfigBindFrm.cs +++ b/src/A032.Process/Forms/OperationConfigBindFrm.cs @@ -14,6 +14,8 @@ using Bro.Common.Base; using Bro.Common.Factory; using A032.Process; +using Bro.Common.Model; +using Autofac; namespace Bro.Device.Station.Forms { @@ -141,38 +143,12 @@ private void LoadMethodCodes() { - IStationProcess sp = new ProcessControl(); - //switch (StationCode) - //{ - // case "S1": - // sp = new StationProcess_S1(false); - // break; - // case "S2": - // sp = new StationProcess_S2(false); - // break; - // case "S3": - // sp = new StationProcess_S3(false); - // break; - // case "S4": - // sp = new StationProcess_S4(false); - // break; - // case "S5": - // sp = new StationProcess_S5(false); - // break; - // case "S6": - // sp = new StationProcess_S6(false); - // break; - // case "S7": - // sp = new StationProcess_S7(false); - // break; - // //case "S0": - // // sp = new StationProcess_S0(false); - // // break; - //} - OpBinds = new Dictionary<string, IOperationConfig>(); - ProcessMethodList = sp.CollectProcessMethods(); + using (var scope = GlobalVar.Container.BeginLifetimeScope()) + { + ProcessMethodList = scope.Resolve<List<ProcessMethodAttribute>>(); + } ProcessMethodList.ForEach(u => { diff --git a/src/A032.Process/ProcessControl.cs b/src/A032.Process/ProcessControl.cs index 7ceda2f..dfd85ab 100644 --- a/src/A032.Process/ProcessControl.cs +++ b/src/A032.Process/ProcessControl.cs @@ -263,7 +263,7 @@ }); } - Dictionary<string, MethodInfo> InvokeMethodDict = new Dictionary<string, MethodInfo>(); + //Dictionary<string, MethodInfo> InvokeMethodDict = new Dictionary<string, MethodInfo>(); public List<ProcessMethodAttribute> CollectProcessMethods() { List<ProcessMethodAttribute> resultList = new List<ProcessMethodAttribute>(); @@ -275,7 +275,7 @@ if (attr != null) { resultList.Add(attr); - InvokeMethodDict[attr.MethodCode] = m; + //InvokeMethodDict[attr.MethodCode] = m; } }); @@ -289,19 +289,16 @@ StationConfig = LoadStationConfig(configPath); #region 涓埆閰嶇疆鐨勭壒鍒鐞� - #endregion _warningRemains.CollectionChanged -= _warningRemains_CollectionChanged; _warningRemains.CollectionChanged += _warningRemains_CollectionChanged; InitialPLCs(); - InitialRobots(); InitialAGVs(); + InitialRobots(); InitialCameras(); - InitialAGVBindUnit(); - InitialMachineTrayNums(); AutoFacRegister(); @@ -393,6 +390,7 @@ agv.OnAGVPositoinChanged = OnAGVPositionChanged; agv.OnAGVTaskStatusChanged = OnAGVTaskStatusChanged; + agv.OnAGVBatteryLvlChanged = OnAGVBatterLvlChanged; }); } @@ -542,6 +540,11 @@ { InitialHalconTool(c as IHalconToolPath); }); + + Config.ProcessOpConfigDict.Values.ToList().ForEach(c => + { + InitialHalconTool(c as IHalconToolPath); + }); #endregion } diff --git a/src/A032.Process/ProcessControl_Calibration.cs b/src/A032.Process/ProcessControl_Calibration.cs index 49fa9ee..44a19ea 100644 --- a/src/A032.Process/ProcessControl_Calibration.cs +++ b/src/A032.Process/ProcessControl_Calibration.cs @@ -3,99 +3,355 @@ using Bro.Common.Helper; using Bro.Common.Interface; using Bro.Common.Model; +using HalconDotNet; using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; +using static Bro.Common.Helper.EnumHelper; namespace A032.Process { public partial class ProcessControl { + CalibReplyMsg _calibReply = new CalibReplyMsg(); + [ProcessMethod("CalibrationCollection", "RobotCalibration", "鏈哄櫒浜�9鐐规爣瀹�", true)] - public ProcessResponse RobotCalibration(IOperationConfig config) + public ProcessResponse RobotCalibration(IOperationConfig config, IDevice device) { + CalibrationConfigCollection calibConfig = config as CalibrationConfigCollection; + + 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‘浣嶇疆淇℃伅"); + } + + if (calibConfig.Configs.Count < 9) + { + throw new ProcessException("璇疯嚦灏戦厤缃�9涓爣瀹氱偣浣�"); + } + + if (calibConfig.IsStartedFromUI) + { + FrmCalib9PDynamic frm = new FrmCalib9PDynamic(this, calibConfig, bind, position, SendMessageToRobot_Calibration, CalculateMatrix); + frm.ShowDialog(); + } + else + { + MultipleStepsProcess(calibConfig, bind, SendMessageToRobot_Calibration); + + 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); } [ProcessMethod("CalibrationCollection", "StandardPointCalibration", "鏍囧噯鐐逛綅鏍囧畾", true)] - public ProcessResponse StandardPointCalibration(IOperationConfig config) + public ProcessResponse StandardPointCalibration(IOperationConfig config, IDevice device) { - return new ProcessResponse(true); - } + CalibrationConfigCollection calibConfig = config as CalibrationConfigCollection; - public void SendCalibrationStartSignal(int stepNum) - { + 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‘浣嶇疆淇℃伅"); + } - private int MultipleStepsCalibration(CalibrationConfigCollection configs, Action<List<CalibrationConfig>> FinalCalculation) - { - throw new NotImplementedException(); + if (calibConfig.Configs.Count < 1) + { + throw new ProcessException("璇疯嚦灏戦厤缃�1涓爣瀹氱偣浣�"); + } - //configs.Configs.ForEach(c => + if (calibConfig.IsStartedFromUI) + { + FrmCalib9PDynamic frm = new FrmCalib9PDynamic(this, calibConfig, bind, position, SendMessageToRobot_Standard, CalculateStandardPoint); + frm.ShowDialog(); + } + else + { + MultipleStepsProcess(calibConfig, bind, SendMessageToRobot_Standard); + + CalculateStandardPoint(calibConfig, bind, position); + } + + //for (int i = 0; i < calibConfig.Configs.Count; i++) //{ - // c.Image = null; - //}); + // bind.Robot.SendMsg(Bro.Device.AuboRobot.RobotMsgAction.Calibration, Bro.Device.AuboRobot.RobotMsgParas.None, calibConfig.PositionNo, new List<float>() { i + 1 }); - //if (string.IsNullOrWhiteSpace(configs.CameraId) || !CameraDict.ContainsKey(configs.CameraId)) - //{ - // throw new ProcessException("鏍囧畾閰嶇疆鏈厤缃纭殑鐩告満缂栧彿"); - //} + // _calibReply.CalibHandle.WaitOne(); - //if (string.IsNullOrWhiteSpace(configs.PositionCode)) - //{ - // throw new ProcessException("鏍囧畾閰嶇疆鏈寚瀹氳矾寰勪綅缃�"); - //} - - //CameraBase camera = CameraDict[configs.CameraId]; - //FrmCalib9PDynamic frm9PDynamic = new FrmCalib9PDynamic(this, camera, configs, FinalCalculation); - //frm9PDynamic.ShowDialog(); - - //if (configs.InputPara == null || configs.InputPara.Count <= 0) - //{ - // return (int)PLCReplyValue.NG; - //} - - //if (configs.InputPara[0] <= 0 || configs.InputPara[0] > configs.Configs.Count) - //{ - // configs.InputPara = null; - // return (int)PLCReplyValue.IGNORE; - //} - - //int sequence = configs.InputPara[0]; - - ////绗竴娆� - //if (sequence == 1) - //{ - // configs.Configs.ForEach(c => + // if (_calibReply.CalibPositionNo != calibConfig.PositionNo) // { - // c.Image = null; - // c.OfflineImagePath = ""; - // c.CurrentPlatPoint = new CustomizedPoint(); - // c.ImageMarkPoint = new CustomizedPoint(); + // 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), // }); //} - //CalibrationConfig stepConfig = configs.Configs[sequence - 1]; + return new ProcessResponse(true); + } - //HDevEngineTool tool = _halconToolDict[] + 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); - //CalibMarkPoint(camera, stepConfig, sequence); + List<double> matrix = GetMovementMatrix(calibConfig.Configs.Select(u => u.ImageMarkPoint as CustomizedPoint).ToList(), calibConfig.Configs.Select(u => u.CurrentPlatPoint).ToList(), out string msg); - ////鑾峰彇褰撳墠骞冲彴鐐逛綅 - //stepConfig.CurrentPlatPoint = new CustomizedPoint(_monitorList.Skip(locationStartIndex).Take(4).ToList()); - ////stepConfig.CurrentPlatPoint = new CustomizedPoint(configs.InputPara.Skip(1).Take(4).ToList()); + 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 }, + }); + } - ////鏈�鍚庝竴娆� - //if (sequence == configs.Configs.Count) + PubSubCenter.Publish(PubTag.CalibAllDone.ToString(), "", msg, true); + } + + /// <summary> + /// 鑾峰彇鏍囧畾鐐圭殑杞崲鐭╅樀 + /// </summary> + /// <param name="points"></param> + /// <returns></returns> + protected List<double> GetMovementMatrix(List<CustomizedPoint> imagePoints, List<CustomizedPoint> platPoints, out string msg) + { + HTuple uList, vList, xList, yList, matrix; + + ConvertPointToHTuple(imagePoints, out uList, out vList); + ConvertPointToHTuple(platPoints, out xList, out yList); + + HOperatorSet.VectorToHomMat2d(uList, vList, xList, yList, out matrix); + + double sum = 0; + for (int i = 0; i < imagePoints.Count; i++) + { + HOperatorSet.AffineTransPoint2d(matrix, imagePoints[i].X, imagePoints[i].Y, out HTuple m, out HTuple n); + + 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()}鑴夊啿"; + + return matrix.DArr.ToList(); + } + + private void ConvertPointToHTuple(List<CustomizedPoint> point, out HTuple x, out HTuple y) + { + x = new HTuple(point.Select(p => p.X).ToArray()); + y = new HTuple(point.Select(p => p.Y).ToArray()); + } + + public void CalculateStandardPoint(CalibrationConfigCollection calibConfig, AGVBindUnit bind, PathPosition position) + { + //var bind = Config.AGVBindCollection.FirstOrDefault(u => u.CameraId == calibConfig.CameraId); + //if (bind == null) //{ - // FinalCalculation?.Invoke(configs.Configs); + // throw new ProcessException("鏈兘鑾峰彇缁戝畾璁惧淇℃伅"); //} - //configs.InputPara = null; - //return (int)PLCReplyValue.OK; + //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) + { + 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), + }); + } + + PubSubCenter.Publish(PubTag.CalibAllDone.ToString(), "", $"鏍囧畾瀹屾垚锛屾爣鍑嗙偣:{markPoint.GetDisplayText()}", true); } + + public void MultipleStepsProcess(CalibrationConfigCollection calibConfig, AGVBindUnit bind, Action<AGVBindUnit, int, int> sendMessageToRobot) + { + for (int i = 0; i < calibConfig.Configs.Count; i++) + { + SingleStepProcess(calibConfig.Configs[i], sendMessageToRobot, bind, calibConfig.PositionNo, i); + } + } + + public void SendMessageToRobot_Calibration(AGVBindUnit bind, int positionNo, 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); + + 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.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("鑾峰彇鐐逛綅淇℃伅涓嶆纭�"); + } + + config.ImageMarkPoint = new CustomizedPointWithAngle(x, y, angel); + } + + 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 97166ab..451d2bd 100644 --- a/src/A032.Process/ProcessControl_Method.cs +++ b/src/A032.Process/ProcessControl_Method.cs @@ -20,9 +20,49 @@ { 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 OnAGVBatterLvlChanged(SeerAGVDriver agv, float batterLvl) + { + var bind = Config.AGVBindCollection.FirstOrDefault(u => u.AGVId == agv.Id); + SeerAGVInitialConfig iConfig = agv.InitialConfig as SeerAGVInitialConfig; + if (batterLvl <= 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 (batterLvl >= iConfig.BatteryLvlChargeDone) + { + bind.SetAGVStatus(TaskStatus.Available); + return; + } + } private void OnAGVTaskStatusChanged(SeerAGVDriver agv, AGVTaskStatus taskStatus) { @@ -42,7 +82,7 @@ // bind.RobotStatus = TaskStatus.Running; //} - bind.AGVStatus = TaskStatus.Available; + bind.SetAGVStatus(TaskStatus.Available); } } @@ -64,7 +104,7 @@ // bind.RobotStatus = TaskStatus.Running; //} - bind.AGVStatus = TaskStatus.Available; + bind.SetAGVStatus(TaskStatus.Available); PathPosition position = Config.PositionCollection.FirstOrDefault(p => p.PositionCode == bind.AGVDest); switch (position.Description) @@ -85,6 +125,7 @@ } } } + #endregion private void OnRobotMsgReceived(DateTime dt, AuboRobotDriver robot, RobotMsg msg) { @@ -210,12 +251,17 @@ 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: @@ -309,7 +355,7 @@ while (bind.IsEmptyTrayEmpty && !bind.IsEmptyTrayTaskAssigned) { //if (bind.TaskList.Count == 0) - if (bind.AGVStatus == TaskStatus.Available && bind.RobotStatus == TaskStatus.Available) + if (bind.UnitStatus == TaskStatus.Available) { //List<AGVTaskModel> models = new List<AGVTaskModel>(); //models.Add(new AGVTaskModel(TaskAvailableLevel.Both, "AGV_LoadEmptyTray")); @@ -317,12 +363,14 @@ //AddNewTaskToBind(device.Id, models); - AGV_LoadEmptyTray(bind.Id); - bind.IsEmptyTrayTaskAssigned = true; + if (AGV_LoadEmptyTray(bind.Id)) + { + bind.IsEmptyTrayTaskAssigned = true; + } } else { - Thread.Sleep(500); + Thread.Sleep(WAITTIME); } } }); @@ -351,7 +399,7 @@ while (bind.IsFullTrayFull && !bind.IsFullTrayTaskAssigned) { //if (bind.TaskList.Count == 0) - if (bind.AGVStatus == TaskStatus.Available && bind.RobotStatus == TaskStatus.Available) + if (bind.UnitStatus == TaskStatus.Available) { //List<AGVTaskModel> models = new List<AGVTaskModel>(); //models.Add(new AGVTaskModel(TaskAvailableLevel.Both, "AGV_UnloadFullTray")); @@ -359,13 +407,14 @@ //AddNewTaskToBind(device.Id, models); - AGV_UnloadFullTray(bind.Id); - - bind.IsFullTrayTaskAssigned = true; + if (AGV_UnloadFullTray(bind.Id)) + { + bind.IsFullTrayTaskAssigned = true; + } } else { - Thread.Sleep(500); + Thread.Sleep(WAITTIME); } } }); @@ -460,7 +509,7 @@ // return new ProcessResponse(true); //} - public void AGV_LoadEmptyTray(string bindId) + 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); @@ -470,10 +519,17 @@ 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 true; + } + else + { + return false; + } } //[ProcessMethod("", "AfterEmptyTrayPositionArrived", "鍒拌揪绌篢ray涓婃枡鐐�", true)] @@ -589,20 +645,21 @@ //bind.AddTask(model_AGV); //bind.AddTask(model_Robot); - AGV_UnloadEmptyTray(bind.Id, position); - - taskStatus.IsTaskAssgined = true; - taskStatus.AgvId = bind.AGVId; + if (AGV_UnloadEmptyTray(bind.Id, position)) + { + taskStatus.IsTaskAssgined = true; + taskStatus.AgvId = bind.AGVId; + } } } - Thread.Sleep(300); + Thread.Sleep(WAITTIME); } }); } //[ProcessMethod("", "AGV_UnloadEmptyTray", "AGV鍘诲線鍗歌浇绌篢ray鏂欎綅缃�", true)] - public void AGV_UnloadEmptyTray(string bindId, PathPosition position) + public bool AGV_UnloadEmptyTray(string bindId, PathPosition position) { var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); @@ -611,10 +668,17 @@ 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 true; + } + else + { + return false; + } } //[ProcessMethod("", "Robot_UnloadEmptyTray", "鏈哄櫒浜鸿繍鍔ㄨ嚦绌篢ray鎷嶇収浣嶇疆", true)] @@ -756,7 +820,7 @@ adjust_X = (float)dx_Robot.D; adjust_Y = (float)dy_Robot.D; - adjust_Angle = angle; + 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 }); @@ -831,10 +895,11 @@ //bind.AddTask(model_AGV); //bind.AddTask(model_Robot); - AGV_LoadFullTray(bind.Id, position); - - taskStatus.IsTaskAssgined = true; - taskStatus.AgvId = bind.AGVId; + if (AGV_LoadFullTray(bind.Id, position)) + { + taskStatus.IsTaskAssgined = true; + taskStatus.AgvId = bind.AGVId; + } } } @@ -844,7 +909,7 @@ } //[ProcessMethod("", "AGV_LoadFullTray", "AGV鍘诲線婊ray涓婃枡浣嶇疆", true)] - public void AGV_LoadFullTray(string bindId, PathPosition position) + public bool AGV_LoadFullTray(string bindId, PathPosition position) { var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); @@ -855,10 +920,17 @@ 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 true; + } + else + { + return false; + } //return new ProcessResponse(true); } @@ -1026,7 +1098,7 @@ adjust_X = (float)dx_Robot.D; adjust_Y = (float)dy_Robot.D; - adjust_Angle = angle; + 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 }); @@ -1060,7 +1132,7 @@ // return new ProcessResponse(true); //} - public void AGV_UnloadFullTray(string bindId) + 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); @@ -1070,10 +1142,17 @@ 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 true; + } + else + { + return false; + } } //[ProcessMethod("", "Robot_UnloadFullTray", "鏈哄櫒浜哄嵏杞芥弧Tray", true)] diff --git a/src/Bro.Common.Model/Helper/UIHelper.cs b/src/Bro.Common.Model/Helper/UIHelper.cs index 8040fd0..2a0c8f9 100644 --- a/src/Bro.Common.Model/Helper/UIHelper.cs +++ b/src/Bro.Common.Model/Helper/UIHelper.cs @@ -14,21 +14,30 @@ { cbo.DataSource = dataSource; cbo.DisplayMember = display; - cbo.ValueMember = value; + if (!string.IsNullOrWhiteSpace(value)) + { + cbo.ValueMember = value; + } } public static void SetCombo(ToolStripComboBox cbo, object dataSource, string display, string value) { cbo.ComboBox.DataSource = dataSource; cbo.ComboBox.DisplayMember = display; - cbo.ComboBox.ValueMember = value; + if (!string.IsNullOrWhiteSpace(value)) + { + cbo.ComboBox.ValueMember = value; + } } public static void SetCombo(DataGridViewComboBoxColumn cbo, object dataSource, string display, string value) { cbo.DataSource = dataSource; cbo.DisplayMember = display; - cbo.ValueMember = value; + if (!string.IsNullOrWhiteSpace(value)) + { + cbo.ValueMember = value; + } } } diff --git a/src/Bro.Common.Model/Interface/IStationConfig.cs b/src/Bro.Common.Model/Interface/IStationConfig.cs index 3e35fba..0531cc1 100644 --- a/src/Bro.Common.Model/Interface/IStationConfig.cs +++ b/src/Bro.Common.Model/Interface/IStationConfig.cs @@ -73,7 +73,7 @@ /// 鎿嶄綔閰嶇疆鐨勫瓧鍏搁泦鍚� /// Key锛歁ethodCode锛孷alue锛氭搷浣滈厤缃� /// </summary> - //Dictionary<string, IOperationConfig> ProcessOpConfigDict { get; set; } + Dictionary<string, IOperationConfig> ProcessOpConfigDict { get; set; } ///// <summary> ///// 浠版媿鐩告満鏍囧畾鐭╅樀 @@ -104,7 +104,7 @@ ///// 浠版媿鐩告満鎷嶆憚鐨勫す鍏峰伐浠剁殑鏃嬭浆涓績鍥惧儚鍧愭爣 ///// </summary> //CustomizedPoint RotationCenter { get; set; } - + /// <summary> /// 鏄惁杈撳嚭CSV鏂囦欢 /// </summary> diff --git a/src/Bro.Device.SeerAGV/SeerAGVConfig.cs b/src/Bro.Device.SeerAGV/SeerAGVConfig.cs index 989fea4..a094f0c 100644 --- a/src/Bro.Device.SeerAGV/SeerAGVConfig.cs +++ b/src/Bro.Device.SeerAGV/SeerAGVConfig.cs @@ -36,6 +36,38 @@ [Category("鐩戝惉閰嶇疆")] [Description("鏄惁閲囩敤绠�鍗曠洃鍚ā寮忋�倀rue锛氱畝鍗曟ā寮忥紝鍙幏鍙栦换鍔$姸鎬侊紱false锛氬叏閮ㄦā寮忥紝鑾峰彇浠诲姟鎵�鏈変俊鎭�")] public bool IsSimpleMonitor { get; set; } = true; + + private float batteryLvlToCharge = 0.1f; + [Category("鍏呯數閰嶇疆")] + [Description("鍏呯數鐢垫睜瀹归噺锛岀數姹犲閲忎綆浜庤鍊兼椂闇�瑕佸厖鐢�")] + public float BatteryLvlToCharge + { + get => batteryLvlToCharge; + set + { + if (value >= 1 || value <= 0) + { + value = 0.1f; + } + batteryLvlToCharge = value; + } + } + + private float batteryLvlChargeDone = 0.9f; + [Category("鍏呯數閰嶇疆")] + [Description("鍏呯數瀹屾垚鐢垫睜瀹归噺锛岀數姹犲閲忛珮浜庤鍊兼椂纭鍏呯數瀹屾垚")] + public float BatteryLvlChargeDone + { + get => batteryLvlChargeDone; + set + { + if (value >= 1 || value <= 0) + { + value = 0.9f; + } + batteryLvlChargeDone = value; + } + } } [Device("SeerAGV", "SeerAGV", EnumHelper.DeviceAttributeType.OperationConfig)] @@ -138,6 +170,8 @@ CancelTask = 0x0BBB, PauseTask = 0x0BB9, TaskOrder = 0x0BEB, + + QueryBattery = 0x2AFF, } public enum AGVTaskStatus diff --git a/src/Bro.Device.SeerAGV/SeerAGVDriver.cs b/src/Bro.Device.SeerAGV/SeerAGVDriver.cs index fdb4428..635132e 100644 --- a/src/Bro.Device.SeerAGV/SeerAGVDriver.cs +++ b/src/Bro.Device.SeerAGV/SeerAGVDriver.cs @@ -19,6 +19,7 @@ { public Action<SeerAGVDriver, string> OnAGVPositoinChanged; public Action<SeerAGVDriver, AGVTaskStatus> OnAGVTaskStatusChanged; + public Action<SeerAGVDriver, float> OnAGVBatteryLvlChanged; SeerAGVInitialConfig IConfig { @@ -64,6 +65,7 @@ { 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 }) : ""); Task.Run(() => { @@ -76,7 +78,7 @@ if (client_Guide != null && client_Guide.Connected) { CancelTask(); - client_Guide.Close(); + client_Guide.Close(); client_Guide = null; } @@ -142,8 +144,23 @@ } } + float batteryLvl = 0; + public float BatteryLvl + { + get => batteryLvl; + set + { + if (batteryLvl != value) + { + batteryLvl = value; + OnAGVBatteryLvlChanged?.Invoke(this, batteryLvl); + } + } + } + SeerMessage msg_Position = new SeerMessage(); SeerMessage msg_GuideStatus = new SeerMessage(); + SeerMessage msg_Battery = new SeerMessage(); private void MonitorAGV() { while (CurrentState != EnumHelper.DeviceState.DSClose && CurrentState != EnumHelper.DeviceState.DSExcept) @@ -153,6 +170,8 @@ SendMsg(client_State, IConfig.StatusPort, msg_Position); Thread.Sleep(IConfig.ScanInterval); SendMsg(client_State, IConfig.StatusPort, msg_GuideStatus); + Thread.Sleep(IConfig.ScanInterval); + SendMsg(client_State, IConfig.StatusPort, msg_Battery); Thread.Sleep(IConfig.ScanInterval); } catch (Exception ex) @@ -231,6 +250,9 @@ case (int)AGVCode.QueryTaskStatus: TaskStatus = (AGVTaskStatus)recMsg.JValues.Value<int>("task_status"); break; + case (int)AGVCode.QueryBattery: + BatteryLvl = recMsg.JValues.Value<float>("battery_level"); + break; default: break; } -- Gitblit v1.8.0