using A032.Process.Calibration; using Bro.Common.Base; 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, 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("未能获取正确位置信息"); } 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() { 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() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary() { { "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() { 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() { matrix[0], matrix[1], 0, matrix[3], matrix[4], 0 }, // }); //} return new ProcessResponse(true); } [ProcessMethod("CalibrationCollection", "StandardPointCalibration", "标准点位标定", true)] public ProcessResponse StandardPointCalibration(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("未能获取正确位置信息"); } if (calibConfig.Configs.Count < 1) { throw new ProcessException("请至少配置1个标定点位"); } 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++) //{ // bind.Robot.SendMsg(Bro.Device.AuboRobot.RobotMsgAction.Calibration, Bro.Device.AuboRobot.RobotMsgParas.None, calibConfig.PositionNo, new List() { 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() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary() { { "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 matrix = GetMovementMatrix(calibConfig.Configs.Select(u => u.ImageMarkPoint as CustomizedPoint).ToList(), calibConfig.Configs.Select(u => u.CurrentPlatPoint).ToList(), out string msg); var visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.CameraId == bind.CameraId && u.PositionCode == position.PositionCode); if (visionConfig != null) { visionConfig.Matrix = new List() { 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() { matrix[0], matrix[1], 0, matrix[3], matrix[4], 0 }, }); } PubSubCenter.Publish(PubTag.CalibAllDone.ToString(), "", msg, true); } /// /// 获取标定点的转换矩阵 /// /// /// protected List GetMovementMatrix(List imagePoints, List 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 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) //{ // throw new ProcessException("未能获取绑定设备信息"); //} //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == calibConfig.PositionNo); //if (position == null) //{ // throw new ProcessException("未能获取正确位置信息"); //} 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 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() { 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 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() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary() { { "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(); } }