|
@@ -1040,7 +1040,9 @@ namespace TeamAAS_VP.Core
|
|
|
/// 移动向下相机拍照结果
|
|
/// 移动向下相机拍照结果
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
OpenCvSharp.Point3f[] UpCameraPutResults = new OpenCvSharp.Point3f[10];
|
|
OpenCvSharp.Point3f[] UpCameraPutResults = new OpenCvSharp.Point3f[10];
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// 二次定位相机的工具坐标
|
|
/// 二次定位相机的工具坐标
|
|
|
/// </summary>
|
|
/// </summary>
|
|
@@ -1621,7 +1623,63 @@ namespace TeamAAS_VP.Core
|
|
|
SendTaskMessage($"触发固定相机锁附/组装拍照...", MessageLevel.Debug);
|
|
SendTaskMessage($"触发固定相机锁附/组装拍照...", MessageLevel.Debug);
|
|
|
//相机的编号
|
|
//相机的编号
|
|
|
//Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameraPutNum.Address);
|
|
//Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameraPutNum.Address);
|
|
|
|
|
+ if (currentProduct.IndependentCamer1ProductProcedureId == Guid.Empty)
|
|
|
|
|
+ {
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (currentProduct.IndependentCamer2ProductProcedureId == Guid.Empty)
|
|
|
|
|
+ {
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (currentProduct.IndependentCamer3ProductProcedureId == Guid.Empty)
|
|
|
|
|
+ {
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (currentProduct.IndependentCamer4ProductProcedureId == Guid.Empty)
|
|
|
|
|
+ {
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ //获取四个独立相机的流程id
|
|
|
|
|
+ var process1 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer1ProductProcedureId);
|
|
|
|
|
+ var process2 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer2ProductProcedureId);
|
|
|
|
|
+ var process3 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer3ProductProcedureId);
|
|
|
|
|
+ var process4 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer4ProductProcedureId);
|
|
|
|
|
+
|
|
|
|
|
+ // 执行视觉任务
|
|
|
|
|
+ var _cts = new CancellationTokenSource();
|
|
|
|
|
+ var task1 = _remoteCommandService.ExecutePhotoGetSinglePoint(process1, null, null, _cts.Token);
|
|
|
|
|
+ var task2 = _remoteCommandService.ExecutePhotoGetSinglePoint(process2, null, null, _cts.Token);
|
|
|
|
|
+ var task3 = _remoteCommandService.ExecutePhotoGetSinglePoint(process3, null, null, _cts.Token);
|
|
|
|
|
+ var task4 = _remoteCommandService.ExecutePhotoGetSinglePoint(process4, null, null, _cts.Token);
|
|
|
|
|
+
|
|
|
|
|
+ var visionResults = await Task.WhenAll(task1, task2, task3, task4);
|
|
|
|
|
+ if (visionResults[0].IsSucceed && visionResults[1].IsSucceed && visionResults[2].IsSucceed && visionResults[3].IsSucceed)
|
|
|
|
|
+ {
|
|
|
|
|
+ Vector<double> p1=Vector<double>.Build.Dense(new double[] { visionResults[0].X, visionResults[0].Y });
|
|
|
|
|
+ Vector<double> p2=Vector<double>.Build.Dense(new double[] { visionResults[1].X, visionResults[1].Y });
|
|
|
|
|
+ Vector<double> p3=Vector<double>.Build.Dense(new double[] { visionResults[2].X, visionResults[2].Y });
|
|
|
|
|
+ Vector<double> p4=Vector<double>.Build.Dense(new double[] { visionResults[3].X, visionResults[3].Y });
|
|
|
|
|
+
|
|
|
|
|
+ var center = RectangleCenterCalculator.CalculateByPCAWithKnownOrder(new List<Vector<double>> { p1, p2, p4, p3 });
|
|
|
|
|
+ UpCameraPutResults[0].X = (float)center.Center[0];
|
|
|
|
|
+ UpCameraPutResults[0].Y = (float)center.Center[1];
|
|
|
|
|
+ UpCameraPutResults[0].Z= (float)center.MajorAxisAngle;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ if (isDryMode)
|
|
|
|
|
+ {
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)1);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)1);
|
|
await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)1);
|
|
|
}
|
|
}
|
|
@@ -1643,6 +1701,63 @@ namespace TeamAAS_VP.Core
|
|
|
//相机的编号
|
|
//相机的编号
|
|
|
//Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameracheckNum.Address);
|
|
//Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameracheckNum.Address);
|
|
|
|
|
|
|
|
|
|
+ if (currentProduct.IndependentCamer1AuxProcedureId == Guid.Empty)
|
|
|
|
|
+ {
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)2);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (currentProduct.IndependentCamer2AuxProcedureId == Guid.Empty)
|
|
|
|
|
+ {
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)2);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (currentProduct.IndependentCamer3AuxProcedureId == Guid.Empty)
|
|
|
|
|
+ {
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)2);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (currentProduct.IndependentCamer4AuxProcedureId == Guid.Empty)
|
|
|
|
|
+ {
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)2);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //获取四个独立相机的流程id
|
|
|
|
|
+ var process1 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer1AuxProcedureId);
|
|
|
|
|
+ var process2 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer2AuxProcedureId);
|
|
|
|
|
+ var process3 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer3AuxProcedureId);
|
|
|
|
|
+ var process4 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer4AuxProcedureId);
|
|
|
|
|
+
|
|
|
|
|
+ // 执行视觉任务
|
|
|
|
|
+ var _cts = new CancellationTokenSource();
|
|
|
|
|
+ var task1 = _remoteCommandService.ExecutePhotoGetSinglePoint(process1, null, null, _cts.Token);
|
|
|
|
|
+ var task2 = _remoteCommandService.ExecutePhotoGetSinglePoint(process2, null, null, _cts.Token);
|
|
|
|
|
+ var task3 = _remoteCommandService.ExecutePhotoGetSinglePoint(process3, null, null, _cts.Token);
|
|
|
|
|
+ var task4 = _remoteCommandService.ExecutePhotoGetSinglePoint(process4, null, null, _cts.Token);
|
|
|
|
|
+
|
|
|
|
|
+ var visionResults = await Task.WhenAll(task1, task2, task3, task4);
|
|
|
|
|
+ if (visionResults[0].IsSucceed && visionResults[1].IsSucceed && visionResults[2].IsSucceed && visionResults[3].IsSucceed)
|
|
|
|
|
+ {
|
|
|
|
|
+ Vector<double> p1 = Vector<double>.Build.Dense(new double[] { visionResults[0].X, visionResults[0].Y });
|
|
|
|
|
+ Vector<double> p2 = Vector<double>.Build.Dense(new double[] { visionResults[1].X, visionResults[1].Y });
|
|
|
|
|
+ Vector<double> p3 = Vector<double>.Build.Dense(new double[] { visionResults[2].X, visionResults[2].Y });
|
|
|
|
|
+ Vector<double> p4 = Vector<double>.Build.Dense(new double[] { visionResults[3].X, visionResults[3].Y });
|
|
|
|
|
+
|
|
|
|
|
+ var center = RectangleCenterCalculator.CalculateByPCAWithKnownOrder(new List<Vector<double>> { p1, p2, p4, p3 });
|
|
|
|
|
+ UpCameraPutResults[1].X = (float)center.Center[0];
|
|
|
|
|
+ UpCameraPutResults[1].Y = (float)center.Center[1];
|
|
|
|
|
+ UpCameraPutResults[1].Z = (float)center.MajorAxisAngle;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ if (isDryMode)
|
|
|
|
|
+ {
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)1);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)2);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)1);
|
|
await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)1);
|
|
|
}
|
|
}
|
|
@@ -1741,6 +1856,7 @@ namespace TeamAAS_VP.Core
|
|
|
if (state == 1)
|
|
if (state == 1)
|
|
|
{
|
|
{
|
|
|
SendTaskMessage($"收到多相机坐标合并请求,开始合并...", MessageLevel.Debug);
|
|
SendTaskMessage($"收到多相机坐标合并请求,开始合并...", MessageLevel.Debug);
|
|
|
|
|
+
|
|
|
if (isDryMode)
|
|
if (isDryMode)
|
|
|
{
|
|
{
|
|
|
var point1 = currentProduct.ScrewPoints[0].Clone();
|
|
var point1 = currentProduct.ScrewPoints[0].Clone();
|
|
@@ -1751,31 +1867,33 @@ namespace TeamAAS_VP.Core
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- double upCameraX = 0, upCameraY = 0, upCameraU = 0;
|
|
|
|
|
- upCameraX = UpCameraPutResults[1].X;
|
|
|
|
|
- upCameraY = UpCameraPutResults[1].Y;
|
|
|
|
|
- upCameraU = UpCameraPutResults[1].Z;
|
|
|
|
|
- //如果下相机拍照的次数是1,则判断用时拍照的相机是几个
|
|
|
|
|
- int upCameraNum = _configService.GetSystemConfiguration().UpCameraPutNum;
|
|
|
|
|
- if (upCameraNum == 2)
|
|
|
|
|
|
|
+ // 获取机器人当前坐标
|
|
|
|
|
+ var robot = _robotService.GetAllRobots().FirstOrDefault();
|
|
|
|
|
+ if (robot == null)
|
|
|
{
|
|
{
|
|
|
- upCameraX = (UpCameraPutResults[1].X + UpCameraPutResults[2].X) / 2;
|
|
|
|
|
- upCameraY = (UpCameraPutResults[1].Y + UpCameraPutResults[2].Y) / 2;
|
|
|
|
|
- upCameraU = Common.CalculateAngleBetweenPointsDegrees(new PointF((float)UpCameraPutResults[1].X, (float)UpCameraPutResults[1].Y), new PointF((float)UpCameraPutResults[2].X, (float)UpCameraPutResults[2].Y));
|
|
|
|
|
|
|
+ SendTaskMessage($"未找到机器人,无法执行上相机锁附/组装拍照视觉任务", MessageLevel.Alarm);
|
|
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
|
|
|
|
|
+ return;
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
+ var currentPosition = robot.GetRobotPos();
|
|
|
|
|
|
|
|
- var point = currentProduct.ScrewPoints[0].Clone();
|
|
|
|
|
- var pn = Vector<double>.Build.Dense(new double[] { upCameraX, upCameraY });
|
|
|
|
|
- //目标角度:
|
|
|
|
|
- double angle = point.U_Position + (DowmCameraResults[1].Z - currentProduct.FixedUpCameraTempletAngle) + (upCameraU - currentProduct.MoveDownCamerTempletAngle);
|
|
|
|
|
|
|
+ //以LCD的中线创建工具坐标
|
|
|
|
|
+ ToolCoord toolCoord = new ToolCoord();
|
|
|
|
|
+ toolCoord.SetTool(UpCameraPutResults[1].X, UpCameraPutResults[1].Y);
|
|
|
|
|
|
|
|
- var toolCoord = new ToolCoord();
|
|
|
|
|
- toolCoord.SetTool(DowmCameraResults[1].X, DowmCameraResults[1].Y);
|
|
|
|
|
- //将_PutPoint转换为Tool0下要走的点
|
|
|
|
|
|
|
+
|
|
|
|
|
+ //计算放料角度
|
|
|
|
|
+ double angle= currentPosition.U - DowmCameraResults[1].Z + DowmCameraResults[0].Z;
|
|
|
|
|
+
|
|
|
|
|
+ //将产品的中心点坐标转换为Tool0下的坐标
|
|
|
|
|
+ var point = currentProduct.ScrewPoints[0].Clone();
|
|
|
|
|
+ var pn = Vector<double>.Build.Dense(new double[] { DowmCameraResults[0].X, DowmCameraResults[0].Y });
|
|
|
var p0 = toolCoord.GetTool0Coord(pn, angle);
|
|
var p0 = toolCoord.GetTool0Coord(pn, angle);
|
|
|
point.X_Position = (float)p0[0];
|
|
point.X_Position = (float)p0[0];
|
|
|
point.Y_Position = (float)p0[1];
|
|
point.Y_Position = (float)p0[1];
|
|
|
point.U_Position = (float)angle;
|
|
point.U_Position = (float)angle;
|
|
|
|
|
+
|
|
|
SendTaskMessage($"点:1,{point.X_Position:F3},{point.Y_Position:F4},{point.U_Position:F4}", MessageLevel.Info);
|
|
SendTaskMessage($"点:1,{point.X_Position:F3},{point.Y_Position:F4},{point.U_Position:F4}", MessageLevel.Info);
|
|
|
await point.WriteToPlcAddress(addressConfig.Out_Screw, plc);
|
|
await point.WriteToPlcAddress(addressConfig.Out_Screw, plc);
|
|
|
await plc.WriteNodeAsync(addressConfig.Out_WorkNum.Address, (Int16)1);
|
|
await plc.WriteNodeAsync(addressConfig.Out_WorkNum.Address, (Int16)1);
|